1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! A dataflow-graph compute engine.
//!
//! Computation is described as a directed graph: nodes are **kernels**, and **timestamped
//! packets** flow along the edges. This crate is the engine itself — scheduling, worker threads,
//! edge queues, topology validation and YAML parsing.
//!
//! # Two interfaces
//!
//! * **Rust API** — the public items of this crate ([`Graph`], [`Packet`], [`Kernel`], …).
//! * **C ABI** — the [`ffi`] module, declared in `include/lmflow/flow.h`. This is the only
//! *stable* interface, and it is what C, C++, Python and mobile hosts use.
//!
//! # Kernels are decoupled from the engine
//!
//! A kernel can be written in **Rust** ([`Kernel`] + [`register_kernel`]), in **C++** (the
//! header-only `flow.hpp` sugar layer), or in **Python** (pybind11). All three register into one
//! registry through the same function-pointer vtable, so the engine neither knows nor cares which
//! language a kernel came from — and kernels written in different languages can be mixed freely
//! in a single graph.
//!
//! This crate is a **pure-Rust engine by default**: it neither compiles nor bundles any C++, so
//! `cargo add lmflow` needs no C++ toolchain. Two structural kernels ship with it and are
//! registered automatically when a graph is built (see [`builtin`]): `PassThrough` (zero-copy
//! forward) and `Sink` (consume only, so a branch can terminate itself). Anything that would have
//! to assume a concrete payload type is deliberately left to you — the engine never interprets
//! payloads.
//!
//! # Running a graph
//!
//! ```
//! use lmflow::{Graph, Packet, Timestamp};
//!
//! # fn main() -> lmflow::Result<()> {
//! let graph = Graph::from_yaml(
//! r#"
//! nodes:
//! - { name: relay, kernel: PassThrough, input_ports: [in], output_ports: [out] }
//! input_ports: [in]
//! output_ports: [out]
//! "#,
//! )?;
//!
//! let out = graph.add_poller("out")?;
//! graph.start()?;
//! graph.input("in")?.send(Packet::from_i64(21).at(Timestamp(0)))?;
//!
//! assert_eq!(out.next().and_then(|p| p.as_i64()), Some(21));
//!
//! graph.close_all_inputs();
//! graph.wait_done()?;
//! # Ok(())
//! # }
//! ```
//!
//! # Writing a kernel
//!
//! ```
//! use lmflow::{register_kernel, 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))
//! }
//! }
//!
//! # fn main() -> lmflow::Result<()> {
//! register_kernel::<Double>("Double")?; // once, before Graph::from_yaml
//! # Ok(())
//! # }
//! ```
//!
//! # Beyond this crate
//!
//! The lm-flow repository also carries 18 built-in C++ kernels (`../cpp/kernels/`), compiled in by
//! the `builtin-kernels` feature. That feature is **off by default and only usable inside the
//! repository**: those sources live outside the crate directory, so they are not distributed with
//! the published crate.
//!
//! Full documentation, including the C/C++ and Python interfaces:
//! <https://laomou.github.io/lm-flow/>. The authoritative design document — scheduling model,
//! timestamp and termination semantics, lock ordering rules and the decision log — is
//! `docs/design.md` (written in Chinese).
pub use ;
pub use ;
pub use ;
pub use ;
pub use Timestamp;
extern "C"
/// Register the built-in C++ kernels. **Idempotent** — only the first call takes effect.
///
/// Must be called before [`Graph::from_yaml`], otherwise graph construction reports an
/// unregistered kernel.
///
/// Only exists under the `builtin-kernels` feature (**off by default**, and only usable inside the
/// lm-flow repository); otherwise register your own Rust kernels with [`register_kernel`].
/// C ABI: register the built-in kernels (see `include/lmflow/flow.h`). This is the exported
/// wrapper around [`register_builtin_kernels`] — defined in Rust and `#[no_mangle]`-exported so it
/// appears in the symbol table of both the static library and the cdylib, matching the declaration
/// in `flow.h`.
///
/// # Safety
/// Takes no arguments and no pointers, and is internally idempotent. Safe to call from any thread.
pub unsafe extern "C"