Skip to main content

Prototype streaming task graphs.
Run them at native speed.

Tomii is a Rust runtime for packet-driven streaming pipelines. Define the DAG in Python or JSON, mix Rust, C, and Python kernels in one graph, replay it across multiple concurrent frames, and let an agent tune it, verifier-gated, without recompiling.

import tomii as tm

app = tm.Graph()

buf = app.var("buf_size", 100)
plan = app.var("fft_planner", func="fft_planner", args=[buf])

gen = app.node("gen_vec", func="generate_vector",
factor=200, args=[buf])
fft = app.node("compute_fft", func="compute_fft",
factor=200, args=[plan, gen.out()])

app.build(func_path="plugin/src/lib.rs",
plugin_manifest="plugin/Cargo.toml")
app.run(workers=4, slots=2)

Tripartite Decoupling: Three artifacts, not one codebase

Streaming frameworks usually fuse what you compute, how each kernel is implemented, and how execution is organized into a single program. Tomii keeps them separate, so each one can change without touching the other two.

graph.json

Graph specification

Declarative, machine-readable, language-agnostic. Nodes, dependencies, barriers, network sources; nothing about how computation runs.

plugin.so

Kernel library

Rust, C, or Python functions compiled independently and loaded at runtime. The runtime never knows what language a kernel is written in.

CLI flags

Runtime control

Workers, slots, scheduler, batching; a bounded, documented control surface. Reconfigure execution without rebuilding anything.

Graphs are data

The topology is pure JSON: nodes, data dependencies ($res), barriers, and network sources ($network) as first-class argument types. The same compiled graph replays across up to 64 concurrent frame slots, with O(1) generational reset between frames; no per-frame graph reconstruction.

Building graphs
{
"name": "vec_mat",
"function": "vec_to_mat",
"factor": "num_nodes",
"args": [
{ "type": "$res",
"predecessor": { "name": "gen_vec" } },
{ "type": "$barrier",
"predecessor": { "name": "compute_fft" } }
]
}

Kernels are polyglot

Annotate a function in Rust, C, or Python and the build step generates the wrapper and registry entry. All three languages compose in one graph, referenced by name; the runtime never knows the kernel language.

One DAG, three languages
#[tomii_export]
pub fn generate_vector(n: usize) -> Vec<Complex32> {
functions::generate_vector(n)
}
// @tomii_export(out_len=n, free=free_vector)
complex_f32* generate_vector(size_t n);
@tomii.export
def compute_fft(v: np.ndarray) -> np.ndarray:
return np.fft.fft(v)

The runtime is machine-readable

Every tuning knob ships with a type, a domain, and a search hint (--list-knobs-json); every graph validates against a published schema. An optimizer — random search, Bayesian, or an LLM — can enumerate, evaluate, and iterate without recompilation. In our 4-arm tuning benchmark over a 14-million-cell knob space, random search found 1 valid configuration in 50 trials; the verifier-gated agent stayed valid in 41 and won best-trial on all three workloads.

Agent-driven tuning
{
"name": "workers",
"cli": "--workers",
"role": "perf",
"description": "Rayon worker threads (match physical cores)",
"search_hint": "unimodal; binary search 1–physical_cores",
"domain": { "kind": "int", "min": 1, "max": 128,
"scale": "pow2" }
}

Is Tomii for you?

Tomii is a research and prototyping framework with a deliberate niche. A fused, application-specific system like Agora will beat it on absolute latency (a bounded 3-4x on massive-MIMO), but changing a subcarrier count, a scheduling policy, or a kernel in Tomii is a graph edit or a CLI flag, not a source change and a recompile.

Built for

  • Packet-driven MIMO-class pipelines: network ingress, FFT/beam stages, concurrent frames
  • Multi-frame replay where the same pipeline fires repeatedly on arriving data (per-task compute ≥ 16 µs)
  • Agent-driven optimization research on a structured, verifier-gated tuning surface

Not for

  • Single-frame micro-task DAGs where dispatch overhead dominates — Taskflow and TBB are faster there
  • Dynamic topology: data-dependent fan-out and parallel_for reductions cannot be expressed
  • Production baseband at the absolute latency limit — that is what fused systems are for

Start with a twelve-line graph.