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