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