From 3bb111ba7d08e1b68f446db1a901688d8ada268f Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Tue, 19 Nov 2024 16:39:54 -0800 Subject: [PATCH 01/18] dummy columns --- crates/core/machine/src/cpu/columns/mod.rs | 2 + crates/core/machine/src/cpu/trace.rs | 59 +++++++++++++ crates/recursion/core/src/chips/alu_base.rs | 3 + crates/recursion/core/src/chips/alu_ext.rs | 2 + crates/recursion/core/src/chips/batch_fri.rs | 2 + .../core/src/chips/exp_reverse_bits.rs | 2 + crates/recursion/core/src/chips/fri_fold.rs | 2 + crates/recursion/core/src/chips/select.rs | 3 + examples/Cargo.lock | 87 ++++++++++++------- 9 files changed, 129 insertions(+), 33 deletions(-) diff --git a/crates/core/machine/src/cpu/columns/mod.rs b/crates/core/machine/src/cpu/columns/mod.rs index 7a32b03db5..d6fc9c652f 100644 --- a/crates/core/machine/src/cpu/columns/mod.rs +++ b/crates/core/machine/src/cpu/columns/mod.rs @@ -112,6 +112,8 @@ pub struct CpuCols { /// This is true for all instructions that are not jumps, branches, and halt. Those /// instructions may move the program counter to a non sequential instruction. pub is_sequential_instr: T, + + pub dummy_cols: [MemoryReadWriteCols; 15], } impl CpuCols { diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index 5a43202608..e05c81b471 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -71,6 +71,65 @@ impl MachineAir for CpuChip { }, ); + let mut instruction_group_by = HashMap::::new(); + for cpu_event in input.cpu_events.iter() { + let instruction = &input.program.fetch(cpu_event.pc); + + match instruction.opcode { + Opcode::ADD | Opcode::SUB => { + *instruction_group_by.entry("AddSub".to_string()).or_insert(0) += 1; + } + Opcode::SLT | Opcode::SLTU => { + *instruction_group_by.entry("Lt".to_string()).or_insert(0) += 1; + } + Opcode::SLL => { + *instruction_group_by.entry("ShiftLeft".to_string()).or_insert(0) += 1; + } + Opcode::SRL | Opcode::SRA => { + *instruction_group_by.entry("ShiftRight".to_string()).or_insert(0) += 1; + } + Opcode::XOR | Opcode::OR | Opcode::AND => { + *instruction_group_by.entry("Bitwise".to_string()).or_insert(0) += 1; + } + Opcode::MUL | Opcode::MULH | Opcode::MULHSU | Opcode::MULHU => { + *instruction_group_by.entry("Mul".to_string()).or_insert(0) += 1; + } + Opcode::DIV | Opcode::DIVU | Opcode::REM | Opcode::REMU => { + *instruction_group_by.entry("DivRem".to_string()).or_insert(0) += 1; + } + Opcode::LB + | Opcode::LH + | Opcode::LW + | Opcode::LBU + | Opcode::LHU + | Opcode::SB + | Opcode::SH + | Opcode::SW => { + *instruction_group_by.entry("MEMORY".to_string()).or_insert(0) += 1; + } + Opcode::BEQ + | Opcode::BNE + | Opcode::BLT + | Opcode::BGE + | Opcode::BLTU + | Opcode::BGEU => { + *instruction_group_by.entry("BRANCH".to_string()).or_insert(0) += 1; + } + Opcode::JALR | Opcode::JAL => { + *instruction_group_by.entry("JUMP".to_string()).or_insert(0) += 1; + } + Opcode::AUIPC => { + *instruction_group_by.entry("AUIPC".to_string()).or_insert(0) += 1; + } + Opcode::ECALL => { + *instruction_group_by.entry("ECALL".to_string()).or_insert(0) += 1; + } + _ => unreachable!(), + } + } + + println!("instruction_group_by: {:?}", instruction_group_by); + // Convert the trace to a row major matrix. RowMajorMatrix::new(values, NUM_CPU_COLS) } diff --git a/crates/recursion/core/src/chips/alu_base.rs b/crates/recursion/core/src/chips/alu_base.rs index f587c73ce8..afafb030e0 100644 --- a/crates/recursion/core/src/chips/alu_base.rs +++ b/crates/recursion/core/src/chips/alu_base.rs @@ -126,6 +126,9 @@ impl MachineAir for BaseAluChip { fn generate_trace(&self, input: &Self::Record, _: &mut Self::Record) -> RowMajorMatrix { let events = &input.base_alu_events; let nb_rows = events.len().div_ceil(NUM_BASE_ALU_ENTRIES_PER_ROW); + + println!("num rows for base alu: {}", nb_rows); + let fixed_log2_rows = input.fixed_log2_rows(self); let padded_nb_rows = match fixed_log2_rows { Some(log2_rows) => 1 << log2_rows, diff --git a/crates/recursion/core/src/chips/alu_ext.rs b/crates/recursion/core/src/chips/alu_ext.rs index b698a5d209..5369a3a1fd 100644 --- a/crates/recursion/core/src/chips/alu_ext.rs +++ b/crates/recursion/core/src/chips/alu_ext.rs @@ -124,6 +124,8 @@ impl> MachineAir for ExtAluChip { fn generate_trace(&self, input: &Self::Record, _: &mut Self::Record) -> RowMajorMatrix { let events = &input.ext_alu_events; let nb_rows = events.len().div_ceil(NUM_EXT_ALU_ENTRIES_PER_ROW); + + println!("num rows for ext alu: {}", nb_rows); let fixed_log2_rows = input.fixed_log2_rows(self); let padded_nb_rows = match fixed_log2_rows { Some(log2_rows) => 1 << log2_rows, diff --git a/crates/recursion/core/src/chips/batch_fri.rs b/crates/recursion/core/src/chips/batch_fri.rs index 6522a9881d..ceb285e6b4 100644 --- a/crates/recursion/core/src/chips/batch_fri.rs +++ b/crates/recursion/core/src/chips/batch_fri.rs @@ -137,6 +137,8 @@ impl MachineAir for BatchFRIChip MachineAir for ExpReverseBitsLenCh overall_rows.extend(rows); }); + println!("num rows for exp reverse bits len: {}", overall_rows.len()); + // Pad the trace to a power of two. pad_rows_fixed( &mut overall_rows, diff --git a/crates/recursion/core/src/chips/fri_fold.rs b/crates/recursion/core/src/chips/fri_fold.rs index 063037032c..34b89e7d8b 100644 --- a/crates/recursion/core/src/chips/fri_fold.rs +++ b/crates/recursion/core/src/chips/fri_fold.rs @@ -209,6 +209,8 @@ impl MachineAir for FriFoldChip }) .collect_vec(); + println!("num rows for fri fold: {}", rows.len()); + // Pad the trace to a power of two. if self.pad { pad_rows_fixed(&mut rows, || [F::zero(); NUM_FRI_FOLD_COLS], self.fixed_log2_rows); diff --git a/crates/recursion/core/src/chips/select.rs b/crates/recursion/core/src/chips/select.rs index d1c44d9b94..091c927e56 100644 --- a/crates/recursion/core/src/chips/select.rs +++ b/crates/recursion/core/src/chips/select.rs @@ -96,6 +96,9 @@ impl MachineAir for SelectChip { fn generate_trace(&self, input: &Self::Record, _: &mut Self::Record) -> RowMajorMatrix { let events = &input.select_events; let nb_rows = events.len(); + + println!("num rows for select: {}", nb_rows); + let fixed_log2_rows = input.fixed_log2_rows(self); let padded_nb_rows = match fixed_log2_rows { Some(log2_rows) => 1 << log2_rows, diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 9acc219708..e49818b5e7 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -219,7 +219,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "tracing", ] @@ -241,7 +241,7 @@ dependencies = [ "async-trait", "auto_impl", "futures-utils-wasm", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -426,7 +426,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -442,7 +442,7 @@ dependencies = [ "async-trait", "k256", "rand 0.8.5", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1053,7 +1053,7 @@ version = "1.1.0" dependencies = [ "rand 0.8.5", "sp1-zkvm", - "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v1)", + "substrate-bn", ] [[package]] @@ -1155,7 +1155,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1834,7 +1834,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "sha2 0.9.9", - "thiserror", + "thiserror 1.0.68", "zeroize", ] @@ -3846,7 +3846,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.68", "ucd-trie", ] @@ -4106,7 +4106,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls", "socket2", - "thiserror", + "thiserror 1.0.68", "tokio", "tracing", ] @@ -4123,7 +4123,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls", "slab", - "thiserror", + "thiserror 1.0.68", "tinyvec", "tracing", ] @@ -4289,7 +4289,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4407,7 +4407,7 @@ dependencies = [ "http", "reqwest", "serde", - "thiserror", + "thiserror 1.0.68", "tower-service", ] @@ -4420,7 +4420,7 @@ dependencies = [ "reth-execution-errors", "reth-primitives", "reth-storage-errors", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4514,7 +4514,7 @@ dependencies = [ "reth-execution-errors", "reth-fs-util", "reth-storage-errors", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4598,7 +4598,7 @@ dependencies = [ "reth-revm", "revm", "revm-primitives", - "thiserror", + "thiserror 1.0.68", "tracing", ] @@ -4637,7 +4637,7 @@ source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374 dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4649,7 +4649,7 @@ dependencies = [ "alloy-rlp", "enr", "serde_with", - "thiserror", + "thiserror 1.0.68", "url", ] @@ -4706,7 +4706,7 @@ dependencies = [ "reth-trie-common", "revm-primitives", "serde", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4741,7 +4741,7 @@ dependencies = [ "modular-bitfield", "reth-codecs", "serde", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4891,7 +4891,7 @@ dependencies = [ "ripemd", "secp256k1", "sha2 0.10.8", - "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v1)", + "substrate-bn", ] [[package]] @@ -5090,7 +5090,7 @@ dependencies = [ "rlp", "rsp-primitives", "serde", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -5713,7 +5713,7 @@ dependencies = [ "sp1-stark", "strum", "strum_macros", - "thiserror", + "thiserror 1.0.68", "tiny-keccak", "tracing", "typenum", @@ -5758,7 +5758,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror", + "thiserror 1.0.68", "tracing", "tracing-forest", "tracing-subscriber", @@ -5888,7 +5888,7 @@ dependencies = [ "sp1-recursion-core", "sp1-recursion-gnark-ffi", "sp1-stark", - "thiserror", + "thiserror 1.0.68", "tracing", "tracing-subscriber", ] @@ -5973,7 +5973,7 @@ dependencies = [ "sp1-primitives", "sp1-stark", "static_assertions", - "thiserror", + "thiserror 1.0.68", "tracing", "vec_map", "zkhash", @@ -6045,7 +6045,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror", + "thiserror 1.0.68", "tokio", "tracing", "twirp-rs", @@ -6091,8 +6091,8 @@ dependencies = [ "hex", "lazy_static", "sha2 0.10.8", - "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v2)", - "thiserror-no-std", + "substrate-bn-succinct", + "thiserror 2.0.3", ] [[package]] @@ -6258,9 +6258,10 @@ dependencies = [ ] [[package]] -name = "substrate-bn" +name = "substrate-bn-succinct" version = "0.6.0" -source = "git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v2#8ef05d3969312eca34fa9f1f566a469022badda6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "114c855c26ad0594c830129cb868552fb41415603a6133276c2ecdd9e5ef4255" dependencies = [ "bytemuck", "byteorder", @@ -6486,7 +6487,16 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.68", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] @@ -6500,6 +6510,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "thiserror-impl-no-std" version = "2.0.2" @@ -6756,7 +6777,7 @@ checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" dependencies = [ "ansi_term", "smallvec", - "thiserror", + "thiserror 1.0.68", "tracing", "tracing-subscriber", ] @@ -6812,7 +6833,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "tokio", "tower", "url", From bc34538fda99e692e1fc0bf4389f0ebb32cea4a1 Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Wed, 20 Nov 2024 18:45:37 -0800 Subject: [PATCH 02/18] checkpoint --- crates/core/executor/src/events/memory.rs | 9 + crates/core/executor/src/record.rs | 21 +- crates/core/machine/src/alu/add_sub/mod.rs | 4 +- crates/core/machine/src/alu/bitwise/mod.rs | 2 +- crates/core/machine/src/alu/divrem/mod.rs | 12 +- crates/core/machine/src/alu/lt/mod.rs | 2 +- crates/core/machine/src/alu/mul/mod.rs | 2 +- crates/core/machine/src/alu/sll/mod.rs | 2 +- crates/core/machine/src/alu/sr/mod.rs | 2 +- crates/core/machine/src/cpu/air/branch.rs | 6 +- crates/core/machine/src/cpu/air/mod.rs | 15 +- crates/core/machine/src/cpu/columns/mod.rs | 2 - .../src/cpu/columns/opcode_specific.rs | 13 +- crates/core/machine/src/cpu/trace.rs | 130 +-------- .../src/memory/{ => consistency}/columns.rs | 0 .../machine/src/memory/consistency/mod.rs | 4 + .../src/memory/{ => consistency}/trace.rs | 0 .../memory.rs => memory/instructions/air.rs} | 251 ++++++++---------- .../instructions/columns.rs} | 30 ++- .../machine/src/memory/instructions/mod.rs | 6 + .../machine/src/memory/instructions/trace.rs | 116 ++++++++ crates/core/machine/src/memory/mod.rs | 9 +- crates/core/machine/src/riscv/mod.rs | 7 +- crates/stark/src/air/builder.rs | 18 +- crates/stark/src/lookup/builder.rs | 4 +- crates/stark/src/lookup/interaction.rs | 15 +- 26 files changed, 347 insertions(+), 335 deletions(-) rename crates/core/machine/src/memory/{ => consistency}/columns.rs (100%) create mode 100644 crates/core/machine/src/memory/consistency/mod.rs rename crates/core/machine/src/memory/{ => consistency}/trace.rs (100%) rename crates/core/machine/src/{cpu/air/memory.rs => memory/instructions/air.rs} (58%) rename crates/core/machine/src/{cpu/columns/memory.rs => memory/instructions/columns.rs} (68%) create mode 100644 crates/core/machine/src/memory/instructions/mod.rs create mode 100644 crates/core/machine/src/memory/instructions/trace.rs diff --git a/crates/core/executor/src/events/memory.rs b/crates/core/executor/src/events/memory.rs index 655e0fc21d..071f0f21f7 100644 --- a/crates/core/executor/src/events/memory.rs +++ b/crates/core/executor/src/events/memory.rs @@ -232,3 +232,12 @@ pub struct MemoryLocalEvent { /// The final memory access. pub final_mem_access: MemoryRecord, } + +/// Memory Instructions Event. +/// +/// This object encapsulates the information needed to prove a memory instruction operation. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct MemoryInstructionsEvent { + /// The address. + pub addr: u32, +} diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index f9e89acb4c..61b509e8a1 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -13,8 +13,8 @@ use super::{program::Program, Opcode}; use crate::{ events::{ add_sharded_byte_lookup_events, AluEvent, ByteLookupEvent, ByteRecord, CpuEvent, LookupId, - MemoryInitializeFinalizeEvent, MemoryLocalEvent, MemoryRecordEnum, PrecompileEvent, - PrecompileEvents, SyscallEvent, + MemoryInitializeFinalizeEvent, MemoryInstructionsEvent, MemoryLocalEvent, MemoryRecordEnum, + PrecompileEvent, PrecompileEvents, SyscallEvent, }, syscalls::SyscallCode, CoreShape, @@ -45,6 +45,8 @@ pub struct ExecutionRecord { pub divrem_events: Vec, /// A trace of the SLT, SLTI, SLTU, and SLTIU events. pub lt_events: Vec, + /// A trace of the memory instructions. + pub memory_instructions_events: Vec, /// A trace of the byte lookups that are needed. pub byte_lookups: HashMap>, /// A trace of the precompile events. @@ -80,6 +82,7 @@ impl Default for ExecutionRecord { shift_right_events: Vec::default(), divrem_events: Vec::default(), lt_events: Vec::default(), + memory_instructions_events: Vec::default(), byte_lookups: HashMap::default(), precompile_events: PrecompileEvents::default(), global_memory_initialize_events: Vec::default(), @@ -161,6 +164,15 @@ impl ExecutionRecord { } } + /// Add a memory instructions event to the execution record. + pub fn add_memory_instructions_event( + &mut self, + memory_instructions_event: MemoryInstructionsEvent, + ) { + self.memory_instructions_events.push(memory_instructions_event); + } + + /// Take out events from the [`ExecutionRecord`] that should be deferred to a separate shard. /// Take out events from the [`ExecutionRecord`] that should be deferred to a separate shard. /// /// Note: we usually defer events that would increase the recursion cost significantly if @@ -331,6 +343,10 @@ impl MachineRecord for ExecutionRecord { stats.insert("shift_right_events".to_string(), self.shift_right_events.len()); stats.insert("divrem_events".to_string(), self.divrem_events.len()); stats.insert("lt_events".to_string(), self.lt_events.len()); + stats.insert( + "memory_instructions_events".to_string(), + self.memory_instructions_events.len(), + ); for (syscall_code, events) in self.precompile_events.iter() { stats.insert(format!("syscall {syscall_code:?}"), events.len()); @@ -367,6 +383,7 @@ impl MachineRecord for ExecutionRecord { self.shift_right_events.append(&mut other.shift_right_events); self.divrem_events.append(&mut other.divrem_events); self.lt_events.append(&mut other.lt_events); + self.memory_instructions_events.append(&mut other.memory_instructions_events); self.syscall_events.append(&mut other.syscall_events); self.precompile_events.append(&mut other.precompile_events); diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index d276820755..666400b2c2 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -193,7 +193,7 @@ where // Receive the arguments. There are separate receives for ADD and SUB. // For add, `add_operation.value` is `a`, `operand_1` is `b`, and `operand_2` is `c`. - builder.receive_alu( + builder.receive_instruction( Opcode::ADD.as_field::(), local.add_operation.value, local.operand_1, @@ -204,7 +204,7 @@ where ); // For sub, `operand_1` is `a`, `add_operation.value` is `b`, and `operand_2` is `c`. - builder.receive_alu( + builder.receive_instruction( Opcode::SUB.as_field::(), local.operand_1, local.add_operation.value, diff --git a/crates/core/machine/src/alu/bitwise/mod.rs b/crates/core/machine/src/alu/bitwise/mod.rs index 88156e286c..9e89213838 100644 --- a/crates/core/machine/src/alu/bitwise/mod.rs +++ b/crates/core/machine/src/alu/bitwise/mod.rs @@ -205,7 +205,7 @@ where + local.is_and * Opcode::AND.as_field::(); // Receive the arguments. - builder.receive_alu( + builder.receive_instruction( cpu_opcode, local.a, local.b, diff --git a/crates/core/machine/src/alu/divrem/mod.rs b/crates/core/machine/src/alu/divrem/mod.rs index 1d4d539fc4..a4afea3067 100644 --- a/crates/core/machine/src/alu/divrem/mod.rs +++ b/crates/core/machine/src/alu/divrem/mod.rs @@ -496,7 +496,7 @@ where ]; // The lower 4 bytes of c_times_quotient must match the lower 4 bytes of (c * quotient). - builder.send_alu( + builder.send_instruction( AB::Expr::from_canonical_u32(Opcode::MUL as u32), Word(lower_half), local.quotient, @@ -521,7 +521,7 @@ where local.c_times_quotient[7].into(), ]; - builder.send_alu( + builder.send_instruction( opcode_for_upper_half, Word(upper_half), local.quotient, @@ -679,7 +679,7 @@ where } // In the case that `c` or `rem` is negative, instead check that their sum is zero by // sending an AddEvent. - builder.send_alu( + builder.send_instruction( AB::Expr::from_canonical_u32(Opcode::ADD as u32), Word([zero.clone(), zero.clone(), zero.clone(), zero.clone()]), local.c, @@ -688,7 +688,7 @@ where local.abs_c_alu_event_nonce, local.abs_c_alu_event, ); - builder.send_alu( + builder.send_instruction( AB::Expr::from_canonical_u32(Opcode::ADD as u32), Word([zero.clone(), zero.clone(), zero.clone(), zero.clone()]), local.remainder, @@ -734,7 +734,7 @@ where // Dispatch abs(remainder) < max(abs(c), 1), this is equivalent to abs(remainder) < // abs(c) if not division by 0. - builder.send_alu( + builder.send_instruction( AB::Expr::from_canonical_u32(Opcode::SLTU as u32), Word([one.clone(), zero.clone(), zero.clone(), zero.clone()]), local.abs_remainder, @@ -816,7 +816,7 @@ where + local.is_rem * rem }; - builder.receive_alu( + builder.receive_instruction( opcode, local.a, local.b, diff --git a/crates/core/machine/src/alu/lt/mod.rs b/crates/core/machine/src/alu/lt/mod.rs index 876fdaaf8f..9b348d813c 100644 --- a/crates/core/machine/src/alu/lt/mod.rs +++ b/crates/core/machine/src/alu/lt/mod.rs @@ -441,7 +441,7 @@ where builder.assert_bool(local.is_slt + local.is_sltu); // Receive the arguments. - builder.receive_alu( + builder.receive_instruction( local.is_slt * AB::F::from_canonical_u32(Opcode::SLT as u32) + local.is_sltu * AB::F::from_canonical_u32(Opcode::SLTU as u32), local.a, diff --git a/crates/core/machine/src/alu/mul/mod.rs b/crates/core/machine/src/alu/mul/mod.rs index 6a1ce272fe..0cd919bd96 100644 --- a/crates/core/machine/src/alu/mul/mod.rs +++ b/crates/core/machine/src/alu/mul/mod.rs @@ -441,7 +441,7 @@ where } // Receive the arguments. - builder.receive_alu( + builder.receive_instruction( opcode, local.a, local.b, diff --git a/crates/core/machine/src/alu/sll/mod.rs b/crates/core/machine/src/alu/sll/mod.rs index af00dd47a5..f8a7e06a5d 100644 --- a/crates/core/machine/src/alu/sll/mod.rs +++ b/crates/core/machine/src/alu/sll/mod.rs @@ -386,7 +386,7 @@ where builder.assert_bool(local.is_real); // Receive the arguments. - builder.receive_alu( + builder.receive_instruction( AB::F::from_canonical_u32(Opcode::SLL as u32), local.a, local.b, diff --git a/crates/core/machine/src/alu/sr/mod.rs b/crates/core/machine/src/alu/sr/mod.rs index b26c949945..fec93c4334 100644 --- a/crates/core/machine/src/alu/sr/mod.rs +++ b/crates/core/machine/src/alu/sr/mod.rs @@ -506,7 +506,7 @@ where builder.assert_eq(local.is_srl + local.is_sra, local.is_real); // Receive the arguments. - builder.receive_alu( + builder.receive_instruction( local.is_srl * AB::F::from_canonical_u32(Opcode::SRL as u32) + local.is_sra * AB::F::from_canonical_u32(Opcode::SRA as u32), local.a, diff --git a/crates/core/machine/src/cpu/air/branch.rs b/crates/core/machine/src/cpu/air/branch.rs index d8c615682f..0fb0271609 100644 --- a/crates/core/machine/src/cpu/air/branch.rs +++ b/crates/core/machine/src/cpu/air/branch.rs @@ -82,7 +82,7 @@ impl CpuChip { ); // When we are branching, calculate branch_cols.next_pc <==> branch_cols.pc + c. - builder.send_alu( + builder.send_instruction( Opcode::ADD.as_field::(), branch_cols.next_pc, branch_cols.pc, @@ -177,7 +177,7 @@ impl CpuChip { // Calculate a_lt_b <==> a < b (using appropriate signedness). let use_signed_comparison = local.selectors.is_blt + local.selectors.is_bge; - builder.send_alu( + builder.send_instruction( use_signed_comparison.clone() * Opcode::SLT.as_field::() + (AB::Expr::one() - use_signed_comparison.clone()) * Opcode::SLTU.as_field::(), @@ -190,7 +190,7 @@ impl CpuChip { ); // Calculate a_gt_b <==> a > b (using appropriate signedness). - builder.send_alu( + builder.send_instruction( use_signed_comparison.clone() * Opcode::SLT.as_field::() + (AB::Expr::one() - use_signed_comparison) * Opcode::SLTU.as_field::(), Word::extend_var::(branch_cols.a_gt_b), diff --git a/crates/core/machine/src/cpu/air/mod.rs b/crates/core/machine/src/cpu/air/mod.rs index 35b6dc18af..7b3da94d84 100644 --- a/crates/core/machine/src/cpu/air/mod.rs +++ b/crates/core/machine/src/cpu/air/mod.rs @@ -1,6 +1,5 @@ pub mod branch; pub mod ecall; -pub mod memory; pub mod register; use core::borrow::Borrow; @@ -47,20 +46,14 @@ where ); // Compute some flags for which type of instruction we are dealing with. - let is_memory_instruction: AB::Expr = self.is_memory_instruction::(&local.selectors); let is_branch_instruction: AB::Expr = self.is_branch_instruction::(&local.selectors); let is_alu_instruction: AB::Expr = self.is_alu_instruction::(&local.selectors); // Register constraints. self.eval_registers::(builder, local, is_branch_instruction.clone()); - // Memory instructions. - self.eval_memory_address_and_access::(builder, local, is_memory_instruction.clone()); - self.eval_memory_load::(builder, local); - self.eval_memory_store::(builder, local); - // ALU instructions. - builder.send_alu( + builder.send_instruction( local.instruction.opcode, local.op_a_val(), local.op_b_val(), @@ -190,7 +183,7 @@ impl CpuChip { ); // Verify that the new pc is calculated correctly for JAL instructions. - builder.send_alu( + builder.send_instruction( AB::Expr::from_canonical_u32(Opcode::ADD as u32), jump_columns.next_pc, jump_columns.pc, @@ -201,7 +194,7 @@ impl CpuChip { ); // Verify that the new pc is calculated correctly for JALR instructions. - builder.send_alu( + builder.send_instruction( AB::Expr::from_canonical_u32(Opcode::ADD as u32), jump_columns.next_pc, local.op_b_val(), @@ -229,7 +222,7 @@ impl CpuChip { ); // Verify that op_a == pc + op_b. - builder.send_alu( + builder.send_instruction( AB::Expr::from_canonical_u32(Opcode::ADD as u32), local.op_a_val(), auipc_columns.pc, diff --git a/crates/core/machine/src/cpu/columns/mod.rs b/crates/core/machine/src/cpu/columns/mod.rs index d6fc9c652f..67d14f179a 100644 --- a/crates/core/machine/src/cpu/columns/mod.rs +++ b/crates/core/machine/src/cpu/columns/mod.rs @@ -3,7 +3,6 @@ mod branch; mod ecall; mod instruction; mod jump; -mod memory; mod opcode; mod opcode_specific; @@ -12,7 +11,6 @@ pub use branch::*; pub use ecall::*; pub use instruction::*; pub use jump::*; -pub use memory::*; pub use opcode::*; pub use opcode_specific::*; diff --git a/crates/core/machine/src/cpu/columns/opcode_specific.rs b/crates/core/machine/src/cpu/columns/opcode_specific.rs index 8406434ef7..411de16e54 100644 --- a/crates/core/machine/src/cpu/columns/opcode_specific.rs +++ b/crates/core/machine/src/cpu/columns/opcode_specific.rs @@ -1,4 +1,4 @@ -use crate::cpu::columns::{AuipcCols, BranchCols, JumpCols, MemoryColumns}; +use crate::cpu::columns::{AuipcCols, BranchCols, JumpCols}; use std::{ fmt::{Debug, Formatter}, mem::{size_of, transmute}, @@ -14,7 +14,6 @@ pub const NUM_OPCODE_SPECIFIC_COLS: usize = size_of::>(); #[derive(Clone, Copy)] #[repr(C)] pub union OpcodeSpecificCols { - memory: MemoryColumns, branch: BranchCols, jump: JumpCols, auipc: AuipcCols, @@ -24,9 +23,9 @@ pub union OpcodeSpecificCols { impl Default for OpcodeSpecificCols { fn default() -> Self { // We must use the largest field to avoid uninitialized padding bytes. - const_assert!(size_of::>() == size_of::>()); + const_assert!(size_of::>() == size_of::>()); - OpcodeSpecificCols { memory: MemoryColumns::default() } + OpcodeSpecificCols { jump: JumpCols::default() } } } @@ -40,12 +39,6 @@ impl Debug for OpcodeSpecificCols { // SAFETY: Each view is a valid interpretation of the underlying array. impl OpcodeSpecificCols { - pub fn memory(&self) -> &MemoryColumns { - unsafe { &self.memory } - } - pub fn memory_mut(&mut self) -> &mut MemoryColumns { - unsafe { &mut self.memory } - } pub fn branch(&self) -> &BranchCols { unsafe { &self.branch } } diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index e05c81b471..6c4e96c2b4 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -5,11 +5,9 @@ use sp1_core_executor::{ syscalls::SyscallCode, ByteOpcode::{self, U16Range}, ExecutionRecord, Instruction, Opcode, Program, - Register::X0, }; -use sp1_primitives::consts::WORD_SIZE; use sp1_stark::{air::MachineAir, Word}; -use std::{array, borrow::BorrowMut}; +use std::borrow::BorrowMut; use p3_field::{PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; @@ -240,14 +238,7 @@ impl CpuChip { c: a_bytes[3] as u8, }); - // Populate memory accesses for reading from memory. - let memory_columns = cols.opcode_specific_columns.memory_mut(); - if let Some(record) = event.memory_record { - memory_columns.memory_access.populate(record, blu_events) - } - // Populate memory, branch, jump, and auipc specific fields. - self.populate_memory(cols, event, blu_events, nonce_lookup, shard, instruction); self.populate_branch(cols, event, nonce_lookup, instruction); self.populate_jump(cols, event, nonce_lookup, instruction); self.populate_auipc(cols, event, nonce_lookup, instruction); @@ -303,125 +294,6 @@ impl CpuChip { )); } - /// Populates columns related to memory. - fn populate_memory( - &self, - cols: &mut CpuCols, - event: &CpuEvent, - blu_events: &mut impl ByteRecord, - nonce_lookup: &[u32], - shard: u32, - instruction: &Instruction, - ) { - if !matches!( - instruction.opcode, - Opcode::LB - | Opcode::LH - | Opcode::LW - | Opcode::LBU - | Opcode::LHU - | Opcode::SB - | Opcode::SH - | Opcode::SW - ) { - return; - } - - // Populate addr_word and addr_aligned columns. - let memory_columns = cols.opcode_specific_columns.memory_mut(); - let memory_addr = event.b.wrapping_add(event.c); - let aligned_addr = memory_addr - memory_addr % WORD_SIZE as u32; - memory_columns.addr_word = memory_addr.into(); - memory_columns.addr_word_range_checker.populate(memory_addr); - memory_columns.addr_aligned = F::from_canonical_u32(aligned_addr); - - // Populate the aa_least_sig_byte_decomp columns. - assert!(aligned_addr % 4 == 0); - let aligned_addr_ls_byte = (aligned_addr & 0x000000FF) as u8; - let bits: [bool; 8] = array::from_fn(|i| aligned_addr_ls_byte & (1 << i) != 0); - memory_columns.aa_least_sig_byte_decomp = array::from_fn(|i| F::from_bool(bits[i + 2])); - memory_columns.addr_word_nonce = F::from_canonical_u32( - nonce_lookup.get(event.memory_add_lookup_id.0 as usize).copied().unwrap_or_default(), - ); - - // Populate memory offsets. - let addr_offset = (memory_addr % WORD_SIZE as u32) as u8; - memory_columns.addr_offset = F::from_canonical_u8(addr_offset); - memory_columns.offset_is_one = F::from_bool(addr_offset == 1); - memory_columns.offset_is_two = F::from_bool(addr_offset == 2); - memory_columns.offset_is_three = F::from_bool(addr_offset == 3); - - // If it is a load instruction, set the unsigned_mem_val column. - let mem_value = event.memory_record.unwrap().value(); - if matches!( - instruction.opcode, - Opcode::LB | Opcode::LBU | Opcode::LH | Opcode::LHU | Opcode::LW - ) { - match instruction.opcode { - Opcode::LB | Opcode::LBU => { - cols.unsigned_mem_val = - (mem_value.to_le_bytes()[addr_offset as usize] as u32).into(); - } - Opcode::LH | Opcode::LHU => { - let value = match (addr_offset >> 1) % 2 { - 0 => mem_value & 0x0000FFFF, - 1 => (mem_value & 0xFFFF0000) >> 16, - _ => unreachable!(), - }; - cols.unsigned_mem_val = value.into(); - } - Opcode::LW => { - cols.unsigned_mem_val = mem_value.into(); - } - _ => unreachable!(), - } - - // For the signed load instructions, we need to check if the loaded value is negative. - if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { - let most_sig_mem_value_byte = if matches!(instruction.opcode, Opcode::LB) { - cols.unsigned_mem_val.to_u32().to_le_bytes()[0] - } else { - cols.unsigned_mem_val.to_u32().to_le_bytes()[1] - }; - - for i in (0..8).rev() { - memory_columns.most_sig_byte_decomp[i] = - F::from_canonical_u8(most_sig_mem_value_byte >> i & 0x01); - } - if memory_columns.most_sig_byte_decomp[7] == F::one() { - cols.mem_value_is_neg_not_x0 = F::from_bool(instruction.op_a != (X0 as u8)); - cols.unsigned_mem_val_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.memory_sub_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), - ); - } - } - - // Set the `mem_value_is_pos_not_x0` composite flag. - cols.mem_value_is_pos_not_x0 = F::from_bool( - ((matches!(instruction.opcode, Opcode::LB | Opcode::LH) - && (memory_columns.most_sig_byte_decomp[7] == F::zero())) - || matches!(instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) - && instruction.op_a != (X0 as u8), - ); - } - - // Add event to byte lookup for byte range checking each byte in the memory addr - let addr_bytes = memory_addr.to_le_bytes(); - for byte_pair in addr_bytes.chunks_exact(2) { - blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, - opcode: ByteOpcode::U8Range, - a1: 0, - a2: 0, - b: byte_pair[0], - c: byte_pair[1], - }); - } - } - /// Populates columns related to branching. fn populate_branch( &self, diff --git a/crates/core/machine/src/memory/columns.rs b/crates/core/machine/src/memory/consistency/columns.rs similarity index 100% rename from crates/core/machine/src/memory/columns.rs rename to crates/core/machine/src/memory/consistency/columns.rs diff --git a/crates/core/machine/src/memory/consistency/mod.rs b/crates/core/machine/src/memory/consistency/mod.rs new file mode 100644 index 0000000000..2a600258b2 --- /dev/null +++ b/crates/core/machine/src/memory/consistency/mod.rs @@ -0,0 +1,4 @@ +mod columns; +mod trace; + +pub use columns::*; diff --git a/crates/core/machine/src/memory/trace.rs b/crates/core/machine/src/memory/consistency/trace.rs similarity index 100% rename from crates/core/machine/src/memory/trace.rs rename to crates/core/machine/src/memory/consistency/trace.rs diff --git a/crates/core/machine/src/cpu/air/memory.rs b/crates/core/machine/src/memory/instructions/air.rs similarity index 58% rename from crates/core/machine/src/cpu/air/memory.rs rename to crates/core/machine/src/memory/instructions/air.rs index 79054d1abf..e944e960ff 100644 --- a/crates/core/machine/src/cpu/air/memory.rs +++ b/crates/core/machine/src/memory/instructions/air.rs @@ -1,52 +1,61 @@ -use p3_air::AirBuilder; +use p3_air::{Air, AirBuilder}; use p3_field::AbstractField; use sp1_stark::{air::SP1AirBuilder, Word}; use crate::{ air::{SP1CoreAirBuilder, WordAirBuilder}, - cpu::{ - columns::{CpuCols, MemoryColumns, OpcodeSelectorCols}, - CpuChip, - }, memory::MemoryCols, operations::BabyBearWordRangeChecker, }; use sp1_core_executor::{events::MemoryAccessPosition, Opcode}; -impl CpuChip { - /// Computes whether the opcode is a memory instruction. - pub(crate) fn is_memory_instruction( - &self, - opcode_selectors: &OpcodeSelectorCols, - ) -> AB::Expr { - opcode_selectors.is_lb - + opcode_selectors.is_lbu - + opcode_selectors.is_lh - + opcode_selectors.is_lhu - + opcode_selectors.is_lw - + opcode_selectors.is_sb - + opcode_selectors.is_sh - + opcode_selectors.is_sw - } +use super::{columns::MemoryInstructionsColumns, MemoryInstructionsChip}; - /// Computes whether the opcode is a load instruction. - pub(crate) fn is_load_instruction( - &self, - opcode_selectors: &OpcodeSelectorCols, - ) -> AB::Expr { - opcode_selectors.is_lb - + opcode_selectors.is_lbu - + opcode_selectors.is_lh - + opcode_selectors.is_lhu - + opcode_selectors.is_lw +impl Air for MemoryInstructionsChip +where + AB: SP1AirBuilder, + AB::Var: Sized, +{ + #[inline(never)] + fn eval(&self, builder: &mut AB) { + let local = builder.local(); + + self.eval_memory_address_and_access::(builder, local); + self.eval_memory_load::(builder, local); + self.eval_memory_store::(builder, local); + + let opcode = self.compute_opcode::(builder, local); + self.receive_instruction( + builder, + opcode, + local.op_a_value, + local.op_b_value, + local.op_c_value, + AB::Expr::zero(), + AB::Expr::zero(), + local.is_real, + ); } +} - /// Computes whether the opcode is a store instruction. - pub(crate) fn is_store_instruction( +impl MemoryInstructionsChip { + /// Computes the opcode based on the instruction selectors. + pub(crate) fn compute_opcode( &self, - opcode_selectors: &OpcodeSelectorCols, + builder: &mut AB, + local: &MemoryInstructionsColumns, ) -> AB::Expr { - opcode_selectors.is_sb + opcode_selectors.is_sh + opcode_selectors.is_sw + builder.assert_bool(local.is_load); + builder.assert_bool(local.is_byte); + builder.assert_bool(local.is_half); + builder.assert_bool(local.is_unsigned); + + // See https://www.notion.so/succinctlabs/Idea-2-Selector-Optimizations-122e020fb42f8054a227cc80f80e5acc + // for the derivation of this formula. + AB::Expr::from_canonical_u32(10) + + (AB::Expr::one() - local.is_load) * AB::Expr::from_canonical_u32(5) + + local.is_half * AB::Expr::from_canonical_u32(2) + + local.is_unsigned * AB::Expr::from_canonical_u32(3) } /// Constrains the addr_aligned, addr_offset, and addr_word memory columns. @@ -59,98 +68,86 @@ impl CpuChip { pub(crate) fn eval_memory_address_and_access( &self, builder: &mut AB, - local: &CpuCols, - is_memory_instruction: AB::Expr, + local: &MemoryInstructionsColumns, ) { - // Get the memory specific columns. - let memory_columns = local.opcode_specific_columns.memory(); - // Send to the ALU table to verify correct calculation of addr_word. - builder.send_alu( + builder.send_instruction( AB::Expr::from_canonical_u32(Opcode::ADD as u32), - memory_columns.addr_word, + local.addr_word, local.op_b_val(), local.op_c_val(), - local.shard, - memory_columns.addr_word_nonce, - is_memory_instruction.clone(), + local.addr_word_nonce, + local.is_real, ); // Range check the addr_word to be a valid babybear word. BabyBearWordRangeChecker::::range_check( builder, - memory_columns.addr_word, - memory_columns.addr_word_range_checker, - is_memory_instruction.clone(), + local.addr_word, + local.addr_word_range_checker, + local.is_real, ); // Check that each addr_word element is a byte. - builder.slice_range_check_u8(&memory_columns.addr_word.0, is_memory_instruction.clone()); + builder.slice_range_check_u8(&local.addr_word.0, local.is_real); // Evaluate the addr_offset column and offset flags. - self.eval_offset_value_flags(builder, memory_columns, local); + self.eval_offset_value_flags(builder, local); // Assert that reduce(addr_word) == addr_aligned + addr_offset. - builder.when(is_memory_instruction.clone()).assert_eq::( - memory_columns.addr_aligned + memory_columns.addr_offset, - memory_columns.addr_word.reduce::(), + builder.when(local.is_real).assert_eq::( + local.addr_aligned + local.addr_offset, + local.addr_word.reduce::(), ); // Verify that the least significant byte of addr_word - addr_offset is divisible by 4. - let offset = [ - memory_columns.offset_is_one, - memory_columns.offset_is_two, - memory_columns.offset_is_three, - ] - .iter() - .enumerate() - .fold(AB::Expr::zero(), |acc, (index, &value)| { - acc + AB::Expr::from_canonical_usize(index + 1) * value - }); + let offset = [local.offset_is_one, local.offset_is_two, local.offset_is_three] + .iter() + .enumerate() + .fold(AB::Expr::zero(), |acc, (index, &value)| { + acc + AB::Expr::from_canonical_usize(index + 1) * value + }); let mut recomposed_byte = AB::Expr::zero(); - memory_columns.aa_least_sig_byte_decomp.iter().enumerate().for_each(|(i, value)| { - builder.when(is_memory_instruction.clone()).assert_bool(*value); + local.aa_least_sig_byte_decomp.iter().enumerate().for_each(|(i, value)| { + builder.when(local.is_real).assert_bool(*value); recomposed_byte = recomposed_byte.clone() + AB::Expr::from_canonical_usize(1 << (i + 2)) * *value; }); - builder - .when(is_memory_instruction.clone()) - .assert_eq(memory_columns.addr_word[0] - offset, recomposed_byte); + builder.when(local.is_real).assert_eq(local.addr_word[0] - offset, recomposed_byte); // For operations that require reading from memory (not registers), we need to read the // value into the memory columns. builder.eval_memory_access( local.shard, local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::Memory as u32), - memory_columns.addr_aligned, - &memory_columns.memory_access, - is_memory_instruction.clone(), + local.addr_aligned, + &local.memory_access, + local.is_real, ); // On memory load instructions, make sure that the memory value is not changed. - builder.when(self.is_load_instruction::(&local.selectors)).assert_word_eq( - *memory_columns.memory_access.value(), - *memory_columns.memory_access.prev_value(), - ); + builder + .when(self.is_load_instruction::(&local.selectors)) + .assert_word_eq(*local.memory_access.value(), *local.memory_access.prev_value()); } /// Evaluates constraints related to loading from memory. pub(crate) fn eval_memory_load( &self, builder: &mut AB, - local: &CpuCols, + local: &MemoryInstructionsColumns, ) { // Get the memory specific columns. let memory_columns = local.opcode_specific_columns.memory(); // Verify the unsigned_mem_value column. - self.eval_unsigned_mem_value(builder, memory_columns, local); + self.eval_unsigned_mem_value(builder, local); // If it's a signed operation (such as LB or LH), then we need verify the bit decomposition // of the most significant byte to get it's sign. - self.eval_most_sig_byte_bit_decomp(builder, memory_columns, local, &local.unsigned_mem_val); + self.eval_most_sig_byte_bit_decomp(builder, local, &local.unsigned_mem_val); // Assert that correct value of `mem_value_is_neg_not_x0`. builder.assert_eq( @@ -168,7 +165,7 @@ impl CpuChip { AB::Expr::one() * local.selectors.is_lh, AB::Expr::zero(), ]); - builder.send_alu( + builder.send_instruction( Opcode::SUB.as_field::(), local.op_a_val(), local.unsigned_mem_val, @@ -200,34 +197,28 @@ impl CpuChip { pub(crate) fn eval_memory_store( &self, builder: &mut AB, - local: &CpuCols, + local: &MemoryInstructionsColumns, ) { - let memory_columns = local.opcode_specific_columns.memory(); - // Get the memory offset flags. - self.eval_offset_value_flags(builder, memory_columns, local); + self.eval_offset_value_flags(builder, local); // Compute the offset_is_zero flag. The other offset flags are already constrained by the // method `eval_memory_address_and_access`, which is called in // `eval_memory_address_and_access`. - let offset_is_zero = AB::Expr::one() - - memory_columns.offset_is_one - - memory_columns.offset_is_two - - memory_columns.offset_is_three; + let offset_is_zero = + AB::Expr::one() - local.offset_is_one - local.offset_is_two - local.offset_is_three; // Compute the expected stored value for a SB instruction. let one = AB::Expr::one(); let a_val = local.op_a_val(); - let mem_val = *memory_columns.memory_access.value(); - let prev_mem_val = *memory_columns.memory_access.prev_value(); + let mem_val = *local.memory_access.value(); + let prev_mem_val = *local.memory_access.prev_value(); let sb_expected_stored_value = Word([ a_val[0] * offset_is_zero.clone() + (one.clone() - offset_is_zero.clone()) * prev_mem_val[0], - a_val[0] * memory_columns.offset_is_one - + (one.clone() - memory_columns.offset_is_one) * prev_mem_val[1], - a_val[0] * memory_columns.offset_is_two - + (one.clone() - memory_columns.offset_is_two) * prev_mem_val[2], - a_val[0] * memory_columns.offset_is_three - + (one.clone() - memory_columns.offset_is_three) * prev_mem_val[3], + a_val[0] * local.offset_is_one + (one.clone() - local.offset_is_one) * prev_mem_val[1], + a_val[0] * local.offset_is_two + (one.clone() - local.offset_is_two) * prev_mem_val[2], + a_val[0] * local.offset_is_three + + (one.clone() - local.offset_is_three) * prev_mem_val[3], ]); builder .when(local.selectors.is_sb) @@ -236,14 +227,14 @@ impl CpuChip { // When the instruction is SH, make sure both offset one and three are off. builder .when(local.selectors.is_sh) - .assert_zero(memory_columns.offset_is_one + memory_columns.offset_is_three); + .assert_zero(local.offset_is_one + local.offset_is_three); // When the instruction is SW, ensure that the offset is 0. builder.when(local.selectors.is_sw).assert_one(offset_is_zero.clone()); // Compute the expected stored value for a SH instruction. let a_is_lower_half = offset_is_zero; - let a_is_upper_half = memory_columns.offset_is_two; + let a_is_upper_half = local.offset_is_two; let sh_expected_stored_value = Word([ a_val[0] * a_is_lower_half.clone() + (one.clone() - a_is_lower_half.clone()) * prev_mem_val[0], @@ -266,24 +257,21 @@ impl CpuChip { pub(crate) fn eval_unsigned_mem_value( &self, builder: &mut AB, - memory_columns: &MemoryColumns, - local: &CpuCols, + local: &MemoryInstructionsColumns, ) { - let mem_val = *memory_columns.memory_access.value(); + let mem_val = *local.memory_access.value(); // Compute the offset_is_zero flag. The other offset flags are already constrained by the // method `eval_memory_address_and_access`, which is called in // `eval_memory_address_and_access`. - let offset_is_zero = AB::Expr::one() - - memory_columns.offset_is_one - - memory_columns.offset_is_two - - memory_columns.offset_is_three; + let offset_is_zero = + AB::Expr::one() - local.offset_is_one - local.offset_is_two - local.offset_is_three; // Compute the byte value. let mem_byte = mem_val[0] * offset_is_zero.clone() - + mem_val[1] * memory_columns.offset_is_one - + mem_val[2] * memory_columns.offset_is_two - + mem_val[3] * memory_columns.offset_is_three; + + mem_val[1] * local.offset_is_one + + mem_val[2] * local.offset_is_two + + mem_val[3] * local.offset_is_three; let byte_value = Word::extend_expr::(mem_byte.clone()); // When the instruction is LB or LBU, just use the lower byte. @@ -294,13 +282,13 @@ impl CpuChip { // When the instruction is LH or LHU, use the lower half. builder .when(local.selectors.is_lh + local.selectors.is_lhu) - .assert_zero(memory_columns.offset_is_one + memory_columns.offset_is_three); + .assert_zero(local.offset_is_one + local.offset_is_three); // When the instruction is LW, ensure that the offset is zero. builder.when(local.selectors.is_lw).assert_one(offset_is_zero.clone()); let use_lower_half = offset_is_zero; - let use_upper_half = memory_columns.offset_is_two; + let use_upper_half = local.offset_is_two; let half_value = Word([ use_lower_half.clone() * mem_val[0] + use_upper_half * mem_val[2], use_lower_half * mem_val[1] + use_upper_half * mem_val[3], @@ -319,16 +307,15 @@ impl CpuChip { pub(crate) fn eval_most_sig_byte_bit_decomp( &self, builder: &mut AB, - memory_columns: &MemoryColumns, - local: &CpuCols, + local: &MemoryInstructionsColumns, unsigned_mem_val: &Word, ) { let is_mem = self.is_memory_instruction::(&local.selectors); let mut recomposed_byte = AB::Expr::zero(); for i in 0..8 { - builder.when(is_mem.clone()).assert_bool(memory_columns.most_sig_byte_decomp[i]); + builder.when(is_mem.clone()).assert_bool(local.most_sig_byte_decomp[i]); recomposed_byte = recomposed_byte.clone() - + memory_columns.most_sig_byte_decomp[i] * AB::Expr::from_canonical_u8(1 << i); + + local.most_sig_byte_decomp[i] * AB::Expr::from_canonical_u8(1 << i); } builder.when(local.selectors.is_lb).assert_eq(recomposed_byte.clone(), unsigned_mem_val[0]); builder.when(local.selectors.is_lh).assert_eq(recomposed_byte, unsigned_mem_val[1]); @@ -338,38 +325,30 @@ impl CpuChip { pub(crate) fn eval_offset_value_flags( &self, builder: &mut AB, - memory_columns: &MemoryColumns, - local: &CpuCols, + local: &MemoryInstructionsColumns, ) { - let is_mem_op = self.is_memory_instruction::(&local.selectors); - let offset_is_zero = AB::Expr::one() - - memory_columns.offset_is_one - - memory_columns.offset_is_two - - memory_columns.offset_is_three; - - let mut filtered_builder = builder.when(is_mem_op); + let offset_is_zero = + AB::Expr::one() - local.offset_is_one - local.offset_is_two - local.offset_is_three; // Assert that the value flags are boolean - filtered_builder.assert_bool(memory_columns.offset_is_one); - filtered_builder.assert_bool(memory_columns.offset_is_two); - filtered_builder.assert_bool(memory_columns.offset_is_three); + builder.assert_bool(local.offset_is_one); + builder.assert_bool(local.offset_is_two); + builder.assert_bool(local.offset_is_three); // Assert that only one of the value flags is true - filtered_builder.assert_one( + builder.assert_one( offset_is_zero.clone() - + memory_columns.offset_is_one - + memory_columns.offset_is_two - + memory_columns.offset_is_three, + + local.offset_is_one + + local.offset_is_two + + local.offset_is_three, ); // Assert that the correct value flag is set - filtered_builder.when(offset_is_zero).assert_zero(memory_columns.addr_offset); - filtered_builder.when(memory_columns.offset_is_one).assert_one(memory_columns.addr_offset); - filtered_builder - .when(memory_columns.offset_is_two) - .assert_eq(memory_columns.addr_offset, AB::Expr::two()); - filtered_builder - .when(memory_columns.offset_is_three) - .assert_eq(memory_columns.addr_offset, AB::Expr::from_canonical_u8(3)); + builder.when(offset_is_zero).assert_zero(local.addr_offset); + builder.when(local.offset_is_one).assert_one(local.addr_offset); + builder.when(local.offset_is_two).assert_eq(local.addr_offset, AB::Expr::two()); + builder + .when(local.offset_is_three) + .assert_eq(local.addr_offset, AB::Expr::from_canonical_u8(3)); } } diff --git a/crates/core/machine/src/cpu/columns/memory.rs b/crates/core/machine/src/memory/instructions/columns.rs similarity index 68% rename from crates/core/machine/src/cpu/columns/memory.rs rename to crates/core/machine/src/memory/instructions/columns.rs index 3eb52337ab..14c4fe8a0f 100644 --- a/crates/core/machine/src/cpu/columns/memory.rs +++ b/crates/core/machine/src/memory/instructions/columns.rs @@ -1,15 +1,39 @@ +use p3_air::BaseAir; use sp1_derive::AlignedBorrow; use sp1_stark::Word; use std::mem::size_of; use crate::{memory::MemoryReadWriteCols, operations::BabyBearWordRangeChecker}; -pub const NUM_MEMORY_COLUMNS: usize = size_of::>(); +use super::MemoryInstructionsChip; + +pub const NUM_MEMORY_INSTRUCTIONS_COLUMNS: usize = size_of::>(); + +impl BaseAir for MemoryInstructionsChip { + fn width(&self) -> usize { + NUM_MEMORY_INSTRUCTIONS_COLUMNS + } +} /// The column layout for memory. #[derive(AlignedBorrow, Default, Debug, Clone, Copy)] #[repr(C)] -pub struct MemoryColumns { +pub struct MemoryInstructionsColumns { + pub pc: T, + pub next_pc: T, + + pub clk: T, + + pub opcode: T, + pub op_a_value: Word, + pub op_b_value: Word, + pub op_c_value: Word, + + pub is_load: T, + pub is_byte: T, + pub is_half: T, + pub is_unsigned: T, + // An addr that we are reading from or writing to as a word. We are guaranteed that this does // not overflow the field when reduced. @@ -36,4 +60,6 @@ pub struct MemoryColumns { pub addr_word_nonce: T, pub unsigned_mem_val_nonce: T, + + pub is_real: T, } diff --git a/crates/core/machine/src/memory/instructions/mod.rs b/crates/core/machine/src/memory/instructions/mod.rs new file mode 100644 index 0000000000..a240680045 --- /dev/null +++ b/crates/core/machine/src/memory/instructions/mod.rs @@ -0,0 +1,6 @@ +pub mod air; +pub mod columns; +pub mod trace; + +#[derive(Default)] +pub struct MemoryInstructionsChip; diff --git a/crates/core/machine/src/memory/instructions/trace.rs b/crates/core/machine/src/memory/instructions/trace.rs new file mode 100644 index 0000000000..731f1d2270 --- /dev/null +++ b/crates/core/machine/src/memory/instructions/trace.rs @@ -0,0 +1,116 @@ +use p3_field::PrimeField32; +use p3_matrix::dense::RowMajorMatrix; +use sp1_core_executor::ExecutionRecord; +use sp1_stark::air::MachineAir; + +use super::MemoryInstructionsChip; + +impl MachineAir for MemoryInstructionsChip { + type Record = ExecutionRecord; + + type Program = Self::Program; + + fn name(&self) -> String { + "MemoryInstructions".to_string() + } + + fn generate_trace( + &self, + input: &ExecutionRecord, + _: &mut ExecutionRecord, + ) -> RowMajorMatrix { + // Populate addr_word and addr_aligned columns. + let memory_columns = cols.opcode_specific_columns.memory_mut(); + let memory_addr = event.b.wrapping_add(event.c); + let aligned_addr = memory_addr - memory_addr % WORD_SIZE as u32; + memory_columns.addr_word = memory_addr.into(); + memory_columns.addr_word_range_checker.populate(memory_addr); + memory_columns.addr_aligned = F::from_canonical_u32(aligned_addr); + + // Populate the aa_least_sig_byte_decomp columns. + assert!(aligned_addr % 4 == 0); + let aligned_addr_ls_byte = (aligned_addr & 0x000000FF) as u8; + let bits: [bool; 8] = array::from_fn(|i| aligned_addr_ls_byte & (1 << i) != 0); + memory_columns.aa_least_sig_byte_decomp = array::from_fn(|i| F::from_bool(bits[i + 2])); + memory_columns.addr_word_nonce = F::from_canonical_u32( + nonce_lookup.get(event.memory_add_lookup_id.0 as usize).copied().unwrap_or_default(), + ); + + // Populate memory offsets. + let addr_offset = (memory_addr % WORD_SIZE as u32) as u8; + memory_columns.addr_offset = F::from_canonical_u8(addr_offset); + memory_columns.offset_is_one = F::from_bool(addr_offset == 1); + memory_columns.offset_is_two = F::from_bool(addr_offset == 2); + memory_columns.offset_is_three = F::from_bool(addr_offset == 3); + + // If it is a load instruction, set the unsigned_mem_val column. + let mem_value = event.memory_record.unwrap().value(); + if matches!( + instruction.opcode, + Opcode::LB | Opcode::LBU | Opcode::LH | Opcode::LHU | Opcode::LW + ) { + match instruction.opcode { + Opcode::LB | Opcode::LBU => { + cols.unsigned_mem_val = + (mem_value.to_le_bytes()[addr_offset as usize] as u32).into(); + } + Opcode::LH | Opcode::LHU => { + let value = match (addr_offset >> 1) % 2 { + 0 => mem_value & 0x0000FFFF, + 1 => (mem_value & 0xFFFF0000) >> 16, + _ => unreachable!(), + }; + cols.unsigned_mem_val = value.into(); + } + Opcode::LW => { + cols.unsigned_mem_val = mem_value.into(); + } + _ => unreachable!(), + } + + // For the signed load instructions, we need to check if the loaded value is negative. + if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { + let most_sig_mem_value_byte = if matches!(instruction.opcode, Opcode::LB) { + cols.unsigned_mem_val.to_u32().to_le_bytes()[0] + } else { + cols.unsigned_mem_val.to_u32().to_le_bytes()[1] + }; + + for i in (0..8).rev() { + memory_columns.most_sig_byte_decomp[i] = + F::from_canonical_u8(most_sig_mem_value_byte >> i & 0x01); + } + if memory_columns.most_sig_byte_decomp[7] == F::one() { + cols.mem_value_is_neg_not_x0 = F::from_bool(instruction.op_a != (X0 as u8)); + cols.unsigned_mem_val_nonce = F::from_canonical_u32( + nonce_lookup + .get(event.memory_sub_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), + ); + } + } + + // Set the `mem_value_is_pos_not_x0` composite flag. + cols.mem_value_is_pos_not_x0 = F::from_bool( + ((matches!(instruction.opcode, Opcode::LB | Opcode::LH) + && (memory_columns.most_sig_byte_decomp[7] == F::zero())) + || matches!(instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) + && instruction.op_a != (X0 as u8), + ); + } + + // Add event to byte lookup for byte range checking each byte in the memory addr + let addr_bytes = memory_addr.to_le_bytes(); + for byte_pair in addr_bytes.chunks_exact(2) { + blu_events.add_byte_lookup_event(ByteLookupEvent { + shard, + opcode: ByteOpcode::U8Range, + a1: 0, + a2: 0, + b: byte_pair[0], + c: byte_pair[1], + }); + } + } +} diff --git a/crates/core/machine/src/memory/mod.rs b/crates/core/machine/src/memory/mod.rs index ba4a7a650a..93f5c6c747 100644 --- a/crates/core/machine/src/memory/mod.rs +++ b/crates/core/machine/src/memory/mod.rs @@ -1,15 +1,16 @@ -mod columns; +mod consistency; mod global; +mod instructions; mod local; mod program; -mod trace; -pub use columns::*; +pub use consistency::*; pub use global::*; +pub use instructions::*; pub use local::*; pub use program::*; -/// The type of memory chip that is being initialized. +/// The type of global/local memory chip that is being initialized. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MemoryChipType { Initialize, diff --git a/crates/core/machine/src/riscv/mod.rs b/crates/core/machine/src/riscv/mod.rs index 5964eba304..a78484f294 100644 --- a/crates/core/machine/src/riscv/mod.rs +++ b/crates/core/machine/src/riscv/mod.rs @@ -10,7 +10,8 @@ use sp1_core_executor::{ use crate::{ memory::{ - MemoryChipType, MemoryLocalChip, MemoryProgramChip, NUM_LOCAL_MEMORY_ENTRIES_PER_ROW, + MemoryChipType, MemoryInstructionsChip, MemoryLocalChip, MemoryProgramChip, + NUM_LOCAL_MEMORY_ENTRIES_PER_ROW, }, riscv::MemoryChipType::{Finalize, Initialize}, syscall::precompiles::fptower::{Fp2AddSubAssignChip, Fp2MulAssignChip, FpOpChip}, @@ -410,6 +411,10 @@ impl RiscvAir { .into_iter() .count(), ), + ( + RiscvAir::MemoryInstructions(MemoryInstructionsChip::default()), + record.memory_instructions_events.len(), + ), (RiscvAir::SyscallCore(SyscallChip::core()), record.syscall_events.len()), ] } diff --git a/crates/stark/src/air/builder.rs b/crates/stark/src/air/builder.rs index dc89f80d2e..b9d1d49f5a 100644 --- a/crates/stark/src/air/builder.rs +++ b/crates/stark/src/air/builder.rs @@ -175,17 +175,16 @@ pub trait ByteAirBuilder: BaseAirBuilder { } } -/// A trait which contains methods related to ALU interactions in an AIR. -pub trait AluAirBuilder: BaseAirBuilder { +/// A trait which contains methods related to RISC-V instruction interactions in an AIR. +pub trait InstructionAirBuilder: BaseAirBuilder { /// Sends an ALU operation to be processed. #[allow(clippy::too_many_arguments)] - fn send_alu( + fn send_instruction( &mut self, opcode: impl Into, a: Word>, b: Word>, c: Word>, - shard: impl Into, nonce: impl Into, multiplicity: impl Into, ) { @@ -193,19 +192,18 @@ pub trait AluAirBuilder: BaseAirBuilder { .chain(a.0.into_iter().map(Into::into)) .chain(b.0.into_iter().map(Into::into)) .chain(c.0.into_iter().map(Into::into)) - .chain(once(shard.into())) .chain(once(nonce.into())) .collect(); self.send( - AirInteraction::new(values, multiplicity.into(), InteractionKind::Alu), + AirInteraction::new(values, multiplicity.into(), InteractionKind::Instruction), InteractionScope::Local, ); } /// Receives an ALU operation to be processed. #[allow(clippy::too_many_arguments)] - fn receive_alu( + fn receive_instruction( &mut self, opcode: impl Into, a: Word>, @@ -224,7 +222,7 @@ pub trait AluAirBuilder: BaseAirBuilder { .collect(); self.receive( - AirInteraction::new(values, multiplicity.into(), InteractionKind::Alu), + AirInteraction::new(values, multiplicity.into(), InteractionKind::Instruction), InteractionScope::Local, ); } @@ -345,7 +343,7 @@ pub trait MachineAirBuilder: } /// A trait which contains all helper methods for building SP1 machine AIRs. -pub trait SP1AirBuilder: MachineAirBuilder + ByteAirBuilder + AluAirBuilder {} +pub trait SP1AirBuilder: MachineAirBuilder + ByteAirBuilder + InstructionAirBuilder {} impl<'a, AB: AirBuilder + MessageBuilder, M> MessageBuilder for FilteredAirBuilder<'a, AB> { fn send(&mut self, message: M, scope: InteractionScope) { @@ -359,7 +357,7 @@ impl<'a, AB: AirBuilder + MessageBuilder, M> MessageBuilder for FilteredAi impl>> BaseAirBuilder for AB {} impl ByteAirBuilder for AB {} -impl AluAirBuilder for AB {} +impl InstructionAirBuilder for AB {} impl ExtensionAirBuilder for AB {} impl MachineAirBuilder for AB {} diff --git a/crates/stark/src/lookup/builder.rs b/crates/stark/src/lookup/builder.rs index 153d660483..834d238f6d 100644 --- a/crates/stark/src/lookup/builder.rs +++ b/crates/stark/src/lookup/builder.rs @@ -244,7 +244,7 @@ mod tests { AirInteraction::new( vec![x.into(), y.into()], AB::F::from_canonical_u32(3).into(), - InteractionKind::Alu, + InteractionKind::Instruction, ), InteractionScope::Local, ); @@ -252,7 +252,7 @@ mod tests { AirInteraction::new( vec![x + y, z.into()], AB::F::from_canonical_u32(5).into(), - InteractionKind::Alu, + InteractionKind::Instruction, ), InteractionScope::Local, ); diff --git a/crates/stark/src/lookup/interaction.rs b/crates/stark/src/lookup/interaction.rs index 0ff89ab592..2d3b6e5356 100644 --- a/crates/stark/src/lookup/interaction.rs +++ b/crates/stark/src/lookup/interaction.rs @@ -27,23 +27,20 @@ pub enum InteractionKind { /// Interaction with the program table, loading an instruction at a given pc address. Program = 2, - /// Interaction with instruction oracle. + /// Interaction with opcode specific tables. Instruction = 3, - /// Interaction with the ALU operations. - Alu = 4, - /// Interaction with the byte lookup table for byte operations. - Byte = 5, + Byte = 4, /// Requesting a range check for a given value and range. - Range = 6, + Range = 5, /// Interaction with the field op table for field operations. - Field = 7, + Field = 6, /// Interaction with a syscall. - Syscall = 8, + Syscall = 7, } impl InteractionKind { @@ -54,7 +51,6 @@ impl InteractionKind { InteractionKind::Memory, InteractionKind::Program, InteractionKind::Instruction, - InteractionKind::Alu, InteractionKind::Byte, InteractionKind::Range, InteractionKind::Field, @@ -95,7 +91,6 @@ impl Display for InteractionKind { InteractionKind::Memory => write!(f, "Memory"), InteractionKind::Program => write!(f, "Program"), InteractionKind::Instruction => write!(f, "Instruction"), - InteractionKind::Alu => write!(f, "Alu"), InteractionKind::Byte => write!(f, "Byte"), InteractionKind::Range => write!(f, "Range"), InteractionKind::Field => write!(f, "Field"), From 50acb86b7383b059525bedafee9ac2c53cffe09d Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Wed, 20 Nov 2024 19:20:06 -0800 Subject: [PATCH 03/18] changes for the executor --- crates/core/executor/src/dependencies.rs | 32 +++++++------- .../executor/src/events/{alu.rs => instr.rs} | 4 +- crates/core/executor/src/events/memory.rs | 9 ---- crates/core/executor/src/events/mod.rs | 4 +- crates/core/executor/src/executor.rs | 26 +++++++++-- crates/core/executor/src/record.rs | 44 ++++++++----------- crates/core/machine/src/alu/add_sub/mod.rs | 12 ++--- crates/core/machine/src/alu/bitwise/mod.rs | 14 +++--- crates/core/machine/src/alu/divrem/mod.rs | 10 ++--- crates/core/machine/src/alu/lt/mod.rs | 36 +++++++-------- crates/core/machine/src/alu/mul/mod.rs | 16 +++---- crates/core/machine/src/alu/sll/mod.rs | 12 ++--- crates/core/machine/src/alu/sr/mod.rs | 12 ++--- crates/core/machine/src/riscv/mod.rs | 2 +- .../syscall/precompiles/sha256/extend/mod.rs | 4 +- 15 files changed, 120 insertions(+), 117 deletions(-) rename crates/core/executor/src/events/{alu.rs => instr.rs} (96%) diff --git a/crates/core/executor/src/dependencies.rs b/crates/core/executor/src/dependencies.rs index 6b0bbbe33c..be1fc7aee4 100644 --- a/crates/core/executor/src/dependencies.rs +++ b/crates/core/executor/src/dependencies.rs @@ -1,12 +1,12 @@ use crate::{ - events::AluEvent, + events::InstrEvent, utils::{get_msb, get_quotient_and_remainder, is_signed_operation}, Executor, Opcode, }; /// Emits the dependencies for division and remainder operations. #[allow(clippy::too_many_lines)] -pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { +pub fn emit_divrem_dependencies(executor: &mut Executor, event: InstrEvent) { let shard = executor.shard(); let (quotient, remainder) = get_quotient_and_remainder(event.b, event.c, event.opcode); let c_msb = get_msb(event.c); @@ -21,7 +21,7 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { if c_neg == 1 { let ids = executor.record.create_lookup_ids(); - executor.record.add_events.push(AluEvent { + executor.record.add_events.push(InstrEvent { lookup_id: event.sub_lookups[4], shard, clk: event.clk, @@ -34,7 +34,7 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { } if rem_neg == 1 { let ids = executor.record.create_lookup_ids(); - executor.record.add_events.push(AluEvent { + executor.record.add_events.push(InstrEvent { lookup_id: event.sub_lookups[5], shard, clk: event.clk, @@ -56,7 +56,7 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { let lower_word = u32::from_le_bytes(c_times_quotient[0..4].try_into().unwrap()); let upper_word = u32::from_le_bytes(c_times_quotient[4..8].try_into().unwrap()); - let lower_multiplication = AluEvent { + let lower_multiplication = InstrEvent { lookup_id: event.sub_lookups[0], shard, clk: event.clk, @@ -68,7 +68,7 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { }; executor.record.mul_events.push(lower_multiplication); - let upper_multiplication = AluEvent { + let upper_multiplication = InstrEvent { lookup_id: event.sub_lookups[1], shard, clk: event.clk, @@ -87,7 +87,7 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { executor.record.mul_events.push(upper_multiplication); let lt_event = if is_signed_operation { - AluEvent { + InstrEvent { lookup_id: event.sub_lookups[2], shard, opcode: Opcode::SLTU, @@ -98,7 +98,7 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { sub_lookups: executor.record.create_lookup_ids(), } } else { - AluEvent { + InstrEvent { lookup_id: event.sub_lookups[3], shard, opcode: Opcode::SLTU, @@ -134,7 +134,7 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { ) { let memory_addr = event.b.wrapping_add(event.c); // Add event to ALU check to check that addr == b + c - let add_event = AluEvent { + let add_event = InstrEvent { lookup_id: event.memory_add_lookup_id, shard, clk: event.clk, @@ -169,7 +169,7 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { }; if most_sig_mem_value_byte >> 7 & 0x01 == 1 { - let sub_event = AluEvent { + let sub_event = InstrEvent { lookup_id: event.memory_sub_lookup_id, shard, clk: event.clk, @@ -200,7 +200,7 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { let alu_op_code = if use_signed_comparison { Opcode::SLT } else { Opcode::SLTU }; // Add the ALU events for the comparisons - let lt_comp_event = AluEvent { + let lt_comp_event = InstrEvent { lookup_id: event.branch_lt_lookup_id, shard, clk: event.clk, @@ -210,7 +210,7 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { c: event.b, sub_lookups: executor.record.create_lookup_ids(), }; - let gt_comp_event = AluEvent { + let gt_comp_event = InstrEvent { lookup_id: event.branch_gt_lookup_id, shard, clk: event.clk, @@ -231,7 +231,7 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { }; if branching { let next_pc = event.pc.wrapping_add(event.c); - let add_event = AluEvent { + let add_event = InstrEvent { lookup_id: event.branch_add_lookup_id, shard, clk: event.clk, @@ -249,7 +249,7 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { match instruction.opcode { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); - let add_event = AluEvent { + let add_event = InstrEvent { lookup_id: event.jump_jal_lookup_id, shard, clk: event.clk, @@ -263,7 +263,7 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { } Opcode::JALR => { let next_pc = event.b.wrapping_add(event.c); - let add_event = AluEvent { + let add_event = InstrEvent { lookup_id: event.jump_jalr_lookup_id, shard, clk: event.clk, @@ -280,7 +280,7 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { } if matches!(instruction.opcode, Opcode::AUIPC) { - let add_event = AluEvent { + let add_event = InstrEvent { lookup_id: event.auipc_lookup_id, shard, clk: event.clk, diff --git a/crates/core/executor/src/events/alu.rs b/crates/core/executor/src/events/instr.rs similarity index 96% rename from crates/core/executor/src/events/alu.rs rename to crates/core/executor/src/events/instr.rs index 2d2b14fe03..f2c8422870 100644 --- a/crates/core/executor/src/events/alu.rs +++ b/crates/core/executor/src/events/instr.rs @@ -9,7 +9,7 @@ use super::{create_random_lookup_ids, LookupId}; /// This object encapsulated the information needed to prove an ALU operation. This includes its /// shard, opcode, operands, and other relevant information. #[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub struct AluEvent { +pub struct InstrEvent { /// The lookup identifier. pub lookup_id: LookupId, /// The shard number. @@ -28,7 +28,7 @@ pub struct AluEvent { pub sub_lookups: [LookupId; 6], } -impl AluEvent { +impl InstrEvent { /// Create a new [`AluEvent`]. #[must_use] pub fn new(shard: u32, clk: u32, opcode: Opcode, a: u32, b: u32, c: u32) -> Self { diff --git a/crates/core/executor/src/events/memory.rs b/crates/core/executor/src/events/memory.rs index 071f0f21f7..655e0fc21d 100644 --- a/crates/core/executor/src/events/memory.rs +++ b/crates/core/executor/src/events/memory.rs @@ -232,12 +232,3 @@ pub struct MemoryLocalEvent { /// The final memory access. pub final_mem_access: MemoryRecord, } - -/// Memory Instructions Event. -/// -/// This object encapsulates the information needed to prove a memory instruction operation. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MemoryInstructionsEvent { - /// The address. - pub addr: u32, -} diff --git a/crates/core/executor/src/events/mod.rs b/crates/core/executor/src/events/mod.rs index da38bb83c2..5e5bd2729c 100644 --- a/crates/core/executor/src/events/mod.rs +++ b/crates/core/executor/src/events/mod.rs @@ -1,16 +1,16 @@ //! Type definitions for the events emitted by the [`crate::Executor`] during execution. -mod alu; mod byte; mod cpu; +mod instr; mod memory; mod precompiles; mod syscall; mod utils; -pub use alu::*; pub use byte::*; pub use cpu::*; +pub use instr::*; pub use memory::*; pub use precompiles::*; pub use syscall::*; diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index fa57bf9177..30054e5e09 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -13,7 +13,7 @@ use crate::{ context::SP1Context, dependencies::{emit_cpu_dependencies, emit_divrem_dependencies}, events::{ - AluEvent, CpuEvent, LookupId, MemoryAccessPosition, MemoryInitializeFinalizeEvent, + CpuEvent, InstrEvent, LookupId, MemoryAccessPosition, MemoryInitializeFinalizeEvent, MemoryLocalEvent, MemoryReadRecord, MemoryRecord, MemoryWriteRecord, SyscallEvent, }, hook::{HookEnv, HookRegistry}, @@ -643,8 +643,16 @@ impl<'a> Executor<'a> { } /// Emit an ALU event. - fn emit_alu(&mut self, clk: u32, opcode: Opcode, a: u32, b: u32, c: u32, lookup_id: LookupId) { - let event = AluEvent { + fn emit_instruction( + &mut self, + clk: u32, + opcode: Opcode, + a: u32, + b: u32, + c: u32, + lookup_id: LookupId, + ) { + let event = InstrEvent { lookup_id, shard: self.shard(), clk, @@ -680,6 +688,16 @@ impl<'a> Executor<'a> { self.record.divrem_events.push(event); emit_divrem_dependencies(self, event); } + Opcode::LB + | Opcode::LH + | Opcode::LW + | Opcode::LBU + | Opcode::LHU + | Opcode::SB + | Opcode::SH + | Opcode::SW => { + self.record.memory_instr_events.push(event); + } _ => {} } } @@ -748,7 +766,7 @@ impl<'a> Executor<'a> { ) { self.rw(rd, a); if self.executor_mode == ExecutorMode::Trace { - self.emit_alu(self.state.clk, instruction.opcode, a, b, c, lookup_id); + self.emit_instruction(self.state.clk, instruction.opcode, a, b, c, lookup_id); } } diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index 61b509e8a1..445750536a 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -12,8 +12,8 @@ use serde::{Deserialize, Serialize}; use super::{program::Program, Opcode}; use crate::{ events::{ - add_sharded_byte_lookup_events, AluEvent, ByteLookupEvent, ByteRecord, CpuEvent, LookupId, - MemoryInitializeFinalizeEvent, MemoryInstructionsEvent, MemoryLocalEvent, MemoryRecordEnum, + add_sharded_byte_lookup_events, ByteLookupEvent, ByteRecord, CpuEvent, InstrEvent, + LookupId, MemoryInitializeFinalizeEvent, MemoryLocalEvent, MemoryRecordEnum, PrecompileEvent, PrecompileEvents, SyscallEvent, }, syscalls::SyscallCode, @@ -30,23 +30,23 @@ pub struct ExecutionRecord { /// A trace of the CPU events which get emitted during execution. pub cpu_events: Vec, /// A trace of the ADD, and ADDI events. - pub add_events: Vec, + pub add_events: Vec, /// A trace of the MUL events. - pub mul_events: Vec, + pub mul_events: Vec, /// A trace of the SUB events. - pub sub_events: Vec, + pub sub_events: Vec, /// A trace of the XOR, XORI, OR, ORI, AND, and ANDI events. - pub bitwise_events: Vec, + pub bitwise_events: Vec, /// A trace of the SLL and SLLI events. - pub shift_left_events: Vec, + pub shift_left_events: Vec, /// A trace of the SRL, SRLI, SRA, and SRAI events. - pub shift_right_events: Vec, + pub shift_right_events: Vec, /// A trace of the DIV, DIVU, REM, and REMU events. - pub divrem_events: Vec, + pub divrem_events: Vec, /// A trace of the SLT, SLTI, SLTU, and SLTIU events. - pub lt_events: Vec, + pub lt_events: Vec, /// A trace of the memory instructions. - pub memory_instructions_events: Vec, + pub memory_instr_events: Vec, /// A trace of the byte lookups that are needed. pub byte_lookups: HashMap>, /// A trace of the precompile events. @@ -82,7 +82,7 @@ impl Default for ExecutionRecord { shift_right_events: Vec::default(), divrem_events: Vec::default(), lt_events: Vec::default(), - memory_instructions_events: Vec::default(), + memory_instr_events: Vec::default(), byte_lookups: HashMap::default(), precompile_events: PrecompileEvents::default(), global_memory_initialize_events: Vec::default(), @@ -123,17 +123,17 @@ impl ExecutionRecord { } /// Add a mul event to the execution record. - pub fn add_mul_event(&mut self, mul_event: AluEvent) { + pub fn add_mul_event(&mut self, mul_event: InstrEvent) { self.mul_events.push(mul_event); } /// Add a lt event to the execution record. - pub fn add_lt_event(&mut self, lt_event: AluEvent) { + pub fn add_lt_event(&mut self, lt_event: InstrEvent) { self.lt_events.push(lt_event); } /// Add a batch of alu events to the execution record. - pub fn add_alu_events(&mut self, mut alu_events: HashMap>) { + pub fn add_alu_events(&mut self, mut alu_events: HashMap>) { for (opcode, value) in &mut alu_events { match opcode { Opcode::ADD => { @@ -165,11 +165,8 @@ impl ExecutionRecord { } /// Add a memory instructions event to the execution record. - pub fn add_memory_instructions_event( - &mut self, - memory_instructions_event: MemoryInstructionsEvent, - ) { - self.memory_instructions_events.push(memory_instructions_event); + pub fn add_memory_instructions_event(&mut self, memory_instructions_event: InstrEvent) { + self.memory_instr_events.push(memory_instructions_event); } /// Take out events from the [`ExecutionRecord`] that should be deferred to a separate shard. @@ -343,10 +340,7 @@ impl MachineRecord for ExecutionRecord { stats.insert("shift_right_events".to_string(), self.shift_right_events.len()); stats.insert("divrem_events".to_string(), self.divrem_events.len()); stats.insert("lt_events".to_string(), self.lt_events.len()); - stats.insert( - "memory_instructions_events".to_string(), - self.memory_instructions_events.len(), - ); + stats.insert("memory_instructions_events".to_string(), self.memory_instr_events.len()); for (syscall_code, events) in self.precompile_events.iter() { stats.insert(format!("syscall {syscall_code:?}"), events.len()); @@ -383,7 +377,7 @@ impl MachineRecord for ExecutionRecord { self.shift_right_events.append(&mut other.shift_right_events); self.divrem_events.append(&mut other.divrem_events); self.lt_events.append(&mut other.lt_events); - self.memory_instructions_events.append(&mut other.memory_instructions_events); + self.memory_instr_events.append(&mut other.memory_instr_events); self.syscall_events.append(&mut other.syscall_events); self.precompile_events.append(&mut other.precompile_events); diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index 666400b2c2..374f14f832 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -10,7 +10,7 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ - events::{AluEvent, ByteLookupEvent, ByteRecord}, + events::{InstrEvent, ByteLookupEvent, ByteRecord}, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; @@ -143,7 +143,7 @@ impl AddSubChip { /// Create a row from an event. fn event_to_row( &self, - event: &AluEvent, + event: &InstrEvent, cols: &mut AddSubCols, blu: &mut impl ByteRecord, ) { @@ -226,7 +226,7 @@ mod tests { use p3_baby_bear::BabyBear; use p3_matrix::dense::RowMajorMatrix; use rand::{thread_rng, Rng}; - use sp1_core_executor::{events::AluEvent, ExecutionRecord, Opcode}; + use sp1_core_executor::{events::InstrEvent, ExecutionRecord, Opcode}; use sp1_stark::{air::MachineAir, baby_bear_poseidon2::BabyBearPoseidon2, StarkGenericConfig}; use super::AddSubChip; @@ -235,7 +235,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.add_events = vec![AluEvent::new(0, 0, Opcode::ADD, 14, 8, 6)]; + shard.add_events = vec![InstrEvent::new(0, 0, Opcode::ADD, 14, 8, 6)]; let chip = AddSubChip::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -252,7 +252,7 @@ mod tests { let operand_1 = thread_rng().gen_range(0..u32::MAX); let operand_2 = thread_rng().gen_range(0..u32::MAX); let result = operand_1.wrapping_add(operand_2); - shard.add_events.push(AluEvent::new( + shard.add_events.push(InstrEvent::new( i % 2, 0, Opcode::ADD, @@ -265,7 +265,7 @@ mod tests { let operand_1 = thread_rng().gen_range(0..u32::MAX); let operand_2 = thread_rng().gen_range(0..u32::MAX); let result = operand_1.wrapping_sub(operand_2); - shard.add_events.push(AluEvent::new( + shard.add_events.push(InstrEvent::new( i % 2, 0, Opcode::SUB, diff --git a/crates/core/machine/src/alu/bitwise/mod.rs b/crates/core/machine/src/alu/bitwise/mod.rs index 9e89213838..a9bca52c71 100644 --- a/crates/core/machine/src/alu/bitwise/mod.rs +++ b/crates/core/machine/src/alu/bitwise/mod.rs @@ -10,7 +10,7 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{IntoParallelRefIterator, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{AluEvent, ByteLookupEvent, ByteRecord}, + events::{InstrEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; @@ -136,7 +136,7 @@ impl BitwiseChip { /// Create a row from an event. fn event_to_row( &self, - event: &AluEvent, + event: &InstrEvent, cols: &mut BitwiseCols, blu: &mut impl ByteRecord, ) { @@ -227,7 +227,7 @@ where mod tests { use p3_baby_bear::BabyBear; use p3_matrix::dense::RowMajorMatrix; - use sp1_core_executor::{events::AluEvent, ExecutionRecord, Opcode}; + use sp1_core_executor::{events::InstrEvent, ExecutionRecord, Opcode}; use sp1_stark::{air::MachineAir, baby_bear_poseidon2::BabyBearPoseidon2, StarkGenericConfig}; use crate::utils::{uni_stark_prove, uni_stark_verify}; @@ -237,7 +237,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.bitwise_events = vec![AluEvent::new(0, 0, Opcode::XOR, 25, 10, 19)]; + shard.bitwise_events = vec![InstrEvent::new(0, 0, Opcode::XOR, 25, 10, 19)]; let chip = BitwiseChip::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -251,9 +251,9 @@ mod tests { let mut shard = ExecutionRecord::default(); shard.bitwise_events = [ - AluEvent::new(0, 0, Opcode::XOR, 25, 10, 19), - AluEvent::new(0, 0, Opcode::OR, 27, 10, 19), - AluEvent::new(0, 0, Opcode::AND, 2, 10, 19), + InstrEvent::new(0, 0, Opcode::XOR, 25, 10, 19), + InstrEvent::new(0, 0, Opcode::OR, 27, 10, 19), + InstrEvent::new(0, 0, Opcode::AND, 2, 10, 19), ] .repeat(1000); let chip = BitwiseChip::default(); diff --git a/crates/core/machine/src/alu/divrem/mod.rs b/crates/core/machine/src/alu/divrem/mod.rs index a4afea3067..047c8fe499 100644 --- a/crates/core/machine/src/alu/divrem/mod.rs +++ b/crates/core/machine/src/alu/divrem/mod.rs @@ -835,7 +835,7 @@ mod tests { use crate::utils::{uni_stark_prove, uni_stark_verify}; use p3_baby_bear::BabyBear; use p3_matrix::dense::RowMajorMatrix; - use sp1_core_executor::{events::AluEvent, ExecutionRecord, Opcode}; + use sp1_core_executor::{events::InstrEvent, ExecutionRecord, Opcode}; use sp1_stark::{air::MachineAir, baby_bear_poseidon2::BabyBearPoseidon2, StarkGenericConfig}; use super::DivRemChip; @@ -843,7 +843,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.divrem_events = vec![AluEvent::new(0, 0, Opcode::DIVU, 2, 17, 3)]; + shard.divrem_events = vec![InstrEvent::new(0, 0, Opcode::DIVU, 2, 17, 3)]; let chip = DivRemChip::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -859,7 +859,7 @@ mod tests { let config = BabyBearPoseidon2::new(); let mut challenger = config.challenger(); - let mut divrem_events: Vec = Vec::new(); + let mut divrem_events: Vec = Vec::new(); let divrems: Vec<(Opcode, u32, u32, u32)> = vec![ (Opcode::DIVU, 3, 20, 6), @@ -896,12 +896,12 @@ mod tests { (Opcode::REM, 0, 1 << 31, neg(1)), ]; for t in divrems.iter() { - divrem_events.push(AluEvent::new(0, 0, t.0, t.1, t.2, t.3)); + divrem_events.push(InstrEvent::new(0, 0, t.0, t.1, t.2, t.3)); } // Append more events until we have 1000 tests. for _ in 0..(1000 - divrems.len()) { - divrem_events.push(AluEvent::new(0, 0, Opcode::DIVU, 1, 1, 1)); + divrem_events.push(InstrEvent::new(0, 0, Opcode::DIVU, 1, 1, 1)); } let mut shard = ExecutionRecord::default(); diff --git a/crates/core/machine/src/alu/lt/mod.rs b/crates/core/machine/src/alu/lt/mod.rs index 9b348d813c..72f3654883 100644 --- a/crates/core/machine/src/alu/lt/mod.rs +++ b/crates/core/machine/src/alu/lt/mod.rs @@ -10,7 +10,7 @@ use p3_field::{AbstractField, Field, PrimeField32}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::*; use sp1_core_executor::{ - events::{AluEvent, ByteLookupEvent, ByteRecord}, + events::{InstrEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; @@ -167,7 +167,7 @@ impl LtChip { /// Create a row from an event. fn event_to_row( &self, - event: &AluEvent, + event: &InstrEvent, cols: &mut LtCols, blu: &mut impl ByteRecord, ) { @@ -460,7 +460,7 @@ mod tests { use crate::utils::{uni_stark_prove as prove, uni_stark_verify as verify}; use p3_baby_bear::BabyBear; use p3_matrix::dense::RowMajorMatrix; - use sp1_core_executor::{events::AluEvent, ExecutionRecord, Opcode}; + use sp1_core_executor::{events::InstrEvent, ExecutionRecord, Opcode}; use sp1_stark::{air::MachineAir, baby_bear_poseidon2::BabyBearPoseidon2, StarkGenericConfig}; use super::LtChip; @@ -468,7 +468,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.lt_events = vec![AluEvent::new(0, 0, Opcode::SLT, 0, 3, 2)]; + shard.lt_events = vec![InstrEvent::new(0, 0, Opcode::SLT, 0, 3, 2)]; let chip = LtChip::default(); let generate_trace = chip.generate_trace(&shard, &mut ExecutionRecord::default()); let trace: RowMajorMatrix = generate_trace; @@ -496,21 +496,21 @@ mod tests { const NEG_4: u32 = 0b11111111111111111111111111111100; shard.lt_events = vec![ // 0 == 3 < 2 - AluEvent::new(0, 0, Opcode::SLT, 0, 3, 2), + InstrEvent::new(0, 0, Opcode::SLT, 0, 3, 2), // 1 == 2 < 3 - AluEvent::new(0, 1, Opcode::SLT, 1, 2, 3), + InstrEvent::new(0, 1, Opcode::SLT, 1, 2, 3), // 0 == 5 < -3 - AluEvent::new(0, 3, Opcode::SLT, 0, 5, NEG_3), + InstrEvent::new(0, 3, Opcode::SLT, 0, 5, NEG_3), // 1 == -3 < 5 - AluEvent::new(0, 2, Opcode::SLT, 1, NEG_3, 5), + InstrEvent::new(0, 2, Opcode::SLT, 1, NEG_3, 5), // 0 == -3 < -4 - AluEvent::new(0, 4, Opcode::SLT, 0, NEG_3, NEG_4), + InstrEvent::new(0, 4, Opcode::SLT, 0, NEG_3, NEG_4), // 1 == -4 < -3 - AluEvent::new(0, 4, Opcode::SLT, 1, NEG_4, NEG_3), + InstrEvent::new(0, 4, Opcode::SLT, 1, NEG_4, NEG_3), // 0 == 3 < 3 - AluEvent::new(0, 5, Opcode::SLT, 0, 3, 3), + InstrEvent::new(0, 5, Opcode::SLT, 0, 3, 3), // 0 == -3 < -3 - AluEvent::new(0, 5, Opcode::SLT, 0, NEG_3, NEG_3), + InstrEvent::new(0, 5, Opcode::SLT, 0, NEG_3, NEG_3), ]; prove_babybear_template(&mut shard); @@ -523,17 +523,17 @@ mod tests { const LARGE: u32 = 0b11111111111111111111111111111101; shard.lt_events = vec![ // 0 == 3 < 2 - AluEvent::new(0, 0, Opcode::SLTU, 0, 3, 2), + InstrEvent::new(0, 0, Opcode::SLTU, 0, 3, 2), // 1 == 2 < 3 - AluEvent::new(0, 1, Opcode::SLTU, 1, 2, 3), + InstrEvent::new(0, 1, Opcode::SLTU, 1, 2, 3), // 0 == LARGE < 5 - AluEvent::new(0, 2, Opcode::SLTU, 0, LARGE, 5), + InstrEvent::new(0, 2, Opcode::SLTU, 0, LARGE, 5), // 1 == 5 < LARGE - AluEvent::new(0, 3, Opcode::SLTU, 1, 5, LARGE), + InstrEvent::new(0, 3, Opcode::SLTU, 1, 5, LARGE), // 0 == 0 < 0 - AluEvent::new(0, 5, Opcode::SLTU, 0, 0, 0), + InstrEvent::new(0, 5, Opcode::SLTU, 0, 0, 0), // 0 == LARGE < LARGE - AluEvent::new(0, 5, Opcode::SLTU, 0, LARGE, LARGE), + InstrEvent::new(0, 5, Opcode::SLTU, 0, LARGE, LARGE), ]; prove_babybear_template(&mut shard); diff --git a/crates/core/machine/src/alu/mul/mod.rs b/crates/core/machine/src/alu/mul/mod.rs index 0cd919bd96..9c3a69b158 100644 --- a/crates/core/machine/src/alu/mul/mod.rs +++ b/crates/core/machine/src/alu/mul/mod.rs @@ -41,7 +41,7 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{AluEvent, ByteLookupEvent, ByteRecord}, + events::{InstrEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; @@ -199,7 +199,7 @@ impl MulChip { /// Create a row from an event. fn event_to_row( &self, - event: &AluEvent, + event: &InstrEvent, cols: &mut MulCols, blu: &mut impl ByteRecord, ) { @@ -459,7 +459,7 @@ mod tests { use crate::utils::{uni_stark_prove as prove, uni_stark_verify as verify}; use p3_baby_bear::BabyBear; use p3_matrix::dense::RowMajorMatrix; - use sp1_core_executor::{events::AluEvent, ExecutionRecord, Opcode}; + use sp1_core_executor::{events::InstrEvent, ExecutionRecord, Opcode}; use sp1_stark::{air::MachineAir, baby_bear_poseidon2::BabyBearPoseidon2, StarkGenericConfig}; use super::MulChip; @@ -469,9 +469,9 @@ mod tests { let mut shard = ExecutionRecord::default(); // Fill mul_events with 10^7 MULHSU events. - let mut mul_events: Vec = Vec::new(); + let mut mul_events: Vec = Vec::new(); for _ in 0..10i32.pow(7) { - mul_events.push(AluEvent::new( + mul_events.push(InstrEvent::new( 0, 0, Opcode::MULHSU, @@ -492,7 +492,7 @@ mod tests { let mut challenger = config.challenger(); let mut shard = ExecutionRecord::default(); - let mut mul_events: Vec = Vec::new(); + let mut mul_events: Vec = Vec::new(); let mul_instructions: Vec<(Opcode, u32, u32, u32)> = vec![ (Opcode::MUL, 0x00001200, 0x00007e00, 0xb6db6db7), @@ -547,12 +547,12 @@ mod tests { (Opcode::MULH, 0xffffffff, 0x00000001, 0xffffffff), ]; for t in mul_instructions.iter() { - mul_events.push(AluEvent::new(0, 0, t.0, t.1, t.2, t.3)); + mul_events.push(InstrEvent::new(0, 0, t.0, t.1, t.2, t.3)); } // Append more events until we have 1000 tests. for _ in 0..(1000 - mul_instructions.len()) { - mul_events.push(AluEvent::new(0, 0, Opcode::MUL, 1, 1, 1)); + mul_events.push(InstrEvent::new(0, 0, Opcode::MUL, 1, 1, 1)); } shard.mul_events = mul_events; diff --git a/crates/core/machine/src/alu/sll/mod.rs b/crates/core/machine/src/alu/sll/mod.rs index f8a7e06a5d..2be166dbaf 100644 --- a/crates/core/machine/src/alu/sll/mod.rs +++ b/crates/core/machine/src/alu/sll/mod.rs @@ -42,7 +42,7 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{AluEvent, ByteLookupEvent, ByteRecord}, + events::{InstrEvent, ByteLookupEvent, ByteRecord}, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; @@ -196,7 +196,7 @@ impl ShiftLeft { /// Create a row from an event. fn event_to_row( &self, - event: &AluEvent, + event: &InstrEvent, cols: &mut ShiftLeftCols, blu: &mut impl ByteRecord, ) { @@ -404,7 +404,7 @@ mod tests { use crate::utils::{uni_stark_prove as prove, uni_stark_verify as verify}; use p3_baby_bear::BabyBear; use p3_matrix::dense::RowMajorMatrix; - use sp1_core_executor::{events::AluEvent, ExecutionRecord, Opcode}; + use sp1_core_executor::{events::InstrEvent, ExecutionRecord, Opcode}; use sp1_stark::{air::MachineAir, baby_bear_poseidon2::BabyBearPoseidon2, StarkGenericConfig}; use super::ShiftLeft; @@ -412,7 +412,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.shift_left_events = vec![AluEvent::new(0, 0, Opcode::SLL, 16, 8, 1)]; + shard.shift_left_events = vec![InstrEvent::new(0, 0, Opcode::SLL, 16, 8, 1)]; let chip = ShiftLeft::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -424,7 +424,7 @@ mod tests { let config = BabyBearPoseidon2::new(); let mut challenger = config.challenger(); - let mut shift_events: Vec = Vec::new(); + let mut shift_events: Vec = Vec::new(); let shift_instructions: Vec<(Opcode, u32, u32, u32)> = vec![ (Opcode::SLL, 0x00000002, 0x00000001, 1), (Opcode::SLL, 0x00000080, 0x00000001, 7), @@ -447,7 +447,7 @@ mod tests { (Opcode::SLL, 0x00000000, 0x21212120, 0xffffffff), ]; for t in shift_instructions.iter() { - shift_events.push(AluEvent::new(0, 0, t.0, t.1, t.2, t.3)); + shift_events.push(InstrEvent::new(0, 0, t.0, t.1, t.2, t.3)); } // Append more events until we have 1000 tests. diff --git a/crates/core/machine/src/alu/sr/mod.rs b/crates/core/machine/src/alu/sr/mod.rs index fec93c4334..9b9e0717da 100644 --- a/crates/core/machine/src/alu/sr/mod.rs +++ b/crates/core/machine/src/alu/sr/mod.rs @@ -54,7 +54,7 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{AluEvent, ByteLookupEvent, ByteRecord}, + events::{InstrEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; @@ -211,7 +211,7 @@ impl ShiftRightChip { /// Create a row from an event. fn event_to_row( &self, - event: &AluEvent, + event: &InstrEvent, cols: &mut ShiftRightCols, blu: &mut impl ByteRecord, ) { @@ -524,7 +524,7 @@ mod tests { use crate::utils::{uni_stark_prove as prove, uni_stark_verify as verify}; use p3_baby_bear::BabyBear; use p3_matrix::dense::RowMajorMatrix; - use sp1_core_executor::{events::AluEvent, ExecutionRecord, Opcode}; + use sp1_core_executor::{events::InstrEvent, ExecutionRecord, Opcode}; use sp1_stark::{air::MachineAir, baby_bear_poseidon2::BabyBearPoseidon2, StarkGenericConfig}; use super::ShiftRightChip; @@ -532,7 +532,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.shift_right_events = vec![AluEvent::new(0, 0, Opcode::SRL, 6, 12, 1)]; + shard.shift_right_events = vec![InstrEvent::new(0, 0, Opcode::SRL, 6, 12, 1)]; let chip = ShiftRightChip::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -581,9 +581,9 @@ mod tests { (Opcode::SRA, 0xfffe0606, 0x81818181, 14), (Opcode::SRA, 0xffffffff, 0x81818181, 31), ]; - let mut shift_events: Vec = Vec::new(); + let mut shift_events: Vec = Vec::new(); for t in shifts.iter() { - shift_events.push(AluEvent::new(0, 0, t.0, t.1, t.2, t.3)); + shift_events.push(InstrEvent::new(0, 0, t.0, t.1, t.2, t.3)); } let mut shard = ExecutionRecord::default(); shard.shift_right_events = shift_events; diff --git a/crates/core/machine/src/riscv/mod.rs b/crates/core/machine/src/riscv/mod.rs index a78484f294..68cc20cc89 100644 --- a/crates/core/machine/src/riscv/mod.rs +++ b/crates/core/machine/src/riscv/mod.rs @@ -413,7 +413,7 @@ impl RiscvAir { ), ( RiscvAir::MemoryInstructions(MemoryInstructionsChip::default()), - record.memory_instructions_events.len(), + record.memory_instr_events.len(), ), (RiscvAir::SyscallCore(SyscallChip::core()), record.syscall_events.len()), ] diff --git a/crates/core/machine/src/syscall/precompiles/sha256/extend/mod.rs b/crates/core/machine/src/syscall/precompiles/sha256/extend/mod.rs index cb3aea1bbb..44259ccca5 100644 --- a/crates/core/machine/src/syscall/precompiles/sha256/extend/mod.rs +++ b/crates/core/machine/src/syscall/precompiles/sha256/extend/mod.rs @@ -34,7 +34,7 @@ pub mod extend_tests { use p3_matrix::dense::RowMajorMatrix; use sp1_core_executor::{ - events::AluEvent, syscalls::SyscallCode, ExecutionRecord, Instruction, Opcode, Program, + events::InstrEvent, syscalls::SyscallCode, ExecutionRecord, Instruction, Opcode, Program, }; use sp1_stark::{air::MachineAir, CpuProver}; @@ -66,7 +66,7 @@ pub mod extend_tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.add_events = vec![AluEvent::new(0, 0, Opcode::ADD, 14, 8, 6)]; + shard.add_events = vec![InstrEvent::new(0, 0, Opcode::ADD, 14, 8, 6)]; let chip = ShaExtendChip::new(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); From 692f3be010c224e522ba8e3f2e79eba3b9b8488f Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Wed, 20 Nov 2024 19:34:31 -0800 Subject: [PATCH 04/18] got shard from public values --- .../core/machine/src/memory/instructions/air.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/crates/core/machine/src/memory/instructions/air.rs b/crates/core/machine/src/memory/instructions/air.rs index e944e960ff..3b6e125b06 100644 --- a/crates/core/machine/src/memory/instructions/air.rs +++ b/crates/core/machine/src/memory/instructions/air.rs @@ -1,6 +1,9 @@ use p3_air::{Air, AirBuilder}; use p3_field::AbstractField; -use sp1_stark::{air::SP1AirBuilder, Word}; +use sp1_stark::{ + air::{PublicValues, SP1AirBuilder, SP1_PROOF_NUM_PV_ELTS}, + Word, +}; use crate::{ air::{SP1CoreAirBuilder, WordAirBuilder}, @@ -20,7 +23,13 @@ where fn eval(&self, builder: &mut AB) { let local = builder.local(); - self.eval_memory_address_and_access::(builder, local); + let public_values_slice: [AB::PublicVar; SP1_PROOF_NUM_PV_ELTS] = + core::array::from_fn(|i| builder.public_values()[i]); + let public_values: &PublicValues, AB::PublicVar> = + public_values_slice.as_slice().borrow(); + let shard: AB::Expr = public_values.shard.into(); + + self.eval_memory_address_and_access::(builder, local, shard); self.eval_memory_load::(builder, local); self.eval_memory_store::(builder, local); @@ -69,6 +78,7 @@ impl MemoryInstructionsChip { &self, builder: &mut AB, local: &MemoryInstructionsColumns, + shard: AB::Expr, ) { // Send to the ALU table to verify correct calculation of addr_word. builder.send_instruction( @@ -120,7 +130,7 @@ impl MemoryInstructionsChip { // For operations that require reading from memory (not registers), we need to read the // value into the memory columns. builder.eval_memory_access( - local.shard, + shard, local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::Memory as u32), local.addr_aligned, &local.memory_access, @@ -170,7 +180,6 @@ impl MemoryInstructionsChip { local.op_a_val(), local.unsigned_mem_val, signed_value, - local.shard, local.unsigned_mem_val_nonce, local.mem_value_is_neg_not_x0, ); From 01b996b6ccf3bdf223a9f8fb3f163d9df877850a Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Thu, 21 Nov 2024 14:46:31 -0800 Subject: [PATCH 05/18] remove shard --- crates/core/executor/src/dependencies.rs | 46 +++----- crates/core/executor/src/events/byte.rs | 109 ++++-------------- crates/core/executor/src/events/instr.rs | 11 +- crates/core/executor/src/executor.rs | 20 ++-- crates/core/executor/src/record.rs | 27 +++-- crates/core/machine/src/alu/add_sub/mod.rs | 51 ++++---- crates/core/machine/src/alu/bitwise/mod.rs | 22 ++-- crates/core/machine/src/alu/divrem/mod.rs | 39 ++++--- crates/core/machine/src/alu/lt/mod.rs | 47 ++++---- crates/core/machine/src/alu/mul/mod.rs | 31 +++-- crates/core/machine/src/alu/sll/mod.rs | 22 ++-- crates/core/machine/src/alu/sr/mod.rs | 27 +++-- crates/core/machine/src/bytes/mod.rs | 19 ++- crates/core/machine/src/cpu/air/branch.rs | 11 +- crates/core/machine/src/cpu/air/mod.rs | 17 ++- crates/core/machine/src/cpu/columns/mod.rs | 3 - crates/core/machine/src/cpu/trace.rs | 27 +---- .../machine/src/memory/instructions/air.rs | 8 +- crates/core/machine/src/operations/add.rs | 6 +- crates/stark/src/air/builder.rs | 14 ++- 20 files changed, 235 insertions(+), 322 deletions(-) diff --git a/crates/core/executor/src/dependencies.rs b/crates/core/executor/src/dependencies.rs index be1fc7aee4..26285c32c8 100644 --- a/crates/core/executor/src/dependencies.rs +++ b/crates/core/executor/src/dependencies.rs @@ -1,13 +1,12 @@ use crate::{ events::InstrEvent, utils::{get_msb, get_quotient_and_remainder, is_signed_operation}, - Executor, Opcode, + Executor, Opcode, UNUSED_PC, }; /// Emits the dependencies for division and remainder operations. #[allow(clippy::too_many_lines)] pub fn emit_divrem_dependencies(executor: &mut Executor, event: InstrEvent) { - let shard = executor.shard(); let (quotient, remainder) = get_quotient_and_remainder(event.b, event.c, event.opcode); let c_msb = get_msb(event.c); let rem_msb = get_msb(remainder); @@ -22,9 +21,8 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: InstrEvent) { if c_neg == 1 { let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(InstrEvent { + pc: UNUSED_PC, lookup_id: event.sub_lookups[4], - shard, - clk: event.clk, opcode: Opcode::ADD, a: 0, b: event.c, @@ -35,9 +33,8 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: InstrEvent) { if rem_neg == 1 { let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(InstrEvent { + pc: UNUSED_PC, lookup_id: event.sub_lookups[5], - shard, - clk: event.clk, opcode: Opcode::ADD, a: 0, b: remainder, @@ -57,9 +54,8 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: InstrEvent) { let upper_word = u32::from_le_bytes(c_times_quotient[4..8].try_into().unwrap()); let lower_multiplication = InstrEvent { + pc: UNUSED_PC, lookup_id: event.sub_lookups[0], - shard, - clk: event.clk, opcode: Opcode::MUL, a: lower_word, c: event.c, @@ -69,9 +65,8 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: InstrEvent) { executor.record.mul_events.push(lower_multiplication); let upper_multiplication = InstrEvent { + pc: UNUSED_PC, lookup_id: event.sub_lookups[1], - shard, - clk: event.clk, opcode: { if is_signed_operation { Opcode::MULH @@ -88,24 +83,22 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: InstrEvent) { let lt_event = if is_signed_operation { InstrEvent { + pc: UNUSED_PC, lookup_id: event.sub_lookups[2], - shard, opcode: Opcode::SLTU, a: 1, b: (remainder as i32).unsigned_abs(), c: u32::max(1, (event.c as i32).unsigned_abs()), - clk: event.clk, sub_lookups: executor.record.create_lookup_ids(), } } else { InstrEvent { + pc: UNUSED_PC, lookup_id: event.sub_lookups[3], - shard, opcode: Opcode::SLTU, a: 1, b: remainder, c: u32::max(1, event.c), - clk: event.clk, sub_lookups: executor.record.create_lookup_ids(), } }; @@ -119,7 +112,6 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: InstrEvent) { #[allow(clippy::too_many_lines)] pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { let event = executor.record.cpu_events[index]; - let shard = executor.shard(); let instruction = &executor.program.fetch(event.pc); if matches!( instruction.opcode, @@ -135,9 +127,8 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { let memory_addr = event.b.wrapping_add(event.c); // Add event to ALU check to check that addr == b + c let add_event = InstrEvent { + pc: UNUSED_PC, lookup_id: event.memory_add_lookup_id, - shard, - clk: event.clk, opcode: Opcode::ADD, a: memory_addr, b: event.b, @@ -170,9 +161,8 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { if most_sig_mem_value_byte >> 7 & 0x01 == 1 { let sub_event = InstrEvent { + pc: UNUSED_PC, lookup_id: event.memory_sub_lookup_id, - shard, - clk: event.clk, opcode: Opcode::SUB, a: event.a, b: unsigned_mem_val, @@ -201,9 +191,8 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { let alu_op_code = if use_signed_comparison { Opcode::SLT } else { Opcode::SLTU }; // Add the ALU events for the comparisons let lt_comp_event = InstrEvent { + pc: UNUSED_PC, lookup_id: event.branch_lt_lookup_id, - shard, - clk: event.clk, opcode: alu_op_code, a: a_lt_b as u32, b: event.a, @@ -211,9 +200,8 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { sub_lookups: executor.record.create_lookup_ids(), }; let gt_comp_event = InstrEvent { + pc: UNUSED_PC, lookup_id: event.branch_gt_lookup_id, - shard, - clk: event.clk, opcode: alu_op_code, a: a_gt_b as u32, b: event.b, @@ -232,9 +220,8 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { if branching { let next_pc = event.pc.wrapping_add(event.c); let add_event = InstrEvent { + pc: UNUSED_PC, lookup_id: event.branch_add_lookup_id, - shard, - clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, @@ -250,9 +237,8 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); let add_event = InstrEvent { + pc: UNUSED_PC, lookup_id: event.jump_jal_lookup_id, - shard, - clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, @@ -264,9 +250,8 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { Opcode::JALR => { let next_pc = event.b.wrapping_add(event.c); let add_event = InstrEvent { + pc: UNUSED_PC, lookup_id: event.jump_jalr_lookup_id, - shard, - clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.b, @@ -281,9 +266,8 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { if matches!(instruction.opcode, Opcode::AUIPC) { let add_event = InstrEvent { + pc: UNUSED_PC, lookup_id: event.auipc_lookup_id, - shard, - clk: event.clk, opcode: Opcode::ADD, a: event.a, b: event.pc, diff --git a/crates/core/executor/src/events/byte.rs b/crates/core/executor/src/events/byte.rs index 3db5c7647b..3adca68d1e 100644 --- a/crates/core/executor/src/events/byte.rs +++ b/crates/core/executor/src/events/byte.rs @@ -1,11 +1,7 @@ use std::hash::Hash; use hashbrown::HashMap; -use itertools::Itertools; use p3_field::{Field, PrimeField32}; -use p3_maybe_rayon::prelude::{ - IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator, -}; use serde::{Deserialize, Serialize}; use crate::{ByteOpcode, Opcode}; @@ -19,8 +15,6 @@ pub const NUM_BYTE_OPS: usize = 9; /// the shard, opcode, operands, and other relevant information. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)] pub struct ByteLookupEvent { - /// The shard number. - pub shard: u32, /// The opcode. pub opcode: ByteOpcode, /// The first operand. @@ -38,10 +32,10 @@ pub trait ByteRecord { /// Adds a new [`ByteLookupEvent`] to the record. fn add_byte_lookup_event(&mut self, blu_event: ByteLookupEvent); - /// Adds a list of sharded [`ByteLookupEvent`]s to the record. - fn add_sharded_byte_lookup_events( + /// Adds a list of [`ByteLookupEvent`] mapss to the record. + fn add_byte_lookup_events_fron_maps( &mut self, - sharded_blu_events_vec: Vec<&HashMap>>, + sharded_blu_events_vec: Vec<&HashMap>, ); /// Adds a list of `ByteLookupEvent`s to the record. @@ -53,9 +47,8 @@ pub trait ByteRecord { } /// Adds a `ByteLookupEvent` to verify `a` and `b` are indeed bytes to the shard. - fn add_u8_range_check(&mut self, shard: u32, a: u8, b: u8) { + fn add_u8_range_check(&mut self, a: u8, b: u8) { self.add_byte_lookup_event(ByteLookupEvent { - shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -65,9 +58,8 @@ pub trait ByteRecord { } /// Adds a `ByteLookupEvent` to verify `a` is indeed u16. - fn add_u16_range_check(&mut self, shard: u32, a: u16) { + fn add_u16_range_check(&mut self, a: u16) { self.add_byte_lookup_event(ByteLookupEvent { - shard, opcode: ByteOpcode::U16Range, a1: a, a2: 0, @@ -77,36 +69,34 @@ pub trait ByteRecord { } /// Adds `ByteLookupEvent`s to verify that all the bytes in the input slice are indeed bytes. - fn add_u8_range_checks(&mut self, shard: u32, bytes: &[u8]) { + fn add_u8_range_checks(&mut self, bytes: &[u8]) { let mut index = 0; while index + 1 < bytes.len() { - self.add_u8_range_check(shard, bytes[index], bytes[index + 1]); + self.add_u8_range_check(bytes[index], bytes[index + 1]); index += 2; } if index < bytes.len() { // If the input slice's length is odd, we need to add a check for the last byte. - self.add_u8_range_check(shard, bytes[index], 0); + self.add_u8_range_check(bytes[index], 0); } } /// Adds `ByteLookupEvent`s to verify that all the field elements in the input slice are indeed /// bytes. - fn add_u8_range_checks_field(&mut self, shard: u32, field_values: &[F]) { + fn add_u8_range_checks_field(&mut self, field_values: &[F]) { self.add_u8_range_checks( - shard, &field_values.iter().map(|x| x.as_canonical_u32() as u8).collect::>(), ); } /// Adds `ByteLookupEvent`s to verify that all the bytes in the input slice are indeed bytes. - fn add_u16_range_checks(&mut self, shard: u32, ls: &[u16]) { - ls.iter().for_each(|x| self.add_u16_range_check(shard, *x)); + fn add_u16_range_checks(&mut self, ls: &[u16]) { + ls.iter().for_each(|x| self.add_u16_range_check(*x)); } /// Adds a `ByteLookupEvent` to compute the bitwise OR of the two input values. - fn lookup_or(&mut self, shard: u32, b: u8, c: u8) { + fn lookup_or(&mut self, b: u8, c: u8) { self.add_byte_lookup_event(ByteLookupEvent { - shard, opcode: ByteOpcode::OR, a1: (b | c) as u16, a2: 0, @@ -119,8 +109,8 @@ pub trait ByteRecord { impl ByteLookupEvent { /// Creates a new `ByteLookupEvent`. #[must_use] - pub fn new(shard: u32, opcode: ByteOpcode, a1: u16, a2: u8, b: u8, c: u8) -> Self { - Self { shard, opcode, a1, a2, b, c } + pub fn new(opcode: ByteOpcode, a1: u16, a2: u8, b: u8, c: u8) -> Self { + Self { opcode, a1, a2, b, c } } } @@ -129,79 +119,26 @@ impl ByteRecord for Vec { self.push(blu_event); } - fn add_sharded_byte_lookup_events( - &mut self, - _: Vec<&HashMap>>, - ) { - todo!() + fn add_byte_lookup_events_fron_maps(&mut self, _: Vec<&HashMap>) { + unimplemented!() } } -impl ByteRecord for HashMap> { +impl ByteRecord for HashMap { #[inline] fn add_byte_lookup_event(&mut self, blu_event: ByteLookupEvent) { - self.entry(blu_event.shard) - .or_default() - .entry(blu_event) - .and_modify(|e| *e += 1) - .or_insert(1); + self.entry(blu_event).and_modify(|e| *e += 1).or_insert(1); } - fn add_sharded_byte_lookup_events( + fn add_byte_lookup_events_fron_maps( &mut self, - new_events: Vec<&HashMap>>, + new_events: Vec<&HashMap>, ) { - add_sharded_byte_lookup_events(self, new_events); - } -} - -pub(crate) fn add_sharded_byte_lookup_events( - sharded_blu_events: &mut HashMap>, - new_events: Vec<&HashMap>>, -) { - // new_sharded_blu_map is a map of shard -> Vec multiplicities>. - // We want to collect the new events in this format so that we can do parallel aggregation - // per shard. - let mut new_sharded_blu_map: HashMap>> = - HashMap::new(); - for new_sharded_blu_events in new_events { - for (shard, new_blu_map) in new_sharded_blu_events { - new_sharded_blu_map.entry(*shard).or_insert(Vec::new()).push(new_blu_map); - } - } - - // Collect all the shard numbers. - let shards: Vec = new_sharded_blu_map.keys().copied().collect_vec(); - - // Move ownership of self's per shard blu maps into a vec. This is so that we - // can do parallel aggregation per shard. - let mut self_blu_maps: Vec> = Vec::new(); - for shard in &shards { - let blu = sharded_blu_events.remove(shard); - - match blu { - Some(blu) => { - self_blu_maps.push(blu); - } - None => { - self_blu_maps.push(HashMap::new()); - } - } - } - - // Increment self's byte lookup events multiplicity. - shards.par_iter().zip_eq(self_blu_maps.par_iter_mut()).for_each(|(shard, self_blu_map)| { - let blu_map_vec = new_sharded_blu_map.get(shard).unwrap(); - for blu_map in blu_map_vec.iter() { - for (blu_event, count) in blu_map.iter() { - *self_blu_map.entry(*blu_event).or_insert(0) += count; + for new_blu_map in new_events { + for (blu_event, count) in new_blu_map.iter() { + *self.entry(*blu_event).or_insert(0) += count; } } - }); - - // Move ownership of the blu maps back to self. - for (shard, blu) in shards.into_iter().zip(self_blu_maps.into_iter()) { - sharded_blu_events.insert(shard, blu); } } diff --git a/crates/core/executor/src/events/instr.rs b/crates/core/executor/src/events/instr.rs index f2c8422870..e3f75da7ce 100644 --- a/crates/core/executor/src/events/instr.rs +++ b/crates/core/executor/src/events/instr.rs @@ -10,12 +10,10 @@ use super::{create_random_lookup_ids, LookupId}; /// shard, opcode, operands, and other relevant information. #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct InstrEvent { + /// The program counter. + pub pc: u32, /// The lookup identifier. pub lookup_id: LookupId, - /// The shard number. - pub shard: u32, - /// The clock cycle. - pub clk: u32, /// The opcode. pub opcode: Opcode, /// The first operand. @@ -31,11 +29,10 @@ pub struct InstrEvent { impl InstrEvent { /// Create a new [`AluEvent`]. #[must_use] - pub fn new(shard: u32, clk: u32, opcode: Opcode, a: u32, b: u32, c: u32) -> Self { + pub fn new(pc: u32, opcode: Opcode, a: u32, b: u32, c: u32) -> Self { Self { + pc, lookup_id: LookupId::default(), - shard, - clk, opcode, a, b, diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index 30054e5e09..57ca224c61 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -26,6 +26,11 @@ use crate::{ Instruction, Opcode, Program, Register, }; +pub const DEFAULT_PC_INC: u32 = 4; +/// This is used in the `InstrEvent` to indicate that the instruction is not from the CPU. +/// A valid pc should be divisible by 4, so we use 1 to indicate that the pc is not used. +pub const UNUSED_PC: u32 = 1; + /// An executor for the SP1 RISC-V zkVM. /// /// The exeuctor is responsible for executing a user program and tracing important events which @@ -643,19 +648,10 @@ impl<'a> Executor<'a> { } /// Emit an ALU event. - fn emit_instruction( - &mut self, - clk: u32, - opcode: Opcode, - a: u32, - b: u32, - c: u32, - lookup_id: LookupId, - ) { + fn emit_instruction(&mut self, opcode: Opcode, a: u32, b: u32, c: u32, lookup_id: LookupId) { let event = InstrEvent { lookup_id, - shard: self.shard(), - clk, + pc: self.state.pc, opcode, a, b, @@ -766,7 +762,7 @@ impl<'a> Executor<'a> { ) { self.rw(rd, a); if self.executor_mode == ExecutorMode::Trace { - self.emit_instruction(self.state.clk, instruction.opcode, a, b, c, lookup_id); + self.emit_instruction(instruction.opcode, a, b, c, lookup_id); } } diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index 445750536a..9ec3ddc89a 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -12,9 +12,8 @@ use serde::{Deserialize, Serialize}; use super::{program::Program, Opcode}; use crate::{ events::{ - add_sharded_byte_lookup_events, ByteLookupEvent, ByteRecord, CpuEvent, InstrEvent, - LookupId, MemoryInitializeFinalizeEvent, MemoryLocalEvent, MemoryRecordEnum, - PrecompileEvent, PrecompileEvents, SyscallEvent, + ByteLookupEvent, ByteRecord, CpuEvent, InstrEvent, LookupId, MemoryInitializeFinalizeEvent, + MemoryLocalEvent, MemoryRecordEnum, PrecompileEvent, PrecompileEvents, SyscallEvent, }, syscalls::SyscallCode, CoreShape, @@ -48,7 +47,7 @@ pub struct ExecutionRecord { /// A trace of the memory instructions. pub memory_instr_events: Vec, /// A trace of the byte lookups that are needed. - pub byte_lookups: HashMap>, + pub byte_lookups: HashMap, /// A trace of the precompile events. pub precompile_events: PrecompileEvents, /// A trace of the global memory initialize events. @@ -356,11 +355,7 @@ impl MachineRecord for ExecutionRecord { ); stats.insert("local_memory_access_events".to_string(), self.cpu_local_memory_access.len()); if !self.cpu_events.is_empty() { - let shard = self.public_values.shard; - stats.insert( - "byte_lookups".to_string(), - self.byte_lookups.get(&shard).map_or(0, hashbrown::HashMap::len), - ); + stats.insert("byte_lookups".to_string(), self.byte_lookups.len()); } // Filter out the empty events. stats.retain(|_, v| *v != 0); @@ -385,7 +380,7 @@ impl MachineRecord for ExecutionRecord { if self.byte_lookups.is_empty() { self.byte_lookups = std::mem::take(&mut other.byte_lookups); } else { - self.add_sharded_byte_lookup_events(vec![&other.byte_lookups]); + self.add_byte_lookup_events_fron_maps(vec![&other.byte_lookups]); } self.global_memory_initialize_events.append(&mut other.global_memory_initialize_events); @@ -435,14 +430,18 @@ impl MachineRecord for ExecutionRecord { impl ByteRecord for ExecutionRecord { fn add_byte_lookup_event(&mut self, blu_event: ByteLookupEvent) { - *self.byte_lookups.entry(blu_event.shard).or_default().entry(blu_event).or_insert(0) += 1; + *self.byte_lookups.entry(blu_event).or_insert(0) += 1; } #[inline] - fn add_sharded_byte_lookup_events( + fn add_byte_lookup_events_fron_maps( &mut self, - new_events: Vec<&HashMap>>, + new_events: Vec<&HashMap>, ) { - add_sharded_byte_lookup_events(&mut self.byte_lookups, new_events); + for new_blu_map in new_events { + for (blu_event, count) in new_blu_map.iter() { + *self.byte_lookups.entry(*blu_event).or_insert(0) += count; + } + } } } diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index 374f14f832..72825977af 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -10,8 +10,8 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ - events::{InstrEvent, ByteLookupEvent, ByteRecord}, - ExecutionRecord, Opcode, Program, + events::{ByteLookupEvent, ByteRecord, InstrEvent}, + ExecutionRecord, Opcode, Program, DEFAULT_PC_INC, }; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -40,8 +40,8 @@ pub struct AddSubChip; #[derive(AlignedBorrow, Default, Clone, Copy)] #[repr(C)] pub struct AddSubCols { - /// The shard number, used for byte lookup table. - pub shard: T, + /// The program counter. + pub pc: T, /// The nonce of the operation. pub nonce: T, @@ -148,10 +148,12 @@ impl AddSubChip { blu: &mut impl ByteRecord, ) { let is_add = event.opcode == Opcode::ADD; - cols.shard = F::from_canonical_u32(event.shard); cols.is_add = F::from_bool(is_add); cols.is_sub = F::from_bool(!is_add); + cols.from_cpu = F::from_bool(event.from_cpu); + cols.pc = F::from_canonical_u32(event.pc); + let operand_1 = if is_add { event.b } else { event.a }; let operand_2 = event.c; @@ -178,6 +180,14 @@ where let next = main.row_slice(1); let next: &AddSubCols = (*next).borrow(); + let is_real = local.is_add + local.is_sub; + + // Calculate the opcode. + // local.is_add == 1 -> opcode == 0 + // local.is_sub == 1 -> opcode == 1 + // We also constrain the local.is_add and local.is_sub are bool and never both true. + let opcode = local.is_sub; + // Constrain the incrementing nonce. builder.when_first_row().assert_zero(local.nonce); builder.when_transition().assert_eq(local.nonce + AB::Expr::one(), next.nonce); @@ -188,33 +198,22 @@ where local.operand_1, local.operand_2, local.add_operation, - local.is_add + local.is_sub, + is_real, ); // Receive the arguments. There are separate receives for ADD and SUB. // For add, `add_operation.value` is `a`, `operand_1` is `b`, and `operand_2` is `c`. builder.receive_instruction( - Opcode::ADD.as_field::(), + local.pc, + local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), + opcode, local.add_operation.value, local.operand_1, local.operand_2, - local.shard, - local.nonce, - local.is_add, - ); - - // For sub, `operand_1` is `a`, `add_operation.value` is `b`, and `operand_2` is `c`. - builder.receive_instruction( - Opcode::SUB.as_field::(), - local.operand_1, - local.add_operation.value, - local.operand_2, - local.shard, local.nonce, - local.is_sub, + is_real, ); - let is_real = local.is_add + local.is_sub; builder.assert_bool(local.is_add); builder.assert_bool(local.is_sub); builder.assert_bool(is_real); @@ -226,7 +225,7 @@ mod tests { use p3_baby_bear::BabyBear; use p3_matrix::dense::RowMajorMatrix; use rand::{thread_rng, Rng}; - use sp1_core_executor::{events::InstrEvent, ExecutionRecord, Opcode}; + use sp1_core_executor::{events::InstrEvent, ExecutionRecord, Opcode, DEFAULT_PC_INC}; use sp1_stark::{air::MachineAir, baby_bear_poseidon2::BabyBearPoseidon2, StarkGenericConfig}; use super::AddSubChip; @@ -235,7 +234,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.add_events = vec![InstrEvent::new(0, 0, Opcode::ADD, 14, 8, 6)]; + shard.add_events = vec![InstrEvent::new(0, Opcode::ADD, 14, 8, 6)]; let chip = AddSubChip::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -253,8 +252,7 @@ mod tests { let operand_2 = thread_rng().gen_range(0..u32::MAX); let result = operand_1.wrapping_add(operand_2); shard.add_events.push(InstrEvent::new( - i % 2, - 0, + i * DEFAULT_PC_INC, Opcode::ADD, result, operand_1, @@ -266,8 +264,7 @@ mod tests { let operand_2 = thread_rng().gen_range(0..u32::MAX); let result = operand_1.wrapping_sub(operand_2); shard.add_events.push(InstrEvent::new( - i % 2, - 0, + i % DEFAULT_PC_INC, Opcode::SUB, result, operand_1, diff --git a/crates/core/machine/src/alu/bitwise/mod.rs b/crates/core/machine/src/alu/bitwise/mod.rs index a9bca52c71..0959fc6285 100644 --- a/crates/core/machine/src/alu/bitwise/mod.rs +++ b/crates/core/machine/src/alu/bitwise/mod.rs @@ -10,8 +10,8 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{IntoParallelRefIterator, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{InstrEvent, ByteLookupEvent, ByteRecord}, - ByteOpcode, ExecutionRecord, Opcode, Program, + events::{ByteLookupEvent, ByteRecord, InstrEvent}, + ByteOpcode, ExecutionRecord, Opcode, Program, DEFAULT_PC_INC, }; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -32,8 +32,8 @@ pub struct BitwiseChip; #[derive(AlignedBorrow, Default, Clone, Copy)] #[repr(C)] pub struct BitwiseCols { - /// The shard number, used for byte lookup table. - pub shard: T, + /// The program counter. + pub pc: T, /// The nonce of the operation. pub nonce: T, @@ -140,6 +140,8 @@ impl BitwiseChip { cols: &mut BitwiseCols, blu: &mut impl ByteRecord, ) { + cols.pc = F::from_canonical_u32(event.pc); + let a = event.a.to_le_bytes(); let b = event.b.to_le_bytes(); let c = event.c.to_le_bytes(); @@ -155,7 +157,6 @@ impl BitwiseChip { for ((b_a, b_b), b_c) in a.into_iter().zip(b).zip(c) { let byte_event = ByteLookupEvent { - shard: event.shard, opcode: ByteOpcode::from(event.opcode), a1: b_a as u16, a2: 0, @@ -206,11 +207,12 @@ where // Receive the arguments. builder.receive_instruction( + local.pc, + local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), cpu_opcode, local.a, local.b, local.c, - local.shard, local.nonce, local.is_xor + local.is_or + local.is_and, ); @@ -237,7 +239,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.bitwise_events = vec![InstrEvent::new(0, 0, Opcode::XOR, 25, 10, 19)]; + shard.bitwise_events = vec![InstrEvent::new(0, Opcode::XOR, 25, 10, 19)]; let chip = BitwiseChip::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -251,9 +253,9 @@ mod tests { let mut shard = ExecutionRecord::default(); shard.bitwise_events = [ - InstrEvent::new(0, 0, Opcode::XOR, 25, 10, 19), - InstrEvent::new(0, 0, Opcode::OR, 27, 10, 19), - InstrEvent::new(0, 0, Opcode::AND, 2, 10, 19), + InstrEvent::new(0, Opcode::XOR, 25, 10, 19), + InstrEvent::new(0, Opcode::OR, 27, 10, 19), + InstrEvent::new(0, Opcode::AND, 2, 10, 19), ] .repeat(1000); let chip = BitwiseChip::default(); diff --git a/crates/core/machine/src/alu/divrem/mod.rs b/crates/core/machine/src/alu/divrem/mod.rs index 047c8fe499..8dc9827354 100644 --- a/crates/core/machine/src/alu/divrem/mod.rs +++ b/crates/core/machine/src/alu/divrem/mod.rs @@ -71,7 +71,7 @@ use p3_matrix::{dense::RowMajorMatrix, Matrix}; use sp1_core_executor::{ events::{ByteLookupEvent, ByteRecord}, get_msb, get_quotient_and_remainder, is_signed_operation, ByteOpcode, ExecutionRecord, Opcode, - Program, + Program, DEFAULT_PC_INC, UNUSED_PC, }; use sp1_derive::AlignedBorrow; use sp1_primitives::consts::WORD_SIZE; @@ -100,8 +100,8 @@ pub struct DivRemChip; #[derive(AlignedBorrow, Default, Debug, Clone, Copy)] #[repr(C)] pub struct DivRemCols { - /// The shard number, used for byte lookup table. - pub shard: T, + /// The program counter. + pub pc: T, /// The nonce of the operation. pub nonce: T, @@ -236,6 +236,8 @@ impl MachineAir for DivRemChip { let mut row = [F::zero(); NUM_DIVREM_COLS]; let cols: &mut DivRemCols = row.as_mut_slice().borrow_mut(); + cols.pc = F::from_canonical_u32(event.pc); + // Initialize cols with basic operands and flags derived from the current event. { cols.a = Word::from(event.a); @@ -301,7 +303,6 @@ impl MachineAir for DivRemChip { for word in words.iter() { let most_significant_byte = word.to_le_bytes()[WORD_SIZE - 1]; blu_events.push(ByteLookupEvent { - shard: event.shard, opcode: ByteOpcode::MSB, a1: get_msb(*word) as u16, a2: 0, @@ -386,9 +387,9 @@ impl MachineAir for DivRemChip { // Range check. { - output.add_u8_range_checks(event.shard, "ient.to_le_bytes()); - output.add_u8_range_checks(event.shard, &remainder.to_le_bytes()); - output.add_u8_range_checks(event.shard, &c_times_quotient); + output.add_u8_range_checks("ient.to_le_bytes()); + output.add_u8_range_checks(&remainder.to_le_bytes()); + output.add_u8_range_checks(&c_times_quotient); } } @@ -497,11 +498,12 @@ where // The lower 4 bytes of c_times_quotient must match the lower 4 bytes of (c * quotient). builder.send_instruction( + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::MUL as u32), Word(lower_half), local.quotient, local.c, - local.shard, local.lower_nonce, local.is_real, ); @@ -522,11 +524,12 @@ where ]; builder.send_instruction( + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), opcode_for_upper_half, Word(upper_half), local.quotient, local.c, - local.shard, local.upper_nonce, local.is_real, ); @@ -680,20 +683,22 @@ where // In the case that `c` or `rem` is negative, instead check that their sum is zero by // sending an AddEvent. builder.send_instruction( + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), Word([zero.clone(), zero.clone(), zero.clone(), zero.clone()]), local.c, local.abs_c, - local.shard, local.abs_c_alu_event_nonce, local.abs_c_alu_event, ); builder.send_instruction( + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), Word([zero.clone(), zero.clone(), zero.clone(), zero.clone()]), local.remainder, local.abs_remainder, - local.shard, local.abs_rem_alu_event_nonce, local.abs_rem_alu_event, ); @@ -735,11 +740,12 @@ where // Dispatch abs(remainder) < max(abs(c), 1), this is equivalent to abs(remainder) < // abs(c) if not division by 0. builder.send_instruction( + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::SLTU as u32), Word([one.clone(), zero.clone(), zero.clone(), zero.clone()]), local.abs_remainder, local.max_abs_c_or_1, - local.shard, local.abs_nonce, local.remainder_check_multiplicity, ); @@ -817,11 +823,12 @@ where }; builder.receive_instruction( + local.pc, + local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), opcode, local.a, local.b, local.c, - local.shard, local.nonce, local.is_real, ); @@ -843,7 +850,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.divrem_events = vec![InstrEvent::new(0, 0, Opcode::DIVU, 2, 17, 3)]; + shard.divrem_events = vec![InstrEvent::new(0, Opcode::DIVU, 2, 17, 3)]; let chip = DivRemChip::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -896,12 +903,12 @@ mod tests { (Opcode::REM, 0, 1 << 31, neg(1)), ]; for t in divrems.iter() { - divrem_events.push(InstrEvent::new(0, 0, t.0, t.1, t.2, t.3)); + divrem_events.push(InstrEvent::new(0, t.0, t.1, t.2, t.3)); } // Append more events until we have 1000 tests. for _ in 0..(1000 - divrems.len()) { - divrem_events.push(InstrEvent::new(0, 0, Opcode::DIVU, 1, 1, 1)); + divrem_events.push(InstrEvent::new(0, Opcode::DIVU, 1, 1, 1)); } let mut shard = ExecutionRecord::default(); diff --git a/crates/core/machine/src/alu/lt/mod.rs b/crates/core/machine/src/alu/lt/mod.rs index 72f3654883..489f1454d3 100644 --- a/crates/core/machine/src/alu/lt/mod.rs +++ b/crates/core/machine/src/alu/lt/mod.rs @@ -10,8 +10,8 @@ use p3_field::{AbstractField, Field, PrimeField32}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::*; use sp1_core_executor::{ - events::{InstrEvent, ByteLookupEvent, ByteRecord}, - ByteOpcode, ExecutionRecord, Opcode, Program, + events::{ByteLookupEvent, ByteRecord, InstrEvent}, + ByteOpcode, ExecutionRecord, Opcode, Program, DEFAULT_PC_INC, }; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -32,8 +32,8 @@ pub struct LtChip; #[derive(AlignedBorrow, Default, Clone, Copy)] #[repr(C)] pub struct LtCols { - /// The shard number, used for byte lookup table. - pub shard: T, + /// The program counter. + pub pc: T, /// The nonce of the operation. pub nonce: T, @@ -175,7 +175,8 @@ impl LtChip { let b = event.b.to_le_bytes(); let c = event.c.to_le_bytes(); - cols.shard = F::from_canonical_u32(event.shard); + cols.pc = F::from_canonical_u32(event.pc); + cols.a = Word(a.map(F::from_canonical_u8)); cols.b = Word(b.map(F::from_canonical_u8)); cols.c = Word(c.map(F::from_canonical_u8)); @@ -188,7 +189,6 @@ impl LtChip { // Send the masked interaction. blu.add_byte_lookup_event(ByteLookupEvent { - shard: event.shard, opcode: ByteOpcode::AND, a1: masked_b as u16, a2: 0, @@ -196,7 +196,6 @@ impl LtChip { c: 0x7f, }); blu.add_byte_lookup_event(ByteLookupEvent { - shard: event.shard, opcode: ByteOpcode::AND, a1: masked_c as u16, a2: 0, @@ -245,7 +244,6 @@ impl LtChip { assert_eq!(cols.a[0], cols.bit_b * (F::one() - cols.bit_c) + cols.is_sign_eq * cols.sltu); blu.add_byte_lookup_event(ByteLookupEvent { - shard: event.shard, opcode: ByteOpcode::LTU, a1: cols.sltu.as_canonical_u32() as u16, a2: 0, @@ -442,12 +440,13 @@ where // Receive the arguments. builder.receive_instruction( + local.pc, + local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), local.is_slt * AB::F::from_canonical_u32(Opcode::SLT as u32) + local.is_sltu * AB::F::from_canonical_u32(Opcode::SLTU as u32), local.a, local.b, local.c, - local.shard, local.nonce, is_real, ); @@ -468,7 +467,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.lt_events = vec![InstrEvent::new(0, 0, Opcode::SLT, 0, 3, 2)]; + shard.lt_events = vec![InstrEvent::new(0, Opcode::SLT, 0, 3, 2)]; let chip = LtChip::default(); let generate_trace = chip.generate_trace(&shard, &mut ExecutionRecord::default()); let trace: RowMajorMatrix = generate_trace; @@ -496,21 +495,21 @@ mod tests { const NEG_4: u32 = 0b11111111111111111111111111111100; shard.lt_events = vec![ // 0 == 3 < 2 - InstrEvent::new(0, 0, Opcode::SLT, 0, 3, 2), + InstrEvent::new(0, Opcode::SLT, 0, 3, 2), // 1 == 2 < 3 - InstrEvent::new(0, 1, Opcode::SLT, 1, 2, 3), + InstrEvent::new(4, Opcode::SLT, 1, 2, 3), // 0 == 5 < -3 - InstrEvent::new(0, 3, Opcode::SLT, 0, 5, NEG_3), + InstrEvent::new(8, Opcode::SLT, 0, 5, NEG_3), // 1 == -3 < 5 - InstrEvent::new(0, 2, Opcode::SLT, 1, NEG_3, 5), + InstrEvent::new(12, Opcode::SLT, 1, NEG_3, 5), // 0 == -3 < -4 - InstrEvent::new(0, 4, Opcode::SLT, 0, NEG_3, NEG_4), + InstrEvent::new(16, Opcode::SLT, 0, NEG_3, NEG_4), // 1 == -4 < -3 - InstrEvent::new(0, 4, Opcode::SLT, 1, NEG_4, NEG_3), + InstrEvent::new(20, Opcode::SLT, 1, NEG_4, NEG_3), // 0 == 3 < 3 - InstrEvent::new(0, 5, Opcode::SLT, 0, 3, 3), + InstrEvent::new(24, Opcode::SLT, 0, 3, 3), // 0 == -3 < -3 - InstrEvent::new(0, 5, Opcode::SLT, 0, NEG_3, NEG_3), + InstrEvent::new(28, Opcode::SLT, 0, NEG_3, NEG_3), ]; prove_babybear_template(&mut shard); @@ -523,17 +522,17 @@ mod tests { const LARGE: u32 = 0b11111111111111111111111111111101; shard.lt_events = vec![ // 0 == 3 < 2 - InstrEvent::new(0, 0, Opcode::SLTU, 0, 3, 2), + InstrEvent::new(0, Opcode::SLTU, 0, 3, 2), // 1 == 2 < 3 - InstrEvent::new(0, 1, Opcode::SLTU, 1, 2, 3), + InstrEvent::new(4, Opcode::SLTU, 1, 2, 3), // 0 == LARGE < 5 - InstrEvent::new(0, 2, Opcode::SLTU, 0, LARGE, 5), + InstrEvent::new(8, Opcode::SLTU, 0, LARGE, 5), // 1 == 5 < LARGE - InstrEvent::new(0, 3, Opcode::SLTU, 1, 5, LARGE), + InstrEvent::new(12, Opcode::SLTU, 1, 5, LARGE), // 0 == 0 < 0 - InstrEvent::new(0, 5, Opcode::SLTU, 0, 0, 0), + InstrEvent::new(16, Opcode::SLTU, 0, 0, 0), // 0 == LARGE < LARGE - InstrEvent::new(0, 5, Opcode::SLTU, 0, LARGE, LARGE), + InstrEvent::new(20, Opcode::SLTU, 0, LARGE, LARGE), ]; prove_babybear_template(&mut shard); diff --git a/crates/core/machine/src/alu/mul/mod.rs b/crates/core/machine/src/alu/mul/mod.rs index 9c3a69b158..2f650e832b 100644 --- a/crates/core/machine/src/alu/mul/mod.rs +++ b/crates/core/machine/src/alu/mul/mod.rs @@ -41,8 +41,8 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{InstrEvent, ByteLookupEvent, ByteRecord}, - ByteOpcode, ExecutionRecord, Opcode, Program, + events::{ByteLookupEvent, ByteRecord, InstrEvent}, + ByteOpcode, ExecutionRecord, Opcode, Program, DEFAULT_PC_INC, }; use sp1_derive::AlignedBorrow; use sp1_primitives::consts::WORD_SIZE; @@ -75,8 +75,8 @@ pub struct MulChip; #[derive(AlignedBorrow, Default, Debug, Clone, Copy)] #[repr(C)] pub struct MulCols { - /// The shard number, used for byte lookup table. - pub shard: T, + /// The program counter. + pub pc: T, /// The nonce of the operation. pub nonce: T, @@ -203,6 +203,8 @@ impl MulChip { cols: &mut MulCols, blu: &mut impl ByteRecord, ) { + cols.pc = F::from_canonical_u32(event.pc); + let a_word = event.a.to_le_bytes(); let b_word = event.b.to_le_bytes(); let c_word = event.c.to_le_bytes(); @@ -236,7 +238,6 @@ impl MulChip { for word in words.iter() { let most_significant_byte = word[WORD_SIZE - 1]; blu_events.push(ByteLookupEvent { - shard: event.shard, opcode: ByteOpcode::MSB, a1: get_msb(*word) as u16, a2: 0, @@ -283,8 +284,8 @@ impl MulChip { // Range check. { - blu.add_u16_range_checks(event.shard, &carry.map(|x| x as u16)); - blu.add_u8_range_checks(event.shard, &product.map(|x| x as u8)); + blu.add_u16_range_checks(&carry.map(|x| x as u16)); + blu.add_u8_range_checks(&product.map(|x| x as u8)); } } } @@ -442,11 +443,12 @@ where // Receive the arguments. builder.receive_instruction( + local.pc, + local.pc + AB::Expr::from_canonical_u32(DEFAULT_PC_INC), opcode, local.a, local.b, local.c, - local.shard, local.nonce, local.is_real, ); @@ -471,14 +473,7 @@ mod tests { // Fill mul_events with 10^7 MULHSU events. let mut mul_events: Vec = Vec::new(); for _ in 0..10i32.pow(7) { - mul_events.push(InstrEvent::new( - 0, - 0, - Opcode::MULHSU, - 0x80004000, - 0x80000000, - 0xffff8000, - )); + mul_events.push(InstrEvent::new(0, Opcode::MULHSU, 0x80004000, 0x80000000, 0xffff8000)); } shard.mul_events = mul_events; let chip = MulChip::default(); @@ -547,12 +542,12 @@ mod tests { (Opcode::MULH, 0xffffffff, 0x00000001, 0xffffffff), ]; for t in mul_instructions.iter() { - mul_events.push(InstrEvent::new(0, 0, t.0, t.1, t.2, t.3)); + mul_events.push(InstrEvent::new(0, t.0, t.1, t.2, t.3)); } // Append more events until we have 1000 tests. for _ in 0..(1000 - mul_instructions.len()) { - mul_events.push(InstrEvent::new(0, 0, Opcode::MUL, 1, 1, 1)); + mul_events.push(InstrEvent::new(0, Opcode::MUL, 1, 1, 1)); } shard.mul_events = mul_events; diff --git a/crates/core/machine/src/alu/sll/mod.rs b/crates/core/machine/src/alu/sll/mod.rs index 2be166dbaf..102027e10d 100644 --- a/crates/core/machine/src/alu/sll/mod.rs +++ b/crates/core/machine/src/alu/sll/mod.rs @@ -42,8 +42,8 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{InstrEvent, ByteLookupEvent, ByteRecord}, - ExecutionRecord, Opcode, Program, + events::{ByteLookupEvent, ByteRecord, InstrEvent}, + ExecutionRecord, Opcode, Program, DEFAULT_PC_INC, }; use sp1_derive::AlignedBorrow; use sp1_primitives::consts::WORD_SIZE; @@ -65,8 +65,8 @@ pub struct ShiftLeft; #[derive(AlignedBorrow, Default, Debug, Clone, Copy)] #[repr(C)] pub struct ShiftLeftCols { - /// The shard number, used for byte lookup table. - pub shard: T, + /// The program counter. + pub pc: T, /// The nonce of the operation. pub nonce: T, @@ -200,10 +200,11 @@ impl ShiftLeft { cols: &mut ShiftLeftCols, blu: &mut impl ByteRecord, ) { + cols.pc = F::from_canonical_u32(event.pc); + let a = event.a.to_le_bytes(); let b = event.b.to_le_bytes(); let c = event.c.to_le_bytes(); - cols.shard = F::from_canonical_u32(event.shard); cols.a = Word(a.map(F::from_canonical_u8)); cols.b = Word(b.map(F::from_canonical_u8)); cols.c = Word(c.map(F::from_canonical_u8)); @@ -242,8 +243,8 @@ impl ShiftLeft { // Range checks. { - blu.add_u8_range_checks(event.shard, &bit_shift_result); - blu.add_u8_range_checks(event.shard, &bit_shift_result_carry); + blu.add_u8_range_checks(&bit_shift_result); + blu.add_u8_range_checks(&bit_shift_result_carry); } // Sanity check. @@ -387,11 +388,12 @@ where // Receive the arguments. builder.receive_instruction( + local.pc, + local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), AB::F::from_canonical_u32(Opcode::SLL as u32), local.a, local.b, local.c, - local.shard, local.nonce, local.is_real, ); @@ -412,7 +414,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.shift_left_events = vec![InstrEvent::new(0, 0, Opcode::SLL, 16, 8, 1)]; + shard.shift_left_events = vec![InstrEvent::new(0, Opcode::SLL, 16, 8, 1)]; let chip = ShiftLeft::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -447,7 +449,7 @@ mod tests { (Opcode::SLL, 0x00000000, 0x21212120, 0xffffffff), ]; for t in shift_instructions.iter() { - shift_events.push(InstrEvent::new(0, 0, t.0, t.1, t.2, t.3)); + shift_events.push(InstrEvent::new(0, t.0, t.1, t.2, t.3)); } // Append more events until we have 1000 tests. diff --git a/crates/core/machine/src/alu/sr/mod.rs b/crates/core/machine/src/alu/sr/mod.rs index 9b9e0717da..d4810fffc3 100644 --- a/crates/core/machine/src/alu/sr/mod.rs +++ b/crates/core/machine/src/alu/sr/mod.rs @@ -54,8 +54,8 @@ use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{InstrEvent, ByteLookupEvent, ByteRecord}, - ByteOpcode, ExecutionRecord, Opcode, Program, + events::{ByteLookupEvent, ByteRecord, InstrEvent}, + ByteOpcode, ExecutionRecord, Opcode, Program, DEFAULT_PC_INC, }; use sp1_derive::AlignedBorrow; use sp1_primitives::consts::WORD_SIZE; @@ -85,8 +85,8 @@ pub struct ShiftRightChip; #[derive(AlignedBorrow, Default, Debug, Clone, Copy)] #[repr(C)] pub struct ShiftRightCols { - /// The shard number, used for byte lookup table. - pub shard: T, + /// The program counter. + pub pc: T, /// The nonce of the operation. pub nonce: T, @@ -217,7 +217,7 @@ impl ShiftRightChip { ) { // Initialize cols with basic operands and flags derived from the current event. { - cols.shard = F::from_canonical_u32(event.shard); + cols.pc = F::from_canonical_u32(event.pc); cols.a = Word::from(event.a); cols.b = Word::from(event.b); cols.c = Word::from(event.c); @@ -236,7 +236,6 @@ impl ShiftRightChip { // Insert the MSB lookup event. let most_significant_byte = event.b.to_le_bytes()[WORD_SIZE - 1]; blu.add_byte_lookup_events(vec![ByteLookupEvent { - shard: event.shard, opcode: ByteOpcode::MSB, a1: ((most_significant_byte >> 7) & 1) as u16, a2: 0, @@ -285,7 +284,6 @@ impl ShiftRightChip { let (shift, carry) = shr_carry(byte_shift_result[i], num_bits_to_shift as u8); let byte_event = ByteLookupEvent { - shard: event.shard, opcode: ByteOpcode::ShrCarry, a1: shift as u16, a2: carry, @@ -307,10 +305,10 @@ impl ShiftRightChip { debug_assert_eq!(cols.a[i], cols.bit_shift_result[i].clone()); } // Range checks. - blu.add_u8_range_checks(event.shard, &byte_shift_result); - blu.add_u8_range_checks(event.shard, &bit_shift_result); - blu.add_u8_range_checks(event.shard, &shr_carry_output_carry); - blu.add_u8_range_checks(event.shard, &shr_carry_output_shifted_byte); + blu.add_u8_range_checks(&byte_shift_result); + blu.add_u8_range_checks(&bit_shift_result); + blu.add_u8_range_checks(&shr_carry_output_carry); + blu.add_u8_range_checks(&shr_carry_output_shifted_byte); } } } @@ -507,12 +505,13 @@ where // Receive the arguments. builder.receive_instruction( + local.pc, + local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), local.is_srl * AB::F::from_canonical_u32(Opcode::SRL as u32) + local.is_sra * AB::F::from_canonical_u32(Opcode::SRA as u32), local.a, local.b, local.c, - local.shard, local.nonce, local.is_real, ); @@ -532,7 +531,7 @@ mod tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.shift_right_events = vec![InstrEvent::new(0, 0, Opcode::SRL, 6, 12, 1)]; + shard.shift_right_events = vec![InstrEvent::new(0, Opcode::SRL, 6, 12, 1)]; let chip = ShiftRightChip::default(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); @@ -583,7 +582,7 @@ mod tests { ]; let mut shift_events: Vec = Vec::new(); for t in shifts.iter() { - shift_events.push(InstrEvent::new(0, 0, t.0, t.1, t.2, t.3)); + shift_events.push(InstrEvent::new(0, t.0, t.1, t.2, t.3)); } let mut shard = ExecutionRecord::default(); shard.shift_right_events = shift_events; diff --git a/crates/core/machine/src/bytes/mod.rs b/crates/core/machine/src/bytes/mod.rs index 3d3798f404..07380c9029 100644 --- a/crates/core/machine/src/bytes/mod.rs +++ b/crates/core/machine/src/bytes/mod.rs @@ -55,50 +55,49 @@ impl ByteChip { col.c = F::from_canonical_u8(c); // Iterate over all operations for results and updating the table map. - let shard = 0; for opcode in opcodes.iter() { match opcode { ByteOpcode::AND => { let and = b & c; col.and = F::from_canonical_u8(and); - ByteLookupEvent::new(shard, *opcode, and as u16, 0, b, c) + ByteLookupEvent::new(*opcode, and as u16, 0, b, c) } ByteOpcode::OR => { let or = b | c; col.or = F::from_canonical_u8(or); - ByteLookupEvent::new(shard, *opcode, or as u16, 0, b, c) + ByteLookupEvent::new(*opcode, or as u16, 0, b, c) } ByteOpcode::XOR => { let xor = b ^ c; col.xor = F::from_canonical_u8(xor); - ByteLookupEvent::new(shard, *opcode, xor as u16, 0, b, c) + ByteLookupEvent::new(*opcode, xor as u16, 0, b, c) } ByteOpcode::SLL => { let sll = b << (c & 7); col.sll = F::from_canonical_u8(sll); - ByteLookupEvent::new(shard, *opcode, sll as u16, 0, b, c) + ByteLookupEvent::new(*opcode, sll as u16, 0, b, c) } - ByteOpcode::U8Range => ByteLookupEvent::new(shard, *opcode, 0, 0, b, c), + ByteOpcode::U8Range => ByteLookupEvent::new(*opcode, 0, 0, b, c), ByteOpcode::ShrCarry => { let (res, carry) = shr_carry(b, c); col.shr = F::from_canonical_u8(res); col.shr_carry = F::from_canonical_u8(carry); - ByteLookupEvent::new(shard, *opcode, res as u16, carry, b, c) + ByteLookupEvent::new(*opcode, res as u16, carry, b, c) } ByteOpcode::LTU => { let ltu = b < c; col.ltu = F::from_bool(ltu); - ByteLookupEvent::new(shard, *opcode, ltu as u16, 0, b, c) + ByteLookupEvent::new(*opcode, ltu as u16, 0, b, c) } ByteOpcode::MSB => { let msb = (b & 0b1000_0000) != 0; col.msb = F::from_bool(msb); - ByteLookupEvent::new(shard, *opcode, msb as u16, 0, b, 0) + ByteLookupEvent::new(*opcode, msb as u16, 0, b, 0) } ByteOpcode::U16Range => { let v = ((b as u32) << 8) + c as u32; col.value_u16 = F::from_canonical_u32(v); - ByteLookupEvent::new(shard, *opcode, v as u16, 0, 0, 0) + ByteLookupEvent::new(*opcode, v as u16, 0, 0, 0) } }; } diff --git a/crates/core/machine/src/cpu/air/branch.rs b/crates/core/machine/src/cpu/air/branch.rs index 0fb0271609..b3503f2b06 100644 --- a/crates/core/machine/src/cpu/air/branch.rs +++ b/crates/core/machine/src/cpu/air/branch.rs @@ -14,7 +14,7 @@ use crate::{ operations::BabyBearWordRangeChecker, }; -use sp1_core_executor::Opcode; +use sp1_core_executor::{Opcode, DEFAULT_PC_INC, UNUSED_PC}; impl CpuChip { /// Computes whether the opcode is a branch instruction. @@ -83,11 +83,12 @@ impl CpuChip { // When we are branching, calculate branch_cols.next_pc <==> branch_cols.pc + c. builder.send_instruction( + AB::Expr::from_canonical_usize(UNUSED_PC), + AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), Opcode::ADD.as_field::(), branch_cols.next_pc, branch_cols.pc, local.op_c_val(), - local.shard, branch_cols.next_pc_nonce, local.branching, ); @@ -178,25 +179,27 @@ impl CpuChip { // Calculate a_lt_b <==> a < b (using appropriate signedness). let use_signed_comparison = local.selectors.is_blt + local.selectors.is_bge; builder.send_instruction( + AB::Expr::from_canonical_usize(UNUSED_PC), + AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), use_signed_comparison.clone() * Opcode::SLT.as_field::() + (AB::Expr::one() - use_signed_comparison.clone()) * Opcode::SLTU.as_field::(), Word::extend_var::(branch_cols.a_lt_b), local.op_a_val(), local.op_b_val(), - local.shard, branch_cols.a_lt_b_nonce, is_branch_instruction.clone(), ); // Calculate a_gt_b <==> a > b (using appropriate signedness). builder.send_instruction( + AB::Expr::from_canonical_usize(UNUSED_PC), + AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), use_signed_comparison.clone() * Opcode::SLT.as_field::() + (AB::Expr::one() - use_signed_comparison) * Opcode::SLTU.as_field::(), Word::extend_var::(branch_cols.a_gt_b), local.op_b_val(), local.op_a_val(), - local.shard, branch_cols.a_gt_b_nonce, is_branch_instruction.clone(), ); diff --git a/crates/core/machine/src/cpu/air/mod.rs b/crates/core/machine/src/cpu/air/mod.rs index 7b3da94d84..05febe3164 100644 --- a/crates/core/machine/src/cpu/air/mod.rs +++ b/crates/core/machine/src/cpu/air/mod.rs @@ -6,7 +6,7 @@ use core::borrow::Borrow; use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir}; use p3_field::AbstractField; use p3_matrix::Matrix; -use sp1_core_executor::ByteOpcode; +use sp1_core_executor::{ByteOpcode, DEFAULT_PC_INC, UNUSED_PC}; use sp1_stark::{ air::{BaseAirBuilder, PublicValues, SP1AirBuilder, SP1_PROOF_NUM_PV_ELTS}, Word, @@ -48,19 +48,21 @@ where // Compute some flags for which type of instruction we are dealing with. let is_branch_instruction: AB::Expr = self.is_branch_instruction::(&local.selectors); let is_alu_instruction: AB::Expr = self.is_alu_instruction::(&local.selectors); + let is_memory_instruction: AB::Expr = self.is_memory_instruction::(&local.selectors); // Register constraints. self.eval_registers::(builder, local, is_branch_instruction.clone()); // ALU instructions. builder.send_instruction( + local.pc, + local.next_pc, local.instruction.opcode, local.op_a_val(), local.op_b_val(), local.op_c_val(), - local.shard, local.nonce, - is_alu_instruction, + is_alu_instruction + is_memory_instruction, ); // Branch instructions. @@ -184,22 +186,24 @@ impl CpuChip { // Verify that the new pc is calculated correctly for JAL instructions. builder.send_instruction( + AB::Expr::from_canonical_usize(UNUSED_PC), + AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), jump_columns.next_pc, jump_columns.pc, local.op_b_val(), - local.shard, jump_columns.jal_nonce, local.selectors.is_jal, ); // Verify that the new pc is calculated correctly for JALR instructions. builder.send_instruction( + AB::Expr::from_canonical_usize(UNUSED_PC), + AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), jump_columns.next_pc, local.op_b_val(), local.op_c_val(), - local.shard, jump_columns.jalr_nonce, local.selectors.is_jalr, ); @@ -223,11 +227,12 @@ impl CpuChip { // Verify that op_a == pc + op_b. builder.send_instruction( + AB::Expr::from_canonical_usize(UNUSED_PC), + AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), local.op_a_val(), auipc_columns.pc, local.op_b_val(), - local.shard, auipc_columns.auipc_nonce, local.selectors.is_auipc, ); diff --git a/crates/core/machine/src/cpu/columns/mod.rs b/crates/core/machine/src/cpu/columns/mod.rs index 67d14f179a..411eaf4ce2 100644 --- a/crates/core/machine/src/cpu/columns/mod.rs +++ b/crates/core/machine/src/cpu/columns/mod.rs @@ -29,9 +29,6 @@ pub const CPU_COL_MAP: CpuCols = make_col_map(); #[derive(AlignedBorrow, Default, Debug, Clone, Copy)] #[repr(C)] pub struct CpuCols { - /// The current shard. - pub shard: T, - pub nonce: T, /// The clock cycle value. This should be within 24 bits. diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index 6c4e96c2b4..836ea81775 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -136,7 +136,6 @@ impl MachineAir for CpuChip { fn generate_dependencies(&self, input: &ExecutionRecord, output: &mut ExecutionRecord) { // Generate the trace rows for each event. let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); - let shard = input.public_values.execution_shard; let blu_events: Vec<_> = input .cpu_events @@ -153,7 +152,7 @@ impl MachineAir for CpuChip { &input.nonce_lookup, cols, &mut blu, - shard, + input.public_values.execution_shard, instruction, ); }); @@ -222,7 +221,6 @@ impl CpuChip { .map(|x| x.as_canonical_u32()) .collect::>(); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -230,7 +228,6 @@ impl CpuChip { c: a_bytes[1] as u8, }); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -260,7 +257,6 @@ impl CpuChip { blu_events: &mut impl ByteRecord, shard: u32, ) { - cols.shard = F::from_canonical_u32(shard); cols.clk = F::from_canonical_u32(event.clk); let clk_16bit_limb = (event.clk & 0xffff) as u16; @@ -268,24 +264,11 @@ impl CpuChip { cols.clk_16bit_limb = F::from_canonical_u16(clk_16bit_limb); cols.clk_8bit_limb = F::from_canonical_u8(clk_8bit_limb); + // TODO: Since we are getting the shard from the public values, I don't think we need to do + // this range check. + blu_events.add_byte_lookup_event(ByteLookupEvent::new(U16Range, shard as u16, 0, 0, 0)); + blu_events.add_byte_lookup_event(ByteLookupEvent::new(U16Range, clk_16bit_limb, 0, 0, 0)); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - shard, - U16Range, - shard as u16, - 0, - 0, - 0, - )); - blu_events.add_byte_lookup_event(ByteLookupEvent::new( - shard, - U16Range, - clk_16bit_limb, - 0, - 0, - 0, - )); - blu_events.add_byte_lookup_event(ByteLookupEvent::new( - shard, ByteOpcode::U8Range, 0, 0, diff --git a/crates/core/machine/src/memory/instructions/air.rs b/crates/core/machine/src/memory/instructions/air.rs index 3b6e125b06..53a7f98018 100644 --- a/crates/core/machine/src/memory/instructions/air.rs +++ b/crates/core/machine/src/memory/instructions/air.rs @@ -10,7 +10,7 @@ use crate::{ memory::MemoryCols, operations::BabyBearWordRangeChecker, }; -use sp1_core_executor::{events::MemoryAccessPosition, Opcode}; +use sp1_core_executor::{events::MemoryAccessPosition, Opcode, DEFAULT_PC_INC, UNUSED_PC}; use super::{columns::MemoryInstructionsColumns, MemoryInstructionsChip}; @@ -37,6 +37,8 @@ where self.receive_instruction( builder, opcode, + local.pc, + local.next_pc, local.op_a_value, local.op_b_value, local.op_c_value, @@ -82,6 +84,8 @@ impl MemoryInstructionsChip { ) { // Send to the ALU table to verify correct calculation of addr_word. builder.send_instruction( + AB::Expr::from_canonical_usize(UNUSED_PC), + AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), local.addr_word, local.op_b_val(), @@ -176,6 +180,8 @@ impl MemoryInstructionsChip { AB::Expr::zero(), ]); builder.send_instruction( + AB::Expr::from_canonical_usize(UNUSED_PC), + AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), Opcode::SUB.as_field::(), local.op_a_val(), local.unsigned_mem_val, diff --git a/crates/core/machine/src/operations/add.rs b/crates/core/machine/src/operations/add.rs index 1ba8eb127f..947eeab236 100644 --- a/crates/core/machine/src/operations/add.rs +++ b/crates/core/machine/src/operations/add.rs @@ -51,9 +51,9 @@ impl AddOperation { // Range check { - record.add_u8_range_checks(shard, &a); - record.add_u8_range_checks(shard, &b); - record.add_u8_range_checks(shard, &expected.to_le_bytes()); + record.add_u8_range_checks(&a); + record.add_u8_range_checks(&b); + record.add_u8_range_checks(&expected.to_le_bytes()); } expected } diff --git a/crates/stark/src/air/builder.rs b/crates/stark/src/air/builder.rs index b9d1d49f5a..3baf11cf8a 100644 --- a/crates/stark/src/air/builder.rs +++ b/crates/stark/src/air/builder.rs @@ -181,6 +181,8 @@ pub trait InstructionAirBuilder: BaseAirBuilder { #[allow(clippy::too_many_arguments)] fn send_instruction( &mut self, + pc: impl Into, + next_pc: impl Into, opcode: impl Into, a: Word>, b: Word>, @@ -188,7 +190,9 @@ pub trait InstructionAirBuilder: BaseAirBuilder { nonce: impl Into, multiplicity: impl Into, ) { - let values = once(opcode.into()) + let values = once(pc.into()) + .chain(once(next_pc.into())) + .chain(once(opcode.into())) .chain(a.0.into_iter().map(Into::into)) .chain(b.0.into_iter().map(Into::into)) .chain(c.0.into_iter().map(Into::into)) @@ -205,19 +209,21 @@ pub trait InstructionAirBuilder: BaseAirBuilder { #[allow(clippy::too_many_arguments)] fn receive_instruction( &mut self, + pc: impl Into, + next_pc: impl Into, opcode: impl Into, a: Word>, b: Word>, c: Word>, - shard: impl Into, nonce: impl Into, multiplicity: impl Into, ) { - let values = once(opcode.into()) + let values = once(pc.into()) + .chain(once(next_pc.into())) + .chain(once(opcode.into())) .chain(a.0.into_iter().map(Into::into)) .chain(b.0.into_iter().map(Into::into)) .chain(c.0.into_iter().map(Into::into)) - .chain(once(shard.into())) .chain(once(nonce.into())) .collect(); From e0e5836293f14fd246374fc2a2d348ec983ad795 Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Thu, 21 Nov 2024 14:49:24 -0800 Subject: [PATCH 06/18] added a comment --- crates/core/executor/src/executor.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index 57ca224c61..33bbf42f52 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -26,6 +26,8 @@ use crate::{ Instruction, Opcode, Program, Register, }; +/// The default increment for the program counter. Is used for all instructions except +/// for branches and jumps. pub const DEFAULT_PC_INC: u32 = 4; /// This is used in the `InstrEvent` to indicate that the instruction is not from the CPU. /// A valid pc should be divisible by 4, so we use 1 to indicate that the pc is not used. From 9c43f66270892d0077ad8903b21bd8fc106b19ca Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Thu, 21 Nov 2024 14:53:11 -0800 Subject: [PATCH 07/18] Revert "dummy columns" This reverts commit 3bb111ba7d08e1b68f446db1a901688d8ada268f. --- crates/core/machine/src/cpu/columns/mod.rs | 2 - crates/core/machine/src/cpu/trace.rs | 59 ------------- crates/recursion/core/src/chips/alu_base.rs | 3 - crates/recursion/core/src/chips/alu_ext.rs | 2 - crates/recursion/core/src/chips/batch_fri.rs | 2 - .../core/src/chips/exp_reverse_bits.rs | 2 - crates/recursion/core/src/chips/fri_fold.rs | 2 - crates/recursion/core/src/chips/select.rs | 3 - examples/Cargo.lock | 87 +++++++------------ 9 files changed, 33 insertions(+), 129 deletions(-) diff --git a/crates/core/machine/src/cpu/columns/mod.rs b/crates/core/machine/src/cpu/columns/mod.rs index 411eaf4ce2..dfbff7a5b1 100644 --- a/crates/core/machine/src/cpu/columns/mod.rs +++ b/crates/core/machine/src/cpu/columns/mod.rs @@ -107,8 +107,6 @@ pub struct CpuCols { /// This is true for all instructions that are not jumps, branches, and halt. Those /// instructions may move the program counter to a non sequential instruction. pub is_sequential_instr: T, - - pub dummy_cols: [MemoryReadWriteCols; 15], } impl CpuCols { diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index 836ea81775..2bd2ecdb17 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -69,65 +69,6 @@ impl MachineAir for CpuChip { }, ); - let mut instruction_group_by = HashMap::::new(); - for cpu_event in input.cpu_events.iter() { - let instruction = &input.program.fetch(cpu_event.pc); - - match instruction.opcode { - Opcode::ADD | Opcode::SUB => { - *instruction_group_by.entry("AddSub".to_string()).or_insert(0) += 1; - } - Opcode::SLT | Opcode::SLTU => { - *instruction_group_by.entry("Lt".to_string()).or_insert(0) += 1; - } - Opcode::SLL => { - *instruction_group_by.entry("ShiftLeft".to_string()).or_insert(0) += 1; - } - Opcode::SRL | Opcode::SRA => { - *instruction_group_by.entry("ShiftRight".to_string()).or_insert(0) += 1; - } - Opcode::XOR | Opcode::OR | Opcode::AND => { - *instruction_group_by.entry("Bitwise".to_string()).or_insert(0) += 1; - } - Opcode::MUL | Opcode::MULH | Opcode::MULHSU | Opcode::MULHU => { - *instruction_group_by.entry("Mul".to_string()).or_insert(0) += 1; - } - Opcode::DIV | Opcode::DIVU | Opcode::REM | Opcode::REMU => { - *instruction_group_by.entry("DivRem".to_string()).or_insert(0) += 1; - } - Opcode::LB - | Opcode::LH - | Opcode::LW - | Opcode::LBU - | Opcode::LHU - | Opcode::SB - | Opcode::SH - | Opcode::SW => { - *instruction_group_by.entry("MEMORY".to_string()).or_insert(0) += 1; - } - Opcode::BEQ - | Opcode::BNE - | Opcode::BLT - | Opcode::BGE - | Opcode::BLTU - | Opcode::BGEU => { - *instruction_group_by.entry("BRANCH".to_string()).or_insert(0) += 1; - } - Opcode::JALR | Opcode::JAL => { - *instruction_group_by.entry("JUMP".to_string()).or_insert(0) += 1; - } - Opcode::AUIPC => { - *instruction_group_by.entry("AUIPC".to_string()).or_insert(0) += 1; - } - Opcode::ECALL => { - *instruction_group_by.entry("ECALL".to_string()).or_insert(0) += 1; - } - _ => unreachable!(), - } - } - - println!("instruction_group_by: {:?}", instruction_group_by); - // Convert the trace to a row major matrix. RowMajorMatrix::new(values, NUM_CPU_COLS) } diff --git a/crates/recursion/core/src/chips/alu_base.rs b/crates/recursion/core/src/chips/alu_base.rs index afafb030e0..f587c73ce8 100644 --- a/crates/recursion/core/src/chips/alu_base.rs +++ b/crates/recursion/core/src/chips/alu_base.rs @@ -126,9 +126,6 @@ impl MachineAir for BaseAluChip { fn generate_trace(&self, input: &Self::Record, _: &mut Self::Record) -> RowMajorMatrix { let events = &input.base_alu_events; let nb_rows = events.len().div_ceil(NUM_BASE_ALU_ENTRIES_PER_ROW); - - println!("num rows for base alu: {}", nb_rows); - let fixed_log2_rows = input.fixed_log2_rows(self); let padded_nb_rows = match fixed_log2_rows { Some(log2_rows) => 1 << log2_rows, diff --git a/crates/recursion/core/src/chips/alu_ext.rs b/crates/recursion/core/src/chips/alu_ext.rs index 5369a3a1fd..b698a5d209 100644 --- a/crates/recursion/core/src/chips/alu_ext.rs +++ b/crates/recursion/core/src/chips/alu_ext.rs @@ -124,8 +124,6 @@ impl> MachineAir for ExtAluChip { fn generate_trace(&self, input: &Self::Record, _: &mut Self::Record) -> RowMajorMatrix { let events = &input.ext_alu_events; let nb_rows = events.len().div_ceil(NUM_EXT_ALU_ENTRIES_PER_ROW); - - println!("num rows for ext alu: {}", nb_rows); let fixed_log2_rows = input.fixed_log2_rows(self); let padded_nb_rows = match fixed_log2_rows { Some(log2_rows) => 1 << log2_rows, diff --git a/crates/recursion/core/src/chips/batch_fri.rs b/crates/recursion/core/src/chips/batch_fri.rs index ceb285e6b4..6522a9881d 100644 --- a/crates/recursion/core/src/chips/batch_fri.rs +++ b/crates/recursion/core/src/chips/batch_fri.rs @@ -137,8 +137,6 @@ impl MachineAir for BatchFRIChip MachineAir for ExpReverseBitsLenCh overall_rows.extend(rows); }); - println!("num rows for exp reverse bits len: {}", overall_rows.len()); - // Pad the trace to a power of two. pad_rows_fixed( &mut overall_rows, diff --git a/crates/recursion/core/src/chips/fri_fold.rs b/crates/recursion/core/src/chips/fri_fold.rs index 34b89e7d8b..063037032c 100644 --- a/crates/recursion/core/src/chips/fri_fold.rs +++ b/crates/recursion/core/src/chips/fri_fold.rs @@ -209,8 +209,6 @@ impl MachineAir for FriFoldChip }) .collect_vec(); - println!("num rows for fri fold: {}", rows.len()); - // Pad the trace to a power of two. if self.pad { pad_rows_fixed(&mut rows, || [F::zero(); NUM_FRI_FOLD_COLS], self.fixed_log2_rows); diff --git a/crates/recursion/core/src/chips/select.rs b/crates/recursion/core/src/chips/select.rs index 091c927e56..d1c44d9b94 100644 --- a/crates/recursion/core/src/chips/select.rs +++ b/crates/recursion/core/src/chips/select.rs @@ -96,9 +96,6 @@ impl MachineAir for SelectChip { fn generate_trace(&self, input: &Self::Record, _: &mut Self::Record) -> RowMajorMatrix { let events = &input.select_events; let nb_rows = events.len(); - - println!("num rows for select: {}", nb_rows); - let fixed_log2_rows = input.fixed_log2_rows(self); let padded_nb_rows = match fixed_log2_rows { Some(log2_rows) => 1 << log2_rows, diff --git a/examples/Cargo.lock b/examples/Cargo.lock index e49818b5e7..9acc219708 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -219,7 +219,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror", "tracing", ] @@ -241,7 +241,7 @@ dependencies = [ "async-trait", "auto_impl", "futures-utils-wasm", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -426,7 +426,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -442,7 +442,7 @@ dependencies = [ "async-trait", "k256", "rand 0.8.5", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -1053,7 +1053,7 @@ version = "1.1.0" dependencies = [ "rand 0.8.5", "sp1-zkvm", - "substrate-bn", + "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v1)", ] [[package]] @@ -1155,7 +1155,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -1834,7 +1834,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "sha2 0.9.9", - "thiserror 1.0.68", + "thiserror", "zeroize", ] @@ -3846,7 +3846,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror 1.0.68", + "thiserror", "ucd-trie", ] @@ -4106,7 +4106,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls", "socket2", - "thiserror 1.0.68", + "thiserror", "tokio", "tracing", ] @@ -4123,7 +4123,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls", "slab", - "thiserror 1.0.68", + "thiserror", "tinyvec", "tracing", ] @@ -4289,7 +4289,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -4407,7 +4407,7 @@ dependencies = [ "http", "reqwest", "serde", - "thiserror 1.0.68", + "thiserror", "tower-service", ] @@ -4420,7 +4420,7 @@ dependencies = [ "reth-execution-errors", "reth-primitives", "reth-storage-errors", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -4514,7 +4514,7 @@ dependencies = [ "reth-execution-errors", "reth-fs-util", "reth-storage-errors", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -4598,7 +4598,7 @@ dependencies = [ "reth-revm", "revm", "revm-primitives", - "thiserror 1.0.68", + "thiserror", "tracing", ] @@ -4637,7 +4637,7 @@ source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374 dependencies = [ "serde", "serde_json", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -4649,7 +4649,7 @@ dependencies = [ "alloy-rlp", "enr", "serde_with", - "thiserror 1.0.68", + "thiserror", "url", ] @@ -4706,7 +4706,7 @@ dependencies = [ "reth-trie-common", "revm-primitives", "serde", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -4741,7 +4741,7 @@ dependencies = [ "modular-bitfield", "reth-codecs", "serde", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -4891,7 +4891,7 @@ dependencies = [ "ripemd", "secp256k1", "sha2 0.10.8", - "substrate-bn", + "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v1)", ] [[package]] @@ -5090,7 +5090,7 @@ dependencies = [ "rlp", "rsp-primitives", "serde", - "thiserror 1.0.68", + "thiserror", ] [[package]] @@ -5713,7 +5713,7 @@ dependencies = [ "sp1-stark", "strum", "strum_macros", - "thiserror 1.0.68", + "thiserror", "tiny-keccak", "tracing", "typenum", @@ -5758,7 +5758,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror 1.0.68", + "thiserror", "tracing", "tracing-forest", "tracing-subscriber", @@ -5888,7 +5888,7 @@ dependencies = [ "sp1-recursion-core", "sp1-recursion-gnark-ffi", "sp1-stark", - "thiserror 1.0.68", + "thiserror", "tracing", "tracing-subscriber", ] @@ -5973,7 +5973,7 @@ dependencies = [ "sp1-primitives", "sp1-stark", "static_assertions", - "thiserror 1.0.68", + "thiserror", "tracing", "vec_map", "zkhash", @@ -6045,7 +6045,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror 1.0.68", + "thiserror", "tokio", "tracing", "twirp-rs", @@ -6091,8 +6091,8 @@ dependencies = [ "hex", "lazy_static", "sha2 0.10.8", - "substrate-bn-succinct", - "thiserror 2.0.3", + "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v2)", + "thiserror-no-std", ] [[package]] @@ -6258,10 +6258,9 @@ dependencies = [ ] [[package]] -name = "substrate-bn-succinct" +name = "substrate-bn" version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "114c855c26ad0594c830129cb868552fb41415603a6133276c2ecdd9e5ef4255" +source = "git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v2#8ef05d3969312eca34fa9f1f566a469022badda6" dependencies = [ "bytemuck", "byteorder", @@ -6487,16 +6486,7 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ - "thiserror-impl 1.0.68", -] - -[[package]] -name = "thiserror" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" -dependencies = [ - "thiserror-impl 2.0.3", + "thiserror-impl", ] [[package]] @@ -6510,17 +6500,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "thiserror-impl" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.87", -] - [[package]] name = "thiserror-impl-no-std" version = "2.0.2" @@ -6777,7 +6756,7 @@ checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" dependencies = [ "ansi_term", "smallvec", - "thiserror 1.0.68", + "thiserror", "tracing", "tracing-subscriber", ] @@ -6833,7 +6812,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror 1.0.68", + "thiserror", "tokio", "tower", "url", From f50ccc1cdd9cc65109a333738c30f6212170692b Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Thu, 21 Nov 2024 15:03:30 -0800 Subject: [PATCH 08/18] fixed types --- crates/core/executor/src/events/byte.rs | 2 +- crates/core/executor/src/events/instr.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/executor/src/events/byte.rs b/crates/core/executor/src/events/byte.rs index 3adca68d1e..b70daa30f2 100644 --- a/crates/core/executor/src/events/byte.rs +++ b/crates/core/executor/src/events/byte.rs @@ -32,7 +32,7 @@ pub trait ByteRecord { /// Adds a new [`ByteLookupEvent`] to the record. fn add_byte_lookup_event(&mut self, blu_event: ByteLookupEvent); - /// Adds a list of [`ByteLookupEvent`] mapss to the record. + /// Adds a list of [`ByteLookupEvent`] maps to the record. fn add_byte_lookup_events_fron_maps( &mut self, sharded_blu_events_vec: Vec<&HashMap>, diff --git a/crates/core/executor/src/events/instr.rs b/crates/core/executor/src/events/instr.rs index e3f75da7ce..8521b7915c 100644 --- a/crates/core/executor/src/events/instr.rs +++ b/crates/core/executor/src/events/instr.rs @@ -27,7 +27,7 @@ pub struct InstrEvent { } impl InstrEvent { - /// Create a new [`AluEvent`]. + /// Create a new [`InstrEvent`]. #[must_use] pub fn new(pc: u32, opcode: Opcode, a: u32, b: u32, c: u32) -> Self { Self { From e559b4ca928fd76d45e2e1cdac3c2d47e72f9a72 Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Thu, 21 Nov 2024 15:34:47 -0800 Subject: [PATCH 09/18] reverted memory table --- crates/core/executor/src/executor.rs | 10 - crates/core/executor/src/record.rs | 10 - crates/core/machine/src/alu/add_sub/mod.rs | 5 +- crates/core/machine/src/cpu/air/ecall.rs | 1 - .../instructions/air.rs => cpu/air/memory.rs} | 278 +++++++++--------- crates/core/machine/src/cpu/air/mod.rs | 9 +- crates/core/machine/src/cpu/air/register.rs | 1 - .../columns.rs => cpu/columns/memory.rs} | 30 +- .../src/cpu/columns/opcode_specific.rs | 11 +- crates/core/machine/src/cpu/trace.rs | 129 +++++++- .../src/memory/{consistency => }/columns.rs | 0 .../machine/src/memory/consistency/mod.rs | 4 - .../machine/src/memory/instructions/mod.rs | 6 - .../machine/src/memory/instructions/trace.rs | 116 -------- crates/core/machine/src/memory/mod.rs | 7 +- .../src/memory/{consistency => }/trace.rs | 0 16 files changed, 293 insertions(+), 324 deletions(-) rename crates/core/machine/src/{memory/instructions/air.rs => cpu/air/memory.rs} (57%) rename crates/core/machine/src/{memory/instructions/columns.rs => cpu/columns/memory.rs} (68%) rename crates/core/machine/src/memory/{consistency => }/columns.rs (100%) delete mode 100644 crates/core/machine/src/memory/consistency/mod.rs delete mode 100644 crates/core/machine/src/memory/instructions/mod.rs delete mode 100644 crates/core/machine/src/memory/instructions/trace.rs rename crates/core/machine/src/memory/{consistency => }/trace.rs (100%) diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index 33bbf42f52..f43828f5a8 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -686,16 +686,6 @@ impl<'a> Executor<'a> { self.record.divrem_events.push(event); emit_divrem_dependencies(self, event); } - Opcode::LB - | Opcode::LH - | Opcode::LW - | Opcode::LBU - | Opcode::LHU - | Opcode::SB - | Opcode::SH - | Opcode::SW => { - self.record.memory_instr_events.push(event); - } _ => {} } } diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index 9ec3ddc89a..d7a5e05e8d 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -44,8 +44,6 @@ pub struct ExecutionRecord { pub divrem_events: Vec, /// A trace of the SLT, SLTI, SLTU, and SLTIU events. pub lt_events: Vec, - /// A trace of the memory instructions. - pub memory_instr_events: Vec, /// A trace of the byte lookups that are needed. pub byte_lookups: HashMap, /// A trace of the precompile events. @@ -81,7 +79,6 @@ impl Default for ExecutionRecord { shift_right_events: Vec::default(), divrem_events: Vec::default(), lt_events: Vec::default(), - memory_instr_events: Vec::default(), byte_lookups: HashMap::default(), precompile_events: PrecompileEvents::default(), global_memory_initialize_events: Vec::default(), @@ -163,11 +160,6 @@ impl ExecutionRecord { } } - /// Add a memory instructions event to the execution record. - pub fn add_memory_instructions_event(&mut self, memory_instructions_event: InstrEvent) { - self.memory_instr_events.push(memory_instructions_event); - } - /// Take out events from the [`ExecutionRecord`] that should be deferred to a separate shard. /// Take out events from the [`ExecutionRecord`] that should be deferred to a separate shard. /// @@ -339,7 +331,6 @@ impl MachineRecord for ExecutionRecord { stats.insert("shift_right_events".to_string(), self.shift_right_events.len()); stats.insert("divrem_events".to_string(), self.divrem_events.len()); stats.insert("lt_events".to_string(), self.lt_events.len()); - stats.insert("memory_instructions_events".to_string(), self.memory_instr_events.len()); for (syscall_code, events) in self.precompile_events.iter() { stats.insert(format!("syscall {syscall_code:?}"), events.len()); @@ -372,7 +363,6 @@ impl MachineRecord for ExecutionRecord { self.shift_right_events.append(&mut other.shift_right_events); self.divrem_events.append(&mut other.divrem_events); self.lt_events.append(&mut other.lt_events); - self.memory_instr_events.append(&mut other.memory_instr_events); self.syscall_events.append(&mut other.syscall_events); self.precompile_events.append(&mut other.precompile_events); diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index 72825977af..cc21423309 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -147,13 +147,12 @@ impl AddSubChip { cols: &mut AddSubCols, blu: &mut impl ByteRecord, ) { + cols.pc = F::from_canonical_u32(event.pc); + let is_add = event.opcode == Opcode::ADD; cols.is_add = F::from_bool(is_add); cols.is_sub = F::from_bool(!is_add); - cols.from_cpu = F::from_bool(event.from_cpu); - cols.pc = F::from_canonical_u32(event.pc); - let operand_1 = if is_add { event.b } else { event.a }; let operand_2 = event.c; diff --git a/crates/core/machine/src/cpu/air/ecall.rs b/crates/core/machine/src/cpu/air/ecall.rs index 59785123fb..5d6c775fd0 100644 --- a/crates/core/machine/src/cpu/air/ecall.rs +++ b/crates/core/machine/src/cpu/air/ecall.rs @@ -15,7 +15,6 @@ use crate::{ columns::{CpuCols, OpcodeSelectorCols}, CpuChip, }, - memory::MemoryCols, operations::{BabyBearWordRangeChecker, IsZeroOperation}, }; diff --git a/crates/core/machine/src/memory/instructions/air.rs b/crates/core/machine/src/cpu/air/memory.rs similarity index 57% rename from crates/core/machine/src/memory/instructions/air.rs rename to crates/core/machine/src/cpu/air/memory.rs index 53a7f98018..79054d1abf 100644 --- a/crates/core/machine/src/memory/instructions/air.rs +++ b/crates/core/machine/src/cpu/air/memory.rs @@ -1,72 +1,52 @@ -use p3_air::{Air, AirBuilder}; +use p3_air::AirBuilder; use p3_field::AbstractField; -use sp1_stark::{ - air::{PublicValues, SP1AirBuilder, SP1_PROOF_NUM_PV_ELTS}, - Word, -}; +use sp1_stark::{air::SP1AirBuilder, Word}; use crate::{ air::{SP1CoreAirBuilder, WordAirBuilder}, + cpu::{ + columns::{CpuCols, MemoryColumns, OpcodeSelectorCols}, + CpuChip, + }, memory::MemoryCols, operations::BabyBearWordRangeChecker, }; -use sp1_core_executor::{events::MemoryAccessPosition, Opcode, DEFAULT_PC_INC, UNUSED_PC}; - -use super::{columns::MemoryInstructionsColumns, MemoryInstructionsChip}; - -impl Air for MemoryInstructionsChip -where - AB: SP1AirBuilder, - AB::Var: Sized, -{ - #[inline(never)] - fn eval(&self, builder: &mut AB) { - let local = builder.local(); - - let public_values_slice: [AB::PublicVar; SP1_PROOF_NUM_PV_ELTS] = - core::array::from_fn(|i| builder.public_values()[i]); - let public_values: &PublicValues, AB::PublicVar> = - public_values_slice.as_slice().borrow(); - let shard: AB::Expr = public_values.shard.into(); - - self.eval_memory_address_and_access::(builder, local, shard); - self.eval_memory_load::(builder, local); - self.eval_memory_store::(builder, local); - - let opcode = self.compute_opcode::(builder, local); - self.receive_instruction( - builder, - opcode, - local.pc, - local.next_pc, - local.op_a_value, - local.op_b_value, - local.op_c_value, - AB::Expr::zero(), - AB::Expr::zero(), - local.is_real, - ); +use sp1_core_executor::{events::MemoryAccessPosition, Opcode}; + +impl CpuChip { + /// Computes whether the opcode is a memory instruction. + pub(crate) fn is_memory_instruction( + &self, + opcode_selectors: &OpcodeSelectorCols, + ) -> AB::Expr { + opcode_selectors.is_lb + + opcode_selectors.is_lbu + + opcode_selectors.is_lh + + opcode_selectors.is_lhu + + opcode_selectors.is_lw + + opcode_selectors.is_sb + + opcode_selectors.is_sh + + opcode_selectors.is_sw } -} -impl MemoryInstructionsChip { - /// Computes the opcode based on the instruction selectors. - pub(crate) fn compute_opcode( + /// Computes whether the opcode is a load instruction. + pub(crate) fn is_load_instruction( &self, - builder: &mut AB, - local: &MemoryInstructionsColumns, + opcode_selectors: &OpcodeSelectorCols, ) -> AB::Expr { - builder.assert_bool(local.is_load); - builder.assert_bool(local.is_byte); - builder.assert_bool(local.is_half); - builder.assert_bool(local.is_unsigned); - - // See https://www.notion.so/succinctlabs/Idea-2-Selector-Optimizations-122e020fb42f8054a227cc80f80e5acc - // for the derivation of this formula. - AB::Expr::from_canonical_u32(10) - + (AB::Expr::one() - local.is_load) * AB::Expr::from_canonical_u32(5) - + local.is_half * AB::Expr::from_canonical_u32(2) - + local.is_unsigned * AB::Expr::from_canonical_u32(3) + opcode_selectors.is_lb + + opcode_selectors.is_lbu + + opcode_selectors.is_lh + + opcode_selectors.is_lhu + + opcode_selectors.is_lw + } + + /// Computes whether the opcode is a store instruction. + pub(crate) fn is_store_instruction( + &self, + opcode_selectors: &OpcodeSelectorCols, + ) -> AB::Expr { + opcode_selectors.is_sb + opcode_selectors.is_sh + opcode_selectors.is_sw } /// Constrains the addr_aligned, addr_offset, and addr_word memory columns. @@ -79,89 +59,98 @@ impl MemoryInstructionsChip { pub(crate) fn eval_memory_address_and_access( &self, builder: &mut AB, - local: &MemoryInstructionsColumns, - shard: AB::Expr, + local: &CpuCols, + is_memory_instruction: AB::Expr, ) { + // Get the memory specific columns. + let memory_columns = local.opcode_specific_columns.memory(); + // Send to the ALU table to verify correct calculation of addr_word. - builder.send_instruction( - AB::Expr::from_canonical_usize(UNUSED_PC), - AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), + builder.send_alu( AB::Expr::from_canonical_u32(Opcode::ADD as u32), - local.addr_word, + memory_columns.addr_word, local.op_b_val(), local.op_c_val(), - local.addr_word_nonce, - local.is_real, + local.shard, + memory_columns.addr_word_nonce, + is_memory_instruction.clone(), ); // Range check the addr_word to be a valid babybear word. BabyBearWordRangeChecker::::range_check( builder, - local.addr_word, - local.addr_word_range_checker, - local.is_real, + memory_columns.addr_word, + memory_columns.addr_word_range_checker, + is_memory_instruction.clone(), ); // Check that each addr_word element is a byte. - builder.slice_range_check_u8(&local.addr_word.0, local.is_real); + builder.slice_range_check_u8(&memory_columns.addr_word.0, is_memory_instruction.clone()); // Evaluate the addr_offset column and offset flags. - self.eval_offset_value_flags(builder, local); + self.eval_offset_value_flags(builder, memory_columns, local); // Assert that reduce(addr_word) == addr_aligned + addr_offset. - builder.when(local.is_real).assert_eq::( - local.addr_aligned + local.addr_offset, - local.addr_word.reduce::(), + builder.when(is_memory_instruction.clone()).assert_eq::( + memory_columns.addr_aligned + memory_columns.addr_offset, + memory_columns.addr_word.reduce::(), ); // Verify that the least significant byte of addr_word - addr_offset is divisible by 4. - let offset = [local.offset_is_one, local.offset_is_two, local.offset_is_three] - .iter() - .enumerate() - .fold(AB::Expr::zero(), |acc, (index, &value)| { - acc + AB::Expr::from_canonical_usize(index + 1) * value - }); + let offset = [ + memory_columns.offset_is_one, + memory_columns.offset_is_two, + memory_columns.offset_is_three, + ] + .iter() + .enumerate() + .fold(AB::Expr::zero(), |acc, (index, &value)| { + acc + AB::Expr::from_canonical_usize(index + 1) * value + }); let mut recomposed_byte = AB::Expr::zero(); - local.aa_least_sig_byte_decomp.iter().enumerate().for_each(|(i, value)| { - builder.when(local.is_real).assert_bool(*value); + memory_columns.aa_least_sig_byte_decomp.iter().enumerate().for_each(|(i, value)| { + builder.when(is_memory_instruction.clone()).assert_bool(*value); recomposed_byte = recomposed_byte.clone() + AB::Expr::from_canonical_usize(1 << (i + 2)) * *value; }); - builder.when(local.is_real).assert_eq(local.addr_word[0] - offset, recomposed_byte); + builder + .when(is_memory_instruction.clone()) + .assert_eq(memory_columns.addr_word[0] - offset, recomposed_byte); // For operations that require reading from memory (not registers), we need to read the // value into the memory columns. builder.eval_memory_access( - shard, + local.shard, local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::Memory as u32), - local.addr_aligned, - &local.memory_access, - local.is_real, + memory_columns.addr_aligned, + &memory_columns.memory_access, + is_memory_instruction.clone(), ); // On memory load instructions, make sure that the memory value is not changed. - builder - .when(self.is_load_instruction::(&local.selectors)) - .assert_word_eq(*local.memory_access.value(), *local.memory_access.prev_value()); + builder.when(self.is_load_instruction::(&local.selectors)).assert_word_eq( + *memory_columns.memory_access.value(), + *memory_columns.memory_access.prev_value(), + ); } /// Evaluates constraints related to loading from memory. pub(crate) fn eval_memory_load( &self, builder: &mut AB, - local: &MemoryInstructionsColumns, + local: &CpuCols, ) { // Get the memory specific columns. let memory_columns = local.opcode_specific_columns.memory(); // Verify the unsigned_mem_value column. - self.eval_unsigned_mem_value(builder, local); + self.eval_unsigned_mem_value(builder, memory_columns, local); // If it's a signed operation (such as LB or LH), then we need verify the bit decomposition // of the most significant byte to get it's sign. - self.eval_most_sig_byte_bit_decomp(builder, local, &local.unsigned_mem_val); + self.eval_most_sig_byte_bit_decomp(builder, memory_columns, local, &local.unsigned_mem_val); // Assert that correct value of `mem_value_is_neg_not_x0`. builder.assert_eq( @@ -179,13 +168,12 @@ impl MemoryInstructionsChip { AB::Expr::one() * local.selectors.is_lh, AB::Expr::zero(), ]); - builder.send_instruction( - AB::Expr::from_canonical_usize(UNUSED_PC), - AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), + builder.send_alu( Opcode::SUB.as_field::(), local.op_a_val(), local.unsigned_mem_val, signed_value, + local.shard, local.unsigned_mem_val_nonce, local.mem_value_is_neg_not_x0, ); @@ -212,28 +200,34 @@ impl MemoryInstructionsChip { pub(crate) fn eval_memory_store( &self, builder: &mut AB, - local: &MemoryInstructionsColumns, + local: &CpuCols, ) { + let memory_columns = local.opcode_specific_columns.memory(); + // Get the memory offset flags. - self.eval_offset_value_flags(builder, local); + self.eval_offset_value_flags(builder, memory_columns, local); // Compute the offset_is_zero flag. The other offset flags are already constrained by the // method `eval_memory_address_and_access`, which is called in // `eval_memory_address_and_access`. - let offset_is_zero = - AB::Expr::one() - local.offset_is_one - local.offset_is_two - local.offset_is_three; + let offset_is_zero = AB::Expr::one() + - memory_columns.offset_is_one + - memory_columns.offset_is_two + - memory_columns.offset_is_three; // Compute the expected stored value for a SB instruction. let one = AB::Expr::one(); let a_val = local.op_a_val(); - let mem_val = *local.memory_access.value(); - let prev_mem_val = *local.memory_access.prev_value(); + let mem_val = *memory_columns.memory_access.value(); + let prev_mem_val = *memory_columns.memory_access.prev_value(); let sb_expected_stored_value = Word([ a_val[0] * offset_is_zero.clone() + (one.clone() - offset_is_zero.clone()) * prev_mem_val[0], - a_val[0] * local.offset_is_one + (one.clone() - local.offset_is_one) * prev_mem_val[1], - a_val[0] * local.offset_is_two + (one.clone() - local.offset_is_two) * prev_mem_val[2], - a_val[0] * local.offset_is_three - + (one.clone() - local.offset_is_three) * prev_mem_val[3], + a_val[0] * memory_columns.offset_is_one + + (one.clone() - memory_columns.offset_is_one) * prev_mem_val[1], + a_val[0] * memory_columns.offset_is_two + + (one.clone() - memory_columns.offset_is_two) * prev_mem_val[2], + a_val[0] * memory_columns.offset_is_three + + (one.clone() - memory_columns.offset_is_three) * prev_mem_val[3], ]); builder .when(local.selectors.is_sb) @@ -242,14 +236,14 @@ impl MemoryInstructionsChip { // When the instruction is SH, make sure both offset one and three are off. builder .when(local.selectors.is_sh) - .assert_zero(local.offset_is_one + local.offset_is_three); + .assert_zero(memory_columns.offset_is_one + memory_columns.offset_is_three); // When the instruction is SW, ensure that the offset is 0. builder.when(local.selectors.is_sw).assert_one(offset_is_zero.clone()); // Compute the expected stored value for a SH instruction. let a_is_lower_half = offset_is_zero; - let a_is_upper_half = local.offset_is_two; + let a_is_upper_half = memory_columns.offset_is_two; let sh_expected_stored_value = Word([ a_val[0] * a_is_lower_half.clone() + (one.clone() - a_is_lower_half.clone()) * prev_mem_val[0], @@ -272,21 +266,24 @@ impl MemoryInstructionsChip { pub(crate) fn eval_unsigned_mem_value( &self, builder: &mut AB, - local: &MemoryInstructionsColumns, + memory_columns: &MemoryColumns, + local: &CpuCols, ) { - let mem_val = *local.memory_access.value(); + let mem_val = *memory_columns.memory_access.value(); // Compute the offset_is_zero flag. The other offset flags are already constrained by the // method `eval_memory_address_and_access`, which is called in // `eval_memory_address_and_access`. - let offset_is_zero = - AB::Expr::one() - local.offset_is_one - local.offset_is_two - local.offset_is_three; + let offset_is_zero = AB::Expr::one() + - memory_columns.offset_is_one + - memory_columns.offset_is_two + - memory_columns.offset_is_three; // Compute the byte value. let mem_byte = mem_val[0] * offset_is_zero.clone() - + mem_val[1] * local.offset_is_one - + mem_val[2] * local.offset_is_two - + mem_val[3] * local.offset_is_three; + + mem_val[1] * memory_columns.offset_is_one + + mem_val[2] * memory_columns.offset_is_two + + mem_val[3] * memory_columns.offset_is_three; let byte_value = Word::extend_expr::(mem_byte.clone()); // When the instruction is LB or LBU, just use the lower byte. @@ -297,13 +294,13 @@ impl MemoryInstructionsChip { // When the instruction is LH or LHU, use the lower half. builder .when(local.selectors.is_lh + local.selectors.is_lhu) - .assert_zero(local.offset_is_one + local.offset_is_three); + .assert_zero(memory_columns.offset_is_one + memory_columns.offset_is_three); // When the instruction is LW, ensure that the offset is zero. builder.when(local.selectors.is_lw).assert_one(offset_is_zero.clone()); let use_lower_half = offset_is_zero; - let use_upper_half = local.offset_is_two; + let use_upper_half = memory_columns.offset_is_two; let half_value = Word([ use_lower_half.clone() * mem_val[0] + use_upper_half * mem_val[2], use_lower_half * mem_val[1] + use_upper_half * mem_val[3], @@ -322,15 +319,16 @@ impl MemoryInstructionsChip { pub(crate) fn eval_most_sig_byte_bit_decomp( &self, builder: &mut AB, - local: &MemoryInstructionsColumns, + memory_columns: &MemoryColumns, + local: &CpuCols, unsigned_mem_val: &Word, ) { let is_mem = self.is_memory_instruction::(&local.selectors); let mut recomposed_byte = AB::Expr::zero(); for i in 0..8 { - builder.when(is_mem.clone()).assert_bool(local.most_sig_byte_decomp[i]); + builder.when(is_mem.clone()).assert_bool(memory_columns.most_sig_byte_decomp[i]); recomposed_byte = recomposed_byte.clone() - + local.most_sig_byte_decomp[i] * AB::Expr::from_canonical_u8(1 << i); + + memory_columns.most_sig_byte_decomp[i] * AB::Expr::from_canonical_u8(1 << i); } builder.when(local.selectors.is_lb).assert_eq(recomposed_byte.clone(), unsigned_mem_val[0]); builder.when(local.selectors.is_lh).assert_eq(recomposed_byte, unsigned_mem_val[1]); @@ -340,30 +338,38 @@ impl MemoryInstructionsChip { pub(crate) fn eval_offset_value_flags( &self, builder: &mut AB, - local: &MemoryInstructionsColumns, + memory_columns: &MemoryColumns, + local: &CpuCols, ) { - let offset_is_zero = - AB::Expr::one() - local.offset_is_one - local.offset_is_two - local.offset_is_three; + let is_mem_op = self.is_memory_instruction::(&local.selectors); + let offset_is_zero = AB::Expr::one() + - memory_columns.offset_is_one + - memory_columns.offset_is_two + - memory_columns.offset_is_three; + + let mut filtered_builder = builder.when(is_mem_op); // Assert that the value flags are boolean - builder.assert_bool(local.offset_is_one); - builder.assert_bool(local.offset_is_two); - builder.assert_bool(local.offset_is_three); + filtered_builder.assert_bool(memory_columns.offset_is_one); + filtered_builder.assert_bool(memory_columns.offset_is_two); + filtered_builder.assert_bool(memory_columns.offset_is_three); // Assert that only one of the value flags is true - builder.assert_one( + filtered_builder.assert_one( offset_is_zero.clone() - + local.offset_is_one - + local.offset_is_two - + local.offset_is_three, + + memory_columns.offset_is_one + + memory_columns.offset_is_two + + memory_columns.offset_is_three, ); // Assert that the correct value flag is set - builder.when(offset_is_zero).assert_zero(local.addr_offset); - builder.when(local.offset_is_one).assert_one(local.addr_offset); - builder.when(local.offset_is_two).assert_eq(local.addr_offset, AB::Expr::two()); - builder - .when(local.offset_is_three) - .assert_eq(local.addr_offset, AB::Expr::from_canonical_u8(3)); + filtered_builder.when(offset_is_zero).assert_zero(memory_columns.addr_offset); + filtered_builder.when(memory_columns.offset_is_one).assert_one(memory_columns.addr_offset); + filtered_builder + .when(memory_columns.offset_is_two) + .assert_eq(memory_columns.addr_offset, AB::Expr::two()); + filtered_builder + .when(memory_columns.offset_is_three) + .assert_eq(memory_columns.addr_offset, AB::Expr::from_canonical_u8(3)); } } diff --git a/crates/core/machine/src/cpu/air/mod.rs b/crates/core/machine/src/cpu/air/mod.rs index 05febe3164..df16e56183 100644 --- a/crates/core/machine/src/cpu/air/mod.rs +++ b/crates/core/machine/src/cpu/air/mod.rs @@ -46,13 +46,18 @@ where ); // Compute some flags for which type of instruction we are dealing with. + let is_memory_instruction: AB::Expr = self.is_memory_instruction::(&local.selectors); let is_branch_instruction: AB::Expr = self.is_branch_instruction::(&local.selectors); let is_alu_instruction: AB::Expr = self.is_alu_instruction::(&local.selectors); - let is_memory_instruction: AB::Expr = self.is_memory_instruction::(&local.selectors); // Register constraints. self.eval_registers::(builder, local, is_branch_instruction.clone()); + // Memory instructions. + self.eval_memory_address_and_access::(builder, local, is_memory_instruction.clone()); + self.eval_memory_load::(builder, local); + self.eval_memory_store::(builder, local); + // ALU instructions. builder.send_instruction( local.pc, @@ -62,7 +67,7 @@ where local.op_b_val(), local.op_c_val(), local.nonce, - is_alu_instruction + is_memory_instruction, + is_alu_instruction, ); // Branch instructions. diff --git a/crates/core/machine/src/cpu/air/register.rs b/crates/core/machine/src/cpu/air/register.rs index 7be28c6099..4df756f2e3 100644 --- a/crates/core/machine/src/cpu/air/register.rs +++ b/crates/core/machine/src/cpu/air/register.rs @@ -4,7 +4,6 @@ use sp1_stark::air::SP1AirBuilder; use crate::{ air::{MemoryAirBuilder, WordAirBuilder}, cpu::{columns::CpuCols, CpuChip}, - memory::MemoryCols, }; use sp1_core_executor::events::MemoryAccessPosition; diff --git a/crates/core/machine/src/memory/instructions/columns.rs b/crates/core/machine/src/cpu/columns/memory.rs similarity index 68% rename from crates/core/machine/src/memory/instructions/columns.rs rename to crates/core/machine/src/cpu/columns/memory.rs index 14c4fe8a0f..3eb52337ab 100644 --- a/crates/core/machine/src/memory/instructions/columns.rs +++ b/crates/core/machine/src/cpu/columns/memory.rs @@ -1,39 +1,15 @@ -use p3_air::BaseAir; use sp1_derive::AlignedBorrow; use sp1_stark::Word; use std::mem::size_of; use crate::{memory::MemoryReadWriteCols, operations::BabyBearWordRangeChecker}; -use super::MemoryInstructionsChip; - -pub const NUM_MEMORY_INSTRUCTIONS_COLUMNS: usize = size_of::>(); - -impl BaseAir for MemoryInstructionsChip { - fn width(&self) -> usize { - NUM_MEMORY_INSTRUCTIONS_COLUMNS - } -} +pub const NUM_MEMORY_COLUMNS: usize = size_of::>(); /// The column layout for memory. #[derive(AlignedBorrow, Default, Debug, Clone, Copy)] #[repr(C)] -pub struct MemoryInstructionsColumns { - pub pc: T, - pub next_pc: T, - - pub clk: T, - - pub opcode: T, - pub op_a_value: Word, - pub op_b_value: Word, - pub op_c_value: Word, - - pub is_load: T, - pub is_byte: T, - pub is_half: T, - pub is_unsigned: T, - +pub struct MemoryColumns { // An addr that we are reading from or writing to as a word. We are guaranteed that this does // not overflow the field when reduced. @@ -60,6 +36,4 @@ pub struct MemoryInstructionsColumns { pub addr_word_nonce: T, pub unsigned_mem_val_nonce: T, - - pub is_real: T, } diff --git a/crates/core/machine/src/cpu/columns/opcode_specific.rs b/crates/core/machine/src/cpu/columns/opcode_specific.rs index 411de16e54..82bad94afe 100644 --- a/crates/core/machine/src/cpu/columns/opcode_specific.rs +++ b/crates/core/machine/src/cpu/columns/opcode_specific.rs @@ -14,6 +14,7 @@ pub const NUM_OPCODE_SPECIFIC_COLS: usize = size_of::>(); #[derive(Clone, Copy)] #[repr(C)] pub union OpcodeSpecificCols { + memory: MemoryColumns, branch: BranchCols, jump: JumpCols, auipc: AuipcCols, @@ -23,9 +24,9 @@ pub union OpcodeSpecificCols { impl Default for OpcodeSpecificCols { fn default() -> Self { // We must use the largest field to avoid uninitialized padding bytes. - const_assert!(size_of::>() == size_of::>()); + const_assert!(size_of::>() == size_of::>()); - OpcodeSpecificCols { jump: JumpCols::default() } + OpcodeSpecificCols { memory: MemoryColumns::default() } } } @@ -39,6 +40,12 @@ impl Debug for OpcodeSpecificCols { // SAFETY: Each view is a valid interpretation of the underlying array. impl OpcodeSpecificCols { + pub fn memory(&self) -> &MemoryColumns { + unsafe { &self.memory } + } + pub fn memory_mut(&mut self) -> &mut MemoryColumns { + unsafe { &mut self.memory } + } pub fn branch(&self) -> &BranchCols { unsafe { &self.branch } } diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index 2bd2ecdb17..65f0274c0c 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -5,9 +5,11 @@ use sp1_core_executor::{ syscalls::SyscallCode, ByteOpcode::{self, U16Range}, ExecutionRecord, Instruction, Opcode, Program, + Register::X0, }; +use sp1_primitives::consts::WORD_SIZE; use sp1_stark::{air::MachineAir, Word}; -use std::borrow::BorrowMut; +use std::{array, borrow::BorrowMut}; use p3_field::{PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; @@ -176,7 +178,14 @@ impl CpuChip { c: a_bytes[3] as u8, }); + // Populate memory accesses for reading from memory. + let memory_columns = cols.opcode_specific_columns.memory_mut(); + if let Some(record) = event.memory_record { + memory_columns.memory_access.populate(record, blu_events) + } + // Populate memory, branch, jump, and auipc specific fields. + self.populate_memory(cols, event, blu_events, nonce_lookup, shard, instruction); self.populate_branch(cols, event, nonce_lookup, instruction); self.populate_jump(cols, event, nonce_lookup, instruction); self.populate_auipc(cols, event, nonce_lookup, instruction); @@ -218,6 +227,124 @@ impl CpuChip { )); } + /// Populates columns related to memory. + fn populate_memory( + &self, + cols: &mut CpuCols, + event: &CpuEvent, + blu_events: &mut impl ByteRecord, + nonce_lookup: &[u32], + shard: u32, + instruction: &Instruction, + ) { + if !matches!( + instruction.opcode, + Opcode::LB + | Opcode::LH + | Opcode::LW + | Opcode::LBU + | Opcode::LHU + | Opcode::SB + | Opcode::SH + | Opcode::SW + ) { + return; + } + + // Populate addr_word and addr_aligned columns. + let memory_columns = cols.opcode_specific_columns.memory_mut(); + let memory_addr = event.b.wrapping_add(event.c); + let aligned_addr = memory_addr - memory_addr % WORD_SIZE as u32; + memory_columns.addr_word = memory_addr.into(); + memory_columns.addr_word_range_checker.populate(memory_addr); + memory_columns.addr_aligned = F::from_canonical_u32(aligned_addr); + + // Populate the aa_least_sig_byte_decomp columns. + assert!(aligned_addr % 4 == 0); + let aligned_addr_ls_byte = (aligned_addr & 0x000000FF) as u8; + let bits: [bool; 8] = array::from_fn(|i| aligned_addr_ls_byte & (1 << i) != 0); + memory_columns.aa_least_sig_byte_decomp = array::from_fn(|i| F::from_bool(bits[i + 2])); + memory_columns.addr_word_nonce = F::from_canonical_u32( + nonce_lookup.get(event.memory_add_lookup_id.0 as usize).copied().unwrap_or_default(), + ); + + // Populate memory offsets. + let addr_offset = (memory_addr % WORD_SIZE as u32) as u8; + memory_columns.addr_offset = F::from_canonical_u8(addr_offset); + memory_columns.offset_is_one = F::from_bool(addr_offset == 1); + memory_columns.offset_is_two = F::from_bool(addr_offset == 2); + memory_columns.offset_is_three = F::from_bool(addr_offset == 3); + + // If it is a load instruction, set the unsigned_mem_val column. + let mem_value = event.memory_record.unwrap().value(); + if matches!( + instruction.opcode, + Opcode::LB | Opcode::LBU | Opcode::LH | Opcode::LHU | Opcode::LW + ) { + match instruction.opcode { + Opcode::LB | Opcode::LBU => { + cols.unsigned_mem_val = + (mem_value.to_le_bytes()[addr_offset as usize] as u32).into(); + } + Opcode::LH | Opcode::LHU => { + let value = match (addr_offset >> 1) % 2 { + 0 => mem_value & 0x0000FFFF, + 1 => (mem_value & 0xFFFF0000) >> 16, + _ => unreachable!(), + }; + cols.unsigned_mem_val = value.into(); + } + Opcode::LW => { + cols.unsigned_mem_val = mem_value.into(); + } + _ => unreachable!(), + } + + // For the signed load instructions, we need to check if the loaded value is negative. + if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { + let most_sig_mem_value_byte = if matches!(instruction.opcode, Opcode::LB) { + cols.unsigned_mem_val.to_u32().to_le_bytes()[0] + } else { + cols.unsigned_mem_val.to_u32().to_le_bytes()[1] + }; + + for i in (0..8).rev() { + memory_columns.most_sig_byte_decomp[i] = + F::from_canonical_u8(most_sig_mem_value_byte >> i & 0x01); + } + if memory_columns.most_sig_byte_decomp[7] == F::one() { + cols.mem_value_is_neg_not_x0 = F::from_bool(instruction.op_a != (X0 as u8)); + cols.unsigned_mem_val_nonce = F::from_canonical_u32( + nonce_lookup + .get(event.memory_sub_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), + ); + } + } + + // Set the `mem_value_is_pos_not_x0` composite flag. + cols.mem_value_is_pos_not_x0 = F::from_bool( + ((matches!(instruction.opcode, Opcode::LB | Opcode::LH) + && (memory_columns.most_sig_byte_decomp[7] == F::zero())) + || matches!(instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) + && instruction.op_a != (X0 as u8), + ); + } + + // Add event to byte lookup for byte range checking each byte in the memory addr + let addr_bytes = memory_addr.to_le_bytes(); + for byte_pair in addr_bytes.chunks_exact(2) { + blu_events.add_byte_lookup_event(ByteLookupEvent { + opcode: ByteOpcode::U8Range, + a1: 0, + a2: 0, + b: byte_pair[0], + c: byte_pair[1], + }); + } + } + /// Populates columns related to branching. fn populate_branch( &self, diff --git a/crates/core/machine/src/memory/consistency/columns.rs b/crates/core/machine/src/memory/columns.rs similarity index 100% rename from crates/core/machine/src/memory/consistency/columns.rs rename to crates/core/machine/src/memory/columns.rs diff --git a/crates/core/machine/src/memory/consistency/mod.rs b/crates/core/machine/src/memory/consistency/mod.rs deleted file mode 100644 index 2a600258b2..0000000000 --- a/crates/core/machine/src/memory/consistency/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod columns; -mod trace; - -pub use columns::*; diff --git a/crates/core/machine/src/memory/instructions/mod.rs b/crates/core/machine/src/memory/instructions/mod.rs deleted file mode 100644 index a240680045..0000000000 --- a/crates/core/machine/src/memory/instructions/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod air; -pub mod columns; -pub mod trace; - -#[derive(Default)] -pub struct MemoryInstructionsChip; diff --git a/crates/core/machine/src/memory/instructions/trace.rs b/crates/core/machine/src/memory/instructions/trace.rs deleted file mode 100644 index 731f1d2270..0000000000 --- a/crates/core/machine/src/memory/instructions/trace.rs +++ /dev/null @@ -1,116 +0,0 @@ -use p3_field::PrimeField32; -use p3_matrix::dense::RowMajorMatrix; -use sp1_core_executor::ExecutionRecord; -use sp1_stark::air::MachineAir; - -use super::MemoryInstructionsChip; - -impl MachineAir for MemoryInstructionsChip { - type Record = ExecutionRecord; - - type Program = Self::Program; - - fn name(&self) -> String { - "MemoryInstructions".to_string() - } - - fn generate_trace( - &self, - input: &ExecutionRecord, - _: &mut ExecutionRecord, - ) -> RowMajorMatrix { - // Populate addr_word and addr_aligned columns. - let memory_columns = cols.opcode_specific_columns.memory_mut(); - let memory_addr = event.b.wrapping_add(event.c); - let aligned_addr = memory_addr - memory_addr % WORD_SIZE as u32; - memory_columns.addr_word = memory_addr.into(); - memory_columns.addr_word_range_checker.populate(memory_addr); - memory_columns.addr_aligned = F::from_canonical_u32(aligned_addr); - - // Populate the aa_least_sig_byte_decomp columns. - assert!(aligned_addr % 4 == 0); - let aligned_addr_ls_byte = (aligned_addr & 0x000000FF) as u8; - let bits: [bool; 8] = array::from_fn(|i| aligned_addr_ls_byte & (1 << i) != 0); - memory_columns.aa_least_sig_byte_decomp = array::from_fn(|i| F::from_bool(bits[i + 2])); - memory_columns.addr_word_nonce = F::from_canonical_u32( - nonce_lookup.get(event.memory_add_lookup_id.0 as usize).copied().unwrap_or_default(), - ); - - // Populate memory offsets. - let addr_offset = (memory_addr % WORD_SIZE as u32) as u8; - memory_columns.addr_offset = F::from_canonical_u8(addr_offset); - memory_columns.offset_is_one = F::from_bool(addr_offset == 1); - memory_columns.offset_is_two = F::from_bool(addr_offset == 2); - memory_columns.offset_is_three = F::from_bool(addr_offset == 3); - - // If it is a load instruction, set the unsigned_mem_val column. - let mem_value = event.memory_record.unwrap().value(); - if matches!( - instruction.opcode, - Opcode::LB | Opcode::LBU | Opcode::LH | Opcode::LHU | Opcode::LW - ) { - match instruction.opcode { - Opcode::LB | Opcode::LBU => { - cols.unsigned_mem_val = - (mem_value.to_le_bytes()[addr_offset as usize] as u32).into(); - } - Opcode::LH | Opcode::LHU => { - let value = match (addr_offset >> 1) % 2 { - 0 => mem_value & 0x0000FFFF, - 1 => (mem_value & 0xFFFF0000) >> 16, - _ => unreachable!(), - }; - cols.unsigned_mem_val = value.into(); - } - Opcode::LW => { - cols.unsigned_mem_val = mem_value.into(); - } - _ => unreachable!(), - } - - // For the signed load instructions, we need to check if the loaded value is negative. - if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { - let most_sig_mem_value_byte = if matches!(instruction.opcode, Opcode::LB) { - cols.unsigned_mem_val.to_u32().to_le_bytes()[0] - } else { - cols.unsigned_mem_val.to_u32().to_le_bytes()[1] - }; - - for i in (0..8).rev() { - memory_columns.most_sig_byte_decomp[i] = - F::from_canonical_u8(most_sig_mem_value_byte >> i & 0x01); - } - if memory_columns.most_sig_byte_decomp[7] == F::one() { - cols.mem_value_is_neg_not_x0 = F::from_bool(instruction.op_a != (X0 as u8)); - cols.unsigned_mem_val_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.memory_sub_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), - ); - } - } - - // Set the `mem_value_is_pos_not_x0` composite flag. - cols.mem_value_is_pos_not_x0 = F::from_bool( - ((matches!(instruction.opcode, Opcode::LB | Opcode::LH) - && (memory_columns.most_sig_byte_decomp[7] == F::zero())) - || matches!(instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) - && instruction.op_a != (X0 as u8), - ); - } - - // Add event to byte lookup for byte range checking each byte in the memory addr - let addr_bytes = memory_addr.to_le_bytes(); - for byte_pair in addr_bytes.chunks_exact(2) { - blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, - opcode: ByteOpcode::U8Range, - a1: 0, - a2: 0, - b: byte_pair[0], - c: byte_pair[1], - }); - } - } -} diff --git a/crates/core/machine/src/memory/mod.rs b/crates/core/machine/src/memory/mod.rs index 93f5c6c747..aefb16fb9c 100644 --- a/crates/core/machine/src/memory/mod.rs +++ b/crates/core/machine/src/memory/mod.rs @@ -1,12 +1,11 @@ -mod consistency; +mod columns; mod global; -mod instructions; mod local; mod program; +mod trace; -pub use consistency::*; +pub use columns::*; pub use global::*; -pub use instructions::*; pub use local::*; pub use program::*; diff --git a/crates/core/machine/src/memory/consistency/trace.rs b/crates/core/machine/src/memory/trace.rs similarity index 100% rename from crates/core/machine/src/memory/consistency/trace.rs rename to crates/core/machine/src/memory/trace.rs From 836fc881864f30c5f9c33ce1b0ccdbee079f4309 Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Thu, 21 Nov 2024 16:33:17 -0800 Subject: [PATCH 10/18] removed shard --- crates/core/executor/src/events/byte.rs | 6 +-- crates/core/executor/src/record.rs | 4 +- crates/core/machine/src/air/program.rs | 4 -- crates/core/machine/src/alu/add_sub/mod.rs | 12 ++--- crates/core/machine/src/alu/bitwise/mod.rs | 7 ++- crates/core/machine/src/alu/divrem/mod.rs | 3 +- crates/core/machine/src/alu/lt/mod.rs | 6 +-- crates/core/machine/src/alu/mul/mod.rs | 5 +- crates/core/machine/src/alu/sll/mod.rs | 6 +-- crates/core/machine/src/alu/sr/mod.rs | 6 +-- crates/core/machine/src/bytes/trace.rs | 20 ++++--- crates/core/machine/src/cpu/air/branch.rs | 12 ++--- crates/core/machine/src/cpu/air/ecall.rs | 10 +++- crates/core/machine/src/cpu/air/memory.rs | 15 +++--- crates/core/machine/src/cpu/air/mod.rs | 53 +++++++++--------- crates/core/machine/src/cpu/air/register.rs | 8 +-- crates/core/machine/src/cpu/columns/mod.rs | 2 + .../src/cpu/columns/opcode_specific.rs | 2 +- crates/core/machine/src/cpu/trace.rs | 7 ++- crates/core/machine/src/memory/trace.rs | 6 +-- crates/core/machine/src/operations/add.rs | 8 +-- crates/core/machine/src/operations/add4.rs | 11 ++-- crates/core/machine/src/operations/add5.rs | 13 +++-- crates/core/machine/src/operations/and.rs | 3 +- .../machine/src/operations/field/field_den.rs | 11 ++-- .../operations/field/field_inner_product.rs | 11 ++-- .../machine/src/operations/field/field_op.rs | 23 ++++---- .../src/operations/field/field_sqrt.rs | 10 ++-- .../machine/src/operations/field/range.rs | 9 +--- .../src/operations/fixed_rotate_right.rs | 18 ++----- .../src/operations/fixed_shift_right.rs | 18 ++----- crates/core/machine/src/operations/lt.rs | 3 +- crates/core/machine/src/operations/not.rs | 4 +- crates/core/machine/src/operations/or.rs | 4 +- crates/core/machine/src/operations/xor.rs | 3 +- crates/core/machine/src/program/mod.rs | 3 -- crates/core/machine/src/riscv/mod.rs | 7 +-- .../src/syscall/precompiles/edwards/ed_add.rs | 22 ++++---- .../precompiles/edwards/ed_decompress.rs | 21 ++++---- .../src/syscall/precompiles/fptower/fp.rs | 13 +---- .../syscall/precompiles/fptower/fp2_addsub.rs | 7 +-- .../syscall/precompiles/fptower/fp2_mul.rs | 18 +------ .../syscall/precompiles/keccak256/trace.rs | 6 +-- .../precompiles/sha256/compress/trace.rs | 54 +++++++++---------- .../syscall/precompiles/sha256/extend/mod.rs | 2 +- .../precompiles/sha256/extend/trace.rs | 27 +++++----- .../syscall/precompiles/u256x2048_mul/air.rs | 17 +++--- .../src/syscall/precompiles/uint256/air.rs | 4 +- .../weierstrass/weierstrass_add.rs | 42 ++++----------- .../weierstrass/weierstrass_decompress.rs | 23 ++++---- .../weierstrass/weierstrass_double.rs | 35 +++--------- 51 files changed, 247 insertions(+), 397 deletions(-) diff --git a/crates/core/executor/src/events/byte.rs b/crates/core/executor/src/events/byte.rs index b70daa30f2..2e004aad2b 100644 --- a/crates/core/executor/src/events/byte.rs +++ b/crates/core/executor/src/events/byte.rs @@ -33,7 +33,7 @@ pub trait ByteRecord { fn add_byte_lookup_event(&mut self, blu_event: ByteLookupEvent); /// Adds a list of [`ByteLookupEvent`] maps to the record. - fn add_byte_lookup_events_fron_maps( + fn add_byte_lookup_events_from_maps( &mut self, sharded_blu_events_vec: Vec<&HashMap>, ); @@ -119,7 +119,7 @@ impl ByteRecord for Vec { self.push(blu_event); } - fn add_byte_lookup_events_fron_maps(&mut self, _: Vec<&HashMap>) { + fn add_byte_lookup_events_from_maps(&mut self, _: Vec<&HashMap>) { unimplemented!() } } @@ -130,7 +130,7 @@ impl ByteRecord for HashMap { self.entry(blu_event).and_modify(|e| *e += 1).or_insert(1); } - fn add_byte_lookup_events_fron_maps( + fn add_byte_lookup_events_from_maps( &mut self, new_events: Vec<&HashMap>, ) { diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index d7a5e05e8d..a108d7e599 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -370,7 +370,7 @@ impl MachineRecord for ExecutionRecord { if self.byte_lookups.is_empty() { self.byte_lookups = std::mem::take(&mut other.byte_lookups); } else { - self.add_byte_lookup_events_fron_maps(vec![&other.byte_lookups]); + self.add_byte_lookup_events_from_maps(vec![&other.byte_lookups]); } self.global_memory_initialize_events.append(&mut other.global_memory_initialize_events); @@ -424,7 +424,7 @@ impl ByteRecord for ExecutionRecord { } #[inline] - fn add_byte_lookup_events_fron_maps( + fn add_byte_lookup_events_from_maps( &mut self, new_events: Vec<&HashMap>, ) { diff --git a/crates/core/machine/src/air/program.rs b/crates/core/machine/src/air/program.rs index 4efaa97f3f..fab6abe603 100644 --- a/crates/core/machine/src/air/program.rs +++ b/crates/core/machine/src/air/program.rs @@ -16,14 +16,12 @@ pub trait ProgramAirBuilder: BaseAirBuilder { pc: impl Into, instruction: InstructionCols + Copy>, selectors: OpcodeSelectorCols + Copy>, - shard: impl Into + Copy, multiplicity: impl Into, ) { let values = once(pc.into()) .chain(once(instruction.opcode.into())) .chain(instruction.into_iter().map(|x| x.into())) .chain(selectors.into_iter().map(|x| x.into())) - .chain(once(shard.into())) .collect(); self.send( @@ -38,14 +36,12 @@ pub trait ProgramAirBuilder: BaseAirBuilder { pc: impl Into, instruction: InstructionCols + Copy>, selectors: OpcodeSelectorCols + Copy>, - shard: impl Into + Copy, multiplicity: impl Into, ) { let values: Vec<::Expr> = once(pc.into()) .chain(once(instruction.opcode.into())) .chain(instruction.into_iter().map(|x| x.into())) .chain(selectors.into_iter().map(|x| x.into())) - .chain(once(shard.into())) .collect(); self.receive( diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index cc21423309..60bcd65262 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -117,7 +117,7 @@ impl MachineAir for AddSubChip { let blu_batches = event_iter .par_bridge() .map(|events| { - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); events.iter().for_each(|event| { let mut row = [F::zero(); NUM_ADD_SUB_COLS]; let cols: &mut AddSubCols = row.as_mut_slice().borrow_mut(); @@ -127,7 +127,7 @@ impl MachineAir for AddSubChip { }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect_vec()); + output.add_byte_lookup_events_from_maps(blu_batches.iter().collect_vec()); } fn included(&self, shard: &Self::Record) -> bool { @@ -156,7 +156,7 @@ impl AddSubChip { let operand_1 = if is_add { event.b } else { event.a }; let operand_2 = event.c; - cols.add_operation.populate(blu, event.shard, operand_1, operand_2); + cols.add_operation.populate(blu, operand_1, operand_2); cols.operand_1 = Word::from(operand_1); cols.operand_2 = Word::from(operand_2); } @@ -197,20 +197,20 @@ where local.operand_1, local.operand_2, local.add_operation, - is_real, + is_real.clone(), ); // Receive the arguments. There are separate receives for ADD and SUB. // For add, `add_operation.value` is `a`, `operand_1` is `b`, and `operand_2` is `c`. builder.receive_instruction( local.pc, - local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), + local.pc + AB::Expr::from_canonical_u32(DEFAULT_PC_INC), opcode, local.add_operation.value, local.operand_1, local.operand_2, local.nonce, - is_real, + is_real.clone(), ); builder.assert_bool(local.is_add); diff --git a/crates/core/machine/src/alu/bitwise/mod.rs b/crates/core/machine/src/alu/bitwise/mod.rs index 0959fc6285..31a74387f1 100644 --- a/crates/core/machine/src/alu/bitwise/mod.rs +++ b/crates/core/machine/src/alu/bitwise/mod.rs @@ -110,7 +110,7 @@ impl MachineAir for BitwiseChip { .bitwise_events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); events.iter().for_each(|event| { let mut row = [F::zero(); NUM_BITWISE_COLS]; let cols: &mut BitwiseCols = row.as_mut_slice().borrow_mut(); @@ -120,7 +120,7 @@ impl MachineAir for BitwiseChip { }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect_vec()); + output.add_byte_lookup_events_from_maps(blu_batches.iter().collect_vec()); } fn included(&self, shard: &Self::Record) -> bool { @@ -146,7 +146,6 @@ impl BitwiseChip { let b = event.b.to_le_bytes(); let c = event.c.to_le_bytes(); - cols.shard = F::from_canonical_u32(event.shard); cols.a = Word::from(event.a); cols.b = Word::from(event.b); cols.c = Word::from(event.c); @@ -208,7 +207,7 @@ where // Receive the arguments. builder.receive_instruction( local.pc, - local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), + local.pc + AB::Expr::from_canonical_u32(DEFAULT_PC_INC), cpu_opcode, local.a, local.b, diff --git a/crates/core/machine/src/alu/divrem/mod.rs b/crates/core/machine/src/alu/divrem/mod.rs index 8dc9827354..4f80285dec 100644 --- a/crates/core/machine/src/alu/divrem/mod.rs +++ b/crates/core/machine/src/alu/divrem/mod.rs @@ -243,7 +243,6 @@ impl MachineAir for DivRemChip { cols.a = Word::from(event.a); cols.b = Word::from(event.b); cols.c = Word::from(event.c); - cols.shard = F::from_canonical_u32(event.shard); cols.is_real = F::one(); cols.is_divu = F::from_bool(event.opcode == Opcode::DIVU); cols.is_remu = F::from_bool(event.opcode == Opcode::REMU); @@ -824,7 +823,7 @@ where builder.receive_instruction( local.pc, - local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), + local.pc + AB::Expr::from_canonical_u32(DEFAULT_PC_INC), opcode, local.a, local.b, diff --git a/crates/core/machine/src/alu/lt/mod.rs b/crates/core/machine/src/alu/lt/mod.rs index 489f1454d3..9dbcb160e5 100644 --- a/crates/core/machine/src/alu/lt/mod.rs +++ b/crates/core/machine/src/alu/lt/mod.rs @@ -141,7 +141,7 @@ impl MachineAir for LtChip { .lt_events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); events.iter().for_each(|event| { let mut row = [F::zero(); NUM_LT_COLS]; let cols: &mut LtCols = row.as_mut_slice().borrow_mut(); @@ -151,7 +151,7 @@ impl MachineAir for LtChip { }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect_vec()); + output.add_byte_lookup_events_from_maps(blu_batches.iter().collect_vec()); } fn included(&self, shard: &Self::Record) -> bool { @@ -441,7 +441,7 @@ where // Receive the arguments. builder.receive_instruction( local.pc, - local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), + local.pc + AB::Expr::from_canonical_u32(DEFAULT_PC_INC), local.is_slt * AB::F::from_canonical_u32(Opcode::SLT as u32) + local.is_sltu * AB::F::from_canonical_u32(Opcode::SLTU as u32), local.a, diff --git a/crates/core/machine/src/alu/mul/mod.rs b/crates/core/machine/src/alu/mul/mod.rs index 2f650e832b..9a7b17bf49 100644 --- a/crates/core/machine/src/alu/mul/mod.rs +++ b/crates/core/machine/src/alu/mul/mod.rs @@ -173,7 +173,7 @@ impl MachineAir for MulChip { .mul_events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); events.iter().for_each(|event| { let mut row = [F::zero(); NUM_MUL_COLS]; let cols: &mut MulCols = row.as_mut_slice().borrow_mut(); @@ -183,7 +183,7 @@ impl MachineAir for MulChip { }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect::>()); + output.add_byte_lookup_events_from_maps(blu_batches.iter().collect::>()); } fn included(&self, shard: &Self::Record) -> bool { @@ -280,7 +280,6 @@ impl MulChip { cols.is_mulh = F::from_bool(event.opcode == Opcode::MULH); cols.is_mulhu = F::from_bool(event.opcode == Opcode::MULHU); cols.is_mulhsu = F::from_bool(event.opcode == Opcode::MULHSU); - cols.shard = F::from_canonical_u32(event.shard); // Range check. { diff --git a/crates/core/machine/src/alu/sll/mod.rs b/crates/core/machine/src/alu/sll/mod.rs index 102027e10d..80a01276f1 100644 --- a/crates/core/machine/src/alu/sll/mod.rs +++ b/crates/core/machine/src/alu/sll/mod.rs @@ -170,7 +170,7 @@ impl MachineAir for ShiftLeft { .shift_left_events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); events.iter().for_each(|event| { let mut row = [F::zero(); NUM_SHIFT_LEFT_COLS]; let cols: &mut ShiftLeftCols = row.as_mut_slice().borrow_mut(); @@ -180,7 +180,7 @@ impl MachineAir for ShiftLeft { }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect_vec()); + output.add_byte_lookup_events_from_maps(blu_batches.iter().collect_vec()); } fn included(&self, shard: &Self::Record) -> bool { @@ -389,7 +389,7 @@ where // Receive the arguments. builder.receive_instruction( local.pc, - local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), + local.pc + AB::Expr::from_canonical_u32(DEFAULT_PC_INC), AB::F::from_canonical_u32(Opcode::SLL as u32), local.a, local.b, diff --git a/crates/core/machine/src/alu/sr/mod.rs b/crates/core/machine/src/alu/sr/mod.rs index d4810fffc3..faf613c86b 100644 --- a/crates/core/machine/src/alu/sr/mod.rs +++ b/crates/core/machine/src/alu/sr/mod.rs @@ -185,7 +185,7 @@ impl MachineAir for ShiftRightChip { .shift_right_events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); events.iter().for_each(|event| { let mut row = [F::zero(); NUM_SHIFT_RIGHT_COLS]; let cols: &mut ShiftRightCols = row.as_mut_slice().borrow_mut(); @@ -195,7 +195,7 @@ impl MachineAir for ShiftRightChip { }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect_vec()); + output.add_byte_lookup_events_from_maps(blu_batches.iter().collect_vec()); } fn included(&self, shard: &Self::Record) -> bool { @@ -506,7 +506,7 @@ where // Receive the arguments. builder.receive_instruction( local.pc, - local.pc + AB::Expr::from_canonical_usize(DEFAULT_PC_INC), + local.pc + AB::Expr::from_canonical_u32(DEFAULT_PC_INC), local.is_srl * AB::F::from_canonical_u32(Opcode::SRL as u32) + local.is_sra * AB::F::from_canonical_u32(Opcode::SRA as u32), local.a, diff --git a/crates/core/machine/src/bytes/trace.rs b/crates/core/machine/src/bytes/trace.rs index 6cfb81bbfc..666e499f50 100644 --- a/crates/core/machine/src/bytes/trace.rs +++ b/crates/core/machine/src/bytes/trace.rs @@ -44,18 +44,16 @@ impl MachineAir for ByteChip { let mut trace = RowMajorMatrix::new(zeroed_f_vec(NUM_BYTE_MULT_COLS * NUM_ROWS), NUM_BYTE_MULT_COLS); - for (_, blu) in input.byte_lookups.iter() { - for (lookup, mult) in blu.iter() { - let row = if lookup.opcode != ByteOpcode::U16Range { - (((lookup.b as u16) << 8) + lookup.c as u16) as usize - } else { - lookup.a1 as usize - }; - let index = lookup.opcode as usize; + for (lookup, mult) in input.byte_lookups.iter() { + let row = if lookup.opcode != ByteOpcode::U16Range { + (((lookup.b as u16) << 8) + lookup.c as u16) as usize + } else { + lookup.a1 as usize + }; + let index = lookup.opcode as usize; - let cols: &mut ByteMultCols = trace.row_mut(row).borrow_mut(); - cols.multiplicities[index] += F::from_canonical_usize(*mult); - } + let cols: &mut ByteMultCols = trace.row_mut(row).borrow_mut(); + cols.multiplicities[index] += F::from_canonical_usize(*mult); } trace diff --git a/crates/core/machine/src/cpu/air/branch.rs b/crates/core/machine/src/cpu/air/branch.rs index b3503f2b06..1216ecff8e 100644 --- a/crates/core/machine/src/cpu/air/branch.rs +++ b/crates/core/machine/src/cpu/air/branch.rs @@ -83,8 +83,8 @@ impl CpuChip { // When we are branching, calculate branch_cols.next_pc <==> branch_cols.pc + c. builder.send_instruction( - AB::Expr::from_canonical_usize(UNUSED_PC), - AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), Opcode::ADD.as_field::(), branch_cols.next_pc, branch_cols.pc, @@ -179,8 +179,8 @@ impl CpuChip { // Calculate a_lt_b <==> a < b (using appropriate signedness). let use_signed_comparison = local.selectors.is_blt + local.selectors.is_bge; builder.send_instruction( - AB::Expr::from_canonical_usize(UNUSED_PC), - AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), use_signed_comparison.clone() * Opcode::SLT.as_field::() + (AB::Expr::one() - use_signed_comparison.clone()) * Opcode::SLTU.as_field::(), @@ -193,8 +193,8 @@ impl CpuChip { // Calculate a_gt_b <==> a > b (using appropriate signedness). builder.send_instruction( - AB::Expr::from_canonical_usize(UNUSED_PC), - AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), use_signed_comparison.clone() * Opcode::SLT.as_field::() + (AB::Expr::one() - use_signed_comparison) * Opcode::SLTU.as_field::(), Word::extend_var::(branch_cols.a_gt_b), diff --git a/crates/core/machine/src/cpu/air/ecall.rs b/crates/core/machine/src/cpu/air/ecall.rs index 5d6c775fd0..79c9ac7de5 100644 --- a/crates/core/machine/src/cpu/air/ecall.rs +++ b/crates/core/machine/src/cpu/air/ecall.rs @@ -15,6 +15,7 @@ use crate::{ columns::{CpuCols, OpcodeSelectorCols}, CpuChip, }, + memory::MemoryCols, operations::{BabyBearWordRangeChecker, IsZeroOperation}, }; @@ -32,7 +33,12 @@ impl CpuChip { /// This method will do the following: /// 1. Send the syscall to the precompile table, if needed. /// 2. Check for valid op_a values. - pub(crate) fn eval_ecall(&self, builder: &mut AB, local: &CpuCols) { + pub(crate) fn eval_ecall( + &self, + builder: &mut AB, + local: &CpuCols, + shard: AB::Expr, + ) { let ecall_cols = local.opcode_specific_columns.ecall(); let is_ecall_instruction = self.is_ecall_instruction::(&local.selectors); @@ -51,7 +57,7 @@ impl CpuChip { .assert_eq(local.ecall_mul_send_to_table, send_to_table * is_ecall_instruction.clone()); builder.send_syscall( - local.shard, + shard, local.clk, ecall_cols.syscall_nonce, syscall_id, diff --git a/crates/core/machine/src/cpu/air/memory.rs b/crates/core/machine/src/cpu/air/memory.rs index 79054d1abf..268efb13bf 100644 --- a/crates/core/machine/src/cpu/air/memory.rs +++ b/crates/core/machine/src/cpu/air/memory.rs @@ -11,7 +11,7 @@ use crate::{ memory::MemoryCols, operations::BabyBearWordRangeChecker, }; -use sp1_core_executor::{events::MemoryAccessPosition, Opcode}; +use sp1_core_executor::{events::MemoryAccessPosition, Opcode, DEFAULT_PC_INC, UNUSED_PC}; impl CpuChip { /// Computes whether the opcode is a memory instruction. @@ -61,17 +61,19 @@ impl CpuChip { builder: &mut AB, local: &CpuCols, is_memory_instruction: AB::Expr, + shard: AB::Expr, ) { // Get the memory specific columns. let memory_columns = local.opcode_specific_columns.memory(); // Send to the ALU table to verify correct calculation of addr_word. - builder.send_alu( + builder.send_instruction( + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), memory_columns.addr_word, local.op_b_val(), local.op_c_val(), - local.shard, memory_columns.addr_word_nonce, is_memory_instruction.clone(), ); @@ -122,7 +124,7 @@ impl CpuChip { // For operations that require reading from memory (not registers), we need to read the // value into the memory columns. builder.eval_memory_access( - local.shard, + shard, local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::Memory as u32), memory_columns.addr_aligned, &memory_columns.memory_access, @@ -168,12 +170,13 @@ impl CpuChip { AB::Expr::one() * local.selectors.is_lh, AB::Expr::zero(), ]); - builder.send_alu( + builder.send_instruction( + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), Opcode::SUB.as_field::(), local.op_a_val(), local.unsigned_mem_val, signed_value, - local.shard, local.unsigned_mem_val_nonce, local.mem_value_is_neg_not_x0, ); diff --git a/crates/core/machine/src/cpu/air/mod.rs b/crates/core/machine/src/cpu/air/mod.rs index df16e56183..c804fc694f 100644 --- a/crates/core/machine/src/cpu/air/mod.rs +++ b/crates/core/machine/src/cpu/air/mod.rs @@ -1,5 +1,6 @@ pub mod branch; pub mod ecall; +pub mod memory; pub mod register; use core::borrow::Borrow; @@ -36,14 +37,14 @@ where let local: &CpuCols = (*local).borrow(); let next: &CpuCols = (*next).borrow(); + let public_values_slice: [AB::PublicVar; SP1_PROOF_NUM_PV_ELTS] = + core::array::from_fn(|i| builder.public_values()[i]); + let public_values: &PublicValues, AB::PublicVar> = + public_values_slice.as_slice().borrow(); + let shard: AB::Expr = public_values.shard.into(); + // Program constraints. - builder.send_program( - local.pc, - local.instruction, - local.selectors, - local.shard, - local.is_real, - ); + builder.send_program(local.pc, local.instruction, local.selectors, local.is_real); // Compute some flags for which type of instruction we are dealing with. let is_memory_instruction: AB::Expr = self.is_memory_instruction::(&local.selectors); @@ -51,10 +52,15 @@ where let is_alu_instruction: AB::Expr = self.is_alu_instruction::(&local.selectors); // Register constraints. - self.eval_registers::(builder, local, is_branch_instruction.clone()); + self.eval_registers::(builder, local, is_branch_instruction.clone(), shard.clone()); // Memory instructions. - self.eval_memory_address_and_access::(builder, local, is_memory_instruction.clone()); + self.eval_memory_address_and_access::( + builder, + local, + is_memory_instruction.clone(), + shard.clone(), + ); self.eval_memory_load::(builder, local); self.eval_memory_store::(builder, local); @@ -80,13 +86,9 @@ where self.eval_auipc(builder, local); // ECALL instruction. - self.eval_ecall(builder, local); + self.eval_ecall(builder, local, shard.clone()); // COMMIT/COMMIT_DEFERRED_PROOFS ecall instruction. - let public_values_slice: [AB::PublicVar; SP1_PROOF_NUM_PV_ELTS] = - core::array::from_fn(|i| builder.public_values()[i]); - let public_values: &PublicValues, AB::PublicVar> = - public_values_slice.as_slice().borrow(); self.eval_commit( builder, local, @@ -98,7 +100,7 @@ where self.eval_halt_unimpl(builder, local, next, public_values); // Check that the shard and clk is updated correctly. - self.eval_shard_clk(builder, local, next); + self.eval_shard_clk(builder, local, next, shard.clone()); // Check that the pc is updated correctly. self.eval_pc(builder, local, next, is_branch_instruction.clone()); @@ -191,8 +193,8 @@ impl CpuChip { // Verify that the new pc is calculated correctly for JAL instructions. builder.send_instruction( - AB::Expr::from_canonical_usize(UNUSED_PC), - AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), jump_columns.next_pc, jump_columns.pc, @@ -203,8 +205,8 @@ impl CpuChip { // Verify that the new pc is calculated correctly for JALR instructions. builder.send_instruction( - AB::Expr::from_canonical_usize(UNUSED_PC), - AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), jump_columns.next_pc, local.op_b_val(), @@ -232,8 +234,8 @@ impl CpuChip { // Verify that op_a == pc + op_b. builder.send_instruction( - AB::Expr::from_canonical_usize(UNUSED_PC), - AB::Expr::from_canonical_usize(UNUSED_PC + DEFAULT_PC_INC), + AB::Expr::from_canonical_u32(UNUSED_PC), + AB::Expr::from_canonical_u32(UNUSED_PC + DEFAULT_PC_INC), AB::Expr::from_canonical_u32(Opcode::ADD as u32), local.op_a_val(), auipc_columns.pc, @@ -255,14 +257,12 @@ impl CpuChip { builder: &mut AB, local: &CpuCols, next: &CpuCols, + shard: AB::Expr, ) { - // Verify that all shard values are the same. - builder.when_transition().when(next.is_real).assert_eq(local.shard, next.shard); - // Verify that the shard value is within 16 bits. builder.send_byte( AB::Expr::from_canonical_u8(ByteOpcode::U16Range as u8), - local.shard, + shard, AB::Expr::zero(), AB::Expr::zero(), local.is_real, @@ -340,9 +340,6 @@ impl CpuChip { next: &CpuCols, public_values: &PublicValues, AB::PublicVar>, ) { - // Verify the public value's shard. - builder.when(local.is_real).assert_eq(public_values.execution_shard, local.shard); - // Verify the public value's start pc. builder.when_first_row().assert_eq(public_values.start_pc, local.pc); diff --git a/crates/core/machine/src/cpu/air/register.rs b/crates/core/machine/src/cpu/air/register.rs index 4df756f2e3..358a1c413c 100644 --- a/crates/core/machine/src/cpu/air/register.rs +++ b/crates/core/machine/src/cpu/air/register.rs @@ -4,6 +4,7 @@ use sp1_stark::air::SP1AirBuilder; use crate::{ air::{MemoryAirBuilder, WordAirBuilder}, cpu::{columns::CpuCols, CpuChip}, + memory::MemoryCols, }; use sp1_core_executor::events::MemoryAccessPosition; @@ -14,6 +15,7 @@ impl CpuChip { builder: &mut AB, local: &CpuCols, is_branch_instruction: AB::Expr, + shard: AB::Expr, ) { // Load immediates into b and c, if the immediate flags are on. builder @@ -25,7 +27,7 @@ impl CpuChip { // If they are not immediates, read `b` and `c` from memory. builder.eval_memory_access( - local.shard, + shard.clone(), local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::B as u32), local.instruction.op_b[0], &local.op_b_access, @@ -33,7 +35,7 @@ impl CpuChip { ); builder.eval_memory_access( - local.shard, + shard.clone(), local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::C as u32), local.instruction.op_c[0], &local.op_c_access, @@ -46,7 +48,7 @@ impl CpuChip { // Write the `a` or the result to the first register described in the instruction unless // we are performing a branch or a store. builder.eval_memory_access( - local.shard, + shard.clone(), local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::A as u32), local.instruction.op_a[0], &local.op_a_access, diff --git a/crates/core/machine/src/cpu/columns/mod.rs b/crates/core/machine/src/cpu/columns/mod.rs index dfbff7a5b1..ccbfa29838 100644 --- a/crates/core/machine/src/cpu/columns/mod.rs +++ b/crates/core/machine/src/cpu/columns/mod.rs @@ -3,6 +3,7 @@ mod branch; mod ecall; mod instruction; mod jump; +mod memory; mod opcode; mod opcode_specific; @@ -11,6 +12,7 @@ pub use branch::*; pub use ecall::*; pub use instruction::*; pub use jump::*; +pub use memory::*; pub use opcode::*; pub use opcode_specific::*; diff --git a/crates/core/machine/src/cpu/columns/opcode_specific.rs b/crates/core/machine/src/cpu/columns/opcode_specific.rs index 82bad94afe..090ead562a 100644 --- a/crates/core/machine/src/cpu/columns/opcode_specific.rs +++ b/crates/core/machine/src/cpu/columns/opcode_specific.rs @@ -6,7 +6,7 @@ use std::{ use static_assertions::const_assert; -use super::ecall::EcallCols; +use super::{ecall::EcallCols, MemoryColumns}; pub const NUM_OPCODE_SPECIFIC_COLS: usize = size_of::>(); diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index 65f0274c0c..43b58d008a 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -85,7 +85,7 @@ impl MachineAir for CpuChip { .par_chunks(chunk_size) .map(|ops: &[CpuEvent]| { // The blu map stores shard -> map(byte lookup event -> multiplicity). - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); ops.iter().for_each(|op| { let mut row = [F::zero(); NUM_CPU_COLS]; let cols: &mut CpuCols = row.as_mut_slice().borrow_mut(); @@ -103,7 +103,7 @@ impl MachineAir for CpuChip { }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_events.iter().collect_vec()); + output.add_byte_lookup_events_from_maps(blu_events.iter().collect_vec()); } fn included(&self, shard: &Self::Record) -> bool { @@ -185,7 +185,7 @@ impl CpuChip { } // Populate memory, branch, jump, and auipc specific fields. - self.populate_memory(cols, event, blu_events, nonce_lookup, shard, instruction); + self.populate_memory(cols, event, blu_events, nonce_lookup, instruction); self.populate_branch(cols, event, nonce_lookup, instruction); self.populate_jump(cols, event, nonce_lookup, instruction); self.populate_auipc(cols, event, nonce_lookup, instruction); @@ -234,7 +234,6 @@ impl CpuChip { event: &CpuEvent, blu_events: &mut impl ByteRecord, nonce_lookup: &[u32], - shard: u32, instruction: &Instruction, ) { if !matches!( diff --git a/crates/core/machine/src/memory/trace.rs b/crates/core/machine/src/memory/trace.rs index 3b451ad241..d4782c0192 100644 --- a/crates/core/machine/src/memory/trace.rs +++ b/crates/core/machine/src/memory/trace.rs @@ -92,12 +92,10 @@ impl MemoryAccessCols { let diff_8bit_limb = (diff_minus_one >> 16) & 0xff; self.diff_8bit_limb = F::from_canonical_u32(diff_8bit_limb); - let shard = current_record.shard; - // Add a byte table lookup with the 16Range op. - output.add_u16_range_check(shard, diff_16bit_limb); + output.add_u16_range_check(diff_16bit_limb); // Add a byte table lookup with the U8Range op. - output.add_u8_range_check(shard, 0, diff_8bit_limb as u8); + output.add_u8_range_check(0, diff_8bit_limb as u8); } } diff --git a/crates/core/machine/src/operations/add.rs b/crates/core/machine/src/operations/add.rs index 947eeab236..428a6ca631 100644 --- a/crates/core/machine/src/operations/add.rs +++ b/crates/core/machine/src/operations/add.rs @@ -19,13 +19,7 @@ pub struct AddOperation { } impl AddOperation { - pub fn populate( - &mut self, - record: &mut impl ByteRecord, - shard: u32, - a_u32: u32, - b_u32: u32, - ) -> u32 { + pub fn populate(&mut self, record: &mut impl ByteRecord, a_u32: u32, b_u32: u32) -> u32 { let expected = a_u32.wrapping_add(b_u32); self.value = Word::from(expected); let a = a_u32.to_le_bytes(); diff --git a/crates/core/machine/src/operations/add4.rs b/crates/core/machine/src/operations/add4.rs index 121acbf767..12d9b8b90e 100644 --- a/crates/core/machine/src/operations/add4.rs +++ b/crates/core/machine/src/operations/add4.rs @@ -37,7 +37,6 @@ impl Add4Operation { pub fn populate( &mut self, record: &mut impl ByteRecord, - shard: u32, a_u32: u32, b_u32: u32, c_u32: u32, @@ -69,11 +68,11 @@ impl Add4Operation { // Range check. { - record.add_u8_range_checks(shard, &a); - record.add_u8_range_checks(shard, &b); - record.add_u8_range_checks(shard, &c); - record.add_u8_range_checks(shard, &d); - record.add_u8_range_checks(shard, &expected.to_le_bytes()); + record.add_u8_range_checks(&a); + record.add_u8_range_checks(&b); + record.add_u8_range_checks(&c); + record.add_u8_range_checks(&d); + record.add_u8_range_checks(&expected.to_le_bytes()); } expected } diff --git a/crates/core/machine/src/operations/add5.rs b/crates/core/machine/src/operations/add5.rs index 14d8dae259..6344045cf3 100644 --- a/crates/core/machine/src/operations/add5.rs +++ b/crates/core/machine/src/operations/add5.rs @@ -39,7 +39,6 @@ impl Add5Operation { pub fn populate( &mut self, record: &mut impl ByteRecord, - shard: u32, a_u32: u32, b_u32: u32, c_u32: u32, @@ -77,12 +76,12 @@ impl Add5Operation { // Range check. { - record.add_u8_range_checks(shard, &a); - record.add_u8_range_checks(shard, &b); - record.add_u8_range_checks(shard, &c); - record.add_u8_range_checks(shard, &d); - record.add_u8_range_checks(shard, &e); - record.add_u8_range_checks(shard, &expected.to_le_bytes()); + record.add_u8_range_checks(&a); + record.add_u8_range_checks(&b); + record.add_u8_range_checks(&c); + record.add_u8_range_checks(&d); + record.add_u8_range_checks(&e); + record.add_u8_range_checks(&expected.to_le_bytes()); } expected diff --git a/crates/core/machine/src/operations/and.rs b/crates/core/machine/src/operations/and.rs index 6f3dfd788a..10fd6adbc3 100644 --- a/crates/core/machine/src/operations/and.rs +++ b/crates/core/machine/src/operations/and.rs @@ -17,7 +17,7 @@ pub struct AndOperation { } impl AndOperation { - pub fn populate(&mut self, record: &mut impl ByteRecord, shard: u32, x: u32, y: u32) -> u32 { + pub fn populate(&mut self, record: &mut impl ByteRecord, x: u32, y: u32) -> u32 { let expected = x & y; let x_bytes = x.to_le_bytes(); let y_bytes = y.to_le_bytes(); @@ -26,7 +26,6 @@ impl AndOperation { self.value[i] = F::from_canonical_u8(and); let byte_event = ByteLookupEvent { - shard, opcode: ByteOpcode::AND, a1: and as u16, a2: 0, diff --git a/crates/core/machine/src/operations/field/field_den.rs b/crates/core/machine/src/operations/field/field_den.rs index b9bb80b306..c9bf8192b0 100644 --- a/crates/core/machine/src/operations/field/field_den.rs +++ b/crates/core/machine/src/operations/field/field_den.rs @@ -35,7 +35,6 @@ impl FieldDenCols { pub fn populate( &mut self, record: &mut impl ByteRecord, - shard: u32, a: &BigUint, b: &BigUint, sign: bool, @@ -83,10 +82,10 @@ impl FieldDenCols { self.witness_high = Limbs(p_witness_high.try_into().unwrap()); // Range checks - record.add_u8_range_checks_field(shard, &self.result.0); - record.add_u8_range_checks_field(shard, &self.carry.0); - record.add_u8_range_checks_field(shard, &self.witness_low.0); - record.add_u8_range_checks_field(shard, &self.witness_high.0); + record.add_u8_range_checks_field(&self.result.0); + record.add_u8_range_checks_field(&self.carry.0); + record.add_u8_range_checks_field(&self.witness_low.0); + record.add_u8_range_checks_field(&self.witness_high.0); result } @@ -230,7 +229,7 @@ mod tests { let cols: &mut TestCols = row.as_mut_slice().borrow_mut(); cols.a = P::to_limbs_field::(a); cols.b = P::to_limbs_field::(b); - cols.a_den_b.populate(output, 0, a, b, self.sign); + cols.a_den_b.populate(output, a, b, self.sign); row }) .collect::>(); diff --git a/crates/core/machine/src/operations/field/field_inner_product.rs b/crates/core/machine/src/operations/field/field_inner_product.rs index 30f2610e74..e042f776ab 100644 --- a/crates/core/machine/src/operations/field/field_inner_product.rs +++ b/crates/core/machine/src/operations/field/field_inner_product.rs @@ -34,7 +34,6 @@ impl FieldInnerProductCols { pub fn populate( &mut self, record: &mut impl ByteRecord, - shard: u32, a: &[BigUint], b: &[BigUint], ) -> BigUint { @@ -78,10 +77,10 @@ impl FieldInnerProductCols { self.witness_high = Limbs(p_witness_high.try_into().unwrap()); // Range checks - record.add_u8_range_checks_field(shard, &self.result.0); - record.add_u8_range_checks_field(shard, &self.carry.0); - record.add_u8_range_checks_field(shard, &self.witness_low.0); - record.add_u8_range_checks_field(shard, &self.witness_high.0); + record.add_u8_range_checks_field(&self.result.0); + record.add_u8_range_checks_field(&self.carry.0); + record.add_u8_range_checks_field(&self.witness_low.0); + record.add_u8_range_checks_field(&self.witness_high.0); result.clone() } @@ -214,7 +213,7 @@ mod tests { let cols: &mut TestCols = row.as_mut_slice().borrow_mut(); cols.a[0] = P::to_limbs_field::(&a[0]); cols.b[0] = P::to_limbs_field::(&b[0]); - cols.a_ip_b.populate(output, 1, a, b); + cols.a_ip_b.populate(output, a, b); row }) .collect::>(); diff --git a/crates/core/machine/src/operations/field/field_op.rs b/crates/core/machine/src/operations/field/field_op.rs index 9e16fe4db2..c9d53fe77a 100644 --- a/crates/core/machine/src/operations/field/field_op.rs +++ b/crates/core/machine/src/operations/field/field_op.rs @@ -47,7 +47,6 @@ impl FieldOpCols { pub fn populate_mul_and_carry( &mut self, record: &mut impl ByteRecord, - shard: u32, a: &BigUint, b: &BigUint, c: &BigUint, @@ -90,10 +89,10 @@ impl FieldOpCols { self.witness_low = Limbs(p_witness_low.try_into().unwrap()); self.witness_high = Limbs(p_witness_high.try_into().unwrap()); - record.add_u8_range_checks_field(shard, &self.result.0); - record.add_u8_range_checks_field(shard, &self.carry.0); - record.add_u8_range_checks_field(shard, &self.witness_low.0); - record.add_u8_range_checks_field(shard, &self.witness_high.0); + record.add_u8_range_checks_field(&self.result.0); + record.add_u8_range_checks_field(&self.carry.0); + record.add_u8_range_checks_field(&self.witness_low.0); + record.add_u8_range_checks_field(&self.witness_high.0); (result, carry) } @@ -162,7 +161,6 @@ impl FieldOpCols { pub fn populate_with_modulus( &mut self, record: &mut impl ByteRecord, - shard: u32, a: &BigUint, b: &BigUint, modulus: &BigUint, @@ -219,10 +217,10 @@ impl FieldOpCols { }; // Range checks - record.add_u8_range_checks_field(shard, &self.result.0); - record.add_u8_range_checks_field(shard, &self.carry.0); - record.add_u8_range_checks_field(shard, &self.witness_low.0); - record.add_u8_range_checks_field(shard, &self.witness_high.0); + record.add_u8_range_checks_field(&self.result.0); + record.add_u8_range_checks_field(&self.carry.0); + record.add_u8_range_checks_field(&self.witness_low.0); + record.add_u8_range_checks_field(&self.witness_high.0); result } @@ -232,12 +230,11 @@ impl FieldOpCols { pub fn populate( &mut self, record: &mut impl ByteRecord, - shard: u32, a: &BigUint, b: &BigUint, op: FieldOperation, ) -> BigUint { - self.populate_with_modulus(record, shard, a, b, &P::modulus(), op) + self.populate_with_modulus(record, a, b, &P::modulus(), op) } } @@ -468,7 +465,7 @@ mod tests { let cols: &mut TestCols = row.as_mut_slice().borrow_mut(); cols.a = P::to_limbs_field::(a); cols.b = P::to_limbs_field::(b); - cols.a_op_b.populate(&mut blu_events, 1, a, b, self.operation); + cols.a_op_b.populate(&mut blu_events, a, b, self.operation); output.add_byte_lookup_events(blu_events); row }) diff --git a/crates/core/machine/src/operations/field/field_sqrt.rs b/crates/core/machine/src/operations/field/field_sqrt.rs index a0f40c6a48..cba896d099 100644 --- a/crates/core/machine/src/operations/field/field_sqrt.rs +++ b/crates/core/machine/src/operations/field/field_sqrt.rs @@ -42,7 +42,6 @@ impl FieldSqrtCols { pub fn populate( &mut self, record: &mut impl ByteRecord, - shard: u32, a: &BigUint, sqrt_fn: impl Fn(&BigUint) -> BigUint, ) -> BigUint { @@ -51,8 +50,7 @@ impl FieldSqrtCols { let sqrt = sqrt_fn(a); // Use FieldOpCols to compute result * result. - let sqrt_squared = - self.multiplication.populate(record, shard, &sqrt, &sqrt, FieldOperation::Mul); + let sqrt_squared = self.multiplication.populate(record, &sqrt, &sqrt, FieldOperation::Mul); // If the result is indeed the square root of a, then result * result = a. assert_eq!(sqrt_squared, a.clone()); @@ -62,13 +60,12 @@ impl FieldSqrtCols { self.multiplication.result = P::to_limbs_field::(&sqrt); // Populate the range columns. - self.range.populate(record, shard, &sqrt, &modulus); + self.range.populate(record, &sqrt, &modulus); let sqrt_bytes = P::to_limbs(&sqrt); self.lsb = F::from_canonical_u8(sqrt_bytes[0] & 1); let and_event = ByteLookupEvent { - shard, opcode: ByteOpcode::AND, a1: self.lsb.as_canonical_u32() as u16, a2: 0, @@ -79,7 +76,6 @@ impl FieldSqrtCols { // Add the byte range check for `sqrt`. record.add_u8_range_checks( - shard, self.multiplication .result .0 @@ -224,7 +220,7 @@ mod tests { let mut row = [F::zero(); NUM_TEST_COLS]; let cols: &mut TestCols = row.as_mut_slice().borrow_mut(); cols.a = P::to_limbs_field::(a); - cols.sqrt.populate(&mut blu_events, 1, a, ed25519_sqrt); + cols.sqrt.populate(&mut blu_events, a, ed25519_sqrt); output.add_byte_lookup_events(blu_events); row }) diff --git a/crates/core/machine/src/operations/field/range.rs b/crates/core/machine/src/operations/field/range.rs index 73a108e775..2f8040272e 100644 --- a/crates/core/machine/src/operations/field/range.rs +++ b/crates/core/machine/src/operations/field/range.rs @@ -27,13 +27,7 @@ pub struct FieldLtCols { } impl FieldLtCols { - pub fn populate( - &mut self, - record: &mut impl ByteRecord, - shard: u32, - lhs: &BigUint, - rhs: &BigUint, - ) { + pub fn populate(&mut self, record: &mut impl ByteRecord, lhs: &BigUint, rhs: &BigUint) { assert!(lhs < rhs); let value_limbs = P::to_limbs(lhs); @@ -51,7 +45,6 @@ impl FieldLtCols { self.rhs_comparison_byte = F::from_canonical_u8(*modulus_byte); record.add_byte_lookup_event(ByteLookupEvent { opcode: ByteOpcode::LTU, - shard, a1: 1, a2: 0, b: *byte, diff --git a/crates/core/machine/src/operations/fixed_rotate_right.rs b/crates/core/machine/src/operations/fixed_rotate_right.rs index 03a4454fdd..d36840bf83 100644 --- a/crates/core/machine/src/operations/fixed_rotate_right.rs +++ b/crates/core/machine/src/operations/fixed_rotate_right.rs @@ -39,13 +39,7 @@ impl FixedRotateRightOperation { 1 << (8 - nb_bits_to_shift) } - pub fn populate( - &mut self, - record: &mut impl ByteRecord, - shard: u32, - input: u32, - rotation: usize, - ) -> u32 { + pub fn populate(&mut self, record: &mut impl ByteRecord, input: u32, rotation: usize) -> u32 { let input_bytes = input.to_le_bytes().map(F::from_canonical_u8); let expected = input.rotate_right(rotation as u32); @@ -72,14 +66,8 @@ impl FixedRotateRightOperation { let (shift, carry) = shr_carry(b, c); - let byte_event = ByteLookupEvent { - shard, - opcode: ByteOpcode::ShrCarry, - a1: shift as u16, - a2: carry, - b, - c, - }; + let byte_event = + ByteLookupEvent { opcode: ByteOpcode::ShrCarry, a1: shift as u16, a2: carry, b, c }; record.add_byte_lookup_event(byte_event); self.shift[i] = F::from_canonical_u8(shift); diff --git a/crates/core/machine/src/operations/fixed_shift_right.rs b/crates/core/machine/src/operations/fixed_shift_right.rs index 50aa896205..a51e7bb7fc 100644 --- a/crates/core/machine/src/operations/fixed_shift_right.rs +++ b/crates/core/machine/src/operations/fixed_shift_right.rs @@ -39,13 +39,7 @@ impl FixedShiftRightOperation { 1 << (8 - nb_bits_to_shift) } - pub fn populate( - &mut self, - record: &mut impl ByteRecord, - shard: u32, - input: u32, - rotation: usize, - ) -> u32 { + pub fn populate(&mut self, record: &mut impl ByteRecord, input: u32, rotation: usize) -> u32 { let input_bytes = input.to_le_bytes().map(F::from_canonical_u8); let expected = input >> rotation; @@ -71,14 +65,8 @@ impl FixedShiftRightOperation { let b = input_bytes_rotated[i].to_string().parse::().unwrap(); let c = nb_bits_to_shift as u8; let (shift, carry) = shr_carry(b, c); - let byte_event = ByteLookupEvent { - shard, - opcode: ByteOpcode::ShrCarry, - a1: shift as u16, - a2: carry, - b, - c, - }; + let byte_event = + ByteLookupEvent { opcode: ByteOpcode::ShrCarry, a1: shift as u16, a2: carry, b, c }; record.add_byte_lookup_event(byte_event); self.shift[i] = F::from_canonical_u8(shift); diff --git a/crates/core/machine/src/operations/lt.rs b/crates/core/machine/src/operations/lt.rs index ae6c4c2bf4..f6aacbe5f2 100644 --- a/crates/core/machine/src/operations/lt.rs +++ b/crates/core/machine/src/operations/lt.rs @@ -22,7 +22,7 @@ pub struct AssertLtColsBytes { } impl AssertLtColsBytes { - pub fn populate(&mut self, record: &mut impl ByteRecord, shard: u32, a: &[u8], b: &[u8]) { + pub fn populate(&mut self, record: &mut impl ByteRecord, a: &[u8], b: &[u8]) { let mut byte_flags = vec![0u8; N]; for (a_byte, b_byte, flag) in @@ -35,7 +35,6 @@ impl AssertLtColsBytes { self.b_comparison_byte = F::from_canonical_u8(*b_byte); record.add_byte_lookup_event(ByteLookupEvent { opcode: ByteOpcode::LTU, - shard, a1: 1, a2: 0, b: *a_byte, diff --git a/crates/core/machine/src/operations/not.rs b/crates/core/machine/src/operations/not.rs index e9d32e5adf..aa773c9116 100644 --- a/crates/core/machine/src/operations/not.rs +++ b/crates/core/machine/src/operations/not.rs @@ -14,13 +14,13 @@ pub struct NotOperation { } impl NotOperation { - pub fn populate(&mut self, record: &mut impl ByteRecord, shard: u32, x: u32) -> u32 { + pub fn populate(&mut self, record: &mut impl ByteRecord, x: u32) -> u32 { let expected = !x; let x_bytes = x.to_le_bytes(); for i in 0..WORD_SIZE { self.value[i] = F::from_canonical_u8(!x_bytes[i]); } - record.add_u8_range_checks(shard, &x_bytes); + record.add_u8_range_checks(&x_bytes); expected } diff --git a/crates/core/machine/src/operations/or.rs b/crates/core/machine/src/operations/or.rs index 2eaa3aadea..d861015063 100644 --- a/crates/core/machine/src/operations/or.rs +++ b/crates/core/machine/src/operations/or.rs @@ -13,13 +13,13 @@ pub struct OrOperation { } impl OrOperation { - pub fn populate(&mut self, record: &mut ExecutionRecord, shard: u32, x: u32, y: u32) -> u32 { + pub fn populate(&mut self, record: &mut ExecutionRecord, x: u32, y: u32) -> u32 { let expected = x | y; let x_bytes = x.to_le_bytes(); let y_bytes = y.to_le_bytes(); for i in 0..WORD_SIZE { self.value[i] = F::from_canonical_u8(x_bytes[i] | y_bytes[i]); - record.lookup_or(shard, x_bytes[i], y_bytes[i]); + record.lookup_or(x_bytes[i], y_bytes[i]); } expected } diff --git a/crates/core/machine/src/operations/xor.rs b/crates/core/machine/src/operations/xor.rs index c69113988c..de74f4ccd5 100644 --- a/crates/core/machine/src/operations/xor.rs +++ b/crates/core/machine/src/operations/xor.rs @@ -16,7 +16,7 @@ pub struct XorOperation { } impl XorOperation { - pub fn populate(&mut self, record: &mut impl ByteRecord, shard: u32, x: u32, y: u32) -> u32 { + pub fn populate(&mut self, record: &mut impl ByteRecord, x: u32, y: u32) -> u32 { let expected = x ^ y; let x_bytes = x.to_le_bytes(); let y_bytes = y.to_le_bytes(); @@ -25,7 +25,6 @@ impl XorOperation { self.value[i] = F::from_canonical_u8(xor); let byte_event = ByteLookupEvent { - shard, opcode: ByteOpcode::XOR, a1: xor as u16, a2: 0, diff --git a/crates/core/machine/src/program/mod.rs b/crates/core/machine/src/program/mod.rs index f6c1f3bc0c..67248053a0 100644 --- a/crates/core/machine/src/program/mod.rs +++ b/crates/core/machine/src/program/mod.rs @@ -37,7 +37,6 @@ pub struct ProgramPreprocessedCols { #[derive(AlignedBorrow, Clone, Copy, Default)] #[repr(C)] pub struct ProgramMultiplicityCols { - pub shard: T, pub multiplicity: T, } @@ -128,7 +127,6 @@ impl MachineAir for ProgramChip { let pc = input.program.pc_base + (i as u32 * 4); let mut row = [F::zero(); NUM_PROGRAM_MULT_COLS]; let cols: &mut ProgramMultiplicityCols = row.as_mut_slice().borrow_mut(); - cols.shard = F::from_canonical_u32(input.public_values.execution_shard); cols.multiplicity = F::from_canonical_usize(*instruction_counts.get(&pc).unwrap_or(&0)); row @@ -174,7 +172,6 @@ where prep_local.pc, prep_local.instruction, prep_local.selectors, - mult_local.shard, mult_local.multiplicity, ); } diff --git a/crates/core/machine/src/riscv/mod.rs b/crates/core/machine/src/riscv/mod.rs index 68cc20cc89..5964eba304 100644 --- a/crates/core/machine/src/riscv/mod.rs +++ b/crates/core/machine/src/riscv/mod.rs @@ -10,8 +10,7 @@ use sp1_core_executor::{ use crate::{ memory::{ - MemoryChipType, MemoryInstructionsChip, MemoryLocalChip, MemoryProgramChip, - NUM_LOCAL_MEMORY_ENTRIES_PER_ROW, + MemoryChipType, MemoryLocalChip, MemoryProgramChip, NUM_LOCAL_MEMORY_ENTRIES_PER_ROW, }, riscv::MemoryChipType::{Finalize, Initialize}, syscall::precompiles::fptower::{Fp2AddSubAssignChip, Fp2MulAssignChip, FpOpChip}, @@ -411,10 +410,6 @@ impl RiscvAir { .into_iter() .count(), ), - ( - RiscvAir::MemoryInstructions(MemoryInstructionsChip::default()), - record.memory_instr_events.len(), - ), (RiscvAir::SyscallCore(SyscallChip::core()), record.syscall_events.len()), ] } diff --git a/crates/core/machine/src/syscall/precompiles/edwards/ed_add.rs b/crates/core/machine/src/syscall/precompiles/edwards/ed_add.rs index 94e81e20cb..afc28f2c2a 100644 --- a/crates/core/machine/src/syscall/precompiles/edwards/ed_add.rs +++ b/crates/core/machine/src/syscall/precompiles/edwards/ed_add.rs @@ -73,7 +73,6 @@ impl EdAddAssignChip { #[allow(clippy::too_many_arguments)] fn populate_field_ops( record: &mut impl ByteRecord, - shard: u32, cols: &mut EdAddAssignCols, p_x: BigUint, p_y: BigUint, @@ -82,25 +81,23 @@ impl EdAddAssignChip { ) { let x3_numerator = cols.x3_numerator.populate( record, - shard, &[p_x.clone(), q_x.clone()], &[q_y.clone(), p_y.clone()], ); let y3_numerator = cols.y3_numerator.populate( record, - shard, &[p_y.clone(), p_x.clone()], &[q_y.clone(), q_x.clone()], ); - let x1_mul_y1 = cols.x1_mul_y1.populate(record, shard, &p_x, &p_y, FieldOperation::Mul); - let x2_mul_y2 = cols.x2_mul_y2.populate(record, shard, &q_x, &q_y, FieldOperation::Mul); - let f = cols.f.populate(record, shard, &x1_mul_y1, &x2_mul_y2, FieldOperation::Mul); + let x1_mul_y1 = cols.x1_mul_y1.populate(record, &p_x, &p_y, FieldOperation::Mul); + let x2_mul_y2 = cols.x2_mul_y2.populate(record, &q_x, &q_y, FieldOperation::Mul); + let f = cols.f.populate(record, &x1_mul_y1, &x2_mul_y2, FieldOperation::Mul); let d = E::d_biguint(); - let d_mul_f = cols.d_mul_f.populate(record, shard, &f, &d, FieldOperation::Mul); + let d_mul_f = cols.d_mul_f.populate(record, &f, &d, FieldOperation::Mul); - cols.x3_ins.populate(record, shard, &x3_numerator, &d_mul_f, true); - cols.y3_ins.populate(record, shard, &y3_numerator, &d_mul_f, false); + cols.x3_ins.populate(record, &x3_numerator, &d_mul_f, true); + cols.y3_ins.populate(record, &y3_numerator, &d_mul_f, false); } } @@ -145,7 +142,6 @@ impl MachineAir for Ed let zero = BigUint::zero(); Self::populate_field_ops( &mut vec![], - 0, cols, zero.clone(), zero.clone(), @@ -178,7 +174,7 @@ impl MachineAir for Ed let blu_batches = events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); events.iter().for_each(|(_, event)| { let event = if let PrecompileEvent::EdAdd(event) = event { event @@ -194,7 +190,7 @@ impl MachineAir for Ed }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect_vec()); + output.add_byte_lookup_events_from_maps(blu_batches.iter().collect_vec()); } fn included(&self, shard: &Self::Record) -> bool { @@ -229,7 +225,7 @@ impl EdAddAssignChip { cols.p_ptr = F::from_canonical_u32(event.p_ptr); cols.q_ptr = F::from_canonical_u32(event.q_ptr); - Self::populate_field_ops(blu, event.shard, cols, p_x, p_y, q_x, q_y); + Self::populate_field_ops(blu, cols, p_x, p_y, q_x, q_y); // Populate the memory access columns. for i in 0..WORDS_CURVE_POINT { diff --git a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs index 97d0e526fe..7324ca8910 100644 --- a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs +++ b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs @@ -81,7 +81,7 @@ impl EdDecompressCols { } let y = &BigUint::from_bytes_le(&event.y_bytes); - self.populate_field_ops::(&mut new_byte_lookup_events, event.shard, y); + self.populate_field_ops::(&mut new_byte_lookup_events, y); record.add_byte_lookup_events(new_byte_lookup_events); } @@ -89,18 +89,17 @@ impl EdDecompressCols { fn populate_field_ops( &mut self, blu_events: &mut Vec, - shard: u32, y: &BigUint, ) { let one = BigUint::one(); - self.y_range.populate(blu_events, shard, y, &Ed25519BaseField::modulus()); - let yy = self.yy.populate(blu_events, shard, y, y, FieldOperation::Mul); - let u = self.u.populate(blu_events, shard, &yy, &one, FieldOperation::Sub); - let dyy = self.dyy.populate(blu_events, shard, &E::d_biguint(), &yy, FieldOperation::Mul); - let v = self.v.populate(blu_events, shard, &one, &dyy, FieldOperation::Add); - let u_div_v = self.u_div_v.populate(blu_events, shard, &u, &v, FieldOperation::Div); - let x = self.x.populate(blu_events, shard, &u_div_v, ed25519_sqrt); - self.neg_x.populate(blu_events, shard, &BigUint::zero(), &x, FieldOperation::Sub); + self.y_range.populate(blu_events, y, &Ed25519BaseField::modulus()); + let yy = self.yy.populate(blu_events, y, y, FieldOperation::Mul); + let u = self.u.populate(blu_events, &yy, &one, FieldOperation::Sub); + let dyy = self.dyy.populate(blu_events, &E::d_biguint(), &yy, FieldOperation::Mul); + let v = self.v.populate(blu_events, &one, &dyy, FieldOperation::Add); + let u_div_v = self.u_div_v.populate(blu_events, &u, &v, FieldOperation::Div); + let x = self.x.populate(blu_events, &u_div_v, ed25519_sqrt); + self.neg_x.populate(blu_events, &BigUint::zero(), &x, FieldOperation::Sub); } } @@ -238,7 +237,7 @@ impl MachineAir for EdDecompressChip = row.as_mut_slice().borrow_mut(); let zero = BigUint::zero(); - cols.populate_field_ops::(&mut vec![], 0, &zero); + cols.populate_field_ops::(&mut vec![], &zero); row }, input.fixed_log2_rows::(self), diff --git a/crates/core/machine/src/syscall/precompiles/fptower/fp.rs b/crates/core/machine/src/syscall/precompiles/fptower/fp.rs index a9c21016c7..868c9a5056 100644 --- a/crates/core/machine/src/syscall/precompiles/fptower/fp.rs +++ b/crates/core/machine/src/syscall/precompiles/fptower/fp.rs @@ -63,7 +63,6 @@ impl FpOpChip

{ #[allow(clippy::too_many_arguments)] fn populate_field_ops( blu_events: &mut Vec, - shard: u32, cols: &mut FpOpCols, p: BigUint, q: BigUint, @@ -71,7 +70,7 @@ impl FpOpChip

{ ) { let modulus_bytes = P::MODULUS; let modulus = BigUint::from_bytes_le(modulus_bytes); - cols.output.populate_with_modulus(blu_events, shard, &p, &q, &modulus, op); + cols.output.populate_with_modulus(blu_events, &p, &q, &modulus, op); } } @@ -123,14 +122,7 @@ impl MachineAir for FpOpChip

{ cols.x_ptr = F::from_canonical_u32(event.x_ptr); cols.y_ptr = F::from_canonical_u32(event.y_ptr); - Self::populate_field_ops( - &mut new_byte_lookup_events, - event.shard, - cols, - p, - q, - event.op, - ); + Self::populate_field_ops(&mut new_byte_lookup_events, cols, p, q, event.op); // Populate the memory access columns. for i in 0..cols.y_access.len() { @@ -153,7 +145,6 @@ impl MachineAir for FpOpChip

{ cols.is_add = F::from_canonical_u8(1); Self::populate_field_ops( &mut vec![], - 0, cols, zero.clone(), zero, diff --git a/crates/core/machine/src/syscall/precompiles/fptower/fp2_addsub.rs b/crates/core/machine/src/syscall/precompiles/fptower/fp2_addsub.rs index 7f28309597..e67011f7d3 100644 --- a/crates/core/machine/src/syscall/precompiles/fptower/fp2_addsub.rs +++ b/crates/core/machine/src/syscall/precompiles/fptower/fp2_addsub.rs @@ -63,7 +63,6 @@ impl Fp2AddSubAssignChip

{ #[allow(clippy::too_many_arguments)] fn populate_field_ops( blu_events: &mut Vec, - shard: u32, cols: &mut Fp2AddSubAssignCols, p_x: BigUint, p_y: BigUint, @@ -73,8 +72,8 @@ impl Fp2AddSubAssignChip

{ ) { let modulus_bytes = P::MODULUS; let modulus = BigUint::from_bytes_le(modulus_bytes); - cols.c0.populate_with_modulus(blu_events, shard, &p_x, &q_x, &modulus, op); - cols.c1.populate_with_modulus(blu_events, shard, &p_y, &q_y, &modulus, op); + cols.c0.populate_with_modulus(blu_events, &p_x, &q_x, &modulus, op); + cols.c1.populate_with_modulus(blu_events, &p_y, &q_y, &modulus, op); } } @@ -131,7 +130,6 @@ impl MachineAir for Fp2AddSubAssignChip

{ Self::populate_field_ops( &mut new_byte_lookup_events, - event.shard, cols, p_x, p_y, @@ -161,7 +159,6 @@ impl MachineAir for Fp2AddSubAssignChip

{ let zero = BigUint::zero(); Self::populate_field_ops( &mut vec![], - 0, cols, zero.clone(), zero.clone(), diff --git a/crates/core/machine/src/syscall/precompiles/fptower/fp2_mul.rs b/crates/core/machine/src/syscall/precompiles/fptower/fp2_mul.rs index 95a624cc2f..9eca33bcf5 100644 --- a/crates/core/machine/src/syscall/precompiles/fptower/fp2_mul.rs +++ b/crates/core/machine/src/syscall/precompiles/fptower/fp2_mul.rs @@ -67,7 +67,6 @@ impl Fp2MulAssignChip

{ #[allow(clippy::too_many_arguments)] fn populate_field_ops( blu_events: &mut Vec, - shard: u32, cols: &mut Fp2MulAssignCols, p_x: BigUint, p_y: BigUint, @@ -78,7 +77,6 @@ impl Fp2MulAssignChip

{ let modulus = BigUint::from_bytes_le(modulus_bytes); let a0_mul_b0 = cols.a0_mul_b0.populate_with_modulus( blu_events, - shard, &p_x, &q_x, &modulus, @@ -86,7 +84,6 @@ impl Fp2MulAssignChip

{ ); let a1_mul_b1 = cols.a1_mul_b1.populate_with_modulus( blu_events, - shard, &p_y, &q_y, &modulus, @@ -94,7 +91,6 @@ impl Fp2MulAssignChip

{ ); let a0_mul_b1 = cols.a0_mul_b1.populate_with_modulus( blu_events, - shard, &p_x, &q_y, &modulus, @@ -102,7 +98,6 @@ impl Fp2MulAssignChip

{ ); let a1_mul_b0 = cols.a1_mul_b0.populate_with_modulus( blu_events, - shard, &p_y, &q_x, &modulus, @@ -110,7 +105,6 @@ impl Fp2MulAssignChip

{ ); cols.c0.populate_with_modulus( blu_events, - shard, &a0_mul_b0, &a1_mul_b1, &modulus, @@ -118,7 +112,6 @@ impl Fp2MulAssignChip

{ ); cols.c1.populate_with_modulus( blu_events, - shard, &a0_mul_b1, &a1_mul_b0, &modulus, @@ -171,15 +164,7 @@ impl MachineAir for Fp2MulAssignChip

{ cols.x_ptr = F::from_canonical_u32(event.x_ptr); cols.y_ptr = F::from_canonical_u32(event.y_ptr); - Self::populate_field_ops( - &mut new_byte_lookup_events, - event.shard, - cols, - p_x, - p_y, - q_x, - q_y, - ); + Self::populate_field_ops(&mut new_byte_lookup_events, cols, p_x, p_y, q_x, q_y); // Populate the memory access columns. for i in 0..cols.y_access.len() { @@ -201,7 +186,6 @@ impl MachineAir for Fp2MulAssignChip

{ let zero = BigUint::zero(); Self::populate_field_ops( &mut vec![], - 0, cols, zero.clone(), zero.clone(), diff --git a/crates/core/machine/src/syscall/precompiles/keccak256/trace.rs b/crates/core/machine/src/syscall/precompiles/keccak256/trace.rs index 020b28c9f0..dc931da302 100644 --- a/crates/core/machine/src/syscall/precompiles/keccak256/trace.rs +++ b/crates/core/machine/src/syscall/precompiles/keccak256/trace.rs @@ -145,8 +145,7 @@ impl KeccakPermuteChip { if i == 0 { for (j, read_record) in event.state_read_records.iter().enumerate() { cols.state_mem[j].populate_read(*read_record, new_byte_lookup_events); - new_byte_lookup_events - .add_u8_range_checks(shard, &read_record.value.to_le_bytes()); + new_byte_lookup_events.add_u8_range_checks(&read_record.value.to_le_bytes()); } cols.do_memory_check = F::one(); cols.receive_ecall = F::one(); @@ -156,8 +155,7 @@ impl KeccakPermuteChip { if i == NUM_ROUNDS - 1 { for (j, write_record) in event.state_write_records.iter().enumerate() { cols.state_mem[j].populate_write(*write_record, new_byte_lookup_events); - new_byte_lookup_events - .add_u8_range_checks(shard, &write_record.value.to_le_bytes()); + new_byte_lookup_events.add_u8_range_checks(&write_record.value.to_le_bytes()); } cols.do_memory_check = F::one(); } diff --git a/crates/core/machine/src/syscall/precompiles/sha256/compress/trace.rs b/crates/core/machine/src/syscall/precompiles/sha256/compress/trace.rs index d6b61b67f2..c2f2961889 100644 --- a/crates/core/machine/src/syscall/precompiles/sha256/compress/trace.rs +++ b/crates/core/machine/src/syscall/precompiles/sha256/compress/trace.rs @@ -100,7 +100,7 @@ impl MachineAir for ShaCompressChip { let blu_batches = events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); events.iter().for_each(|(_, event)| { let event = if let PrecompileEvent::ShaCompress(event) = event { event @@ -113,7 +113,7 @@ impl MachineAir for ShaCompressChip { }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect_vec()); + output.add_byte_lookup_events_from_maps(blu_batches.iter().collect_vec()); } fn included(&self, shard: &Self::Record) -> bool { @@ -132,8 +132,6 @@ impl ShaCompressChip { rows: &mut Option>, blu: &mut impl ByteRecord, ) { - let shard = event.shard; - let og_h = event.h; let mut octet_num_idx = 0; @@ -209,35 +207,35 @@ impl ShaCompressChip { cols.g = Word::from(g); cols.h = Word::from(h); - let e_rr_6 = cols.e_rr_6.populate(blu, shard, e, 6); - let e_rr_11 = cols.e_rr_11.populate(blu, shard, e, 11); - let e_rr_25 = cols.e_rr_25.populate(blu, shard, e, 25); - let s1_intermediate = cols.s1_intermediate.populate(blu, shard, e_rr_6, e_rr_11); - let s1 = cols.s1.populate(blu, shard, s1_intermediate, e_rr_25); + let e_rr_6 = cols.e_rr_6.populate(blu, e, 6); + let e_rr_11 = cols.e_rr_11.populate(blu, e, 11); + let e_rr_25 = cols.e_rr_25.populate(blu, e, 25); + let s1_intermediate = cols.s1_intermediate.populate(blu, e_rr_6, e_rr_11); + let s1 = cols.s1.populate(blu, s1_intermediate, e_rr_25); - let e_and_f = cols.e_and_f.populate(blu, shard, e, f); - let e_not = cols.e_not.populate(blu, shard, e); - let e_not_and_g = cols.e_not_and_g.populate(blu, shard, e_not, g); - let ch = cols.ch.populate(blu, shard, e_and_f, e_not_and_g); + let e_and_f = cols.e_and_f.populate(blu, e, f); + let e_not = cols.e_not.populate(blu, e); + let e_not_and_g = cols.e_not_and_g.populate(blu, e_not, g); + let ch = cols.ch.populate(blu, e_and_f, e_not_and_g); - let temp1 = cols.temp1.populate(blu, shard, h, s1, ch, event.w[j], SHA_COMPRESS_K[j]); + let temp1 = cols.temp1.populate(blu, h, s1, ch, event.w[j], SHA_COMPRESS_K[j]); - let a_rr_2 = cols.a_rr_2.populate(blu, shard, a, 2); - let a_rr_13 = cols.a_rr_13.populate(blu, shard, a, 13); - let a_rr_22 = cols.a_rr_22.populate(blu, shard, a, 22); - let s0_intermediate = cols.s0_intermediate.populate(blu, shard, a_rr_2, a_rr_13); - let s0 = cols.s0.populate(blu, shard, s0_intermediate, a_rr_22); + let a_rr_2 = cols.a_rr_2.populate(blu, a, 2); + let a_rr_13 = cols.a_rr_13.populate(blu, a, 13); + let a_rr_22 = cols.a_rr_22.populate(blu, a, 22); + let s0_intermediate = cols.s0_intermediate.populate(blu, a_rr_2, a_rr_13); + let s0 = cols.s0.populate(blu, s0_intermediate, a_rr_22); - let a_and_b = cols.a_and_b.populate(blu, shard, a, b); - let a_and_c = cols.a_and_c.populate(blu, shard, a, c); - let b_and_c = cols.b_and_c.populate(blu, shard, b, c); - let maj_intermediate = cols.maj_intermediate.populate(blu, shard, a_and_b, a_and_c); - let maj = cols.maj.populate(blu, shard, maj_intermediate, b_and_c); + let a_and_b = cols.a_and_b.populate(blu, a, b); + let a_and_c = cols.a_and_c.populate(blu, a, c); + let b_and_c = cols.b_and_c.populate(blu, b, c); + let maj_intermediate = cols.maj_intermediate.populate(blu, a_and_b, a_and_c); + let maj = cols.maj.populate(blu, maj_intermediate, b_and_c); - let temp2 = cols.temp2.populate(blu, shard, s0, maj); + let temp2 = cols.temp2.populate(blu, s0, maj); - let d_add_temp1 = cols.d_add_temp1.populate(blu, shard, d, temp1); - let temp1_add_temp2 = cols.temp1_add_temp2.populate(blu, shard, temp1, temp2); + let d_add_temp1 = cols.d_add_temp1.populate(blu, d, temp1); + let temp1_add_temp2 = cols.temp1_add_temp2.populate(blu, temp1, temp2); h_array[7] = g; h_array[6] = f; @@ -273,7 +271,7 @@ impl ShaCompressChip { cols.octet_num[octet_num_idx] = F::one(); cols.is_finalize = F::one(); - cols.finalize_add.populate(blu, shard, og_h[j], h_array[j]); + cols.finalize_add.populate(blu, og_h[j], h_array[j]); cols.mem.populate_write(event.h_write_records[j], blu); cols.mem_addr = F::from_canonical_u32(event.h_ptr + (j * 4) as u32); diff --git a/crates/core/machine/src/syscall/precompiles/sha256/extend/mod.rs b/crates/core/machine/src/syscall/precompiles/sha256/extend/mod.rs index 44259ccca5..8548d6e159 100644 --- a/crates/core/machine/src/syscall/precompiles/sha256/extend/mod.rs +++ b/crates/core/machine/src/syscall/precompiles/sha256/extend/mod.rs @@ -66,7 +66,7 @@ pub mod extend_tests { #[test] fn generate_trace() { let mut shard = ExecutionRecord::default(); - shard.add_events = vec![InstrEvent::new(0, 0, Opcode::ADD, 14, 8, 6)]; + shard.add_events = vec![InstrEvent::new(0, Opcode::ADD, 14, 8, 6)]; let chip = ShaExtendChip::new(); let trace: RowMajorMatrix = chip.generate_trace(&shard, &mut ExecutionRecord::default()); diff --git a/crates/core/machine/src/syscall/precompiles/sha256/extend/trace.rs b/crates/core/machine/src/syscall/precompiles/sha256/extend/trace.rs index 75e1a16533..5d0148a23d 100644 --- a/crates/core/machine/src/syscall/precompiles/sha256/extend/trace.rs +++ b/crates/core/machine/src/syscall/precompiles/sha256/extend/trace.rs @@ -73,7 +73,7 @@ impl MachineAir for ShaExtendChip { let blu_batches = events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); + let mut blu: HashMap = HashMap::new(); events.iter().for_each(|(_, event)| { let event = if let PrecompileEvent::ShaExtend(event) = event { event @@ -86,7 +86,7 @@ impl MachineAir for ShaExtendChip { }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect_vec()); + output.add_byte_lookup_events_from_maps(blu_batches.iter().collect_vec()); } fn included(&self, shard: &Self::Record) -> bool { @@ -105,7 +105,6 @@ impl ShaExtendChip { rows: &mut Option>, blu: &mut impl ByteRecord, ) { - let shard = event.shard; for j in 0..48usize { let mut row = [F::zero(); NUM_SHA_EXTEND_COLS]; let cols: &mut ShaExtendCols = row.as_mut_slice().borrow_mut(); @@ -123,27 +122,27 @@ impl ShaExtendChip { // `s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift // 3)`. let w_i_minus_15 = event.w_i_minus_15_reads[j].value; - let w_i_minus_15_rr_7 = cols.w_i_minus_15_rr_7.populate(blu, shard, w_i_minus_15, 7); - let w_i_minus_15_rr_18 = cols.w_i_minus_15_rr_18.populate(blu, shard, w_i_minus_15, 18); - let w_i_minus_15_rs_3 = cols.w_i_minus_15_rs_3.populate(blu, shard, w_i_minus_15, 3); + let w_i_minus_15_rr_7 = cols.w_i_minus_15_rr_7.populate(blu, w_i_minus_15, 7); + let w_i_minus_15_rr_18 = cols.w_i_minus_15_rr_18.populate(blu, w_i_minus_15, 18); + let w_i_minus_15_rs_3 = cols.w_i_minus_15_rs_3.populate(blu, w_i_minus_15, 3); let s0_intermediate = - cols.s0_intermediate.populate(blu, shard, w_i_minus_15_rr_7, w_i_minus_15_rr_18); - let s0 = cols.s0.populate(blu, shard, s0_intermediate, w_i_minus_15_rs_3); + cols.s0_intermediate.populate(blu, w_i_minus_15_rr_7, w_i_minus_15_rr_18); + let s0 = cols.s0.populate(blu, s0_intermediate, w_i_minus_15_rs_3); // `s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift // 10)`. let w_i_minus_2 = event.w_i_minus_2_reads[j].value; - let w_i_minus_2_rr_17 = cols.w_i_minus_2_rr_17.populate(blu, shard, w_i_minus_2, 17); - let w_i_minus_2_rr_19 = cols.w_i_minus_2_rr_19.populate(blu, shard, w_i_minus_2, 19); - let w_i_minus_2_rs_10 = cols.w_i_minus_2_rs_10.populate(blu, shard, w_i_minus_2, 10); + let w_i_minus_2_rr_17 = cols.w_i_minus_2_rr_17.populate(blu, w_i_minus_2, 17); + let w_i_minus_2_rr_19 = cols.w_i_minus_2_rr_19.populate(blu, w_i_minus_2, 19); + let w_i_minus_2_rs_10 = cols.w_i_minus_2_rs_10.populate(blu, w_i_minus_2, 10); let s1_intermediate = - cols.s1_intermediate.populate(blu, shard, w_i_minus_2_rr_17, w_i_minus_2_rr_19); - let s1 = cols.s1.populate(blu, shard, s1_intermediate, w_i_minus_2_rs_10); + cols.s1_intermediate.populate(blu, w_i_minus_2_rr_17, w_i_minus_2_rr_19); + let s1 = cols.s1.populate(blu, s1_intermediate, w_i_minus_2_rs_10); // Compute `s2`. let w_i_minus_7 = event.w_i_minus_7_reads[j].value; let w_i_minus_16 = event.w_i_minus_16_reads[j].value; - cols.s2.populate(blu, shard, w_i_minus_16, s0, w_i_minus_7, s1); + cols.s2.populate(blu, w_i_minus_16, s0, w_i_minus_7, s1); cols.w_i.populate(event.w_i_writes[j], blu); diff --git a/crates/core/machine/src/syscall/precompiles/u256x2048_mul/air.rs b/crates/core/machine/src/syscall/precompiles/u256x2048_mul/air.rs index 43a9906581..ea4e8d2bba 100644 --- a/crates/core/machine/src/syscall/precompiles/u256x2048_mul/air.rs +++ b/crates/core/machine/src/syscall/precompiles/u256x2048_mul/air.rs @@ -182,7 +182,6 @@ impl MachineAir for U256x2048MulChip { for (i, col) in ab_plus_carry_cols.iter_mut().enumerate() { let (_, carry) = col.populate_mul_and_carry( &mut new_byte_lookup_events, - event.shard, &a, &b_array[i], &carries[i], @@ -217,14 +216,14 @@ impl MachineAir for U256x2048MulChip { let modulus = BigUint::one() << 256; // Populate all the mul and carry columns with zero values. - cols.a_mul_b1.populate(&mut vec![], 0, &x, &y, FieldOperation::Mul); - cols.ab2_plus_carry.populate_mul_and_carry(&mut vec![], 0, &x, &y, &z, &modulus); - cols.ab3_plus_carry.populate_mul_and_carry(&mut vec![], 0, &x, &y, &z, &modulus); - cols.ab4_plus_carry.populate_mul_and_carry(&mut vec![], 0, &x, &y, &z, &modulus); - cols.ab5_plus_carry.populate_mul_and_carry(&mut vec![], 0, &x, &y, &z, &modulus); - cols.ab6_plus_carry.populate_mul_and_carry(&mut vec![], 0, &x, &y, &z, &modulus); - cols.ab7_plus_carry.populate_mul_and_carry(&mut vec![], 0, &x, &y, &z, &modulus); - cols.ab8_plus_carry.populate_mul_and_carry(&mut vec![], 0, &x, &y, &z, &modulus); + cols.a_mul_b1.populate(&mut vec![], &x, &y, FieldOperation::Mul); + cols.ab2_plus_carry.populate_mul_and_carry(&mut vec![], &x, &y, &z, &modulus); + cols.ab3_plus_carry.populate_mul_and_carry(&mut vec![], &x, &y, &z, &modulus); + cols.ab4_plus_carry.populate_mul_and_carry(&mut vec![], &x, &y, &z, &modulus); + cols.ab5_plus_carry.populate_mul_and_carry(&mut vec![], &x, &y, &z, &modulus); + cols.ab6_plus_carry.populate_mul_and_carry(&mut vec![], &x, &y, &z, &modulus); + cols.ab7_plus_carry.populate_mul_and_carry(&mut vec![], &x, &y, &z, &modulus); + cols.ab8_plus_carry.populate_mul_and_carry(&mut vec![], &x, &y, &z, &modulus); row }, diff --git a/crates/core/machine/src/syscall/precompiles/uint256/air.rs b/crates/core/machine/src/syscall/precompiles/uint256/air.rs index 54e0925f9e..7e225b1a40 100644 --- a/crates/core/machine/src/syscall/precompiles/uint256/air.rs +++ b/crates/core/machine/src/syscall/precompiles/uint256/air.rs @@ -158,7 +158,6 @@ impl MachineAir for Uint256MulChip { if modulus.is_zero() { BigUint::one() << 256 } else { modulus.clone() }; let result = cols.output.populate_with_modulus( &mut new_byte_lookup_events, - event.shard, &x, &y, &effective_modulus, @@ -170,7 +169,6 @@ impl MachineAir for Uint256MulChip { if cols.modulus_is_not_zero == F::one() { cols.output_range_check.populate( &mut new_byte_lookup_events, - event.shard, &result, &effective_modulus, ); @@ -199,7 +197,7 @@ impl MachineAir for Uint256MulChip { let x = BigUint::zero(); let y = BigUint::zero(); - cols.output.populate(&mut vec![], 0, &x, &y, FieldOperation::Mul); + cols.output.populate(&mut vec![], &x, &y, FieldOperation::Mul); row }, diff --git a/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_add.rs b/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_add.rs index d678f93086..e501764708 100644 --- a/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_add.rs +++ b/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_add.rs @@ -77,7 +77,6 @@ impl WeierstrassAddAssignChip { #[allow(clippy::too_many_arguments)] fn populate_field_ops( blu_events: &mut Vec, - shard: u32, cols: &mut WeierstrassAddAssignCols, p_x: BigUint, p_y: BigUint, @@ -90,14 +89,13 @@ impl WeierstrassAddAssignChip { // slope = (q.y - p.y) / (q.x - p.x). let slope = { let slope_numerator = - cols.slope_numerator.populate(blu_events, shard, &q_y, &p_y, FieldOperation::Sub); + cols.slope_numerator.populate(blu_events, &q_y, &p_y, FieldOperation::Sub); let slope_denominator = - cols.slope_denominator.populate(blu_events, shard, &q_x, &p_x, FieldOperation::Sub); + cols.slope_denominator.populate(blu_events, &q_x, &p_x, FieldOperation::Sub); cols.slope.populate( blu_events, - shard, &slope_numerator, &slope_denominator, FieldOperation::Div, @@ -107,36 +105,22 @@ impl WeierstrassAddAssignChip { // x = slope * slope - (p.x + q.x). let x = { let slope_squared = - cols.slope_squared.populate(blu_events, shard, &slope, &slope, FieldOperation::Mul); + cols.slope_squared.populate(blu_events, &slope, &slope, FieldOperation::Mul); let p_x_plus_q_x = - cols.p_x_plus_q_x.populate(blu_events, shard, &p_x, &q_x, FieldOperation::Add); - cols.x3_ins.populate( - blu_events, - shard, - &slope_squared, - &p_x_plus_q_x, - FieldOperation::Sub, - ) + cols.p_x_plus_q_x.populate(blu_events, &p_x, &q_x, FieldOperation::Add); + cols.x3_ins.populate(blu_events, &slope_squared, &p_x_plus_q_x, FieldOperation::Sub) }; // y = slope * (p.x - x_3n) - p.y. { - let p_x_minus_x = - cols.p_x_minus_x.populate(blu_events, shard, &p_x, &x, FieldOperation::Sub); + let p_x_minus_x = cols.p_x_minus_x.populate(blu_events, &p_x, &x, FieldOperation::Sub); let slope_times_p_x_minus_x = cols.slope_times_p_x_minus_x.populate( blu_events, - shard, &slope, &p_x_minus_x, FieldOperation::Mul, ); - cols.y3_ins.populate( - blu_events, - shard, - &slope_times_p_x_minus_x, - &p_y, - FieldOperation::Sub, - ); + cols.y3_ins.populate(blu_events, &slope_times_p_x_minus_x, &p_y, FieldOperation::Sub); } } } @@ -220,15 +204,7 @@ impl MachineAir let cols: &mut WeierstrassAddAssignCols = dummy_row.as_mut_slice().borrow_mut(); let zero = BigUint::zero(); - Self::populate_field_ops( - &mut vec![], - 0, - cols, - zero.clone(), - zero.clone(), - zero.clone(), - zero, - ); + Self::populate_field_ops(&mut vec![], cols, zero.clone(), zero.clone(), zero.clone(), zero); values.chunks_mut(chunk_size * num_cols).enumerate().par_bridge().for_each(|(i, rows)| { rows.chunks_mut(num_cols).enumerate().for_each(|(j, row)| { @@ -449,7 +425,7 @@ impl WeierstrassAddAssignChip { cols.p_ptr = F::from_canonical_u32(event.p_ptr); cols.q_ptr = F::from_canonical_u32(event.q_ptr); - Self::populate_field_ops(new_byte_lookup_events, event.shard, cols, p_x, p_y, q_x, q_y); + Self::populate_field_ops(new_byte_lookup_events, cols, p_x, p_y, q_x, q_y); // Populate the memory access columns. for i in 0..cols.q_access.len() { diff --git a/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_decompress.rs b/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_decompress.rs index 1edc1440f9..3b1cc3245e 100644 --- a/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_decompress.rs +++ b/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_decompress.rs @@ -110,21 +110,20 @@ impl WeierstrassDecompressChip { fn populate_field_ops( record: &mut impl ByteRecord, - shard: u32, cols: &mut WeierstrassDecompressCols, x: BigUint, ) { // Y = sqrt(x^3 + ax + b) - cols.range_x.populate(record, shard, &x, &E::BaseField::modulus()); - let x_2 = cols.x_2.populate(record, shard, &x.clone(), &x.clone(), FieldOperation::Mul); - let x_3 = cols.x_3.populate(record, shard, &x_2, &x, FieldOperation::Mul); + cols.range_x.populate(record, &x, &E::BaseField::modulus()); + let x_2 = cols.x_2.populate(record, &x.clone(), &x.clone(), FieldOperation::Mul); + let x_3 = cols.x_3.populate(record, &x_2, &x, FieldOperation::Mul); let b = E::b_int(); let a = E::a_int(); let param_vec = vec![a, b]; let x_vec = vec![x, BigUint::one()]; - let ax_plus_b = cols.ax_plus_b.populate(record, shard, ¶m_vec, &x_vec); + let ax_plus_b = cols.ax_plus_b.populate(record, ¶m_vec, &x_vec); let x_3_plus_b_plus_ax = - cols.x_3_plus_b_plus_ax.populate(record, shard, &x_3, &ax_plus_b, FieldOperation::Add); + cols.x_3_plus_b_plus_ax.populate(record, &x_3, &ax_plus_b, FieldOperation::Add); let sqrt_fn = match E::CURVE_TYPE { CurveType::Secp256k1 => secp256k1_sqrt, @@ -133,9 +132,9 @@ impl WeierstrassDecompressChip { _ => panic!("Unsupported curve"), }; - let y = cols.y.populate(record, shard, &x_3_plus_b_plus_ax, sqrt_fn); + let y = cols.y.populate(record, &x_3_plus_b_plus_ax, sqrt_fn); let zero = BigUint::zero(); - cols.neg_y.populate(record, shard, &zero, &y, FieldOperation::Sub); + cols.neg_y.populate(record, &zero, &y, FieldOperation::Sub); } } @@ -193,7 +192,7 @@ impl MachineAir cols.sign_bit = F::from_bool(event.sign_bit); let x = BigUint::from_bytes_le(&event.x_bytes); - Self::populate_field_ops(&mut new_byte_lookup_events, event.shard, cols, x); + Self::populate_field_ops(&mut new_byte_lookup_events, cols, x); for i in 0..cols.x_access.len() { cols.x_access[i].populate(event.x_memory_records[i], &mut new_byte_lookup_events); @@ -218,14 +217,12 @@ impl MachineAir if is_y_eq_sqrt_y_result { choice_cols.neg_y_range_check.populate( &mut new_byte_lookup_events, - event.shard, &neg_y, &modulus, ); } else { choice_cols.neg_y_range_check.populate( &mut new_byte_lookup_events, - event.shard, &decompressed_y, &modulus, ); @@ -236,7 +233,6 @@ impl MachineAir choice_cols.when_neg_y_res_is_lt = F::from_bool(is_y_eq_sqrt_y_result); choice_cols.comparison_lt_cols.populate( &mut new_byte_lookup_events, - event.shard, &neg_y, &decompressed_y, ); @@ -246,7 +242,6 @@ impl MachineAir choice_cols.when_neg_y_res_is_lt = F::from_bool(!is_y_eq_sqrt_y_result); choice_cols.comparison_lt_cols.populate( &mut new_byte_lookup_events, - event.shard, &decompressed_y, &neg_y, ); @@ -272,7 +267,7 @@ impl MachineAir cols.x_access[i].access.value = words[i].into(); } - Self::populate_field_ops(&mut vec![], 0, cols, dummy_value); + Self::populate_field_ops(&mut vec![], cols, dummy_value); row }, input.fixed_log2_rows::(self), diff --git a/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_double.rs b/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_double.rs index 9e18fc60f1..32e7311d30 100644 --- a/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_double.rs +++ b/crates/core/machine/src/syscall/precompiles/weierstrass/weierstrass_double.rs @@ -75,7 +75,6 @@ impl WeierstrassDoubleAssignChip { fn populate_field_ops( blu_events: &mut Vec, - shard: u32, cols: &mut WeierstrassDoubleAssignCols, p_x: BigUint, p_y: BigUint, @@ -87,17 +86,15 @@ impl WeierstrassDoubleAssignChip { // slope_numerator = a + (p.x * p.x) * 3. let slope_numerator = { let p_x_squared = - cols.p_x_squared.populate(blu_events, shard, &p_x, &p_x, FieldOperation::Mul); + cols.p_x_squared.populate(blu_events, &p_x, &p_x, FieldOperation::Mul); let p_x_squared_times_3 = cols.p_x_squared_times_3.populate( blu_events, - shard, &p_x_squared, &BigUint::from(3u32), FieldOperation::Mul, ); cols.slope_numerator.populate( blu_events, - shard, &a, &p_x_squared_times_3, FieldOperation::Add, @@ -107,7 +104,6 @@ impl WeierstrassDoubleAssignChip { // slope_denominator = 2 * y. let slope_denominator = cols.slope_denominator.populate( blu_events, - shard, &BigUint::from(2u32), &p_y, FieldOperation::Mul, @@ -115,7 +111,6 @@ impl WeierstrassDoubleAssignChip { cols.slope.populate( blu_events, - shard, &slope_numerator, &slope_denominator, FieldOperation::Div, @@ -125,36 +120,22 @@ impl WeierstrassDoubleAssignChip { // x = slope * slope - (p.x + p.x). let x = { let slope_squared = - cols.slope_squared.populate(blu_events, shard, &slope, &slope, FieldOperation::Mul); + cols.slope_squared.populate(blu_events, &slope, &slope, FieldOperation::Mul); let p_x_plus_p_x = - cols.p_x_plus_p_x.populate(blu_events, shard, &p_x, &p_x, FieldOperation::Add); - cols.x3_ins.populate( - blu_events, - shard, - &slope_squared, - &p_x_plus_p_x, - FieldOperation::Sub, - ) + cols.p_x_plus_p_x.populate(blu_events, &p_x, &p_x, FieldOperation::Add); + cols.x3_ins.populate(blu_events, &slope_squared, &p_x_plus_p_x, FieldOperation::Sub) }; // y = slope * (p.x - x) - p.y. { - let p_x_minus_x = - cols.p_x_minus_x.populate(blu_events, shard, &p_x, &x, FieldOperation::Sub); + let p_x_minus_x = cols.p_x_minus_x.populate(blu_events, &p_x, &x, FieldOperation::Sub); let slope_times_p_x_minus_x = cols.slope_times_p_x_minus_x.populate( blu_events, - shard, &slope, &p_x_minus_x, FieldOperation::Mul, ); - cols.y3_ins.populate( - blu_events, - shard, - &slope_times_p_x_minus_x, - &p_y, - FieldOperation::Sub, - ); + cols.y3_ins.populate(blu_events, &slope_times_p_x_minus_x, &p_y, FieldOperation::Sub); } } } @@ -250,7 +231,7 @@ impl MachineAir let zero = BigUint::zero(); let one = BigUint::one(); cols.p_access[num_words_field_element].populate(dummy_memory_record, &mut vec![]); - Self::populate_field_ops(&mut vec![], 0, cols, zero, one); + Self::populate_field_ops(&mut vec![], cols, zero, one); values.chunks_mut(chunk_size * num_cols).enumerate().par_bridge().for_each(|(i, rows)| { rows.chunks_mut(num_cols).enumerate().for_each(|(j, row)| { @@ -328,7 +309,7 @@ impl WeierstrassDoubleAssignChip { cols.clk = F::from_canonical_u32(event.clk); cols.p_ptr = F::from_canonical_u32(event.p_ptr); - Self::populate_field_ops(new_byte_lookup_events, event.shard, cols, p_x, p_y); + Self::populate_field_ops(new_byte_lookup_events, cols, p_x, p_y); // Populate the memory access columns. for i in 0..cols.p_access.len() { From c55fe19974f6a48dbb9c9b3c42771247b7a2856c Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Thu, 21 Nov 2024 17:14:39 -0800 Subject: [PATCH 11/18] changes --- crates/core/machine/src/cpu/air/mod.rs | 2 +- examples/Cargo.lock | 98 ++++++++++++++++++-------- 2 files changed, 71 insertions(+), 29 deletions(-) diff --git a/crates/core/machine/src/cpu/air/mod.rs b/crates/core/machine/src/cpu/air/mod.rs index c804fc694f..6d2c19b4ad 100644 --- a/crates/core/machine/src/cpu/air/mod.rs +++ b/crates/core/machine/src/cpu/air/mod.rs @@ -41,7 +41,7 @@ where core::array::from_fn(|i| builder.public_values()[i]); let public_values: &PublicValues, AB::PublicVar> = public_values_slice.as_slice().borrow(); - let shard: AB::Expr = public_values.shard.into(); + let shard: AB::Expr = public_values.execution_shard.into(); // Program constraints. builder.send_program(local.pc, local.instruction, local.selectors, local.is_real); diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 53dd96cfd5..eae6798d95 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -219,7 +219,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "tracing", ] @@ -241,7 +241,7 @@ dependencies = [ "async-trait", "auto_impl", "futures-utils-wasm", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -426,7 +426,7 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -442,7 +442,7 @@ dependencies = [ "async-trait", "k256", "rand 0.8.5", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1155,7 +1155,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -1377,6 +1377,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -1834,7 +1843,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "sha2 0.9.9", - "thiserror", + "thiserror 1.0.68", "zeroize", ] @@ -3846,7 +3855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.68", "ucd-trie", ] @@ -4106,7 +4115,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls", "socket2", - "thiserror", + "thiserror 1.0.68", "tokio", "tracing", ] @@ -4123,7 +4132,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustls", "slab", - "thiserror", + "thiserror 1.0.68", "tinyvec", "tracing", ] @@ -4289,7 +4298,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4407,7 +4416,7 @@ dependencies = [ "http", "reqwest", "serde", - "thiserror", + "thiserror 1.0.68", "tower-service", ] @@ -4420,7 +4429,7 @@ dependencies = [ "reth-execution-errors", "reth-primitives", "reth-storage-errors", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4514,7 +4523,7 @@ dependencies = [ "reth-execution-errors", "reth-fs-util", "reth-storage-errors", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4598,7 +4607,7 @@ dependencies = [ "reth-revm", "revm", "revm-primitives", - "thiserror", + "thiserror 1.0.68", "tracing", ] @@ -4637,7 +4646,7 @@ source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374 dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4649,7 +4658,7 @@ dependencies = [ "alloy-rlp", "enr", "serde_with", - "thiserror", + "thiserror 1.0.68", "url", ] @@ -4706,7 +4715,7 @@ dependencies = [ "reth-trie-common", "revm-primitives", "serde", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -4741,7 +4750,7 @@ dependencies = [ "modular-bitfield", "reth-codecs", "serde", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -5090,7 +5099,7 @@ dependencies = [ "rlp", "rsp-primitives", "serde", - "thiserror", + "thiserror 1.0.68", ] [[package]] @@ -5713,7 +5722,7 @@ dependencies = [ "sp1-stark", "strum", "strum_macros", - "thiserror", + "thiserror 1.0.68", "tiny-keccak", "tracing", "typenum", @@ -5758,7 +5767,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror", + "thiserror 1.0.68", "tracing", "tracing-forest", "tracing-subscriber", @@ -5888,8 +5897,9 @@ dependencies = [ "sp1-recursion-core", "sp1-recursion-gnark-ffi", "sp1-stark", - "thiserror", + "thiserror 1.0.68", "tracing", + "tracing-appender", "tracing-subscriber", ] @@ -5973,7 +5983,7 @@ dependencies = [ "sp1-primitives", "sp1-stark", "static_assertions", - "thiserror", + "thiserror 1.0.68", "tracing", "vec_map", "zkhash", @@ -6046,7 +6056,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror", + "thiserror 1.0.68", "tokio", "tracing", "twirp-rs", @@ -6093,7 +6103,7 @@ dependencies = [ "lazy_static", "sha2 0.10.8", "substrate-bn-succinct", - "thiserror-no-std", + "thiserror 2.0.3", ] [[package]] @@ -6488,7 +6498,16 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.68", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] @@ -6502,6 +6521,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "thiserror-impl-no-std" version = "2.0.2" @@ -6729,6 +6759,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror 1.0.68", + "time", + "tracing-subscriber", +] + [[package]] name = "tracing-attributes" version = "0.1.27" @@ -6758,7 +6800,7 @@ checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" dependencies = [ "ansi_term", "smallvec", - "thiserror", + "thiserror 1.0.68", "tracing", "tracing-subscriber", ] @@ -6814,7 +6856,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror", + "thiserror 1.0.68", "tokio", "tower", "url", From 1bf08ac86b2903cc9e62e6d2e1e103e87a62b20f Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Fri, 22 Nov 2024 09:56:58 -0800 Subject: [PATCH 12/18] put back shard column into cpu table --- Cargo.lock | 18 ----- Cargo.toml | 80 ++++++++++----------- crates/core/machine/src/cpu/air/ecall.rs | 9 +-- crates/core/machine/src/cpu/air/memory.rs | 3 +- crates/core/machine/src/cpu/air/mod.rs | 22 +++--- crates/core/machine/src/cpu/air/register.rs | 7 +- crates/core/machine/src/cpu/columns/mod.rs | 3 + crates/core/machine/src/cpu/trace.rs | 4 +- crates/test-artifacts/programs/Cargo.lock | 16 ----- 9 files changed, 59 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21b1074ae0..e7dda7533e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3799,7 +3799,6 @@ dependencies = [ [[package]] name = "p3-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "p3-field", "p3-matrix", @@ -3808,7 +3807,6 @@ dependencies = [ [[package]] name = "p3-baby-bear" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "num-bigint 0.4.6", "p3-field", @@ -3822,7 +3820,6 @@ dependencies = [ [[package]] name = "p3-bn254-fr" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "ff 0.13.0", "num-bigint 0.4.6", @@ -3836,7 +3833,6 @@ dependencies = [ [[package]] name = "p3-challenger" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -3849,7 +3845,6 @@ dependencies = [ [[package]] name = "p3-commit" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -3862,7 +3857,6 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "p3-field", "p3-matrix", @@ -3874,7 +3868,6 @@ dependencies = [ [[package]] name = "p3-field" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "itertools 0.12.1", "num-bigint 0.4.6", @@ -3887,7 +3880,6 @@ dependencies = [ [[package]] name = "p3-fri" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -3905,7 +3897,6 @@ dependencies = [ [[package]] name = "p3-interpolation" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "p3-field", "p3-matrix", @@ -3915,7 +3906,6 @@ dependencies = [ [[package]] name = "p3-keccak-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "p3-air", "p3-field", @@ -3928,7 +3918,6 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "itertools 0.12.1", "p3-field", @@ -3942,7 +3931,6 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "rayon", ] @@ -3950,7 +3938,6 @@ dependencies = [ [[package]] name = "p3-mds" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "itertools 0.12.1", "p3-dft", @@ -3964,7 +3951,6 @@ dependencies = [ [[package]] name = "p3-merkle-tree" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -3980,7 +3966,6 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "gcd", "p3-field", @@ -3993,7 +3978,6 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "itertools 0.12.1", "p3-field", @@ -4003,7 +3987,6 @@ dependencies = [ [[package]] name = "p3-uni-stark" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "itertools 0.12.1", "p3-air", @@ -4021,7 +4004,6 @@ dependencies = [ [[package]] name = "p3-util" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#d33eaa69b1ef96ad678ebd96ae8e75aef3508b2a" dependencies = [ "serde", ] diff --git a/Cargo.toml b/Cargo.toml index f48c993410..226aee3fdc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,47 +100,47 @@ test-artifacts = { path = "crates/test-artifacts", version = "3.0.0" } # For local development. -p3-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-field = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-commit = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-matrix = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-util = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-challenger = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-dft = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-fri = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-keccak = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-keccak-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-blake3 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-mds = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-symmetric = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-uni-stark = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-field = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-commit = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-matrix = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-util = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-challenger = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-dft = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-fri = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-keccak = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-keccak-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-blake3 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-mds = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-symmetric = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-uni-stark = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +# p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-air = { path = "../Plonky3/air" } -# p3-field = { path = "../Plonky3/field" } -# p3-commit = { path = "../Plonky3/commit" } -# p3-matrix = { path = "../Plonky3/matrix" } -# p3-baby-bear = { path = "../Plonky3/baby-bear" } -# p3-util = { path = "../Plonky3/util" } -# p3-challenger = { path = "../Plonky3/challenger" } -# p3-dft = { path = "../Plonky3/dft" } -# p3-fri = { path = "../Plonky3/fri" } -# p3-goldilocks = { path = "../Plonky3/goldilocks" } -# p3-keccak = { path = "../Plonky3/keccak" } -# p3-keccak-air = { path = "../Plonky3/keccak-air" } -# p3-blake3 = { path = "../Plonky3/blake3" } -# p3-mds = { path = "../Plonky3/mds" } -# p3-merkle-tree = { path = "../Plonky3/merkle-tree" } -# p3-poseidon2 = { path = "../Plonky3/poseidon2" } -# p3-symmetric = { path = "../Plonky3/symmetric" } -# p3-uni-stark = { path = "../Plonky3/uni-stark" } -# p3-maybe-rayon = { path = "../Plonky3/maybe-rayon" } -# p3-bn254-fr = { path = "../Plonky3/bn254-fr" } +p3-air = { path = "../Plonky3/air" } +p3-field = { path = "../Plonky3/field" } +p3-commit = { path = "../Plonky3/commit" } +p3-matrix = { path = "../Plonky3/matrix" } +p3-baby-bear = { path = "../Plonky3/baby-bear" } +p3-util = { path = "../Plonky3/util" } +p3-challenger = { path = "../Plonky3/challenger" } +p3-dft = { path = "../Plonky3/dft" } +p3-fri = { path = "../Plonky3/fri" } +p3-goldilocks = { path = "../Plonky3/goldilocks" } +p3-keccak = { path = "../Plonky3/keccak" } +p3-keccak-air = { path = "../Plonky3/keccak-air" } +p3-blake3 = { path = "../Plonky3/blake3" } +p3-mds = { path = "../Plonky3/mds" } +p3-merkle-tree = { path = "../Plonky3/merkle-tree" } +p3-poseidon2 = { path = "../Plonky3/poseidon2" } +p3-symmetric = { path = "../Plonky3/symmetric" } +p3-uni-stark = { path = "../Plonky3/uni-stark" } +p3-maybe-rayon = { path = "../Plonky3/maybe-rayon" } +p3-bn254-fr = { path = "../Plonky3/bn254-fr" } # misc hashbrown = "0.14.5" diff --git a/crates/core/machine/src/cpu/air/ecall.rs b/crates/core/machine/src/cpu/air/ecall.rs index 79c9ac7de5..59785123fb 100644 --- a/crates/core/machine/src/cpu/air/ecall.rs +++ b/crates/core/machine/src/cpu/air/ecall.rs @@ -33,12 +33,7 @@ impl CpuChip { /// This method will do the following: /// 1. Send the syscall to the precompile table, if needed. /// 2. Check for valid op_a values. - pub(crate) fn eval_ecall( - &self, - builder: &mut AB, - local: &CpuCols, - shard: AB::Expr, - ) { + pub(crate) fn eval_ecall(&self, builder: &mut AB, local: &CpuCols) { let ecall_cols = local.opcode_specific_columns.ecall(); let is_ecall_instruction = self.is_ecall_instruction::(&local.selectors); @@ -57,7 +52,7 @@ impl CpuChip { .assert_eq(local.ecall_mul_send_to_table, send_to_table * is_ecall_instruction.clone()); builder.send_syscall( - shard, + local.shard, local.clk, ecall_cols.syscall_nonce, syscall_id, diff --git a/crates/core/machine/src/cpu/air/memory.rs b/crates/core/machine/src/cpu/air/memory.rs index 268efb13bf..7b355724fb 100644 --- a/crates/core/machine/src/cpu/air/memory.rs +++ b/crates/core/machine/src/cpu/air/memory.rs @@ -61,7 +61,6 @@ impl CpuChip { builder: &mut AB, local: &CpuCols, is_memory_instruction: AB::Expr, - shard: AB::Expr, ) { // Get the memory specific columns. let memory_columns = local.opcode_specific_columns.memory(); @@ -124,7 +123,7 @@ impl CpuChip { // For operations that require reading from memory (not registers), we need to read the // value into the memory columns. builder.eval_memory_access( - shard, + local.shard, local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::Memory as u32), memory_columns.addr_aligned, &memory_columns.memory_access, diff --git a/crates/core/machine/src/cpu/air/mod.rs b/crates/core/machine/src/cpu/air/mod.rs index 6d2c19b4ad..7badd5fe60 100644 --- a/crates/core/machine/src/cpu/air/mod.rs +++ b/crates/core/machine/src/cpu/air/mod.rs @@ -37,12 +37,6 @@ where let local: &CpuCols = (*local).borrow(); let next: &CpuCols = (*next).borrow(); - let public_values_slice: [AB::PublicVar; SP1_PROOF_NUM_PV_ELTS] = - core::array::from_fn(|i| builder.public_values()[i]); - let public_values: &PublicValues, AB::PublicVar> = - public_values_slice.as_slice().borrow(); - let shard: AB::Expr = public_values.execution_shard.into(); - // Program constraints. builder.send_program(local.pc, local.instruction, local.selectors, local.is_real); @@ -52,15 +46,10 @@ where let is_alu_instruction: AB::Expr = self.is_alu_instruction::(&local.selectors); // Register constraints. - self.eval_registers::(builder, local, is_branch_instruction.clone(), shard.clone()); + self.eval_registers::(builder, local, is_branch_instruction.clone()); // Memory instructions. - self.eval_memory_address_and_access::( - builder, - local, - is_memory_instruction.clone(), - shard.clone(), - ); + self.eval_memory_address_and_access::(builder, local, is_memory_instruction.clone()); self.eval_memory_load::(builder, local); self.eval_memory_store::(builder, local); @@ -86,9 +75,14 @@ where self.eval_auipc(builder, local); // ECALL instruction. - self.eval_ecall(builder, local, shard.clone()); + self.eval_ecall(builder, local); // COMMIT/COMMIT_DEFERRED_PROOFS ecall instruction. + let public_values_slice: [AB::PublicVar; SP1_PROOF_NUM_PV_ELTS] = + core::array::from_fn(|i| builder.public_values()[i]); + let public_values: &PublicValues, AB::PublicVar> = + public_values_slice.as_slice().borrow(); + let shard: AB::Expr = public_values.execution_shard.into(); self.eval_commit( builder, local, diff --git a/crates/core/machine/src/cpu/air/register.rs b/crates/core/machine/src/cpu/air/register.rs index 358a1c413c..7be28c6099 100644 --- a/crates/core/machine/src/cpu/air/register.rs +++ b/crates/core/machine/src/cpu/air/register.rs @@ -15,7 +15,6 @@ impl CpuChip { builder: &mut AB, local: &CpuCols, is_branch_instruction: AB::Expr, - shard: AB::Expr, ) { // Load immediates into b and c, if the immediate flags are on. builder @@ -27,7 +26,7 @@ impl CpuChip { // If they are not immediates, read `b` and `c` from memory. builder.eval_memory_access( - shard.clone(), + local.shard, local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::B as u32), local.instruction.op_b[0], &local.op_b_access, @@ -35,7 +34,7 @@ impl CpuChip { ); builder.eval_memory_access( - shard.clone(), + local.shard, local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::C as u32), local.instruction.op_c[0], &local.op_c_access, @@ -48,7 +47,7 @@ impl CpuChip { // Write the `a` or the result to the first register described in the instruction unless // we are performing a branch or a store. builder.eval_memory_access( - shard.clone(), + local.shard, local.clk + AB::F::from_canonical_u32(MemoryAccessPosition::A as u32), local.instruction.op_a[0], &local.op_a_access, diff --git a/crates/core/machine/src/cpu/columns/mod.rs b/crates/core/machine/src/cpu/columns/mod.rs index ccbfa29838..7a32b03db5 100644 --- a/crates/core/machine/src/cpu/columns/mod.rs +++ b/crates/core/machine/src/cpu/columns/mod.rs @@ -31,6 +31,9 @@ pub const CPU_COL_MAP: CpuCols = make_col_map(); #[derive(AlignedBorrow, Default, Debug, Clone, Copy)] #[repr(C)] pub struct CpuCols { + /// The current shard. + pub shard: T, + pub nonce: T, /// The clock cycle value. This should be within 24 bits. diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index 43b58d008a..ace1bd8d6b 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -42,7 +42,6 @@ impl MachineAir for CpuChip { n_real_rows.next_power_of_two() }; let mut values = zeroed_f_vec(padded_nb_rows * NUM_CPU_COLS); - let shard = input.public_values.execution_shard; let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); values.chunks_mut(chunk_size * NUM_CPU_COLS).enumerate().par_bridge().for_each( @@ -63,7 +62,7 @@ impl MachineAir for CpuChip { &input.nonce_lookup, cols, &mut byte_lookup_events, - shard, + input.public_values.execution_shard, instruction, ); } @@ -207,6 +206,7 @@ impl CpuChip { blu_events: &mut impl ByteRecord, shard: u32, ) { + cols.shard = F::from_canonical_u32(shard); cols.clk = F::from_canonical_u32(event.clk); let clk_16bit_limb = (event.clk & 0xffff) as u16; diff --git a/crates/test-artifacts/programs/Cargo.lock b/crates/test-artifacts/programs/Cargo.lock index b404318c5a..41a8d7d7ee 100644 --- a/crates/test-artifacts/programs/Cargo.lock +++ b/crates/test-artifacts/programs/Cargo.lock @@ -1122,7 +1122,6 @@ dependencies = [ [[package]] name = "p3-air" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-matrix", @@ -1131,7 +1130,6 @@ dependencies = [ [[package]] name = "p3-baby-bear" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "num-bigint", "p3-field", @@ -1145,7 +1143,6 @@ dependencies = [ [[package]] name = "p3-challenger" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -1158,7 +1155,6 @@ dependencies = [ [[package]] name = "p3-commit" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -1171,7 +1167,6 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-matrix", @@ -1183,7 +1178,6 @@ dependencies = [ [[package]] name = "p3-field" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "num-bigint", @@ -1196,7 +1190,6 @@ dependencies = [ [[package]] name = "p3-fri" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -1214,7 +1207,6 @@ dependencies = [ [[package]] name = "p3-interpolation" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-matrix", @@ -1224,7 +1216,6 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-field", @@ -1238,7 +1229,6 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "rayon", ] @@ -1246,7 +1236,6 @@ dependencies = [ [[package]] name = "p3-mds" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-dft", @@ -1260,7 +1249,6 @@ dependencies = [ [[package]] name = "p3-merkle-tree" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -1276,7 +1264,6 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "gcd", "p3-field", @@ -1289,7 +1276,6 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-field", @@ -1299,7 +1285,6 @@ dependencies = [ [[package]] name = "p3-uni-stark" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-air", @@ -1317,7 +1302,6 @@ dependencies = [ [[package]] name = "p3-util" version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "serde", ] From 617d96262103bbdf8e776f0b3591c95e2aeda1fd Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Fri, 22 Nov 2024 10:57:24 -0800 Subject: [PATCH 13/18] fix --- crates/core/machine/src/cpu/air/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/core/machine/src/cpu/air/mod.rs b/crates/core/machine/src/cpu/air/mod.rs index 7badd5fe60..bb5eba9af9 100644 --- a/crates/core/machine/src/cpu/air/mod.rs +++ b/crates/core/machine/src/cpu/air/mod.rs @@ -82,7 +82,6 @@ where core::array::from_fn(|i| builder.public_values()[i]); let public_values: &PublicValues, AB::PublicVar> = public_values_slice.as_slice().borrow(); - let shard: AB::Expr = public_values.execution_shard.into(); self.eval_commit( builder, local, @@ -94,7 +93,7 @@ where self.eval_halt_unimpl(builder, local, next, public_values); // Check that the shard and clk is updated correctly. - self.eval_shard_clk(builder, local, next, shard.clone()); + self.eval_shard_clk(builder, local, next); // Check that the pc is updated correctly. self.eval_pc(builder, local, next, is_branch_instruction.clone()); @@ -251,12 +250,14 @@ impl CpuChip { builder: &mut AB, local: &CpuCols, next: &CpuCols, - shard: AB::Expr, ) { + // Verify that all shard values are the same. + builder.when_transition().when(next.is_real).assert_eq(local.shard, next.shard); + // Verify that the shard value is within 16 bits. builder.send_byte( AB::Expr::from_canonical_u8(ByteOpcode::U16Range as u8), - shard, + local.shard, AB::Expr::zero(), AB::Expr::zero(), local.is_real, @@ -334,6 +335,9 @@ impl CpuChip { next: &CpuCols, public_values: &PublicValues, AB::PublicVar>, ) { + // Verify the public value's shard. + builder.when(local.is_real).assert_eq(public_values.execution_shard, local.shard); + // Verify the public value's start pc. builder.when_first_row().assert_eq(public_values.start_pc, local.pc); From 84deca289b4788543f01e32a0ec5d6a550dbfc2f Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Fri, 22 Nov 2024 11:12:09 -0800 Subject: [PATCH 14/18] fix --- crates/core/machine/src/alu/add_sub/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index 60bcd65262..c09719277d 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -210,7 +210,19 @@ where local.operand_1, local.operand_2, local.nonce, - is_real.clone(), + local.is_add, + ); + + // For sub, `operand_1` is `a`, `add_operation.value` is `b`, and `operand_2` is `c`. + builder.receive_instruction( + local.pc, + local.pc + AB::Expr::from_canonical_u32(DEFAULT_PC_INC), + opcode, + local.operand_1, + local.add_operation.value, + local.operand_2, + local.nonce, + local.is_sub, ); builder.assert_bool(local.is_add); From 8681a5629146eb2de53c214635ef3de172386b64 Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Fri, 22 Nov 2024 11:17:14 -0800 Subject: [PATCH 15/18] revert p3 dependencies --- Cargo.lock | 18 +++++ Cargo.toml | 80 +++++++++++------------ crates/test-artifacts/programs/Cargo.lock | 16 +++++ 3 files changed, 74 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7dda7533e..eb43930c6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3799,6 +3799,7 @@ dependencies = [ [[package]] name = "p3-air" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "p3-field", "p3-matrix", @@ -3807,6 +3808,7 @@ dependencies = [ [[package]] name = "p3-baby-bear" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "num-bigint 0.4.6", "p3-field", @@ -3820,6 +3822,7 @@ dependencies = [ [[package]] name = "p3-bn254-fr" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "ff 0.13.0", "num-bigint 0.4.6", @@ -3833,6 +3836,7 @@ dependencies = [ [[package]] name = "p3-challenger" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -3845,6 +3849,7 @@ dependencies = [ [[package]] name = "p3-commit" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -3857,6 +3862,7 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "p3-field", "p3-matrix", @@ -3868,6 +3874,7 @@ dependencies = [ [[package]] name = "p3-field" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "num-bigint 0.4.6", @@ -3880,6 +3887,7 @@ dependencies = [ [[package]] name = "p3-fri" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -3897,6 +3905,7 @@ dependencies = [ [[package]] name = "p3-interpolation" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "p3-field", "p3-matrix", @@ -3906,6 +3915,7 @@ dependencies = [ [[package]] name = "p3-keccak-air" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "p3-air", "p3-field", @@ -3918,6 +3928,7 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-field", @@ -3931,6 +3942,7 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "rayon", ] @@ -3938,6 +3950,7 @@ dependencies = [ [[package]] name = "p3-mds" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-dft", @@ -3951,6 +3964,7 @@ dependencies = [ [[package]] name = "p3-merkle-tree" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -3966,6 +3980,7 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "gcd", "p3-field", @@ -3978,6 +3993,7 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-field", @@ -3987,6 +4003,7 @@ dependencies = [ [[package]] name = "p3-uni-stark" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-air", @@ -4004,6 +4021,7 @@ dependencies = [ [[package]] name = "p3-util" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 226aee3fdc..f48c993410 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,47 +100,47 @@ test-artifacts = { path = "crates/test-artifacts", version = "3.0.0" } # For local development. -# p3-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-field = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-commit = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-matrix = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-util = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-challenger = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-dft = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-fri = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-keccak = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-keccak-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-blake3 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-mds = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-symmetric = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-uni-stark = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -# p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-field = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-commit = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-matrix = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-util = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-challenger = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-dft = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-fri = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-keccak = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-keccak-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-blake3 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-mds = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-symmetric = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-uni-stark = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } -p3-air = { path = "../Plonky3/air" } -p3-field = { path = "../Plonky3/field" } -p3-commit = { path = "../Plonky3/commit" } -p3-matrix = { path = "../Plonky3/matrix" } -p3-baby-bear = { path = "../Plonky3/baby-bear" } -p3-util = { path = "../Plonky3/util" } -p3-challenger = { path = "../Plonky3/challenger" } -p3-dft = { path = "../Plonky3/dft" } -p3-fri = { path = "../Plonky3/fri" } -p3-goldilocks = { path = "../Plonky3/goldilocks" } -p3-keccak = { path = "../Plonky3/keccak" } -p3-keccak-air = { path = "../Plonky3/keccak-air" } -p3-blake3 = { path = "../Plonky3/blake3" } -p3-mds = { path = "../Plonky3/mds" } -p3-merkle-tree = { path = "../Plonky3/merkle-tree" } -p3-poseidon2 = { path = "../Plonky3/poseidon2" } -p3-symmetric = { path = "../Plonky3/symmetric" } -p3-uni-stark = { path = "../Plonky3/uni-stark" } -p3-maybe-rayon = { path = "../Plonky3/maybe-rayon" } -p3-bn254-fr = { path = "../Plonky3/bn254-fr" } +# p3-air = { path = "../Plonky3/air" } +# p3-field = { path = "../Plonky3/field" } +# p3-commit = { path = "../Plonky3/commit" } +# p3-matrix = { path = "../Plonky3/matrix" } +# p3-baby-bear = { path = "../Plonky3/baby-bear" } +# p3-util = { path = "../Plonky3/util" } +# p3-challenger = { path = "../Plonky3/challenger" } +# p3-dft = { path = "../Plonky3/dft" } +# p3-fri = { path = "../Plonky3/fri" } +# p3-goldilocks = { path = "../Plonky3/goldilocks" } +# p3-keccak = { path = "../Plonky3/keccak" } +# p3-keccak-air = { path = "../Plonky3/keccak-air" } +# p3-blake3 = { path = "../Plonky3/blake3" } +# p3-mds = { path = "../Plonky3/mds" } +# p3-merkle-tree = { path = "../Plonky3/merkle-tree" } +# p3-poseidon2 = { path = "../Plonky3/poseidon2" } +# p3-symmetric = { path = "../Plonky3/symmetric" } +# p3-uni-stark = { path = "../Plonky3/uni-stark" } +# p3-maybe-rayon = { path = "../Plonky3/maybe-rayon" } +# p3-bn254-fr = { path = "../Plonky3/bn254-fr" } # misc hashbrown = "0.14.5" diff --git a/crates/test-artifacts/programs/Cargo.lock b/crates/test-artifacts/programs/Cargo.lock index 41a8d7d7ee..427eae2494 100644 --- a/crates/test-artifacts/programs/Cargo.lock +++ b/crates/test-artifacts/programs/Cargo.lock @@ -1122,6 +1122,7 @@ dependencies = [ [[package]] name = "p3-air" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "p3-field", "p3-matrix", @@ -1130,6 +1131,7 @@ dependencies = [ [[package]] name = "p3-baby-bear" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "num-bigint", "p3-field", @@ -1143,6 +1145,7 @@ dependencies = [ [[package]] name = "p3-challenger" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -1155,6 +1158,7 @@ dependencies = [ [[package]] name = "p3-commit" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -1167,6 +1171,7 @@ dependencies = [ [[package]] name = "p3-dft" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "p3-field", "p3-matrix", @@ -1178,6 +1183,7 @@ dependencies = [ [[package]] name = "p3-field" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "num-bigint", @@ -1190,6 +1196,7 @@ dependencies = [ [[package]] name = "p3-fri" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -1207,6 +1214,7 @@ dependencies = [ [[package]] name = "p3-interpolation" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "p3-field", "p3-matrix", @@ -1216,6 +1224,7 @@ dependencies = [ [[package]] name = "p3-matrix" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-field", @@ -1229,6 +1238,7 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "rayon", ] @@ -1236,6 +1246,7 @@ dependencies = [ [[package]] name = "p3-mds" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-dft", @@ -1249,6 +1260,7 @@ dependencies = [ [[package]] name = "p3-merkle-tree" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -1264,6 +1276,7 @@ dependencies = [ [[package]] name = "p3-poseidon2" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "gcd", "p3-field", @@ -1276,6 +1289,7 @@ dependencies = [ [[package]] name = "p3-symmetric" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-field", @@ -1285,6 +1299,7 @@ dependencies = [ [[package]] name = "p3-uni-stark" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "itertools 0.12.1", "p3-air", @@ -1302,6 +1317,7 @@ dependencies = [ [[package]] name = "p3-util" version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#bba88386261c3eaceb7f922b99bea56c1d6c6c58" dependencies = [ "serde", ] From 5d6f56cb029ab16bd2856eecb327d4224f59331e Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Fri, 22 Nov 2024 11:56:12 -0800 Subject: [PATCH 16/18] finishing touches --- crates/core/executor/src/executor.rs | 2 +- crates/core/executor/src/record.rs | 1 - crates/core/machine/src/alu/add_sub/mod.rs | 7 ++++--- crates/core/machine/src/cpu/air/mod.rs | 7 ++++--- crates/core/machine/src/cpu/trace.rs | 5 ++++- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index da2746cf02..e9549aeb19 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -666,7 +666,7 @@ impl<'a> Executor<'a> { emit_cpu_dependencies(self, self.record.cpu_events.len() - 1); } - /// Emit an ALU event. + /// Emit an instruction event. fn emit_instruction(&mut self, opcode: Opcode, a: u32, b: u32, c: u32, lookup_id: LookupId) { let event = InstrEvent { lookup_id, diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index a108d7e599..e0df1d3194 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -160,7 +160,6 @@ impl ExecutionRecord { } } - /// Take out events from the [`ExecutionRecord`] that should be deferred to a separate shard. /// Take out events from the [`ExecutionRecord`] that should be deferred to a separate shard. /// /// Note: we usually defer events that would increase the recursion cost significantly if diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index c09719277d..6ccbc15e1f 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -182,9 +182,10 @@ where let is_real = local.is_add + local.is_sub; // Calculate the opcode. - // local.is_add == 1 -> opcode == 0 - // local.is_sub == 1 -> opcode == 1 - // We also constrain the local.is_add and local.is_sub are bool and never both true. + // For add instruction, we should set Opcode == 0. + // For sub instruction, we should set Opcode == 1. + // We can simply set opcode = local.is_sub since local.is_add and local.is_sub are + // contraints to be bool and mutually exclusive. let opcode = local.is_sub; // Constrain the incrementing nonce. diff --git a/crates/core/machine/src/cpu/air/mod.rs b/crates/core/machine/src/cpu/air/mod.rs index bb5eba9af9..e236a30d78 100644 --- a/crates/core/machine/src/cpu/air/mod.rs +++ b/crates/core/machine/src/cpu/air/mod.rs @@ -307,12 +307,13 @@ impl CpuChip { - (is_branch_instruction + local.selectors.is_jal + local.selectors.is_jalr + + local.selectors.is_alu + is_halt), ); - // Verify that the pc increments by 4 for all instructions except branch, jump and halt - // instructions. The other case is handled by eval_jump, eval_branch and eval_ecall - // (for halt). + // Verify that the pc increments by 4 for all instructions except branch, jump, halt, and + // ALU instructions. The other case is handled by eval_jump, eval_branch, eval_ecall + // (for halt), and the ALU specific tables. builder .when_transition() .when(next.is_real) diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index ace1bd8d6b..9fbd1da6dd 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -191,7 +191,10 @@ impl CpuChip { let is_halt = self.populate_ecall(cols, event, nonce_lookup); cols.is_sequential_instr = F::from_bool( - !instruction.is_branch_instruction() && !instruction.is_jump_instruction() && !is_halt, + !instruction.is_branch_instruction() + && !instruction.is_jump_instruction() + && !is_halt + && !instruction.is_alu_instruction(), ); // Assert that the instruction is not a no-op. From a2268a524c05e6361d333eac040dfe827b7a4a37 Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Fri, 22 Nov 2024 11:58:16 -0800 Subject: [PATCH 17/18] Update crates/core/machine/src/alu/add_sub/mod.rs Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- crates/core/machine/src/alu/add_sub/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index 6ccbc15e1f..a6e4a2bfc0 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -185,7 +185,7 @@ where // For add instruction, we should set Opcode == 0. // For sub instruction, we should set Opcode == 1. // We can simply set opcode = local.is_sub since local.is_add and local.is_sub are - // contraints to be bool and mutually exclusive. + // constraints to be bool and mutually exclusive. let opcode = local.is_sub; // Constrain the incrementing nonce. From cc2b9dbf40f8e161b36dc2f84315c3579b4a202a Mon Sep 17 00:00:00 2001 From: Kevin Jue Date: Fri, 22 Nov 2024 12:26:11 -0800 Subject: [PATCH 18/18] more intuitive code --- crates/core/machine/src/alu/add_sub/mod.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index 6ccbc15e1f..fc05d24326 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -180,13 +180,12 @@ where let next: &AddSubCols = (*next).borrow(); let is_real = local.is_add + local.is_sub; + builder.assert_bool(local.is_add); + builder.assert_bool(local.is_sub); + builder.assert_bool(is_real.clone()); - // Calculate the opcode. - // For add instruction, we should set Opcode == 0. - // For sub instruction, we should set Opcode == 1. - // We can simply set opcode = local.is_sub since local.is_add and local.is_sub are - // contraints to be bool and mutually exclusive. - let opcode = local.is_sub; + let opcode = AB::Expr::from_f(Opcode::ADD.as_field()) * local.is_add + + AB::Expr::from_f(Opcode::SUB.as_field()) * local.is_sub; // Constrain the incrementing nonce. builder.when_first_row().assert_zero(local.nonce); @@ -206,7 +205,7 @@ where builder.receive_instruction( local.pc, local.pc + AB::Expr::from_canonical_u32(DEFAULT_PC_INC), - opcode, + opcode.clone(), local.add_operation.value, local.operand_1, local.operand_2, @@ -225,10 +224,6 @@ where local.nonce, local.is_sub, ); - - builder.assert_bool(local.is_add); - builder.assert_bool(local.is_sub); - builder.assert_bool(is_real); } }