ASE - Remote Procedure Call
A lightweight RPC framework for serving ASE (Atomic Simulation Environment) calculators over ZeroMQ.
This package is primarily designed to run MLIP calculators in dedicated python environments to handle dependency conflicts or for multi-GPU distribution.
Quick Start
- Start the broker:
aserpc broker
- Check available calculators:
aserpc list
# or
aserpc list --registry tmp/registry.py:CALCULATORS
A registry file (or module via pck.registry:CALCULATORS) example:
# tmp/registry.py
from ase.calculators.lj import LennardJones
# Registry: name -> calculator factory
CALCULATORS = {
"LJ": LennardJones,
}
- Start a worker:
aserpc worker LJ # optional --registry tmp/registry.py:CALCULATORS
- Use the remote calculator:
from aserpc import RemoteCalculator
from ase.build import molecule
water = molecule("H2O")
water.calc = RemoteCalculator("LJ")
energy = water.get_potential_energy()
# With retries for fault tolerance (retries=1 means 1 retry on failure, 2 total attempts)
water.calc = RemoteCalculator("LJ", retries=2)
Calculator Discovery
Workers discover calculators through Python entry point providers. This allows packages to register calculators that aserpc can automatically find.
Provider Functions
Register a provider function that returns calculator metadata:
# pyproject.toml
[project.entry-points."aserpc.calculators"]
mypackage = "mypackage.aserpc:get_calculators"
# mypackage/aserpc.py
import importlib.util
def get_calculators() -> dict[str, dict]:
"""Return metadata for available calculators.
Each entry is: {"factory": "module:class", "args": [...], "kwargs": {...}}
Use importlib.util.find_spec() to check availability without importing.
"""
calcs = {}
# Simple calculators (always available with ASE)
calcs["LJ"] = {"factory": "ase.calculators.lj:LennardJones"}
calcs["EMT"] = {"factory": "ase.calculators.emt:EMT"}
# Check if mace is installed (without importing torch!)
if importlib.util.find_spec("mace") is not None:
calcs["mace_mp"] = {
"factory": "mace.calculators:mace_mp",
"kwargs": {"model": "medium"},
}
# Check if chgnet is installed
if importlib.util.find_spec("chgnet") is not None:
calcs["chgnet"] = {"factory": "chgnet.model:CHGNetCalculator"}
return calcs
After installing the package, the new calculators should show up on aserpc list and can be started as workers:
aserpc worker LJ
aserpc worker mace_mp
Using a Registry File
Alternatively, specify a registry file with calculator factories:
# registry.py
from ase.calculators.lj import LennardJones
CALCULATORS = {
"LJ": LennardJones,
}
aserpc worker LJ --registry registry.py:CALCULATORS
Direct Module Import
You can also specify a calculator factory directly:
# Direct module:callable syntax
aserpc worker ase.calculators.lj:LennardJones
aserpc worker mace.calculators:mace_mp
# With kwargs for the factory
aserpc worker mace.calculators:mace_mp --kwargs '{"model": "medium"}'
aserpc worker mace.calculators:mace_mp --kwargs '{"model": "large", "device": "cuda"}'
# With a custom name for broker registration
aserpc worker mace.calculators:mace_mp --name mace_medium --kwargs '{"model": "medium"}'
aserpc worker mace.calculators:mace_mp --name mace_large --kwargs '{"model": "large"}'
# With positional args
aserpc worker my.module:Calculator --args '[1, 2]' --kwargs '{"key": "value"}'
This is particularly useful with uvx for running calculators without pre-installing them:
# Run MACE calculator directly with uvx
uvx --with mace-torch aserpc worker mace.calculators:mace_mp --kwargs '{"model": "medium"}'
# Run CHGNet
uvx --with chgnet aserpc worker chgnet.model:CHGNetCalculator
Listing Available Calculators
List all discoverable calculators:
# From entry points
aserpc list
# From a registry file
aserpc list --registry registry.py:CALCULATORS
# From a running broker
aserpc list --broker ipc:///tmp/aserpc/frontend.ipc
Scale-to-Zero with Manager
The Manager enables automatic worker spawning on demand, allowing scale-to-zero deployments where workers are only running when needed.
How It Works
- Client requests a calculator with no available workers
- Broker forwards spawn request to Manager
- Manager spawns a worker process using configured command
- Worker registers with broker and handles the request
- Worker auto-shuts down after idle timeout
flowchart TD
Client -->|REQUEST| Broker
Broker -->|SPAWN_REQUEST| Manager
Manager -->|spawns| Worker
Worker -->|READY| Broker
Broker -->|routes request| Worker
Worker -->|RESPONSE| Broker
Broker -->|RESPONSE| Client
Worker -->|idle timeout| Worker
Worker -->|DISCONNECT| Broker
Setup
- Create spawn configurations:
# mypackage/aserpc.py
from aserpc.spawn import SpawnConfig
def get_spawn_configs() -> dict[str, SpawnConfig]:
return {
"mace_mp": SpawnConfig(
name="mace_mp",
command=[
"uvx", "--with", "mace-torch", "aserpc", "worker",
"mace.calculators:mace_mp", "--kwargs", '{"model": "medium"}',
],
idle_timeout=120.0,
),
"lj": SpawnConfig(
name="lj",
command=["aserpc", "worker", "ase.calculators.lj:LennardJones", "--name", "lj"],
idle_timeout=60.0,
),
}
- Register via entry points:
# pyproject.toml
[project.entry-points."aserpc.spawn"]
mypackage = "mypackage.aserpc:get_spawn_configs"
- Start the broker and manager:
# Terminal 1: Start broker
aserpc broker
# Terminal 2: Start manager (discovers from entry points)
aserpc manager
# Or with explicit registry
aserpc manager --registry mypackage.aserpc:get_spawn_configs
- Use as normal - workers spawn automatically:
from aserpc import RemoteCalculator
from ase.build import molecule
# No workers running initially
water = molecule("H2O")
water.calc = RemoteCalculator("mace_mp")
energy = water.get_potential_energy() # Manager spawns worker on demand
SpawnConfig Options
SpawnConfig(
name="calc_name", # Calculator name (must match worker registration)
command=["cmd", "args"], # Command to spawn worker
env={"KEY": "value"}, # Additional environment variables
cwd="/path/to/workdir", # Working directory
idle_timeout=300.0, # Worker idle timeout in seconds
)
Command templates support variables:
{name}- Calculator name{broker}- Broker backend address{idle_timeout}- Idle timeout value
Example with templates:
SpawnConfig(
name="mace",
command=["aserpc", "worker", "{name}", "--broker", "{broker}", "--idle-timeout", "{idle_timeout}"],
)
Without a Manager
If no manager is running, the broker returns an error when no workers are available for a requested calculator.
Architecture
flowchart TD
Client <--> Broker <--> Worker1[Worker 1]
Broker <--> Worker2[Worker 2]
Broker <--> WorkerN[Worker N]
Manager -.->|spawns on demand| Worker1
Manager -.->|spawns on demand| Worker2
Broker <-->|SPAWN_REQUEST| Manager
- Broker: Routes requests to available workers, handles load balancing
- Worker: Runs calculator computations, sends heartbeats
- Client:
RemoteCalculatoracts as a drop-in ASE calculator - Manager: Spawns workers on demand for scale-to-zero deployments
Configuration
Configuration can be set via environment variables or pyproject.toml. Environment variables take precedence.
Environment Variables
| Variable | Default | Description |
|---|---|---|
ASERPC_IPC_DIR |
.aserpc (cwd) |
Directory for IPC sockets |
ASERPC_IPC_FRONTEND |
ipc://{IPC_DIR}/frontend.ipc |
Client socket address |
ASERPC_IPC_BACKEND |
ipc://{IPC_DIR}/backend.ipc |
Worker socket address |
ASERPC_WORKER_TIMEOUT |
30.0 | Seconds before broker considers worker dead |
ASERPC_HEARTBEAT_INTERVAL |
5.0 | Seconds between heartbeats |
ASERPC_IDLE_TIMEOUT |
300.0 | Seconds before idle worker shuts down |
ASERPC_REQUEST_QUEUE_TIMEOUT |
60.0 | Seconds before queued request expires |
ASERPC_CLIENT_TIMEOUT_MS |
60000 | Client timeout in milliseconds |
pyproject.toml
[tool.aserpc]
ipc_dir = "/tmp/aserpc"
worker_timeout = 30.0
heartbeat_interval = 5.0
idle_timeout = 300.0
request_queue_timeout = 60.0
client_timeout_ms = 60000
Metadata
Release files for aserpc 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aserpc-0.1.3.tar.gz | 120.0 kB | Details |
Release files / aserpc-0.1.3.tar.gz
| Download URL | aserpc-0.1.3.tar.gz |
|---|---|
| Size | 120.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d63f5560b3cb99c2835706460bcd8e2d699b0ea082fea3824a2805d9c767919f
|
|
BLAKE2b-256 checksum How to use checksums |
e69dc8da7160fc3d2ed8fb82c9b0a56e3ff02b66503d9158505b2b6a26b5eeb7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 4, 2025.
Transparency log