bb_ops/syscalls/structural/tee/
mod.rs1use bb_ir::proto::onnx::NodeProto;
5use bb_runtime::atomic::DispatchResult;
6use bb_runtime::bus::OpError;
7use bb_runtime::registry::OpRegistration;
8use bb_runtime::runtime::RuntimeResourceRef;
9use bb_runtime::slot_value::SlotValue;
10
11pub use bb_ir::syscall_ids::OP_TEE as OP_TYPE;
12pub use bb_ir::syscall_ids::SYSCALL_DOMAIN as DOMAIN;
13
14pub struct TeeOp;
16
17pub fn invoke(
21 node: &NodeProto,
22 inputs: &[(&str, &dyn SlotValue)],
23 _ctx: &mut RuntimeResourceRef<'_>,
24) -> Result<DispatchResult, OpError> {
25 let Some((_, input)) = inputs.first() else {
26 return Err(OpError {
27 detail: "Tee requires one input".to_string(),
28 ..Default::default()
29 });
30 };
31 let fanout = node
32 .attribute
33 .iter()
34 .find(|a| a.name == "fanout")
35 .map(|a| a.i.max(1) as usize)
36 .unwrap_or(2);
37
38 let mut outs: Vec<(String, Box<dyn SlotValue>)> = Vec::with_capacity(fanout);
39 for i in 0..fanout {
40 outs.push((format!("out_{i}"), input.clone_boxed()));
41 }
42 Ok(DispatchResult::Immediate(outs))
43}
44
45inventory::submit! {
46 OpRegistration {
47 domain: DOMAIN,
48 op_type: OP_TYPE,
49 invoke,
50 kind: bb_runtime::registry::RegistrationKind::Syscall,
51 }
52}
53