openvm_native_circuit/
lib.rs

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