Skip to main content

Running graphs

app.run(**options) writes the graph JSON to a temp file and launches the Tomii runtime binary. Every keyword maps 1:1 to a CLI flag of the same name (workers--workers). The tables below come from python -m tomii --list-knobs; the same list, with search hints, is in the knob catalog reference.

What a frame is, and what slots are

A frame is one unit of input — the runtime executes the graph once per frame. In packet-driven graphs a frame is the group of packets that triggers one execution; in generated workloads it is simply the Nth run of the graph. Over a run, Tomii processes a stream of frames.

A slot holds the in-flight execution state for one frame: result buffers, dependency counters, and per-node instances. With slots=1 frames run one at a time, which minimizes latency. With slots=N up to N frames execute concurrently and slot state is reused generationally between frames, which raises throughput.

Integer options

OptionCLI flagMeaning
workers--workersRayon worker threads (match physical cores)
core_offset--core-offsetFirst CPU to pin workers to (use 1 to leave CPU 0 for the OS)
system_threads--system-threadsResolution/scheduler threads (default 1)
receiver_threads--receiver-threadsDedicated network receiver threads
slots--slotsConcurrent in-flight frames
max_frames--max-framesTotal frames to process (0 = run indefinitely)
max_runtime--max-runtimeStop after N seconds (0 = run until max_frames complete)
batching_size--batching-sizeMax tasks per scheduler batch
batching_limit--batching-limitMax outstanding batches before back-pressure
exclude_frames--exclude-framesSkip the first N frames from timing output
record_frame--record-frameRecord timing for one frame index only

Boolean options

OptionCLI flagMeaning
fifo--fifoFIFO task scheduling instead of the default depth-first
custom--customCustom scheduling strategy
slot_priority--slot-priorityPrioritize tasks from the earliest active slot
coalesce_barriers--coalesce-barriersBatch barrier fan-outs into bulk tasks
inline_continuation--inline-continuationRun single-successor tasks inline
inits--initsRe-run graph initializations on each frame
record--recordEnable timing/event recording to file
use_rdtsc--use-rdtscRDTSC for sub-microsecond timing (x86 only)
debug--debugVerbose debug output

Output options

OptionCLI flagMeaning
output--outputRaw timing output file
timing--timingPer-node timing CSV
report--reportJSON summary report
dump_state--dump-stateRuntime state snapshot at shutdown

run() also accepts env={...}, a dict of environment variables passed to the runtime process. The matrix-compute example uses it to pass SCRIPT_DIR so the plugin can resolve its output path.

The report

Pass report="report.json" to get a structured performance report after each run. Its keys (from the repository README.md):

KeyContent
summary.avg_latency_us / p50 / p99Frame latency statistics
summary.throughput_frames_per_secEnd-to-end throughput
summary.scheduling_overhead_diagnosticoverhead_pct, overhead_us, interpretation
per_nodePer-node avg/p99 exec time, on_critical_path flag
optimization_suggestionsPrioritized list: category, action, knob, estimated speedup

The report is the input to the tuning workflow — see Observability and Runtime knobs.

Running without Python

The runtime binary takes the same flags directly:

cargo run -p tomii-core --bin main -- \
--json graph.json --dylib plugin.so \
--workers 4 --slots 2 --max-frames 100

See the CLI reference for the full flag list.