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:
If
endpointsis set, each endpoint is served in its own thread.If
gateway_port > 0, a single pool port is opened backed by a pool ofreplicaspotential instances.Otherwise,
replicasindependent servers are started on sequential ports beginning atport.
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 replicas: int = 1¶
Number of replicated server instances. In gateway mode, this is the pool size.
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 |
|---|---|
|
Multi-model serve spec: |
|
Host for single-potential mode (default: |
|
Port for single-potential mode with |
|
Number of server instances or |
|
Single port, round-robin pool |
|
INI config file for potential and serve parameters |
|
Potential type (used with |