openvm_circuit/arch/
config.rsuse derive_new::new;
use openvm_circuit::system::memory::MemoryTraceHeights;
use openvm_instructions::program::DEFAULT_MAX_NUM_PUBLIC_VALUES;
use openvm_poseidon2_air::Poseidon2Config;
use openvm_stark_backend::{p3_field::PrimeField32, ChipUsageGetter};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
#[cfg(any(test, feature = "test-utils"))]
pub use super::testing::{
BITWISE_OP_LOOKUP_BUS, BYTE_XOR_BUS, EXECUTION_BUS, MEMORY_BUS, MEMORY_MERKLE_BUS,
POSEIDON2_DIRECT_BUS, RANGE_TUPLE_CHECKER_BUS, READ_INSTRUCTION_BUS,
};
use super::{
AnyEnum, InstructionExecutor, SystemComplex, SystemExecutor, SystemPeriphery, VmChipComplex,
VmInventoryError, PUBLIC_VALUES_AIR_ID,
};
use crate::system::memory::BOUNDARY_AIR_OFFSET;
const DEFAULT_MAX_SEGMENT_LEN: usize = (1 << 22) - 100;
const DEFAULT_POSEIDON2_MAX_CONSTRAINT_DEGREE: usize = 3;
pub const POSEIDON2_WIDTH: usize = 16;
pub fn vm_poseidon2_config<F: PrimeField32>() -> Poseidon2Config<F> {
Poseidon2Config::default()
}
pub trait VmConfig<F: PrimeField32>: Clone + Serialize + DeserializeOwned {
type Executor: InstructionExecutor<F> + AnyEnum + ChipUsageGetter;
type Periphery: AnyEnum + ChipUsageGetter;
fn system(&self) -> &SystemConfig;
fn system_mut(&mut self) -> &mut SystemConfig;
fn create_chip_complex(
&self,
) -> Result<VmChipComplex<F, Self::Executor, Self::Periphery>, VmInventoryError>;
}
#[derive(Debug, Serialize, Deserialize, Clone, new, Copy)]
pub struct MemoryConfig {
pub as_height: usize,
pub as_offset: u32,
pub pointer_max_bits: usize,
pub clk_max_bits: usize,
pub decomp: usize,
pub max_access_adapter_n: usize,
}
impl Default for MemoryConfig {
fn default() -> Self {
Self::new(29, 1, 29, 29, 17, 64)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemConfig {
pub max_constraint_degree: usize,
pub continuation_enabled: bool,
pub memory_config: MemoryConfig,
pub num_public_values: usize,
pub max_segment_len: usize,
pub collect_metrics: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SystemTraceHeights {
pub memory: MemoryTraceHeights,
}
impl SystemConfig {
pub fn new(
max_constraint_degree: usize,
memory_config: MemoryConfig,
num_public_values: usize,
) -> Self {
Self {
max_constraint_degree,
continuation_enabled: false,
memory_config,
num_public_values,
max_segment_len: DEFAULT_MAX_SEGMENT_LEN,
collect_metrics: false,
}
}
pub fn with_max_constraint_degree(mut self, max_constraint_degree: usize) -> Self {
self.max_constraint_degree = max_constraint_degree;
self
}
pub fn with_continuations(mut self) -> Self {
self.continuation_enabled = true;
self
}
pub fn without_continuations(mut self) -> Self {
self.continuation_enabled = false;
self
}
pub fn with_public_values(mut self, num_public_values: usize) -> Self {
self.num_public_values = num_public_values;
self
}
pub fn with_max_segment_len(mut self, max_segment_len: usize) -> Self {
self.max_segment_len = max_segment_len;
self
}
pub fn with_metric_collection(mut self) -> Self {
self.collect_metrics = true;
self
}
pub fn without_metric_collection(mut self) -> Self {
self.collect_metrics = false;
self
}
pub fn has_public_values_chip(&self) -> bool {
!self.continuation_enabled && self.num_public_values > 0
}
pub fn memory_boundary_air_id(&self) -> usize {
let mut ret = PUBLIC_VALUES_AIR_ID;
if self.has_public_values_chip() {
ret += 1;
}
ret += BOUNDARY_AIR_OFFSET;
ret
}
}
impl Default for SystemConfig {
fn default() -> Self {
Self::new(
DEFAULT_POSEIDON2_MAX_CONSTRAINT_DEGREE,
Default::default(),
DEFAULT_MAX_NUM_PUBLIC_VALUES,
)
}
}
impl SystemTraceHeights {
pub fn round_to_next_power_of_two(&mut self) {
self.memory.round_to_next_power_of_two();
}
pub fn round_to_next_power_of_two_or_zero(&mut self) {
self.memory.round_to_next_power_of_two_or_zero();
}
}
impl<F: PrimeField32> VmConfig<F> for SystemConfig {
type Executor = SystemExecutor<F>;
type Periphery = SystemPeriphery<F>;
fn system(&self) -> &SystemConfig {
self
}
fn system_mut(&mut self) -> &mut SystemConfig {
self
}
fn create_chip_complex(
&self,
) -> Result<VmChipComplex<F, Self::Executor, Self::Periphery>, VmInventoryError> {
let complex = SystemComplex::new(self.clone());
Ok(complex)
}
}