lm-flow
English | 简体中文
A dataflow-graph engine: computation is described as a directed graph — nodes are kernels, and timestamped packets flow along the edges. The engine is written in Rust (scheduling, threads, queues, topology) and exposes a single stable C ABI; kernels can be written in Rust, C++ or Python.
📖 Documentation: https://laomou.github.io/lm-flow/ — Rust · C / C++ · Python
Host (Rust / C++ / Python) ── drives the graph
│ C ABI (lmflow/flow.h)
▼
Engine (Rust): scheduler · executors · edge queues · topology · YAML
│ C ABI (callbacks)
▼
Kernels: Rust (trait Kernel) / C++ (flow.hpp sugar) / Python
Layout
First-party source lives under lmflow/; build files and the vendored submodule sit at the repo root (which is also the Python project root, so wheels bundle everything they need).
lm-flow/
├── lmflow/ All first-party source
│ ├── core/ Engine — the `lmflow` crate, **pure Rust** (package = lib = lmflow → liblmflow.a)
│ │ ├── build.rs Repository-only Rust test path for bundled C++ kernels
│ │ ├── Cargo.toml · Cargo.lock
│ │ └── src/ · tests/ · benches/
│ ├── include/lmflow/ Public core headers — flow.h · flow.hpp · flow_platform_log.hpp
│ ├── adapters/opencv/ Optional OpenCV adapter — <lmflow/opencv.hpp> · lmflow::opencv
│ ├── cpp/ C++ side (not the engine) — kernels/ (18 built-ins) · abi_assert.cc · tests/
│ ├── python/ pybind11 bindings (src/) + the lmflow package + CMakeLists
│ └── examples/ each example is self-contained: examples/<lang>/<name>/
│ ├── cpp/ hello_world/, custom_type/ (find_package or build-from-source)
│ ├── rust/ hello_world/ (a standalone cargo project)
│ ├── python/ hello_world/, async_pipeline/, realtime_pipeline/, opencv_pipeline/
│ └── {android,ios,harmonyos}/hello_world/ mobile integration examples
├── third_party/pybind11/ vendored git submodule (only used to build the Python wheel)
├── cmake/ engine.cmake · install-sdk.cmake · find_package config
├── docs/ design.md (authoritative design doc, Chinese) · web/ (doc-site sources)
├── CHANGELOG.md Release notes (crate · wheel · native SDK share one version)
├── CMakeLists.txt Top-level build (drives cargo; C/C++ SDK + Python extension)
└── pyproject.toml Python wheel (scikit-build-core → the same CMake)
Core concepts
| Concept | Description |
|---|---|
Graph |
A computation graph described in YAML; handles init, start, input-close and termination |
Node |
A node in the graph, holding one kernel instance |
Kernel |
User-written compute logic implementing Open/Process/Close |
Edge/Port |
Edges and ports connect producers to consumers by name; an edge carries a queue of timestamped packets |
Packet |
A packet = an immutable shared payload + a timestamp |
Contract |
Port type contract, declared by the kernel in GetContract |
Poller/Observer |
Pull or push graph output; bounded Pollers support block/drop/latest policies |
Concrete port contracts are checked across edges while the graph is built, so a known
I64 → F64 connection fails before execution. An any endpoint keeps runtime packet checks,
and a kernel's emitted packets must also satisfy its own output contract.
Quick start
Rust — from crates.io, no C++ toolchain needed:
cargo add lmflow
use lmflow::{register_kernel, Graph, Kernel, KernelCtx, Packet};
#[derive(Default)]
struct Double;
impl Kernel for Double {
fn process(&mut self, cc: &mut KernelCtx) -> lmflow::Result<()> {
let v = cc.input(0).and_then(|p| p.as_i64()).unwrap_or(0);
cc.emit(0, Packet::from_i64(v * 2))
}
}
register_kernel::<Double>("Double")?; // register before building the graph
let g = Graph::from_yaml(yaml)?;
The published crate is the pure-Rust engine. The 18 bundled C++ kernels are a separate CMake component and are never compiled by the core crate.
To unit-test a single kernel, use KernelRunner from Rust,
lmflow::KernelRunner from C++, or lmflow.KernelRunner from Python. It directly
drives get_contract/open/process/close without parsing graph YAML or starting
graph executors:
runner = lmflow.KernelRunner("MyKernel", input_ports=1, output_ports=1)
runner.add_input(0, value, ts=7)
runner.process(7)
result = runner.try_next(0)
runner.close()
Working in this repo instead (the engine crate is lmflow/core):
cd lmflow/core
cargo build # pure-Rust engine, no C++ compiled
cargo test # unit tests + ABI layout + Rust-kernel tests
# C++ kernels are built and tested through the root CMake project:
cd ../..
cmake -B build -DLMFLOW_BUILD_KERNELS=ON
cmake --build build
ctest --test-dir build
Python:
pip install lm-lmflow # prebuilt wheels (Linux manylinux / macOS)
import lmflow
@lmflow.kernel("Double")
class Double(lmflow.Kernel):
def process(self, cc):
cc.emit(0, cc.input(0).as_int() * 2)
g = lmflow.Graph.from_yaml("""
nodes:
- { name: d, kernel: Double, input_ports: [in], output_ports: [out] }
input_ports: [in]
output_ports: [out]
""")
out = g.add_poller("out")
g.start()
g.input("in").send(21, ts=0)
print(out.next(timeout=5.0).as_int()) # 42
g.close_all_inputs(); g.wait_done(timeout=5.0)
Python kernel-side APIs are declared in lmflow/python/lmflow/__init__.pyi,
so IDEs and type checkers can discover Context.side_packet,
Context.input_timestamp, Packet.timestamp, and the other pybind11 methods.
For DelegatingExecutor event-loop hosts, Graph.pump_steps(max_steps) provides
a bounded alternative to repeatedly calling Graph.pump_step().
Only prebuilt wheels are published — if no wheel matches your platform,
pip installfails rather than compiling on your machine. To build locally instead, clone with submodules and build the wheel from source (needs a Rust toolchain + CMake):git clone --recursive https://github.com/laomou/lm-flow pip install ./lm-flow # scikit-build-core drives CMake → cargo + pybind11
A kernel looks like this (C++, using the sugar layer):
class PassThroughKernel : public lmflow::Kernel {
public:
static void GetContract(lmflow::Contract& c) { c.InputSetAny(0); c.OutputSetAny(0); }
lmflow::Status Process(lmflow::Context& cc) override {
cc.Forward(0, 0); // zero-copy passthrough
return lmflow::Status::Ok();
}
};
A graph looks like this (YAML):
nodes:
- name: "scale"
kernel: "ScaleKernel"
input_ports: ["in"]
output_ports: ["out"]
options: { factor: 3 }
input_ports: ["in"]
output_ports: ["out"]
See docs/design.md for the full design.
Validate a graph before deployment
The core crate includes a configuration-only checker. It parses YAML, resolves
include, expands subgraphs, and validates ports, topology, queue policies, and
executor references without loading kernels or starting worker threads:
cargo run --manifest-path lmflow/core/Cargo.toml --bin lmflow -- \
check-config graph.yaml
cargo run --manifest-path lmflow/core/Cargo.toml --bin lmflow -- \
check-config graph.yaml --json
The JSON output is suitable for CI tooling. An editor schema is available at
docs/lmflow-config.schema.json.
Native SDK (C / C++ / mobile)
C/C++ and mobile hosts don't use pip — they use the headers + library directly. Each tagged GitHub Release ships per-platform lmflow-<version>-<platform>.tar.gz (Linux x86_64/aarch64, macOS arm64, iOS arm64, Android arm64):
lmflow-v0.3.3-linux-x86_64/
├── include/lmflow/ flow.h · flow.hpp · flow_platform_log.hpp
└── lib/ liblmflow_core.a · liblmflow_kernels.a · liblmflow.so
# Recommended: the target preserves all static kernel registrars cross-platform.
find_package(lmflow REQUIRED)
target_link_libraries(my_host PRIVATE lmflow::lmflow)
Without CMake, retain the complete kernels archive explicitly:
g++ -std=c++17 -Iinclude my_host.cc \
-Wl,--whole-archive lib/liblmflow_kernels.a -Wl,--no-whole-archive \
lib/liblmflow_core.a -lpthread -ldl -lm -o my_host
Or build the native SDK locally:
cmake -B build -DCMAKE_BUILD_TYPE=Release \
-DLMFLOW_BUILD_SHARED_LIBS=ON -DLMFLOW_BUILD_KERNELS=ON
cmake --build build
Build & consume with CMake
CMake is the top-level build for the C++/native side. Cargo builds the pure Rust core, while CMake builds the optional bundled C++ kernels and combines them for native consumers:
cmake -B build -DCMAKE_BUILD_TYPE=Release \
-DLMFLOW_BUILD_SHARED_LIBS=ON \
-DLMFLOW_BUILD_KERNELS=ON
cmake --build build
ctest --test-dir build # flow.hpp test; CV test if OpenCV is present
cmake --install build --prefix /opt/lmflow # → headers + lib + lib/cmake/lmflow
The switches are independent:
LMFLOW_BUILD_SHARED_LIBS=ON(default): installliblmflow_core.soand the completeliblmflow.so.LMFLOW_BUILD_SHARED_LIBS=OFF: expose static CMake targets backed byliblmflow_core.aand, when enabled,liblmflow_kernels.a.LMFLOW_BUILD_KERNELS=ON(default): include the 18 bundled C++ kernels inlmflow::lmflow.LMFLOW_BUILD_KERNELS=OFF: build a pure Rust engine only, without bundled C++ kernels.
Consumers choose the desired boundary:
find_package(lmflow REQUIRED)
target_link_libraries(my_app PRIVATE lmflow::lmflow) # core + optional bundled kernels
# target_link_libraries(my_app PRIVATE lmflow::core) # selected pure-core variant
# target_link_libraries(my_app PRIVATE lmflow::core_static)
Rust developers use
cargoinlmflow/core; Python users justpip install lm-lmflow(prebuilt wheels). The wheel is built by scikit-build-core driving this same root CMake (-DLMFLOW_BUILD_PYTHON=ON), so there is one build definition, not three.
Asyncio applications can consume typed output events without polling:
events = graph.events("out")
async for event in events:
if isinstance(event, lmflow.PacketEvent):
handle(event.packet)
elif isinstance(event, lmflow.TimestampBoundEvent):
advance_watermark(event.timestamp)
else: # DoneEvent
break
events() starts the graph on first iteration and shares the same event-loop wakeup driver as
graph.run_async(), so multiple output ports can be consumed concurrently.
The C ABI is the only stable interface (lmflow/flow.h). flow.hpp adds header-only C++ RAII
host wrappers (lmflow::Graph, lmflow::Input, lmflow::Poller) with Rust-compatible method
names, plus the existing C++ kernel authoring sugar. flow_platform_log.hpp bridges engine logs
to the platform logger (logcat / os_log / HiLog). OpenCV interop is a separate opt-in component
under adapters/opencv, exposed as <lmflow/opencv.hpp> and the CMake target lmflow::opencv.
Mobile integration examples: lmflow/examples/android/hello_world (JNI), lmflow/examples/ios/hello_world (Swift), lmflow/examples/harmonyos/hello_world (NAPI).
The asyncio production host example is lmflow/examples/python/async_pipeline. It demonstrates event-loop wakeups, typed output events, timeout cancellation, and graceful cleanup.
Performance benchmarks
Benchmarks are split by boundary so measuring C++ never adds a second C++ build path to the pure Rust core:
cd lmflow/core
cargo bench --bench dispatch # scheduler/executor dispatch
cargo bench --bench throughput # Rust Input → Graph → Poller
cargo bench --bench packet # Packet clone and copy-on-write
See lmflow/benchmarks/README.md for complete
C/C++ SDK and Python/NumPy binding benchmarks. CI compiles benchmark targets but
does not enforce noisy timing thresholds on shared runners.
Documentation
https://laomou.github.io/lm-flow/ — one site, three API surfaces:
| Surface | Reference | Generated from |
|---|---|---|
| Rust | /rust/ (tracks main) · docs.rs/lmflow (released version) |
doc comments in lmflow/core/src/ |
| C / C++ | /cpp/ — hand-written guide |
lmflow/include/lmflow/flow.h, the authoritative ABI definition |
| Python | /python/ |
docstrings in lmflow/python/lmflow/__init__.py |
The design document — scheduling model, timestamp and termination semantics, lock ordering rules and the decision log — is docs/design.md (Chinese, authoritative), also rendered at /design/.
Release notes are in CHANGELOG.md.
The site is built and deployed by .github/workflows/docs.yml on every push to main; the hand-written pages live in docs/web/. To preview it locally:
pip install pdoc # also brings markdown2 + pygments
cargo doc --no-deps --manifest-path lmflow/core/Cargo.toml
python docs/web/build.py site
cp -R lmflow/core/target/doc/. site/rust/ && rm -f site/rust/.lock
python -m pdoc lmflow -o site/python # needs `pip install .` first
python -m http.server -d site 8000
Metadata
Release files for lm-lmflow 0.3.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
Total release size: 13.5 MB
Release files / lm_lmflow-0.3.3-cp312-cp312-manylinux_2_28_x86_64.whl
| Download URL | lm_lmflow-0.3.3-cp312-cp312-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.12 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
446e2253f46feb6344c07427fe3280aea059016f9bdf5862425d2c1019077620
|
|
BLAKE2b-256 checksum How to use checksums |
e6dcd6083a78b568e5465589845a452758b52d3eebf85ea66dc0ff7e2302030e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency logRelease files / lm_lmflow-0.3.3-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | lm_lmflow-0.3.3-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
848900dbc2e5aa8279100c550685978a55b7e3ddafd1a5d3cc2d3f097361de63
|
|
BLAKE2b-256 checksum How to use checksums |
2dd3e8fa995d85a9ed0701e91f745820496b35e6495997d75d949ca0f716f202
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency logRelease files / lm_lmflow-0.3.3-cp311-cp311-manylinux_2_28_x86_64.whl
| Download URL | lm_lmflow-0.3.3-cp311-cp311-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.11 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
da69c3c5bfa074ea5c4b7d888401711d4208fd4dbc33280a18c124b48277c999
|
|
BLAKE2b-256 checksum How to use checksums |
fad6c780b02ac6af9358b78b62503e4839a3c2fa51c1d52708d4cce67aac4a35
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency logRelease files / lm_lmflow-0.3.3-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | lm_lmflow-0.3.3-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
34ffd9279a0149333ca7ee7a4d3ad9cc8be3abc99863c0eb756d7d4237faf008
|
|
BLAKE2b-256 checksum How to use checksums |
0b88a48afbac115a0f653edc26a85609a10712ca854c50395675218d65e6dd28
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency logRelease files / lm_lmflow-0.3.3-cp310-cp310-manylinux_2_28_x86_64.whl
| Download URL | lm_lmflow-0.3.3-cp310-cp310-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
4370095a6f09c414404a8eadb24e90e8e61bbac216076d224c81b98d990ecf84
|
|
BLAKE2b-256 checksum How to use checksums |
37b777b17b0f157225a160d1e01db575d8480c8f1cf0b1a42c30d8405025a693
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency logRelease files / lm_lmflow-0.3.3-cp310-cp310-macosx_11_0_arm64.whl
| Download URL | lm_lmflow-0.3.3-cp310-cp310-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.10 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
15eba894aab6ed3a30bbbf66e02bbacf30eb900c2d61dd2e93d209a68d3c00da
|
|
BLAKE2b-256 checksum How to use checksums |
b94555dbc15683bfa02461d7b92d4c22048f083a29484ef5dc1120ad90bb890e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency logRelease files / lm_lmflow-0.3.3-cp39-cp39-manylinux_2_28_x86_64.whl
| Download URL | lm_lmflow-0.3.3-cp39-cp39-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.9 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
6577744caac90e1e2189415d8c641cf536a7c1e8dfdb684aa291f09457226df4
|
|
BLAKE2b-256 checksum How to use checksums |
0df7dbeffd0a834bec7a2f111ef87886bd3f54c9c5fd77d09c9909ede7e3fb0e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency logRelease files / lm_lmflow-0.3.3-cp39-cp39-macosx_11_0_arm64.whl
| Download URL | lm_lmflow-0.3.3-cp39-cp39-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.9 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
cc56cdcb372322cfb30071a36cc4ff7340ea883128f0c5614918dfe49baa0a2e
|
|
BLAKE2b-256 checksum How to use checksums |
6c45f1fcd341fffa48db844982be1d6d9877f738a8f5f63701db40f4a4d4327d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency logRelease files / lm_lmflow-0.3.3-cp38-cp38-manylinux_2_28_x86_64.whl
| Download URL | lm_lmflow-0.3.3-cp38-cp38-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | CPython 3.8 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
ac90ec71365d4e09bc119c4c0e8aff77eef0d52358b3da8a44026288ed087ebb
|
|
BLAKE2b-256 checksum How to use checksums |
8472d719f07a1b671bd0e3fb753e4f857848f657065e25f392be93e5940b417d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 28, 2026.
Transparency log