1use crate::ir::graph::*;
11
12pub struct ScGraphBuilder {
14 graph: ScGraph,
15}
16
17impl ScGraphBuilder {
18 pub fn new(name: impl Into<String>) -> Self {
20 Self {
21 graph: ScGraph::new(name),
22 }
23 }
24
25 pub fn input(&mut self, name: impl Into<String>, ty: ScType) -> ValueId {
27 let id = self.graph.fresh_id();
28 self.graph.push(ScOp::Input {
29 id,
30 name: name.into(),
31 ty,
32 })
33 }
34
35 pub fn output(&mut self, name: impl Into<String>, source: ValueId) -> ValueId {
37 let id = self.graph.fresh_id();
38 self.graph.push(ScOp::Output {
39 id,
40 name: name.into(),
41 source,
42 })
43 }
44
45 pub fn constant(&mut self, value: ScConst, ty: ScType) -> ValueId {
47 let id = self.graph.fresh_id();
48 self.graph.push(ScOp::Constant { id, value, ty })
49 }
50
51 pub fn encode(&mut self, prob: ValueId, length: usize, seed: u16) -> ValueId {
53 let id = self.graph.fresh_id();
54 self.graph.push(ScOp::Encode {
55 id,
56 prob,
57 length,
58 seed,
59 })
60 }
61
62 pub fn bitwise_and(&mut self, lhs: ValueId, rhs: ValueId) -> ValueId {
64 let id = self.graph.fresh_id();
65 self.graph.push(ScOp::BitwiseAnd { id, lhs, rhs })
66 }
67
68 pub fn popcount(&mut self, input: ValueId) -> ValueId {
70 let id = self.graph.fresh_id();
71 self.graph.push(ScOp::Popcount { id, input })
72 }
73
74 pub fn lif_step(
76 &mut self,
77 current: ValueId,
78 leak: ValueId,
79 gain: ValueId,
80 noise: ValueId,
81 params: LifParams,
82 ) -> ValueId {
83 let id = self.graph.fresh_id();
84 self.graph.push(ScOp::LifStep {
85 id,
86 current,
87 leak,
88 gain,
89 noise,
90 params,
91 })
92 }
93
94 pub fn dense_forward(
96 &mut self,
97 inputs: ValueId,
98 weights: ValueId,
99 leak: ValueId,
100 gain: ValueId,
101 params: DenseParams,
102 ) -> ValueId {
103 let id = self.graph.fresh_id();
104 self.graph.push(ScOp::DenseForward {
105 id,
106 inputs,
107 weights,
108 leak,
109 gain,
110 params,
111 })
112 }
113
114 pub fn bitwise_xor(&mut self, lhs: ValueId, rhs: ValueId) -> ValueId {
116 let id = self.graph.fresh_id();
117 self.graph.push(ScOp::BitwiseXor { id, lhs, rhs })
118 }
119
120 pub fn reduce(&mut self, input: ValueId, mode: ReduceMode) -> ValueId {
122 let id = self.graph.fresh_id();
123 self.graph.push(ScOp::Reduce { id, input, mode })
124 }
125
126 pub fn graph_forward(
128 &mut self,
129 features: ValueId,
130 adjacency: ValueId,
131 n_nodes: usize,
132 n_features: usize,
133 ) -> ValueId {
134 let id = self.graph.fresh_id();
135 self.graph.push(ScOp::GraphForward {
136 id,
137 features,
138 adjacency,
139 n_nodes,
140 n_features,
141 })
142 }
143
144 pub fn softmax_attention(
146 &mut self,
147 q: ValueId,
148 k: ValueId,
149 v: ValueId,
150 dim_k: usize,
151 ) -> ValueId {
152 let id = self.graph.fresh_id();
153 self.graph
154 .push(ScOp::SoftmaxAttention { id, q, k, v, dim_k })
155 }
156
157 pub fn kuramoto_step(
159 &mut self,
160 phases: ValueId,
161 omega: ValueId,
162 coupling: ValueId,
163 dt: f64,
164 ) -> ValueId {
165 let id = self.graph.fresh_id();
166 self.graph.push(ScOp::KuramotoStep {
167 id,
168 phases,
169 omega,
170 coupling,
171 dt,
172 })
173 }
174
175 pub fn scale(&mut self, input: ValueId, factor: f64) -> ValueId {
177 let id = self.graph.fresh_id();
178 self.graph.push(ScOp::Scale { id, input, factor })
179 }
180
181 pub fn offset(&mut self, input: ValueId, offset_val: f64) -> ValueId {
183 let id = self.graph.fresh_id();
184 self.graph.push(ScOp::Offset {
185 id,
186 input,
187 offset: offset_val,
188 })
189 }
190
191 pub fn div_const(&mut self, input: ValueId, divisor: u64) -> ValueId {
193 let id = self.graph.fresh_id();
194 self.graph.push(ScOp::DivConst { id, input, divisor })
195 }
196
197 pub fn build(self) -> ScGraph {
199 self.graph
200 }
201}