Skip to main content

ASE - Remote Procedure Call

Project description

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

  1. Start the broker:
aserpc broker
  1. 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,
}
  1. Start a worker:
aserpc worker LJ # optional --registry tmp/registry.py:CALCULATORS
  1. 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

  1. Client requests a calculator with no available workers
  2. Broker forwards spawn request to Manager
  3. Manager spawns a worker process using configured command
  4. Worker registers with broker and handles the request
  5. 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

  1. 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,
        ),
    }
  1. Register via entry points:
# pyproject.toml
[project.entry-points."aserpc.spawn"]
mypackage = "mypackage.aserpc:get_spawn_configs"
  1. 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
  1. 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: RemoteCalculator acts 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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aserpc-0.1.3.tar.gz (120.0 kB view details)

Uploaded Source

File details

Details for the file aserpc-0.1.3.tar.gz.

File metadata

  • Download URL: aserpc-0.1.3.tar.gz
  • Upload date:
  • Size: 120.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for aserpc-0.1.3.tar.gz
Algorithm Hash digest
SHA256 d63f5560b3cb99c2835706460bcd8e2d699b0ea082fea3824a2805d9c767919f
MD5 2238d16afd7cec8779043debe76e9ebf
BLAKE2b-256 e69dc8da7160fc3d2ed8fb82c9b0a56e3ff02b66503d9158505b2b6a26b5eeb7

See more details on using hashes here.

Provenance

The following attestation bundles were made for aserpc-0.1.3.tar.gz:

Publisher: publish.yaml on zincware/aserpc

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page