openvm_native_circuit/
lib.rs

1#![cfg_attr(feature = "tco", allow(incomplete_features))]
2#![cfg_attr(feature = "tco", feature(explicit_tail_calls))]
3#![cfg_attr(feature = "tco", feature(core_intrinsics))]
4
5use openvm_circuit::{
6    arch::{
7        AirInventory, ChipInventoryError, InitFileGenerator, MatrixRecordArena, MemoryConfig,
8        SystemConfig, VmBuilder, VmChipComplex, VmProverExtension,
9    },
10    system::{SystemChipInventory, SystemCpuBuilder, SystemExecutor},
11};
12use openvm_circuit_derive::VmConfig;
13use openvm_rv32im_circuit::{
14    Rv32I, Rv32IExecutor, Rv32ImCpuProverExt, Rv32Io, Rv32IoExecutor, Rv32M, Rv32MExecutor,
15};
16use openvm_stark_backend::{
17    config::{StarkGenericConfig, Val},
18    p3_field::PrimeField32,
19    prover::cpu::{CpuBackend, CpuDevice},
20};
21use openvm_stark_sdk::engine::StarkEngine;
22use serde::{Deserialize, Serialize};
23
24cfg_if::cfg_if! {
25    if #[cfg(feature = "cuda")] {
26        use openvm_circuit::arch::DenseRecordArena;
27        use openvm_circuit::system::cuda::{extensions::SystemGpuBuilder, SystemChipInventoryGPU};
28        use openvm_cuda_backend::{engine::GpuBabyBearPoseidon2Engine, prover_backend::GpuBackend};
29        use openvm_stark_sdk::config::baby_bear_poseidon2::BabyBearPoseidon2Config;
30        pub(crate) mod cuda_abi;
31    }
32}
33pub use extension::NativeBuilder;
34
35pub mod adapters;
36
37mod branch_eq;
38mod castf;
39mod field_arithmetic;
40mod field_extension;
41mod fri;
42mod jal_rangecheck;
43mod loadstore;
44mod poseidon2;
45
46mod extension;
47pub use extension::*;
48
49mod utils;
50#[cfg(any(test, feature = "test-utils"))]
51pub use utils::test_utils::*;
52pub(crate) use utils::*;
53
54#[derive(Clone, Debug, derive_new::new, VmConfig, Serialize, Deserialize)]
55pub struct NativeConfig {
56    #[config(executor = "SystemExecutor<F>")]
57    pub system: SystemConfig,
58    #[extension(generics = true)]
59    pub native: Native,
60}
61
62impl NativeConfig {
63    pub fn aggregation(num_public_values: usize, max_constraint_degree: usize) -> Self {
64        Self {
65            system: SystemConfig::new(
66                max_constraint_degree,
67                MemoryConfig::aggregation(),
68                num_public_values,
69            )
70            .without_continuations()
71            .with_max_segment_len((1 << 24) - 100),
72            native: Default::default(),
73        }
74    }
75}
76
77// Default implementation uses no init file
78impl InitFileGenerator for NativeConfig {}
79
80#[derive(Clone, Default)]
81pub struct NativeCpuBuilder;
82
83impl<E, SC> VmBuilder<E> for NativeCpuBuilder
84where
85    SC: StarkGenericConfig,
86    E: StarkEngine<SC = SC, PB = CpuBackend<SC>, PD = CpuDevice<SC>>,
87    Val<SC>: PrimeField32,
88{
89    type VmConfig = NativeConfig;
90    type SystemChipInventory = SystemChipInventory<SC>;
91    type RecordArena = MatrixRecordArena<Val<SC>>;
92
93    fn create_chip_complex(
94        &self,
95        config: &NativeConfig,
96        circuit: AirInventory<SC>,
97    ) -> Result<
98        VmChipComplex<SC, Self::RecordArena, E::PB, Self::SystemChipInventory>,
99        ChipInventoryError,
100    > {
101        let mut chip_complex =
102            VmBuilder::<E>::create_chip_complex(&SystemCpuBuilder, &config.system, circuit)?;
103        let inventory = &mut chip_complex.inventory;
104        VmProverExtension::<E, _, _>::extend_prover(
105            &NativeCpuProverExt,
106            &config.native,
107            inventory,
108        )?;
109        Ok(chip_complex)
110    }
111}
112
113#[cfg(feature = "cuda")]
114#[derive(Clone, Default)]
115pub struct NativeGpuBuilder;
116
117#[cfg(feature = "cuda")]
118impl VmBuilder<GpuBabyBearPoseidon2Engine> for NativeGpuBuilder {
119    type VmConfig = NativeConfig;
120    type SystemChipInventory = SystemChipInventoryGPU;
121    type RecordArena = DenseRecordArena;
122
123    fn create_chip_complex(
124        &self,
125        config: &Self::VmConfig,
126        circuit: AirInventory<BabyBearPoseidon2Config>,
127    ) -> Result<
128        VmChipComplex<
129            BabyBearPoseidon2Config,
130            Self::RecordArena,
131            GpuBackend,
132            Self::SystemChipInventory,
133        >,
134        ChipInventoryError,
135    > {
136        let mut chip_complex = VmBuilder::<GpuBabyBearPoseidon2Engine>::create_chip_complex(
137            &SystemGpuBuilder,
138            &config.system,
139            circuit,
140        )?;
141        let inventory = &mut chip_complex.inventory;
142        VmProverExtension::<GpuBabyBearPoseidon2Engine, _, _>::extend_prover(
143            &NativeGpuProverExt,
144            &config.native,
145            inventory,
146        )?;
147        Ok(chip_complex)
148    }
149}
150
151#[derive(Clone, Debug, VmConfig, derive_new::new, Serialize, Deserialize)]
152pub struct Rv32WithKernelsConfig {
153    #[config(executor = "SystemExecutor<F>")]
154    pub system: SystemConfig,
155    #[extension]
156    pub rv32i: Rv32I,
157    #[extension]
158    pub rv32m: Rv32M,
159    #[extension]
160    pub io: Rv32Io,
161    #[extension(generics = true)]
162    pub native: Native,
163    #[extension]
164    pub castf: CastFExtension,
165}
166
167impl Default for Rv32WithKernelsConfig {
168    fn default() -> Self {
169        Self {
170            system: SystemConfig::default(),
171            rv32i: Rv32I,
172            rv32m: Rv32M::default(),
173            io: Rv32Io,
174            native: Native,
175            castf: CastFExtension,
176        }
177    }
178}
179
180// Default implementation uses no init file
181impl InitFileGenerator for Rv32WithKernelsConfig {}
182
183#[derive(Clone)]
184pub struct Rv32WithKernelsCpuBuilder;
185
186impl<E, SC> VmBuilder<E> for Rv32WithKernelsCpuBuilder
187where
188    SC: StarkGenericConfig,
189    E: StarkEngine<SC = SC, PB = CpuBackend<SC>, PD = CpuDevice<SC>>,
190    Val<SC>: PrimeField32,
191{
192    type VmConfig = Rv32WithKernelsConfig;
193    type SystemChipInventory = SystemChipInventory<SC>;
194    type RecordArena = MatrixRecordArena<Val<SC>>;
195
196    fn create_chip_complex(
197        &self,
198        config: &Rv32WithKernelsConfig,
199        circuit: AirInventory<SC>,
200    ) -> Result<
201        VmChipComplex<SC, Self::RecordArena, E::PB, Self::SystemChipInventory>,
202        ChipInventoryError,
203    > {
204        let mut chip_complex =
205            VmBuilder::<E>::create_chip_complex(&SystemCpuBuilder, &config.system, circuit)?;
206        let inventory = &mut chip_complex.inventory;
207        VmProverExtension::<E, _, _>::extend_prover(&Rv32ImCpuProverExt, &config.rv32i, inventory)?;
208        VmProverExtension::<E, _, _>::extend_prover(&Rv32ImCpuProverExt, &config.rv32m, inventory)?;
209        VmProverExtension::<E, _, _>::extend_prover(&Rv32ImCpuProverExt, &config.io, inventory)?;
210        VmProverExtension::<E, _, _>::extend_prover(
211            &NativeCpuProverExt,
212            &config.native,
213            inventory,
214        )?;
215        VmProverExtension::<E, _, _>::extend_prover(&NativeCpuProverExt, &config.castf, inventory)?;
216        Ok(chip_complex)
217    }
218}