Skip to main content

miden_processor/trace/chiplets/ace/
mod.rs

1use alloc::{collections::BTreeMap, vec::Vec};
2
3use miden_air::trace::{RowIndex, chiplets::ace::ACE_CHIPLET_NUM_COLS};
4use miden_core::{Felt, ZERO};
5
6use crate::trace::TraceFragment;
7
8mod trace;
9pub use trace::CircuitEvaluation;
10
11mod instruction;
12#[cfg(test)]
13mod tests;
14
15pub const PTR_OFFSET_ELEM: Felt = Felt::ONE;
16pub const PTR_OFFSET_WORD: Felt = Felt::new_unchecked(4);
17pub const MAX_NUM_ACE_WIRES: u32 = instruction::MAX_ID;
18
19/// Arithmetic circuit evaluation (ACE) chiplet.
20///
21/// This is a VM chiplet used to evaluate arithmetic circuits given some input, which is equivalent
22/// to evaluating some multi-variate polynomial at a tuple representing the input.
23///
24/// During the course of the VM execution, we keep track of all calls to the ACE chiplet in an
25/// [`CircuitEvaluation`] per call. This is then used to generate the full trace of the ACE chiplet.
26#[derive(Debug, Default)]
27pub struct Ace {
28    circuit_evaluations: BTreeMap<RowIndex, CircuitEvaluation>,
29}
30
31impl Ace {
32    /// Gets the total trace length of the ACE chiplet.
33    pub(crate) fn trace_len(&self) -> usize {
34        self.circuit_evaluations.values().map(CircuitEvaluation::num_rows).sum()
35    }
36
37    /// Fills the portion of the main trace allocated to the ACE chiplet.
38    pub(crate) fn fill_trace(self, trace: &mut TraceFragment) {
39        // make sure fragment dimensions are consistent with the dimensions of this trace
40        debug_assert_eq!(self.trace_len(), trace.len(), "inconsistent trace lengths");
41        debug_assert_eq!(ACE_CHIPLET_NUM_COLS, trace.width(), "inconsistent trace widths");
42
43        let mut gen_trace: [Vec<Felt>; ACE_CHIPLET_NUM_COLS] = (0..ACE_CHIPLET_NUM_COLS)
44            .map(|_| vec![ZERO; self.trace_len()])
45            .collect::<Vec<_>>()
46            .try_into()
47            .expect("failed to convert vector to array");
48
49        let mut offset = 0;
50        for eval_ctx in self.circuit_evaluations.into_values() {
51            eval_ctx.fill(offset, &mut gen_trace);
52            offset += eval_ctx.num_rows();
53        }
54
55        for (out_column, column) in trace.columns().zip(gen_trace) {
56            out_column.copy_from_slice(&column);
57        }
58    }
59
60    /// Adds an entry resulting from a call to the ACE chiplet.
61    pub(crate) fn add_circuit_evaluation(
62        &mut self,
63        clk: RowIndex,
64        circuit_eval: CircuitEvaluation,
65    ) {
66        self.circuit_evaluations.insert(clk, circuit_eval);
67    }
68}