Skip to content

Commit f745481

Browse files
committed
fix: add memcpy executer to tests + lint
1 parent c6e2232 commit f745481

File tree

14 files changed

+110
-57
lines changed

14 files changed

+110
-57
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmarks/execute/benches/execute.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,11 @@ where
193193
&config.keccak,
194194
inventory,
195195
)?;
196-
VmProverExtension::<E, _, _>::extend_prover(&MemcpyCpuProverExt, &config.memcpy, inventory)?;
196+
VmProverExtension::<E, _, _>::extend_prover(
197+
&MemcpyCpuProverExt,
198+
&config.memcpy,
199+
inventory,
200+
)?;
197201
VmProverExtension::<E, _, _>::extend_prover(&Sha2CpuProverExt, &config.sha256, inventory)?;
198202
VmProverExtension::<E, _, _>::extend_prover(
199203
&AlgebraCpuProverExt,

crates/sdk/src/config/global.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use openvm_ecc_circuit::{
1818
use openvm_ecc_transpiler::EccTranspilerExtension;
1919
use openvm_keccak256_circuit::{Keccak256, Keccak256CpuProverExt, Keccak256Executor};
2020
use openvm_keccak256_transpiler::Keccak256TranspilerExtension;
21+
use openvm_memcpy_circuit::{Memcpy, MemcpyCpuProverExt, MemcpyExecutor};
22+
use openvm_memcpy_transpiler::MemcpyTranspilerExtension;
2123
use openvm_native_circuit::{
2224
CastFExtension, CastFExtensionExecutor, Native, NativeCpuProverExt, NativeExecutor,
2325
};
@@ -33,8 +35,6 @@ use openvm_rv32im_circuit::{
3335
use openvm_rv32im_transpiler::{
3436
Rv32ITranspilerExtension, Rv32IoTranspilerExtension, Rv32MTranspilerExtension,
3537
};
36-
use openvm_memcpy_circuit::{Memcpy, MemcpyCpuProverExt, MemcpyExecutor};
37-
use openvm_memcpy_transpiler::MemcpyTranspilerExtension;
3838
use openvm_sha256_circuit::{Sha256, Sha256Executor, Sha2CpuProverExt};
3939
use openvm_sha256_transpiler::Sha256TranspilerExtension;
4040
use openvm_stark_backend::{

extensions/algebra/circuit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ openvm-stark-backend = { workspace = true }
1717
openvm-mod-circuit-builder = { workspace = true }
1818
openvm-stark-sdk = { workspace = true }
1919
openvm-rv32im-circuit = { workspace = true }
20+
openvm-memcpy-circuit = { workspace = true }
2021
openvm-rv32-adapters = { workspace = true }
2122
openvm-algebra-transpiler = { workspace = true }
2223
openvm-cuda-backend = { workspace = true, optional = true }

extensions/algebra/circuit/src/extension/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use openvm_circuit::{
99
system::{SystemChipInventory, SystemCpuBuilder, SystemExecutor},
1010
};
1111
use openvm_circuit_derive::VmConfig;
12+
use openvm_memcpy_circuit::{Memcpy, MemcpyCpuProverExt, MemcpyExecutor};
1213
use openvm_rv32im_circuit::{
1314
Rv32I, Rv32IExecutor, Rv32ImCpuProverExt, Rv32Io, Rv32IoExecutor, Rv32M, Rv32MExecutor,
1415
};
@@ -57,6 +58,8 @@ pub struct Rv32ModularConfig {
5758
pub io: Rv32Io,
5859
#[extension]
5960
pub modular: ModularExtension,
61+
#[extension]
62+
pub memcpy: Memcpy,
6063
}
6164

6265
impl InitFileGenerator for Rv32ModularConfig {
@@ -76,6 +79,7 @@ impl Rv32ModularConfig {
7679
mul: Default::default(),
7780
io: Default::default(),
7881
modular: ModularExtension::new(moduli),
82+
memcpy: Memcpy,
7983
}
8084
}
8185
}
@@ -143,6 +147,11 @@ where
143147
&config.modular,
144148
inventory,
145149
)?;
150+
VmProverExtension::<E, _, _>::extend_prover(
151+
&MemcpyCpuProverExt,
152+
&config.memcpy,
153+
inventory,
154+
)?;
146155
Ok(chip_complex)
147156
}
148157
}

extensions/memcpy/circuit/src/extension.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use openvm_circuit::{
1212
};
1313
use openvm_circuit_derive::{AnyEnum, Executor, MeteredExecutor, PreflightExecutor};
1414
use openvm_instructions::*;
15+
use openvm_memcpy_transpiler::Rv32MemcpyOpcode;
1516
use openvm_stark_backend::{
1617
config::{StarkGenericConfig, Val},
1718
engine::StarkEngine,
@@ -23,8 +24,6 @@ use strum::IntoEnumIterator;
2324

2425
use crate::*;
2526

26-
use openvm_memcpy_transpiler::Rv32MemcpyOpcode;
27-
2827
// =================================== VM Extension Implementation =================================
2928
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
3029
pub struct Memcpy;

extensions/memcpy/circuit/src/iteration.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ use crate::{
4848
bus::MemcpyBus, MemcpyLoopChip, A1_REGISTER_PTR, A2_REGISTER_PTR, A3_REGISTER_PTR,
4949
A4_REGISTER_PTR,
5050
};
51-
5251
// Import constants from lib.rs
5352
use crate::{MEMCPY_LOOP_LIMB_BITS, MEMCPY_LOOP_NUM_LIMBS};
5453

@@ -177,7 +176,8 @@ impl<AB: InteractionBuilder> Air<AB> for MemcpyIterAir {
177176
is_not_valid_when.assert_zero(local.is_boundary);
178177
is_not_valid_when.assert_zero(shift.clone());
179178

180-
// if is_valid_not_start = 1, then len = prev_len - 16, source = prev_source + 16, dest = prev_dest + 16
179+
// if is_valid_not_start = 1, then len = prev_len - 16, source = prev_source + 16,
180+
// and dest = prev_dest + 16
181181
let mut is_valid_not_start_when = builder.when(local.is_valid_not_start);
182182
is_valid_not_start_when
183183
.assert_eq(local.len[0], prev.len[0] - AB::Expr::from_canonical_u32(16));
@@ -190,7 +190,7 @@ impl<AB: InteractionBuilder> Air<AB> for MemcpyIterAir {
190190
builder
191191
.when(not::<AB::Expr>(prev.is_valid_not_start) - not::<AB::Expr>(prev.is_valid))
192192
.assert_eq(local.timestamp, prev.timestamp + is_shift_non_zero.clone());
193-
// if prev.is_valid_not_start and local.is_valid_not_start, then timestamp = prev_timestamp + 8
193+
// if prev.is_valid_not_start and local.is_valid_not_start, then timestamp=prev_timestamp+8
194194
// prev.is_valid_not_start is the opposite of previous condition
195195
builder
196196
.when(
@@ -602,8 +602,8 @@ impl<F: PrimeField32> TraceFiller<F> for MemcpyIterFiller {
602602
.for_each(|(row, (idx, var))| {
603603
let cols: &mut MemcpyIterCols<F> = row.borrow_mut();
604604

605-
let is_end = (idx == 0);
606-
let is_start = (idx == num_rows - 1);
605+
let is_end = idx == 0;
606+
let is_start = idx == num_rows - 1;
607607

608608
// Range check len
609609
let len_u16_limbs = [len & 0xffff, len >> 16];

extensions/memcpy/circuit/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
mod bus;
2-
mod core;
32
mod extension;
43
mod iteration;
4+
mod loops;
55

6-
pub use core::*;
76
pub use extension::*;
87
pub use iteration::*;
8+
pub use loops::*;
99

1010
// ==== Do not change these constants! ====
1111
pub const MEMCPY_LOOP_NUM_LIMBS: usize = 4;

extensions/memcpy/circuit/src/core.rs renamed to extensions/memcpy/circuit/src/loops.rs

Lines changed: 65 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,42 @@
11
use std::{
2-
array,
32
borrow::{Borrow, BorrowMut},
4-
mem::{align_of, size_of},
3+
mem::size_of,
54
sync::{Arc, Mutex},
65
};
76

87
use openvm_circuit::{
9-
arch::*,
10-
system::{memory::{
11-
offline_checker::{
12-
MemoryBaseAuxCols, MemoryBaseAuxRecord, MemoryBridge, MemoryExtendedAuxRecord, MemoryReadAuxRecord, MemoryWriteAuxCols, MemoryWriteBytesAuxRecord
8+
arch::{ExecutionBridge, ExecutionState},
9+
system::{
10+
memory::{
11+
offline_checker::{
12+
MemoryBaseAuxCols, MemoryBaseAuxRecord, MemoryBridge, MemoryExtendedAuxRecord,
13+
MemoryWriteAuxCols,
14+
},
15+
MemoryAddress, MemoryAuxColsFactory,
1316
},
14-
online::{GuestMemory, TracingMemory},
15-
MemoryAddress, MemoryAuxColsFactory,
16-
}, SystemPort},
17+
SystemPort,
18+
},
1719
};
1820
use openvm_circuit_primitives::{
1921
utils::{not, or, select},
2022
var_range::{SharedVariableRangeCheckerChip, VariableRangeCheckerBus},
2123
AlignedBytesBorrow,
2224
};
2325
use openvm_circuit_primitives_derive::AlignedBorrow;
24-
use openvm_instructions::{
25-
instruction::Instruction,
26-
program::DEFAULT_PC_STEP,
27-
riscv::{RV32_MEMORY_AS, RV32_REGISTER_AS},
28-
LocalOpcode,
29-
};
30-
use openvm_rv32im_circuit::adapters::{read_rv32_register, tracing_read, tracing_write};
26+
use openvm_instructions::riscv::RV32_MEMORY_AS;
27+
use openvm_memcpy_transpiler::Rv32MemcpyOpcode;
3128
use openvm_stark_backend::{
32-
config::{StarkGenericConfig, Val}, interaction::InteractionBuilder, p3_air::{Air, AirBuilder, BaseAir}, p3_field::{Field, FieldAlgebra, PrimeField32}, p3_matrix::{dense::RowMajorMatrix, Matrix}, prover::{cpu::CpuBackend, types::AirProvingContext}, rap::{get_air_name, BaseAirWithPublicValues, PartitionedBaseAir}, Chip, ChipUsageGetter
29+
config::{StarkGenericConfig, Val},
30+
interaction::InteractionBuilder,
31+
p3_air::{Air, AirBuilder, BaseAir},
32+
p3_field::{Field, FieldAlgebra, PrimeField32},
33+
p3_matrix::{dense::RowMajorMatrix, Matrix},
34+
prover::{cpu::CpuBackend, types::AirProvingContext},
35+
rap::{get_air_name, BaseAirWithPublicValues, PartitionedBaseAir},
36+
Chip, ChipUsageGetter,
3337
};
3438

35-
use crate::{bus::MemcpyBus, MemcpyIterChip};
36-
use openvm_circuit::arch::{
37-
execution_mode::{ExecutionCtxTrait, MeteredExecutionCtxTrait},
38-
get_record_from_slice, ExecuteFunc, ExecutionError, Executor, MeteredExecutor, RecordArena,
39-
StaticProgramError, TraceFiller, VmExecState,
40-
};
41-
use openvm_memcpy_transpiler::Rv32MemcpyOpcode;
42-
39+
use crate::bus::MemcpyBus;
4340
// Import constants from lib.rs
4441
use crate::{
4542
A1_REGISTER_PTR, A2_REGISTER_PTR, A3_REGISTER_PTR, A4_REGISTER_PTR, MEMCPY_LOOP_LIMB_BITS,
@@ -94,7 +91,8 @@ impl<AB: InteractionBuilder> Air<AB> for MemcpyLoopAir {
9491
let mut timestamp_delta: u32 = 0;
9592
let mut timestamp_pp = || {
9693
timestamp_delta += 1;
97-
local.to_timestamp - AB::Expr::from_canonical_u32(MEMCPY_LOOP_NUM_WRITES + timestamp_delta - 1)
94+
local.to_timestamp
95+
- AB::Expr::from_canonical_u32(MEMCPY_LOOP_NUM_WRITES + timestamp_delta - 1)
9896
};
9997

10098
let from_le_bytes = |data: [AB::Var; 4]| {
@@ -257,7 +255,8 @@ impl<AB: InteractionBuilder> Air<AB> for MemcpyLoopAir {
257255

258256
// Make sure the request and response match
259257
builder.assert_eq(
260-
local.to_timestamp - (local.from_state.timestamp + AB::Expr::from_canonical_u32(timestamp_delta)),
258+
local.to_timestamp
259+
- (local.from_state.timestamp + AB::Expr::from_canonical_u32(timestamp_delta)),
261260
AB::Expr::TWO * (len.clone() - to_len) + is_shift_non_zero.clone(),
262261
);
263262

@@ -301,7 +300,13 @@ impl MemcpyLoopChip {
301300
range_checker_chip: SharedVariableRangeCheckerChip,
302301
) -> Self {
303302
Self {
304-
air: MemcpyLoopAir::new(system_port.memory_bridge, ExecutionBridge::new(system_port.execution_bus, system_port.program_bus), range_bus, memcpy_bus, pointer_max_bits),
303+
air: MemcpyLoopAir::new(
304+
system_port.memory_bridge,
305+
ExecutionBridge::new(system_port.execution_bus, system_port.program_bus),
306+
range_bus,
307+
memcpy_bus,
308+
pointer_max_bits,
309+
),
305310
records: Arc::new(Mutex::new(Vec::new())),
306311
pointer_max_bits,
307312
range_checker_chip,
@@ -327,18 +332,24 @@ impl MemcpyLoopChip {
327332
shift: u8,
328333
register_aux: [MemoryBaseAuxRecord; 3],
329334
) {
330-
let mut timestamp = from_timestamp + (((len - shift as u32) & !0x0f) >> 1) + (shift != 0) as u32;
331-
let write_aux = register_aux.iter().map(|aux_record| {
332-
let mut aux_col = MemoryBaseAuxCols::default();
333-
mem_helper.fill(aux_record.prev_timestamp, timestamp, &mut aux_col);
334-
timestamp += 1;
335-
MemoryExtendedAuxRecord::from_aux_cols(aux_col)
336-
}).collect::<Vec<_>>().try_into().unwrap();
335+
let mut timestamp =
336+
from_timestamp + (((len - shift as u32) & !0x0f) >> 1) + (shift != 0) as u32;
337+
let write_aux = register_aux
338+
.iter()
339+
.map(|aux_record| {
340+
let mut aux_col = MemoryBaseAuxCols::default();
341+
mem_helper.fill(aux_record.prev_timestamp, timestamp, &mut aux_col);
342+
timestamp += 1;
343+
MemoryExtendedAuxRecord::from_aux_cols(aux_col)
344+
})
345+
.collect::<Vec<_>>()
346+
.try_into()
347+
.unwrap();
337348

338349
let num_copies = (len - shift as u32) & !0x0f;
339350
let to_dest = dest + num_copies;
340351
let to_source = source + num_copies;
341-
352+
342353
let word_to_u16 = |data: u32| [data & 0xffff, data >> 16];
343354
let range_check_data = [
344355
(word_to_u16(len), false),
@@ -379,7 +390,7 @@ impl MemcpyLoopChip {
379390

380391
/// Generates trace
381392
pub fn generate_trace<F: PrimeField32>(&self) -> RowMajorMatrix<F> {
382-
let mut rows = F::zero_vec((self.records.lock().unwrap().len() as usize) * NUM_MEMCPY_LOOP_COLS);
393+
let mut rows = F::zero_vec(self.records.lock().unwrap().len() * NUM_MEMCPY_LOOP_COLS);
383394

384395
for (i, record) in self.records.lock().unwrap().iter().enumerate() {
385396
let row = &mut rows[i * NUM_MEMCPY_LOOP_COLS..(i + 1) * NUM_MEMCPY_LOOP_COLS];
@@ -394,11 +405,22 @@ impl MemcpyLoopChip {
394405
cols.dest = record.dest.to_le_bytes().map(F::from_canonical_u8);
395406
cols.source = record.source.to_le_bytes().map(F::from_canonical_u8);
396407
cols.len = record.len.to_le_bytes().map(F::from_canonical_u8);
397-
cols.shift = [F::from_canonical_u8(shift % 2), F::from_canonical_u8(shift / 2)];
408+
cols.shift = [
409+
F::from_canonical_u8(shift % 2),
410+
F::from_canonical_u8(shift / 2),
411+
];
398412
cols.is_valid = F::ONE;
399-
// We have MEMCPY_LOOP_NUM_WRITES writes in the loop, (num_copies / 4 + shift != 0) reads and (num_copies / 4) writes in iterations
400-
cols.to_timestamp = F::from_canonical_u32(record.from_timestamp + MEMCPY_LOOP_NUM_WRITES + (num_copies >> 1) + (shift != 0) as u32);
401-
cols.to_dest = (record.dest + num_copies).to_le_bytes().map(F::from_canonical_u8);
413+
// We have MEMCPY_LOOP_NUM_WRITES writes in the loop, (num_copies / 4) writes
414+
// and (num_copies / 4 + shift != 0) reads in iterations
415+
cols.to_timestamp = F::from_canonical_u32(
416+
record.from_timestamp
417+
+ MEMCPY_LOOP_NUM_WRITES
418+
+ (num_copies >> 1)
419+
+ (shift != 0) as u32,
420+
);
421+
cols.to_dest = (record.dest + num_copies)
422+
.to_le_bytes()
423+
.map(F::from_canonical_u8);
402424
cols.to_source = to_source.to_le_bytes().map(F::from_canonical_u8);
403425
cols.to_len = F::from_canonical_u32(record.len - num_copies);
404426
cols.write_aux = record.write_aux.clone().map(|aux| aux.to_aux_cols());
@@ -426,10 +448,10 @@ impl ChipUsageGetter for MemcpyLoopChip {
426448
get_air_name(&self.air)
427449
}
428450
fn constant_trace_height(&self) -> Option<usize> {
429-
Some(self.records.lock().unwrap().len() as usize)
451+
Some(self.records.lock().unwrap().len())
430452
}
431453
fn current_trace_height(&self) -> usize {
432-
self.records.lock().unwrap().len() as usize
454+
self.records.lock().unwrap().len()
433455
}
434456
fn trace_width(&self) -> usize {
435457
NUM_MEMCPY_LOOP_COLS

extensions/pairing/circuit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ openvm-stark-backend = { workspace = true }
2323
openvm-rv32im-circuit = { workspace = true }
2424
openvm-algebra-circuit = { workspace = true }
2525
openvm-ecc-circuit = { workspace = true }
26+
openvm-memcpy-circuit = { workspace = true }
2627
openvm-pairing-transpiler = { workspace = true }
2728
openvm-cuda-backend = { workspace = true, optional = true }
2829
openvm-stark-sdk = { workspace = true, optional = true }

0 commit comments

Comments
 (0)