Run plans and local execution
RunPlan is the wire-format boundary between simulation intent and an execution
backend. It combines a SimulationSpec, deterministic seed, resource requirements,
tracked-run identity, and references to runtime services. Plans contain no JAX
arrays, live clients, callables, or credentials and round-trip through canonical
JSON:
from adept import (
AcceleratorKind,
LocalExecutor,
ResourceRequirements,
RunPlan,
RunRequest,
ServiceReference,
SimulationSpec,
)
plan = RunPlan(
simulation=SimulationSpec.from_legacy_config(config),
seed=42,
resources=ResourceRequirements(accelerator=AcceleratorKind.CPU),
run=RunRequest(experiment="local", run_id="example-42"),
artifact_sink=ServiceReference("directory", {"root": "./adept-results"}),
)
payload = plan.to_json()
restored = RunPlan.from_json(payload)
with LocalExecutor() as executor:
completed = executor.execute(restored)
LocalExecutor.validate checks the solver’s import-light registry declaration,
topology, precision, requested features, and tracker/artifact adapters before it
loads the solver builder. Submission passes a serialized copy to the worker, which
performs JAX precision bootstrap before importing a JAX-dependent builder. The
prepared solver’s actual capabilities are checked again before numerical execution.
An individual configuration may narrow differentiable from true to false
(for example, FARSIGHT’s dynamic tree walk). A run requiring differentiation
then fails at this prepared check, before numerical execution. All other
prepared capability fields must still match the registry declaration exactly;
preparation cannot add undeclared differentiability or change bootstrap requirements.
The local adapter supports null or MLflow tracking and null, directory, or MLflow
artifact sinks. MLflow modules are imported only when an MLflow reference is
selected. A directory sink implies the artifact-access requirement and is
preflighted by the host runtime before the solve.
Capability requirements
ResourceRequirements describes placement, precision, accelerator kind, host count,
devices per host, and optional features. Multi-host placement automatically requires
distributed-jax. Other typed features cover shared durable storage, rank-zero I/O,
checkpointing, differentiability, batching, and artifact access. Unsupported
requirements fail together in one actionable preflight error.
Built-in solver capabilities are registered without importing their builders. This lets an executor discover that TF1D and PIC1D require x64 and configure a fresh JAX worker before solver import. If JAX was already initialized with x64 disabled, local execution fails instead of silently running at the wrong precision.
Service configuration may contain locations such as directory roots and tracking URIs. Credential-like fields are rejected. Configure credentials in the worker environment, an AWS profile, or the backend’s normal credential provider instead of embedding them in a plan.
Submission lifecycle
submit returns an ExecutionHandle. status, cancel, and result operate on
that explicit handle; execute is the blocking submit-and-result convenience. A
local run can be cancelled while queued, but an already-running JAX call is not
interruptible.
Checkpoint store references and policies are serialized in schema version 2. Active
policies request the checkpointing capability; multi-host checkpointing also
requests shared durable storage and rank-zero I/O. See Versioned checkpoints
for the initial store contract and current executor-integration boundary.
This is the first executor slice. Parsl submission, collective multi-host JAX, external-process execution, retry/chunk policy, and managed checkpoint scheduling will use the same serialized plan and executor lifecycle in follow-up work.