openvm_circuit/system/cuda/
extensions.rs1use std::sync::Arc;
2
3use openvm_circuit::{
4 arch::{
5 AirInventory, ChipInventory, ChipInventoryError, DenseRecordArena, SystemConfig, VmBuilder,
6 VmChipComplex,
7 },
8 system::poseidon2::air::Poseidon2PeripheryAir,
9};
10use openvm_circuit_primitives::{
11 bitwise_op_lookup::{
12 BitwiseOperationLookupAir, BitwiseOperationLookupChip, BitwiseOperationLookupChipGPU,
13 },
14 var_range::{VariableRangeCheckerAir, VariableRangeCheckerChip, VariableRangeCheckerChipGPU},
15};
16use openvm_cuda_backend::{BabyBearPoseidon2GpuEngine, GpuBackend};
17use openvm_stark_sdk::config::baby_bear_poseidon2::BabyBearPoseidon2Config;
18use p3_baby_bear::BabyBear;
19
20use super::{phantom::PhantomChipGPU, Poseidon2PeripheryChipGPU, SystemChipInventoryGPU};
21
22pub fn get_inventory_range_checker(
25 inventory: &mut ChipInventory<BabyBearPoseidon2Config, DenseRecordArena, GpuBackend>,
26) -> Arc<VariableRangeCheckerChipGPU> {
27 inventory
28 .find_chip::<Arc<VariableRangeCheckerChipGPU>>()
29 .next()
30 .unwrap()
31 .clone()
32}
33
34pub fn get_or_create_bitwise_op_lookup(
37 inventory: &mut ChipInventory<BabyBearPoseidon2Config, DenseRecordArena, GpuBackend>,
38) -> Result<Arc<BitwiseOperationLookupChipGPU<8>>, ChipInventoryError> {
39 let device_ctx = get_inventory_range_checker(inventory).device_ctx.clone();
40 let bitwise_lu = {
41 let existing_chip = inventory
42 .find_chip::<Arc<BitwiseOperationLookupChipGPU<8>>>()
43 .next();
44 if let Some(chip) = existing_chip {
45 chip.clone()
46 } else {
47 let air: &BitwiseOperationLookupAir<8> = inventory.next_air()?;
48
49 let chip = Arc::new(BitwiseOperationLookupChipGPU::hybrid(
50 Arc::new(BitwiseOperationLookupChip::new(air.bus)),
51 device_ctx,
52 ));
53 inventory.add_periphery_chip(chip.clone());
54 chip
55 }
56 };
57 Ok(bitwise_lu)
58}
59
60const POSEIDON2_INSERTION_IDX: usize = 1;
62pub const PV_EXECUTOR_IDX: usize = 0;
64
65#[derive(Clone)]
66pub struct SystemGpuBuilder;
67
68impl VmBuilder<BabyBearPoseidon2GpuEngine> for SystemGpuBuilder {
69 type VmConfig = SystemConfig;
70 type RecordArena = DenseRecordArena;
71 type SystemChipInventory = SystemChipInventoryGPU;
72
73 fn create_chip_complex(
74 &self,
75 config: &SystemConfig,
76 airs: AirInventory<BabyBearPoseidon2Config>,
77 device_ctx: &openvm_stark_backend::EngineDeviceCtx<BabyBearPoseidon2GpuEngine>,
78 ) -> Result<
79 VmChipComplex<
80 BabyBearPoseidon2Config,
81 DenseRecordArena,
82 GpuBackend,
83 SystemChipInventoryGPU,
84 >,
85 ChipInventoryError,
86 > {
87 let device_ctx = device_ctx.clone();
88 let range_bus = airs.range_checker().bus;
89 let range_checker = Arc::new(VariableRangeCheckerChipGPU::hybrid(
90 Arc::new(VariableRangeCheckerChip::new(range_bus)),
91 device_ctx.clone(),
92 ));
93
94 let mut inventory = ChipInventory::new(airs);
95 inventory.next_air::<VariableRangeCheckerAir>()?;
96 inventory.add_periphery_chip(range_checker.clone());
97
98 assert_eq!(inventory.chips().len(), POSEIDON2_INSERTION_IDX);
99 let sbox_registers = if config.max_constraint_degree >= 7 {
100 0
101 } else {
102 1
103 };
104 let _direct_bus = if sbox_registers == 0 {
106 inventory
107 .next_air::<Poseidon2PeripheryAir<BabyBear, 0>>()?
108 .bus
109 } else {
110 inventory
111 .next_air::<Poseidon2PeripheryAir<BabyBear, 1>>()?
112 .bus
113 };
114 let hasher_chip = Arc::new(Poseidon2PeripheryChipGPU::new(
115 sbox_registers,
116 device_ctx.clone(),
117 ));
118 inventory.add_periphery_chip(hasher_chip.clone());
119 let system =
120 SystemChipInventoryGPU::new(config, range_checker, hasher_chip, device_ctx.clone());
121
122 let phantom_chip = PhantomChipGPU::new(device_ctx.clone());
123 inventory.add_executor_chip(phantom_chip);
124
125 Ok(VmChipComplex { system, inventory })
126 }
127}