Serve mode

Added in version 2.2.

conda-forge availability

Included in the conda-forge package (v2.12+). No additional build flags required.

Serve mode makes eOn the Cap’n Proto RPC server: it wraps any eOn potential as an rgpot-compatible endpoint so external tools (e.g. ChemGP) can evaluate energies and forces without embedding C++.

The three roles (in-process RGPOT, this RPC server, potserv client) are in rgpot integration.

Compilation

Serve mode requires the with_serve build option and a Cap’n Proto installation. The serve pixi environment provides all necessary dependencies:

pixi run -e serve bash
meson setup builddir -Dwith_serve=true
meson compile -C builddir

To also enable Metatomic (ML) potentials:

meson setup builddir \
    -Dwith_serve=true \
    -Dwith_metatomic=true \
    -Dpip_metatomic=true \
    -Dtorch_version=2.9
meson compile -C builddir

Usage

Serve mode supports four modes of operation: single-potential, replicated, --gateway pool, and multi-model. Each mode is selected by the combination of CLI flags provided.

Single potential

The simplest usage serves one potential on a single port:

eonclient -p lj --serve-port 12345

This starts a blocking RPC server on localhost:12345 serving the Lennard-Jones potential. The server runs until interrupted with Ctrl+C.

To bind to all interfaces:

eonclient -p lj --serve-host 0.0.0.0 --serve-port 12345

Replicated

To start multiple copies of the same potential on sequential ports:

eonclient -p lj --serve-port 12345 --replicas 4

This starts 4 independent servers on ports 12345 through 12348, each with its own potential instance and event loop. Useful when clients can load-balance across known ports.

Gateway pool

--gateway exposes a single port backed by a pool of potential instances. Incoming requests are dispatched round-robin across the pool, so clients only need to know one address:

eonclient -p lj --serve-port 12345 --replicas 6 --gateway

This creates 6 LJ potential instances and serves them all behind port 12345. Each incoming RPC call is routed to the next available instance. This is the recommended mode for high-throughput use cases where clients should not need to track multiple ports.

Multi-model

The --serve flag accepts a comma-separated specification of potential:port or potential:host:port pairs, each served concurrently in its own thread:

eonclient --serve "lj:12345,eam_al:12346"

With explicit hosts:

eonclient --serve "lj:0.0.0.0:12345,eam_al:0.0.0.0:12346"

Potential configuration

Potentials that require parameters (Metatomic, XTB, etc.) can be configured via the --config flag, which loads an INI-format config file:

eonclient --serve "metatomic:12345" --config model.ini

The config file uses the same INI format as eOn’s standard config.ini. For example, a Metatomic model:

[Metatomic]
model_path = /path/to/model.pt
device = cuda
length_unit = angstrom

Or for XTB:

[XTBPot]
paramset = GFN2xTB
accuracy = 1.0

Config-driven serve

The [Serve] section selects host, port, replicas, and gateway_port without CLI flags beyond --config:

[Potential]
potential = lj

[Serve]
host = localhost
port = 12345
replicas = 4
gateway_port = 0
eonclient --config serve.ini

The dispatch logic when serving from config:

  1. If endpoints is set, each endpoint is served in its own thread.

  2. If gateway_port > 0, a single pool port is opened backed by a pool of replicas potential instances.

  3. Otherwise, replicas independent servers are started on sequential ports beginning at port.

Examples

--gateway with a Metatomic model:

[Potential]
potential = metatomic

[Metatomic]
model_path = /path/to/model.pt
device = cuda

[Serve]
host = 0.0.0.0
gateway_port = 12345
replicas = 6

Multi-model endpoints:

[Serve]
endpoints = lj:12345,eam_al:12346,metatomic:0.0.0.0:12347

[Metatomic]
model_path = /path/to/model.pt

Configuration

[Serve]
pydantic model eon.schema.ServeConfig[source]
Fields:
  • host (str)

  • port (int)

  • replicas (int)

  • gateway_port (int)

  • endpoints (str)

field host: str = 'localhost'

Hostname to bind serve mode RPC servers to.

field port: int = 12345

TCP port for single-potential or replicated serve mode.

field replicas: int = 1

Number of replicated server instances. In gateway mode, this is the pool size.

field gateway_port: int = 0

If > 0, start a single gateway on this port backed by a pool of ‘replicas’ potential instances dispatched round-robin. Set to 0 to disable gateway mode.

field endpoints: str = ''

Multi-model serve spec: comma-separated ‘potential:port’ or ‘potential:host:port’ entries. When set, overrides single-potential serve.

JSON configuration

Added in version 2.12.

Parameters can also be loaded from JSON strings programmatically, enabling serve mode clients to send configuration without INI files:

Parameters params;
params.load_json(R"({
  "Potential": {"potential": "LJ"},
  "Serve": {"host": "0.0.0.0", "port": 12345, "replicas": 4}
})");

The JSON format mirrors the INI section/key structure. See Parameters system for the full schema.

Protocol

The RPC protocol is defined by rgpot’s Potentials.capnp schema. Each request sends:

  • positions: flat array [x1, y1, z1, x2, y2, z2, ...] (Angstroms)

  • atmnrs: atomic numbers [Z1, Z2, ...]

  • box: 3x3 cell matrix (row-major flat array)

Each response returns:

  • energy: total potential energy (eV)

  • forces: flat array matching positions layout (eV/Angstrom)

Integration with ChemGP

ChemGP connects to serve mode via its RpcPotential oracle:

using ChemGP

# Connect to a running eonclient --serve instance
pot = RpcPotential("localhost", 12345, atmnrs, box)
E, F = ChemGP.calculate(pot, positions)

# Use as a GP optimization oracle (gradient = -forces)
oracle = make_rpc_oracle(pot)

See the ChemGP RPC tutorial for details.

Architecture notes

The serve mode uses a ForceCallback (flat-array std::function) interface internally, completely decoupling the eOn potential from the capnp server. This avoids a type collision between eOn’s Eigen-based AtomMatrix and rgpot’s custom AtomMatrix by never allowing both types to coexist in the same translation unit. The capnp schema code is compiled in a separate TU (ServeRpcServer.cpp) from the eOn potential wrapper (ServeMode.cpp). For more on the integration pattern, see the rgpot integration guide.

Command reference

Flag

Description

--serve <spec>

Multi-model serve spec: pot:port or pot:host:port, comma-separated

--serve-host <host>

Host for single-potential mode (default: localhost)

--serve-port <port>

Port for single-potential mode with -p (default: 12345)

--replicas <N>

Number of server instances or --gateway pool size (default: 1)

--gateway

Single port, round-robin pool

--config <file>

INI config file for potential and serve parameters

-p <potential>

Potential type (used with --serve-port)