openvm_circuit/arch/testing/
mod.rs

1mod cpu;
2#[cfg(feature = "cuda")]
3mod cuda;
4pub mod execution;
5pub mod memory;
6pub mod program;
7mod utils;
8
9use std::marker::PhantomData;
10
11pub use cpu::*;
12#[cfg(feature = "cuda")]
13pub use cuda::*;
14pub use execution::ExecutionTester;
15pub use memory::MemoryTester;
16use openvm_circuit_primitives::utils::next_power_of_two_or_zero;
17use openvm_instructions::instruction::Instruction;
18use openvm_stark_backend::{interaction::BusIndex, p3_air::BaseAir};
19use p3_field::Field;
20pub use utils::*;
21
22use crate::arch::{Arena, ExecutionState, MatrixRecordArena, PreflightExecutor, Streams};
23
24pub const EXECUTION_BUS: BusIndex = 0;
25pub const MEMORY_BUS: BusIndex = 1;
26pub const POSEIDON2_DIRECT_BUS: BusIndex = 6;
27pub const READ_INSTRUCTION_BUS: BusIndex = 8;
28pub const BITWISE_OP_LOOKUP_BUS: BusIndex = 9;
29pub const BYTE_XOR_BUS: BusIndex = 10;
30pub const RANGE_TUPLE_CHECKER_BUS: BusIndex = 11;
31pub const MEMORY_MERKLE_BUS: BusIndex = 12;
32
33pub const RANGE_CHECKER_BUS: BusIndex = 4;
34
35pub type ArenaId = usize;
36
37pub struct TestChipHarness<F, E, A, C, RA = MatrixRecordArena<F>> {
38    pub executor: E,
39    pub air: A,
40    pub chip: C,
41    pub arena: RA,
42    phantom: PhantomData<F>,
43}
44
45impl<F, E, A, C, RA> TestChipHarness<F, E, A, C, RA>
46where
47    F: Field,
48    A: BaseAir<F>,
49    RA: Arena,
50{
51    pub fn with_capacity(executor: E, air: A, chip: C, height: usize) -> Self {
52        let width = air.width();
53        let height = next_power_of_two_or_zero(height);
54        let arena = RA::with_capacity(height, width);
55        Self {
56            executor,
57            air,
58            chip,
59            arena,
60            phantom: PhantomData,
61        }
62    }
63}
64
65pub trait TestBuilder<F> {
66    fn execute<E: PreflightExecutor<F, RA>, RA: Arena>(
67        &mut self,
68        executor: &mut E,
69        arena: &mut RA,
70        instruction: &Instruction<F>,
71    );
72
73    fn execute_with_pc<E: PreflightExecutor<F, RA>, RA: Arena>(
74        &mut self,
75        executor: &mut E,
76        arena: &mut RA,
77        instruction: &Instruction<F>,
78        initial_pc: u32,
79    );
80
81    fn write_cell(&mut self, address_space: usize, pointer: usize, value: F);
82    fn read_cell(&mut self, address_space: usize, pointer: usize) -> F;
83
84    fn write<const N: usize>(&mut self, address_space: usize, pointer: usize, value: [F; N]);
85    fn read<const N: usize>(&mut self, address_space: usize, pointer: usize) -> [F; N];
86
87    fn write_usize<const N: usize>(
88        &mut self,
89        address_space: usize,
90        pointer: usize,
91        value: [usize; N],
92    );
93
94    fn address_bits(&self) -> usize;
95
96    fn last_to_pc(&self) -> F;
97    fn last_from_pc(&self) -> F;
98
99    fn execution_final_state(&self) -> ExecutionState<F>;
100    fn streams_mut(&mut self) -> &mut Streams<F>;
101
102    fn get_default_register(&mut self, increment: usize) -> usize;
103    fn get_default_pointer(&mut self, increment: usize) -> usize;
104
105    fn write_heap_pointer_default(
106        &mut self,
107        reg_increment: usize,
108        pointer_increment: usize,
109    ) -> (usize, usize);
110
111    fn write_heap_default<const NUM_LIMBS: usize>(
112        &mut self,
113        reg_increment: usize,
114        pointer_increment: usize,
115        writes: Vec<[F; NUM_LIMBS]>,
116    ) -> (usize, usize);
117}