bb_compiler/
validate_runtime_complete.rs1use bb_ir::proto::onnx::GraphProto;
9
10use crate::error::CompileError;
11use crate::partition_by_wire_ops::WIRE_DOMAIN;
12
13const SYSCALL_DOMAIN: &str = "ai.bytesandbrains.syscall";
14const SEND_OP: &str = "Send";
15const RECV_OP: &str = "Recv";
16
17const PEER_HEALTH_GATE_TX_OP: &str = "PeerHealthGateTx";
18const BACKOFF_GATE_TX_OP: &str = "BackoffGateTx";
19const DEDUP_GATE_RX_OP: &str = "DedupGateRx";
20const PEER_HEALTH_GATE_RX_OP: &str = "PeerHealthGateRx";
21const BACKOFF_GATE_RX_OP: &str = "BackoffGateRx";
22const DEADLINE_CHECK_OP: &str = "DeadlineCheck";
23
24const DEADLINE_NS_ATTR: &str = "deadline_ns";
25
26const PEER_ATTR: &str = "peer";
27
28pub fn validate_runtime_complete(sub_graph: &GraphProto) -> Result<(), CompileError> {
37 let nodes = &sub_graph.node;
38 let has_op = |op_type: &str, domain: &str| -> bool {
39 nodes
40 .iter()
41 .any(|n| n.op_type == op_type && n.domain == domain)
42 };
43
44 let has_peer_send = nodes.iter().any(|n| {
46 n.domain == WIRE_DOMAIN
47 && n.op_type == SEND_OP
48 && n.attribute.iter().any(|a| a.name == PEER_ATTR)
49 });
50 if has_peer_send {
51 if !has_op(PEER_HEALTH_GATE_TX_OP, SYSCALL_DOMAIN) {
52 return Err(CompileError::Internal {
53 detail: format!(
54 "validate_runtime_complete: partition `{}` has a peer-routed wire.Send but no PeerHealthGateTx",
55 sub_graph.name,
56 ),
57 });
58 }
59 if !has_op(BACKOFF_GATE_TX_OP, SYSCALL_DOMAIN) {
60 return Err(CompileError::Internal {
61 detail: format!(
62 "validate_runtime_complete: partition `{}` has a peer-routed wire.Send but no BackoffGateTx",
63 sub_graph.name,
64 ),
65 });
66 }
67 }
68
69 let has_peer_recv = nodes.iter().any(|n| {
71 n.domain == WIRE_DOMAIN
72 && n.op_type == RECV_OP
73 && n.attribute.iter().any(|a| a.name == PEER_ATTR)
74 });
75 if has_peer_recv {
76 if !has_op(DEDUP_GATE_RX_OP, SYSCALL_DOMAIN) {
77 return Err(CompileError::Internal {
78 detail: format!(
79 "validate_runtime_complete: partition `{}` has a peer-routed wire.Recv but no DedupGateRx",
80 sub_graph.name,
81 ),
82 });
83 }
84 if !has_op(PEER_HEALTH_GATE_RX_OP, SYSCALL_DOMAIN) {
85 return Err(CompileError::Internal {
86 detail: format!(
87 "validate_runtime_complete: partition `{}` has a peer-routed wire.Recv but no PeerHealthGateRx",
88 sub_graph.name,
89 ),
90 });
91 }
92 if !has_op(BACKOFF_GATE_RX_OP, SYSCALL_DOMAIN) {
93 return Err(CompileError::Internal {
94 detail: format!(
95 "validate_runtime_complete: partition `{}` has a peer-routed wire.Recv but no BackoffGateRx",
96 sub_graph.name,
97 ),
98 });
99 }
100 }
101
102 let any_deadline = nodes
104 .iter()
105 .any(|n| n.attribute.iter().any(|a| a.name == DEADLINE_NS_ATTR));
106 if any_deadline && !has_op(DEADLINE_CHECK_OP, SYSCALL_DOMAIN) {
107 return Err(CompileError::Internal {
108 detail: format!(
109 "validate_runtime_complete: partition `{}` carries deadline_ns but no DeadlineCheck",
110 sub_graph.name,
111 ),
112 });
113 }
114
115 for reg in crate::gate_contract::contracts() {
121 reg.contract.assert_inserted(sub_graph)?;
122 }
123
124 Ok(())
125}
126