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 bitwise_xor(&mut self, lhs: ValueId, rhs: ValueId) -> ValueId {
117 let id = self.graph.fresh_id();
118 self.graph.push(ScOp::BitwiseXor { id, lhs, rhs })
119 }
120
121 pub fn reduce(&mut self, input: ValueId, mode: ReduceMode) -> ValueId {
123 let id = self.graph.fresh_id();
124 self.graph.push(ScOp::Reduce { id, input, mode })
125 }
126
127 pub fn graph_forward(
129 &mut self,
130 features: ValueId,
131 adjacency: ValueId,
132 n_nodes: usize,
133 n_features: usize,
134 ) -> ValueId {
135 let id = self.graph.fresh_id();
136 self.graph.push(ScOp::GraphForward {
137 id,
138 features,
139 adjacency,
140 n_nodes,
141 n_features,
142 })
143 }
144
145 pub fn softmax_attention(
147 &mut self,
148 q: ValueId,
149 k: ValueId,
150 v: ValueId,
151 dim_k: usize,
152 ) -> ValueId {
153 let id = self.graph.fresh_id();
154 self.graph
155 .push(ScOp::SoftmaxAttention { id, q, k, v, dim_k })
156 }
157
158 pub fn kuramoto_step(
160 &mut self,
161 phases: ValueId,
162 omega: ValueId,
163 coupling: ValueId,
164 dt: f64,
165 ) -> ValueId {
166 let id = self.graph.fresh_id();
167 self.graph.push(ScOp::KuramotoStep {
168 id,
169 phases,
170 omega,
171 coupling,
172 dt,
173 })
174 }
175
176 pub fn scale(&mut self, input: ValueId, factor: f64) -> ValueId {
178 let id = self.graph.fresh_id();
179 self.graph.push(ScOp::Scale { id, input, factor })
180 }
181
182 pub fn offset(&mut self, input: ValueId, offset_val: f64) -> ValueId {
184 let id = self.graph.fresh_id();
185 self.graph.push(ScOp::Offset {
186 id,
187 input,
188 offset: offset_val,
189 })
190 }
191
192 pub fn div_const(&mut self, input: ValueId, divisor: u64) -> ValueId {
194 let id = self.graph.fresh_id();
195 self.graph.push(ScOp::DivConst { id, input, divisor })
196 }
197
198 pub fn build(self) -> ScGraph {
200 self.graph
201 }
202}