1use crate::ir::graph::*;
26
27pub fn print(graph: &ScGraph) -> String {
29 let mut out = String::new();
30 out.push_str(&format!("sc.graph @{} {{\n", graph.name));
31
32 for op in &graph.ops {
33 out.push_str(" ");
34 match op {
35 ScOp::Input { id, name, ty } => {
36 out.push_str(&format!("{} = sc.input \"{}\" : {}\n", id, name, ty));
37 }
38 ScOp::Output { name, source, .. } => {
39 out.push_str(&format!("sc.output \"{}\" {}\n", name, source));
40 }
41 ScOp::Constant { id, value, ty } => {
42 let val_str = match value {
43 ScConst::F64(v) => format!("{v}"),
44 ScConst::I64(v) => format!("{v}"),
45 ScConst::U64(v) => format!("{v}"),
46 ScConst::F64Vec(v) => format!(
47 "[{}]",
48 v.iter()
49 .map(|x| format!("{x}"))
50 .collect::<Vec<_>>()
51 .join(", ")
52 ),
53 ScConst::I64Vec(v) => format!(
54 "[{}]",
55 v.iter()
56 .map(|x| format!("{x}"))
57 .collect::<Vec<_>>()
58 .join(", ")
59 ),
60 };
61 out.push_str(&format!("{} = sc.constant {} : {}\n", id, val_str, ty));
62 }
63 ScOp::Encode {
64 id,
65 prob,
66 length,
67 seed,
68 } => {
69 out.push_str(&format!(
70 "{} = sc.encode {}, length={}, seed=0x{:04X} : bitstream<{}>\n",
71 id, prob, length, seed, length
72 ));
73 }
74 ScOp::BitwiseAnd { id, lhs, rhs } => {
75 out.push_str(&format!("{} = sc.and {}, {} : bitstream\n", id, lhs, rhs));
76 }
77 ScOp::BitwiseXor { id, lhs, rhs } => {
78 out.push_str(&format!("{} = sc.xor {}, {} : bitstream\n", id, lhs, rhs));
79 }
80 ScOp::Popcount { id, input } => {
81 out.push_str(&format!("{} = sc.popcount {} : u64\n", id, input));
82 }
83 ScOp::Reduce { id, input, mode } => {
84 out.push_str(&format!(
85 "{} = sc.reduce {}, mode={} : rate\n",
86 id, input, mode
87 ));
88 }
89 ScOp::LifStep {
90 id,
91 current,
92 leak,
93 gain,
94 noise,
95 params,
96 } => {
97 out.push_str(&format!(
98 "{} = sc.lif_step {}, leak={}, gain={}, noise={}, \
99 dw={}, frac={}, vt={}, rp={} : (bool, fixed<{},{}>)\n",
100 id,
101 current,
102 leak,
103 gain,
104 noise,
105 params.data_width,
106 params.fraction,
107 params.v_threshold,
108 params.refractory_period,
109 params.data_width,
110 params.fraction
111 ));
112 }
113 ScOp::DenseForward {
114 id,
115 inputs,
116 weights,
117 leak,
118 gain,
119 params,
120 } => {
121 out.push_str(&format!(
122 "{} = sc.dense_forward {}, weights={}, leak={}, gain={}, \
123 ni={}, nn={}, len={} : vec<bool,{}>\n",
124 id,
125 inputs,
126 weights,
127 leak,
128 gain,
129 params.n_inputs,
130 params.n_neurons,
131 params.stream_length,
132 params.n_neurons
133 ));
134 }
135 ScOp::GraphForward {
136 id,
137 features,
138 adjacency,
139 n_nodes,
140 n_features,
141 } => {
142 out.push_str(&format!(
143 "{} = sc.graph_forward {}, adj={}, nodes={}, features={} : rate\n",
144 id, features, adjacency, n_nodes, n_features
145 ));
146 }
147 ScOp::SoftmaxAttention { id, q, k, v, dim_k } => {
148 out.push_str(&format!(
149 "{} = sc.softmax_attention {}, {}, {}, dim_k={} : rate\n",
150 id, q, k, v, dim_k
151 ));
152 }
153 ScOp::KuramotoStep {
154 id,
155 phases,
156 omega,
157 coupling,
158 dt,
159 } => {
160 out.push_str(&format!(
161 "{} = sc.kuramoto_step {}, omega={}, K={}, dt={} : rate\n",
162 id, phases, omega, coupling, dt
163 ));
164 }
165 ScOp::Scale { id, input, factor } => {
166 out.push_str(&format!(
167 "{} = sc.scale {}, factor={} : rate\n",
168 id, input, factor
169 ));
170 }
171 ScOp::Offset { id, input, offset } => {
172 out.push_str(&format!(
173 "{} = sc.offset {}, offset={} : rate\n",
174 id, input, offset
175 ));
176 }
177 ScOp::DivConst { id, input, divisor } => {
178 out.push_str(&format!(
179 "{} = sc.div_const {}, divisor={} : u64\n",
180 id, input, divisor
181 ));
182 }
183 }
184 }
185
186 out.push_str("}\n");
187 out
188}