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