1use alloc::{string::ToString, vec::Vec};
2use core::slice;
3
4use miden_air::{RowIndex, trace::main_trace::MainTrace};
5#[cfg(test)]
6use miden_core::{Operation, utils::ToElements};
7
8use super::{Felt, FieldElement, NUM_RAND_ROWS};
9use crate::{chiplets::Chiplets, debug::BusDebugger, utils::uninit_vector};
10
11pub struct TraceFragment<'a> {
16 data: Vec<&'a mut [Felt]>,
17}
18
19impl<'a> TraceFragment<'a> {
20 pub fn new(capacity: usize) -> Self {
22 TraceFragment { data: Vec::with_capacity(capacity) }
23 }
24
25 pub fn width(&self) -> usize {
30 self.data.len()
31 }
32
33 pub fn len(&self) -> usize {
35 self.data[0].len()
36 }
37
38 #[inline(always)]
43 pub fn set(&mut self, row_idx: RowIndex, col_idx: usize, value: Felt) {
44 self.data[col_idx][row_idx] = value;
45 }
46
47 pub fn columns(&mut self) -> slice::IterMut<'_, &'a mut [Felt]> {
49 self.data.iter_mut()
50 }
51
52 pub fn push_column_slice(&mut self, column: &'a mut [Felt], len: usize) -> &'a mut [Felt] {
56 let (column_fragment, rest) = column.split_at_mut(len);
57 self.data.push(column_fragment);
58 rest
59 }
60
61 #[cfg(test)]
65 pub fn trace_to_fragment(trace: &'a mut [Vec<Felt>]) -> Self {
66 let mut data = Vec::new();
67 for column in trace.iter_mut() {
68 data.push(column.as_mut_slice());
69 }
70 Self { data }
71 }
72}
73
74#[derive(Debug, Default, Eq, PartialEq, Clone, Copy)]
84pub struct TraceLenSummary {
85 main_trace_len: usize,
86 range_trace_len: usize,
87 chiplets_trace_len: ChipletsLengths,
88}
89
90impl TraceLenSummary {
91 pub fn new(
92 main_trace_len: usize,
93 range_trace_len: usize,
94 chiplets_trace_len: ChipletsLengths,
95 ) -> Self {
96 TraceLenSummary {
97 main_trace_len,
98 range_trace_len,
99 chiplets_trace_len,
100 }
101 }
102
103 pub fn main_trace_len(&self) -> usize {
105 self.main_trace_len
106 }
107
108 pub fn range_trace_len(&self) -> usize {
110 self.range_trace_len
111 }
112
113 pub fn chiplets_trace_len(&self) -> ChipletsLengths {
115 self.chiplets_trace_len
116 }
117
118 pub fn trace_len(&self) -> usize {
120 self.range_trace_len
121 .max(self.main_trace_len)
122 .max(self.chiplets_trace_len.trace_len())
123 }
124
125 pub fn padded_trace_len(&self) -> usize {
127 (self.trace_len() + NUM_RAND_ROWS).next_power_of_two()
128 }
129
130 pub fn padding_percentage(&self) -> usize {
133 (self.padded_trace_len() - self.trace_len()) * 100 / self.padded_trace_len()
134 }
135}
136
137#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
140pub struct ChipletsLengths {
141 hash_chiplet_len: usize,
142 bitwise_chiplet_len: usize,
143 memory_chiplet_len: usize,
144 kernel_rom_len: usize,
145}
146
147impl ChipletsLengths {
148 pub fn new(chiplets: &Chiplets) -> Self {
149 ChipletsLengths {
150 hash_chiplet_len: chiplets.bitwise_start().into(),
151 bitwise_chiplet_len: chiplets.memory_start() - chiplets.bitwise_start(),
152 memory_chiplet_len: chiplets.kernel_rom_start() - chiplets.memory_start(),
153 kernel_rom_len: chiplets.padding_start() - chiplets.kernel_rom_start(),
154 }
155 }
156
157 pub fn from_parts(
158 hash_len: usize,
159 bitwise_len: usize,
160 memory_len: usize,
161 kernel_len: usize,
162 ) -> Self {
163 ChipletsLengths {
164 hash_chiplet_len: hash_len,
165 bitwise_chiplet_len: bitwise_len,
166 memory_chiplet_len: memory_len,
167 kernel_rom_len: kernel_len,
168 }
169 }
170
171 pub fn hash_chiplet_len(&self) -> usize {
173 self.hash_chiplet_len
174 }
175
176 pub fn bitwise_chiplet_len(&self) -> usize {
178 self.bitwise_chiplet_len
179 }
180
181 pub fn memory_chiplet_len(&self) -> usize {
183 self.memory_chiplet_len
184 }
185
186 pub fn kernel_rom_len(&self) -> usize {
188 self.kernel_rom_len
189 }
190
191 pub fn trace_len(&self) -> usize {
195 self.hash_chiplet_len()
196 + self.bitwise_chiplet_len()
197 + self.memory_chiplet_len()
198 + self.kernel_rom_len()
199 + 1
200 }
201}
202
203pub trait AuxColumnBuilder<E: FieldElement<BaseField = Felt>> {
209 fn get_requests_at(
213 &self,
214 main_trace: &MainTrace,
215 alphas: &[E],
216 row: RowIndex,
217 debugger: &mut BusDebugger<E>,
218 ) -> E;
219
220 fn get_responses_at(
221 &self,
222 main_trace: &MainTrace,
223 alphas: &[E],
224 row: RowIndex,
225 debugger: &mut BusDebugger<E>,
226 ) -> E;
227
228 fn init_requests(
232 &self,
233 _main_trace: &MainTrace,
234 _alphas: &[E],
235 _debugger: &mut BusDebugger<E>,
236 ) -> E {
237 E::ONE
238 }
239
240 fn init_responses(
241 &self,
242 _main_trace: &MainTrace,
243 _alphas: &[E],
244 _debugger: &mut BusDebugger<E>,
245 ) -> E {
246 E::ONE
247 }
248
249 fn build_aux_column(&self, main_trace: &MainTrace, alphas: &[E]) -> Vec<E> {
251 let mut bus_debugger = BusDebugger::new("chiplets bus".to_string());
252
253 let mut requests: Vec<E> = unsafe { uninit_vector(main_trace.num_rows()) };
254 requests[0] = self.init_requests(main_trace, alphas, &mut bus_debugger);
255
256 let mut responses_prod: Vec<E> = unsafe { uninit_vector(main_trace.num_rows()) };
257 responses_prod[0] = self.init_responses(main_trace, alphas, &mut bus_debugger);
258
259 let mut requests_running_prod = requests[0];
260
261 for row_idx in 0..main_trace.num_rows() - 1 {
263 let row = row_idx.into();
264
265 let response = self.get_responses_at(main_trace, alphas, row, &mut bus_debugger);
266 responses_prod[row_idx + 1] = responses_prod[row_idx] * response;
267
268 let request = self.get_requests_at(main_trace, alphas, row, &mut bus_debugger);
269 requests[row_idx + 1] = request;
270 requests_running_prod *= request;
271 }
272
273 let mut result_aux_column = responses_prod;
275 let mut requests_running_divisor = requests_running_prod.inv();
276 for i in (0..main_trace.num_rows()).rev() {
277 result_aux_column[i] *= requests_running_divisor;
278 requests_running_divisor *= requests[i];
279 }
280
281 #[cfg(any(test, feature = "bus-debugger"))]
282 assert!(bus_debugger.is_empty(), "{bus_debugger}");
283
284 result_aux_column
285 }
286}
287
288#[cfg(test)]
292pub fn build_span_with_respan_ops() -> (Vec<Operation>, Vec<Felt>) {
293 let iv = [1, 3, 5, 7, 9, 11, 13, 15, 17].to_elements();
294 let ops = vec![
295 Operation::Push(iv[0]),
296 Operation::Push(iv[1]),
297 Operation::Push(iv[2]),
298 Operation::Push(iv[3]),
299 Operation::Push(iv[4]),
300 Operation::Push(iv[5]),
301 Operation::Push(iv[6]),
302 Operation::Push(iv[7]),
304 Operation::Push(iv[8]),
305 Operation::Add,
306 Operation::Drop,
308 Operation::Drop,
309 Operation::Drop,
310 Operation::Drop,
311 Operation::Drop,
312 Operation::Drop,
313 Operation::Drop,
314 Operation::Drop,
315 ];
316 (ops, iv)
317}