BYTES AND BRAINS v0.3.0 . CRATES.IO
UPLINK OK
post/bytesandbrains-0-3-0-first-public-release

bytesandbrains 0.3.0 - First public release

First public release: framework + sans-IO Engine + Wire + role traits + CpuBackend reference.

First public release of the BytesAndBrains framework.

Quick start

cargo add bytesandbrains
[dependencies]
bytesandbrains = "0.3"

The shipped examples/federated_learning.rs is the canonical end-to-end pattern. The condensed shape is the three-phase pipeline every program follows: author, compile, install.

// pattern condensed from examples/federated_learning.rs
use bytesandbrains::placeholders::ModelSlot;
use bytesandbrains::{install, Address, Compiler, Config, Graph, Module, PeerId};

struct ClientLogic;

impl Module for ClientLogic {
    fn name(&self) -> &str { "ClientLogic" }
    fn body(&self, g: &mut Graph) {
        // Record an op that consumes the server's params, applies them
        // to the bound Model, then ships the updated params back.
        let server_params = g.input("server_params");
        let _            = ModelSlot.load_parameters(g, server_params);
        let updated      = ModelSlot.params(g);
        let server_peer  = g.input("server_peer");
        g.net_out("updated_params", server_peer, updated);
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // AUTHOR. Module body records into a ModelProto.
    let client_proto = ClientLogic.build()?;

    // COMPILE. Bind concretes, partition, get back the installed ModelProto.
    let client_artifact = Compiler::new()
        .bind_model::<MyModel>("model")
        .compile(client_proto)?;

    // INSTALL. Produce a Node bound to this peer's partition.
    let target = client_artifact.functions[0].name.clone();
    let peer   = PeerId::from(101);
    let mut client = install(
        peer,
        Address::empty().p2p(peer),
        client_artifact,
        &target,
        Config::new(),
    )?;

    // The host drives client.poll(&mut cx) and ships outbound envelopes.
    Ok(())
}

Added

  • Module trait. Authors record their workload as a Rust struct whose body(&self, g: &mut Graph) method records computation against an ONNX ModelProto.
  • Graph DSL records NodeProtos through method calls. Inputs declared with g.input("name"); local sinks with g.output("name", value); network sinks with g.net_out("name", peers, value).
  • Compiler: Compiler::new().bind_<role>::<T>("slot").compile(module) -> ModelProto binds concretes and partitions the graph across Nodes, inserting cross-node edges as wire ops.
  • Sans-IO Engine: single-threaded state machine driven by the host’s poll(), eight-phase poll cycle.
  • Wire: one WireEnvelope proto carries both data-plane values and control-plane protocol traffic. Framed protobuf on the byte side, address-suffix routing on the wire side.
  • Eight role traits: BackendRuntime, ModelRuntime, IndexRuntime, AggregatorRuntime, CodecRuntime, DataSourceRuntime, PeerSelectorRuntime, ProtocolRuntime. Library makers implement the matching bb::<Role> Contract traits in bb-runtime/src/contracts/; the #[derive(bb::<Role>)] bridges generate the engine-side <Role>Runtime impl.
  • ConcreteComponent trait. Every plug-in derives this through #[derive(bb::Concrete)] and submits itself through inventory::submit!. DCE strips unreferenced entries.
  • Snapshot and restore on the Node.
  • Cross-Component event bus and lock-free MPMC ingress queue.
  • Companion crate bb-derive: proc-macros for #[derive(bb::Concrete)] and #[derive(bb::<Role>)], plus the declarative bb::register_op!{} and bb::register_protocol!{} macros.
  • Reference CpuBackend under bytesandbrains::backends::cpu, implementing the ai.onnx v1 op subset the framework needs.

Details: whitepaper | docs.rs | GitHub.