use crate::graph::{attr_tensor, kv, Graph};
use crate::output::Output;
use bb_ir::proto::onnx::{tensor_proto, NodeProto, TensorProto};
pub mod ids {
pub use bb_ir::syscall_ids::{
OP_CONSTANT as CONSTANT_OP, OP_GATE_DISPATCH as GATE_DISPATCH_OP,
OP_PASS_THROUGH as PASS_THROUGH_OP, SYSCALL_DOMAIN,
};
}
const ADDRESS_BOOK_DOMAIN: &str = "ai.bytesandbrains.address_book";
const INSERT_MANY_OP: &str = "InsertMany";
const LOOKUP_OP: &str = "Lookup";
const GLOBAL_REGISTRY_DOMAIN: &str = "ai.bytesandbrains.protocol.global_registry";
const ANNOUNCE_OP: &str = "Announce";
const BOOTSTRAP_SEED_KEY: &str = "ai.bytesandbrains.bootstrap.seed";
const ANNOUNCE_SERVER_PEER_KEY: &str = "ai.bytesandbrains.input.server_peer";
pub fn pass_through(g: &mut Graph, input: Output) -> Output {
let out_name = g.next_site_name();
g.push_node(NodeProto {
op_type: ids::PASS_THROUGH_OP.into(),
domain: ids::SYSCALL_DOMAIN.into(),
input: vec![input.name],
output: vec![out_name.clone()],
..Default::default()
});
g.declare_value_info(&out_name, input.type_node);
Output::new(out_name, input.type_node)
}
pub fn address_book_insert_many(g: &mut Graph, peer: Output, addresses: Output) -> Output {
let out_name = g.next_site_name();
g.push_node(NodeProto {
op_type: INSERT_MANY_OP.into(),
domain: ADDRESS_BOOK_DOMAIN.into(),
input: vec![peer.name, addresses.name],
output: vec![out_name.clone()],
..Default::default()
});
g.declare_value_info(&out_name, &bb_ir::types::TYPE_TRIGGER);
Output::new(out_name, &bb_ir::types::TYPE_TRIGGER)
}
pub fn address_book_lookup(g: &mut Graph, peer: Output) -> Output {
let out_name = g.next_site_name();
g.push_node(NodeProto {
op_type: LOOKUP_OP.into(),
domain: ADDRESS_BOOK_DOMAIN.into(),
input: vec![peer.name],
output: vec![out_name.clone()],
..Default::default()
});
g.declare_value_info(&out_name, &bb_ir::types::TYPE_ADDRESS_VEC);
Output::new(out_name, &bb_ir::types::TYPE_ADDRESS_VEC)
}
pub fn gate_dispatch(g: &mut Graph, inputs: &[Output]) -> Output {
let out_name = g.next_site_name();
g.push_node(NodeProto {
op_type: ids::GATE_DISPATCH_OP.into(),
domain: ids::SYSCALL_DOMAIN.into(),
input: inputs.iter().map(|o| o.name.clone()).collect(),
output: vec![out_name.clone()],
..Default::default()
});
g.declare_value_info(&out_name, &bb_ir::types::TYPE_BYTES);
Output::new(out_name, &bb_ir::types::TYPE_BYTES)
}
pub fn constant(
g: &mut Graph,
label: &'static str,
output_type: &'static bb_ir::types::TypeNode,
data_type: tensor_proto::DataType,
) -> Output {
let out_name = g.next_site_name();
let tensor = TensorProto {
data_type: data_type as i32,
dims: vec![1],
..Default::default()
};
g.push_node(NodeProto {
op_type: ids::CONSTANT_OP.into(),
domain: ids::SYSCALL_DOMAIN.into(),
input: vec![],
output: vec![out_name.clone()],
attribute: vec![attr_tensor("value", tensor)],
metadata_props: vec![kv(BOOTSTRAP_SEED_KEY, label)],
..Default::default()
});
g.declare_value_info(&out_name, output_type);
Output::new(out_name, output_type)
}
pub fn announce(g: &mut Graph, server_peer: Output) -> Output {
let out_name = g.next_site_name();
g.push_node(NodeProto {
op_type: ANNOUNCE_OP.into(),
domain: GLOBAL_REGISTRY_DOMAIN.into(),
input: vec![server_peer.name.clone()],
output: vec![out_name.clone()],
metadata_props: vec![kv(ANNOUNCE_SERVER_PEER_KEY, &server_peer.name)],
..Default::default()
});
g.declare_value_info(&out_name, &bb_ir::types::TYPE_TRIGGER);
Output::new(out_name, &bb_ir::types::TYPE_TRIGGER)
}