From a138e211b5210fb9f7d8902e579d6583d7829742 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Sun, 27 Oct 2024 22:47:14 +0000 Subject: [PATCH 01/22] enable continuations and mem on main, reduce intermediates stage 3 --- pil/zisk.pil | 12 +-- state-machines/main/pil/main.pil | 157 ++++++++++++++++++------------- state-machines/mem/pil/mem.pil | 27 +++--- 3 files changed, 110 insertions(+), 86 deletions(-) diff --git a/pil/zisk.pil b/pil/zisk.pil index fc90d2cc..b8199c94 100644 --- a/pil/zisk.pil +++ b/pil/zisk.pil @@ -6,7 +6,7 @@ require "binary/pil/binary.pil" require "binary/pil/binary_table.pil" require "binary/pil/binary_extension.pil" require "binary/pil/binary_extension_table.pil" -// require "mem/pil/mem.pil" +require "mem/pil/mem.pil" const int OPERATION_BUS_ID = 5000; airgroup Main { @@ -14,14 +14,12 @@ airgroup Main { } airgroup Rom { - Rom(N: 2**16) alias RomS; - Rom(N: 2**22) alias RomM; - Rom(N: 2**26) alias RomL; + Rom(N: 2**23); } -// airgroup Mem { -// Mem(N: 2**21, RC: 2); -// } +airgroup Mem { + Mem(N: 2**21, RC: 2); +} airgroup Binary { Binary(N: 2**21, operation_bus_id: OPERATION_BUS_ID); diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index e6b06b2c..8e8dfcda 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -5,46 +5,49 @@ const int BOOT_ADDR = 0x1000; airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int operation_bus_id, int MAIN_CONTINUATION_ID = 1000) { col fixed SEGMENT_L1 = [1,0...]; - col fixed SEGMENT_STEP = [0..(N-1)]; + col fixed SEGMENT_STEP = [0,0..(N-2)]; const expr SEGMENT_LAST = SEGMENT_L1'; - airval main_first_segment; airval main_last_segment; airval main_segment; - main_first_segment * (1 - main_first_segment) === 0; + // continuations + // + // first row of each segment is its initial state and must match with last + // row of previous segment. This first row it's a valid rom line, same that + // last of previous segment. This way to do continuations implies that: + // + // - each segment only has N-1 valid rows. + // + // - it's possible reference previous row, but no next row. + // + // - the first two rows has same STEP 0. + // + // - global bus constraint with initial state of main (as initial PC) + // [segment:0, is_last_segment: 0, pc: INITIAL_PC, a, b, c, flag] + // + // - global bus constraint with final state of main (as expected PC) + // [segment:0, is_last_segment: 1, pc: FINAL_PC, a, b, c, flag] + // + // - is_last_segment it's used for security to avoid used to do more cycles of main. + // + // - registers a,b could be removed from main continuations. + // + main_last_segment * (1 - main_last_segment) === 0; - main_first_segment * main_segment === 0; - const expr L1 = SEGMENT_L1 * main_first_segment; - const expr LAST = SEGMENT_LAST * main_last_segment; - const expr STEP = main_segment * N + SEGMENT_STEP; + const expr STEP = main_segment * (N - 1) + SEGMENT_STEP; // Registers col witness a[RC]; col witness b[RC]; col witness c[RC]; - col witness last_c[RC]; col witness flag; col witness pc; // Program counter - // continuations - - // continuations_setup(MAIN_CONTINUATION_ID, main_segment, main_end); - - // Instruction - - // a_src_step - // a_src_mem - // a_src_imm - // a_src_sp - // b_src_mem - // b_src_imm - // b_src_ind - // Source A col witness a_src_imm; // Selector @@ -113,39 +116,57 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope sel_mem_b = b_src_mem + b_src_ind; if (stack_enabled) { - addr[0] = a_offset_imm0 + a_use_sp_imm1 * sp; - addr[1] = b_offset_imm0 + b_src_ind * (a[0] + 2**32 * a[1]) + b_use_sp_imm1 * sp; - addr[2] = store_offset + store_ind * a[0] + store_use_sp * sp; + col witness air.addr0; + col witness air.addr1; + col witness air.addr2; + + addr0 === a_offset_imm0 + a_use_sp_imm1 * sp; + addr1 === b_offset_imm0 + b_src_ind * (a[0] + 2**32 * a[1]) + b_use_sp_imm1 * sp; + addr2 === store_offset + store_ind * a[0] + store_use_sp * sp; } else { - addr[0] = a_offset_imm0; - addr[1] = b_offset_imm0 + b_src_ind * (a[0] + 2**32 * a[1]); - addr[2] = store_offset + store_ind * a[0]; + const expr air.addr0; + col witness air.addr1; + col witness air.addr2; + addr0 = a_offset_imm0; + addr1 === b_offset_imm0 + b_src_ind * (a[0] + 2**32 * a[1]); + addr2 === store_offset + store_ind * a[0]; } + // Mem.load - // mem_load(sel: a_src_mem, - // step: addr_step, - // addr: addr[0], - // value: a); + mem_load(sel: a_src_mem, + step: addr_step, + addr: addr0, + value: a); // Mem.load - // mem_load(sel: sel_mem_b, - // step: addr_step + 1, - // bytes: ind_width, - // addr: addr[1], - // value: b); + mem_load(sel: sel_mem_b, + step: addr_step + 1, + bytes: ind_width, + addr: addr1, + value: b); + + col witness store_value[2]; + store_value[0] === store_ra*(pc + jmp_offset2 - c[0]) + c[0]; + store_value[1] === (1 - store_ra) * c[1]; // Mem.store - // mem_store(sel: store_mem + store_ind, - // step: addr_step + 2, - // bytes: ind_width, - // addr: addr[2], - // value: [store_ra*(pc + jmp_offset2 - c[0]) + c[0], (1 - store_ra) * c[1]]); + mem_store(sel: store_mem + store_ind, + step: addr_step + 2, + bytes: ind_width, + addr: addr2, + value: store_value); // Operation.assume => how organize software - col witness operation_bus_enabled; - lookup_assumes(operation_bus_id, [STEP, op, a[0], (1 - m32) * a[1], b[0], (1 - m32) * b[1], ...c, flag], sel: is_external_op * operation_bus_enabled); + col witness __debug_operation_bus_enabled; + col witness hi_a; + col witness hi_b; + + hi_a === a[1] * (1 - m32); + hi_b === b[1] * (1 - m32); + lookup_assumes(operation_bus_id, [STEP, op, a[0], hi_a, b[0], hi_b, ...c, flag], sel: is_external_op * __debug_operation_bus_enabled, name: PIOP_NAME_ISOLATED); + // lookup_assumes(operation_bus_id, [STEP, op, a[0], (1 - m32) * a[1], b[0], (1 - m32) * b[1], ...c, flag], sel: is_external_op * (1 - SEGMENT_L1), name: PIOP_NAME_ISOLATED); const expr a_src_c; const expr b_src_c; @@ -174,8 +195,8 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope a_src_sp * (a[index] - (index == 0 ? sp: 0 )) === 0; } a_src_step * (a[index] - (index == 0 ? STEP : 0)) === 0; - a_src_c * (a[index] - last_c[index]) === 0; - b_src_c * (b[index] - last_c[index]) === 0; + a_src_c * (a[index] - 'c[index]) === 0; + b_src_c * (b[index] - 'c[index]) === 0; a_src_imm * (a[index] - a_imm[index]) === 0; b_src_imm * (b[index] - b_imm[index]) === 0; @@ -197,34 +218,36 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope (1 - is_external_op) * op * (flag) === 0; - // continuations - // continuations_transition(pc, set_pc * (c[0] + jmp_offset1 - new_pc) + new_pc); - // continuations_transition(last_c[0], c[0]); // last_c[0]' = c[0]; - // continuations_transition(last_c[1], c[1]); // last_c[1]' = c[1]; + flag * set_pc === 0; + const expr next_pc = set_pc * (c[0] + jmp_offset1) + (1 - set_pc) * (pc + jmp_offset2) + flag * (jmp_offset1 - jmp_offset2); + (1 - SEGMENT_L1') * (pc - 'next_pc) === 0; - // const expr new_pc = pc + flag*(jmp_offset1 - jmp_offset2) + jmp_offset2; - // const expr next_pc = set_pc * (c[0] + jmp_offset1 - new_pc) + new_pc + end * L1' * (0x8000_0000 - (pc + jmp_offset1)); + // + end * L1' * (0x8000_0000 - (pc + jmp_offset1)); - // (1 - SEGMENT_LAST) * (pc' - next_pc) === 0; - // (1 - SEGMENT_LAST) * (last_c[0]' - c[0]) === 0; - // (1 - SEGMENT_LAST) * (last_c[1]' - c[1]) === 0; + const expr is_last_continuation = SEGMENT_LAST * main_last_segment; + const expr specific_registers[stack_enabled ? 2:1]; + specific_registers[0] = pc; if (stack_enabled) { - // sp' === set_sp*(c - sp) + sp + inc_sp + end * L1'*(0 - sp); // assume that when end=1 then set_sp=0 and inc_sp=0 - // sp * L1 === 0; // Force sp == 0 at the begining - // continuations_transition(sp, set_sp*(c - sp) + sp + inc_sp); - const expr next_sp = set_sp * (c[0] - sp) + sp + inc_sp;; - (1 - SEGMENT_LAST) * (sp' - next_sp) === 0; - // permutation_proves(MAIN_CONTINUATION_ID, sel: SEGMENT_LAST, cols: [next_pc, ...c, next_sp]); - // permutation_assumes(MAIN_CONTINUATION_ID, sel: SEGMENT_L1, cols: [pc, ...last_c, sp]); - } else { - // permutation_proves(MAIN_CONTINUATION_ID, sel: SEGMENT_LAST, cols: [next_pc, ...c]); - // permutation_assumes(MAIN_CONTINUATION_ID, sel: SEGMENT_L1, cols: [pc, ...last_c]); + const expr next_sp = set_sp * (c[0] - sp) + sp + inc_sp; + + (1 - SEGMENT_LAST) * (sp - 'next_sp) === 0; + specific_registers[1] = sp; } - // pc' === set_pc * ( c[0] + jmp_offset1 - new_pc) + new_pc + end * L1'*(0x8000_0000 - (pc + jmp_offset1 )); // Assume that when end=1 then set_pc = 0 and flag = 0 + // main_last_segment = 0 => row = 0 => bus_main_segment = K (assumes) + // row = N-1 => bus_main_segment = K + 1 (proves) + // + // main_last_segment = 1 => row = 0 => bus_main_segment = J (assumes) + // row = N-1 => bus_main_segment = 0 (proves) + // + + const expr bus_main_segment = main_segment - SEGMENT_LAST * (main_segment * main_last_segment + 1 - main_last_segment); + permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, ...specific_registers, ...a, ...b, ...c, flag], + sel: SEGMENT_LAST - SEGMENT_L1, name: PIOP_NAME_ISOLATED, bus_type: PIOP_BUS_SUM); - L1 * (pc - BOOT_ADDR) === 0; // when end of program jump to this address + // BOOT_ADDR es called from + // L1 * (pc - BOOT_ADDR) === 0; // when end of program jump to this address flag * (1 - flag) === 0; diff --git a/state-machines/mem/pil/mem.pil b/state-machines/mem/pil/mem.pil index 50bd652e..143e552c 100644 --- a/state-machines/mem/pil/mem.pil +++ b/state-machines/mem/pil/mem.pil @@ -14,8 +14,8 @@ airtemplate Mem (int N = 2**21, int RC = 2, int id = MEMORY_ID, int MAX_STEP = 2 col fixed SEGMENT_L1 = [1,0...]; const expr SEGMENT_LAST = SEGMENT_L1'; - airval mem_segment; - airval mem_last_segment; + airval mem_segment; + airval mem_last_segment; col witness addr; // n-byte address, real address = addr * MEM_BYTES col witness step; @@ -35,8 +35,11 @@ airtemplate Mem (int N = 2**21, int RC = 2, int id = MEMORY_ID, int MAX_STEP = 2 addr_changes * (1 - addr_changes) === 0; + col witness range_to_check; + range_to_check === addr_changes * (addr - 'addr - step + 'step) + step - 'step; + // check increment of memory - range_check(sel: (1 - SEGMENT_L1), colu: addr_changes * (addr - 'addr - step + 'step) + step - 'step, min: 1, max: MEMORY_MAX_DIFF); + range_check(sel: (1 - SEGMENT_L1), colu:range_to_check, min: 1, max: MEMORY_MAX_DIFF); // PADDING: At end of memory fill with same addr, incrementing step, same value, sel = 0, rd = 1, wr = 0 // setting mem_last_segment = 1 @@ -56,16 +59,16 @@ airtemplate Mem (int N = 2**21, int RC = 2, int id = MEMORY_ID, int MAX_STEP = 2 } // CONTINUATIONS - // + // // segments: S, S+1 - // + // // CASE: last row of segment is read - // + // // S[n-1] wr = 0, sel = 1, addr, step, value => BUS.proves(MEM_CONT_ID, S+1, addr, step-1, value) // S+1[0] wr = 0, sel = 0, addr, step, value => BUS.assumes(MEM_CONT_ID, S, addr, step, value) // // CASE: last row of segment is write - // + // // S[n-1] wr = 1, sel = 1, addr, step, value => BUS.proves(MEM_CONT_ID, S+1, addr, step-1, value) // S+1[0] wr = 0, sel = 0, addr, step, value => BUS.assumes(MEM_CONT_ID, S, addr, step, value) // @@ -73,19 +76,19 @@ airtemplate Mem (int N = 2**21, int RC = 2, int id = MEMORY_ID, int MAX_STEP = 2 // on row = 0 forced by constraint that sel = 0 => wr = 0. // on S+1[0].step = S[n-1].step - 1; // - // FIRST SEGMENT: + // FIRST SEGMENT: // the BUS.proves needed by BUS.assumes of the first segment it's generated by global constraint to avoid // generate more than one cycle of memory. In this constraint we could force the initial address (to split // in two memories, one register-memory and other standard-memory). // - // LAST SEGMENT: + // LAST SEGMENT: // the last not used rows are filled with last addr and value and sel = 0 and wr = 0 incrementing steps. // last BUS.proves not it's generated to avoid generate more than one memory cycle. // permutation_proves(MEMORY_CONT_ID, [(mem_segment + 1), addr, step, ...value], sel: mem_last_segment * 'SEGMENT_L1); // last row // permutation_assumes(MEMORY_CONT_ID, [mem_segment, 0, addr, step, ...value], sel: SEGMENT_L1); // first row - permutation_proves(MEMORY_ID, cols: [wr, addr * MEM_BYTES, step, MEM_BYTES, ...value], sel: sel); + permutation_proves(MEMORY_ID, cols: [wr, addr * MEM_BYTES, step, MEM_BYTES, ...value], sel: sel, bus_type: PIOP_BUS_SUM); } // TODO: detect non default value but not called, mandatory parameter. @@ -94,7 +97,7 @@ function mem_load(int id = MEMORY_ID, expr sel = 1, expr addr, expr step, expr s error("max step_offset ${step_offset} is greater than max value ${MAX_MEM_STEP_OFFSET}"); } // adding one for first continuation - permutation_assumes(id, [MEMORY_LOAD_OP, addr, 1 + ((MAX_MEM_STEP_OFFSET + 1) * step) + step_offset, bytes, ...value], sel:sel); + permutation_assumes(id, [MEMORY_LOAD_OP, addr, 1 + ((MAX_MEM_STEP_OFFSET + 1) * step) + step_offset, bytes, ...value], sel:sel, bus_type: PIOP_BUS_SUM); } function mem_store(int id = MEMORY_ID, expr sel = 1, expr addr, expr step, expr step_offset = 0, expr bytes = 8, expr value[]) { @@ -102,5 +105,5 @@ function mem_store(int id = MEMORY_ID, expr sel = 1, expr addr, expr step, expr error("max step_offset ${step_offset} is greater than max value ${MAX_MEM_STEP_OFFSET}"); } // adding one for first continuation - permutation_assumes(id, [MEMORY_STORE_OP, addr, 1 + ((MAX_MEM_STEP_OFFSET + 1) * step), bytes, ...value], sel:sel); + permutation_assumes(id, [MEMORY_STORE_OP, addr, 1 + ((MAX_MEM_STEP_OFFSET + 1) * step), bytes, ...value], sel:sel, bus_type: PIOP_BUS_SUM); } \ No newline at end of file From 0cec4a56204f6adb59c82b527fd1c06e3afe438b Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:24:00 +0100 Subject: [PATCH 02/22] fix-sctx (#137) --- Cargo.lock | 72 +++++++++---------- state-machines/arith/src/arith.rs | 5 +- state-machines/binary/src/binary.rs | 17 +---- state-machines/binary/src/binary_basic.rs | 20 +++--- .../binary/src/binary_basic_table.rs | 23 +++--- state-machines/binary/src/binary_extension.rs | 36 ++++------ .../binary/src/binary_extension_table.rs | 25 +++---- state-machines/mem/src/mem.rs | 4 +- witness-computation/src/zisk_lib.rs | 6 +- 9 files changed, 86 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c134299d..ec4be183 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,9 +47,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -62,36 +62,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -282,9 +282,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" @@ -1322,7 +1322,7 @@ dependencies = [ [[package]] name = "pil-std-lib" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "log", "num-bigint", @@ -1340,7 +1340,7 @@ dependencies = [ [[package]] name = "pilout" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "bytes", "log", @@ -1351,9 +1351,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -1440,9 +1440,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "910d41a655dac3b764f1ade94821093d3610248694320cd072303a8eedcf221d" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", "syn", @@ -1460,7 +1460,7 @@ dependencies = [ [[package]] name = "proofman" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "colored", "env_logger", @@ -1481,7 +1481,7 @@ dependencies = [ [[package]] name = "proofman-common" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "env_logger", "log", @@ -1499,7 +1499,7 @@ dependencies = [ [[package]] name = "proofman-hints" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "p3-field", "proofman-common", @@ -1509,7 +1509,7 @@ dependencies = [ [[package]] name = "proofman-macros" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "proc-macro2", "quote", @@ -1519,7 +1519,7 @@ dependencies = [ [[package]] name = "proofman-starks-lib-c" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "log", ] @@ -1527,7 +1527,7 @@ dependencies = [ [[package]] name = "proofman-util" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "colored", "sysinfo", @@ -1724,9 +1724,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1841,9 +1841,9 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ "bitflags 2.6.0", "errno", @@ -2124,7 +2124,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stark" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "log", "p3-field", @@ -2188,9 +2188,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.82" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -2419,7 +2419,7 @@ dependencies = [ [[package]] name = "transcript" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#d9c07ae8a1fb474edbf8d63ab6dcf291347fa6ea" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" dependencies = [ "proofman-starks-lib-c", ] @@ -2615,9 +2615,9 @@ checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-streams" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", diff --git a/state-machines/arith/src/arith.rs b/state-machines/arith/src/arith.rs index 424ee84b..f26e6177 100644 --- a/state-machines/arith/src/arith.rs +++ b/state-machines/arith/src/arith.rs @@ -29,12 +29,10 @@ pub struct ArithSM { arith32_sm: Arc, arith64_sm: Arc, arith3264_sm: Arc, - - sctx: Arc, } impl ArithSM { - pub fn new(wcm: Arc>, sctx: Arc) -> Arc { + pub fn new(wcm: Arc>) -> Arc { let arith32_sm = Arith32SM::new(wcm.clone()); let arith64_sm = Arith64SM::new(wcm.clone()); let arith3264_sm = Arith3264SM::new(wcm.clone()); @@ -47,7 +45,6 @@ impl ArithSM { arith32_sm, arith64_sm, arith3264_sm, - sctx, }; let arith_sm = Arc::new(arith_sm); diff --git a/state-machines/binary/src/binary.rs b/state-machines/binary/src/binary.rs index 60f991d7..57bb7e6a 100644 --- a/state-machines/binary/src/binary.rs +++ b/state-machines/binary/src/binary.rs @@ -7,7 +7,6 @@ use crate::{BinaryBasicSM, BinaryBasicTableSM, BinaryExtensionSM, BinaryExtensio use p3_field::PrimeField; use pil_std_lib::Std; use proofman::{WitnessComponent, WitnessManager}; -use proofman_common::SetupCtx; use rayon::Scope; use sm_common::{OpResult, Provable, ThreadController}; use zisk_core::ZiskRequiredOperation; @@ -34,21 +33,14 @@ pub struct BinarySM { // Secondary State machines binary_basic_sm: Arc>, binary_extension_sm: Arc>, - - sctx: Arc, } impl BinarySM { - pub fn new(wcm: Arc>, std: Arc>, sctx: Arc) -> Arc { - let binary_basic_table_sm = BinaryBasicTableSM::new( - wcm.clone(), - sctx.clone(), - BINARY_TABLE_AIRGROUP_ID, - BINARY_TABLE_AIR_IDS, - ); + pub fn new(wcm: Arc>, std: Arc>) -> Arc { + let binary_basic_table_sm = + BinaryBasicTableSM::new(wcm.clone(), BINARY_TABLE_AIRGROUP_ID, BINARY_TABLE_AIR_IDS); let binary_basic_sm = BinaryBasicSM::new( wcm.clone(), - sctx.clone(), binary_basic_table_sm, BINARY_AIRGROUP_ID, BINARY_AIR_IDS, @@ -56,14 +48,12 @@ impl BinarySM { let binary_extension_table_sm = BinaryExtensionTableSM::new( wcm.clone(), - sctx.clone(), BINARY_EXTENSION_TABLE_AIRGROUP_ID, BINARY_EXTENSION_TABLE_AIR_IDS, ); let binary_extension_sm = BinaryExtensionSM::new( wcm.clone(), std, - sctx.clone(), binary_extension_table_sm, BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS, @@ -76,7 +66,6 @@ impl BinarySM { inputs_extension: Mutex::new(Vec::new()), binary_basic_sm, binary_extension_sm, - sctx, }; let binary_sm = Arc::new(binary_sm); diff --git a/state-machines/binary/src/binary_basic.rs b/state-machines/binary/src/binary_basic.rs index 1058b445..b1d368ac 100644 --- a/state-machines/binary/src/binary_basic.rs +++ b/state-machines/binary/src/binary_basic.rs @@ -6,7 +6,7 @@ use std::sync::{ use log::info; use p3_field::Field; use proofman::{WitnessComponent, WitnessManager}; -use proofman_common::{AirInstance, SetupCtx}; +use proofman_common::AirInstance; use proofman_util::{timer_start_trace, timer_stop_and_log_trace}; use rayon::Scope; use sm_common::{create_prover_buffer, OpResult, Provable, ThreadController}; @@ -30,8 +30,6 @@ pub struct BinaryBasicSM { // Secondary State machines binary_basic_table_sm: Arc>, - - sctx: Arc, } #[derive(Debug)] @@ -44,14 +42,12 @@ impl BinaryBasicSM { pub fn new( wcm: Arc>, - sctx: Arc, binary_basic_table_sm: Arc>, airgroup_id: usize, air_ids: &[usize], ) -> Arc { let binary_basic = Self { wcm: wcm.clone(), - sctx, registered_predecessors: AtomicU32::new(0), threads_controller: Arc::new(ThreadController::new()), inputs: Mutex::new(Vec::new()), @@ -676,9 +672,10 @@ impl BinaryBasicSM { scope: &Scope, ) { timer_start_trace!(BINARY_TRACE); - let air = wcm.get_pctx().pilout.get_air(BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]); + let pctx = wcm.get_pctx(); + let air = pctx.pilout.get_air(BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]); let air_binary_table = - wcm.get_pctx().pilout.get_air(BINARY_TABLE_AIRGROUP_ID, BINARY_TABLE_AIR_IDS[0]); + pctx.pilout.get_air(BINARY_TABLE_AIRGROUP_ID, BINARY_TABLE_AIR_IDS[0]); assert!(operations.len() <= air.num_rows()); info!( @@ -747,7 +744,8 @@ impl Provable for BinaryBasicSM { if let Ok(mut inputs) = self.inputs.lock() { inputs.extend_from_slice(operations); - let air = self.wcm.get_pctx().pilout.get_air(BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]); + let pctx = self.wcm.get_pctx(); + let air = pctx.pilout.get_air(BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]); while inputs.len() >= air.num_rows() || (drain && !inputs.is_empty()) { let num_drained = std::cmp::min(air.num_rows(), inputs.len()); @@ -759,12 +757,12 @@ impl Provable for BinaryBasicSM { self.threads_controller.add_working_thread(); let thread_controller = self.threads_controller.clone(); - let sctx = self.sctx.clone(); + let sctx = self.wcm.get_sctx().clone(); scope.spawn(move |scope| { let (mut prover_buffer, offset) = create_prover_buffer( - wcm.get_ectx(), - wcm.get_sctx(), + &wcm.get_ectx(), + &wcm.get_sctx(), BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0], ); diff --git a/state-machines/binary/src/binary_basic_table.rs b/state-machines/binary/src/binary_basic_table.rs index 131d4fca..02b51888 100644 --- a/state-machines/binary/src/binary_basic_table.rs +++ b/state-machines/binary/src/binary_basic_table.rs @@ -6,7 +6,7 @@ use std::sync::{ use log::info; use p3_field::Field; use proofman::{WitnessComponent, WitnessManager}; -use proofman_common::{AirInstance, SetupCtx}; +use proofman_common::AirInstance; use rayon::{prelude::*, Scope}; use sm_common::create_prover_buffer; use zisk_core::{zisk_ops::ZiskOp, P2_16, P2_17, P2_18, P2_19, P2_8}; @@ -34,7 +34,6 @@ pub enum BinaryBasicTableOp { pub struct BinaryBasicTableSM { wcm: Arc>, - sctx: Arc, // Count of registered predecessors registered_predecessors: AtomicU32, @@ -52,17 +51,12 @@ pub enum BasicTableSMErr { impl BinaryBasicTableSM { const MY_NAME: &'static str = "BinaryT "; - pub fn new( - wcm: Arc>, - sctx: Arc, - airgroup_id: usize, - air_ids: &[usize], - ) -> Arc { - let air = wcm.get_pctx().pilout.get_air(BINARY_TABLE_AIRGROUP_ID, BINARY_TABLE_AIR_IDS[0]); + pub fn new(wcm: Arc>, airgroup_id: usize, air_ids: &[usize]) -> Arc { + let pctx = wcm.get_pctx(); + let air = pctx.pilout.get_air(BINARY_TABLE_AIRGROUP_ID, BINARY_TABLE_AIR_IDS[0]); let binary_basic_table = Self { wcm: wcm.clone(), - sctx, registered_predecessors: AtomicU32::new(0), num_rows: air.num_rows(), multiplicity: Mutex::new(vec![0; air.num_rows()]), @@ -81,8 +75,8 @@ impl BinaryBasicTableSM { if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { // Create the prover buffer let (mut prover_buffer, offset) = create_prover_buffer( - self.wcm.get_ectx(), - self.wcm.get_sctx(), + &self.wcm.get_ectx(), + &self.wcm.get_sctx(), BINARY_TABLE_AIRGROUP_ID, BINARY_TABLE_AIR_IDS[0], ); @@ -101,13 +95,14 @@ impl BinaryBasicTableSM { ); let air_instance = AirInstance::new( - self.sctx.clone(), + self.wcm.get_sctx().clone(), BINARY_TABLE_AIRGROUP_ID, BINARY_TABLE_AIR_IDS[0], None, prover_buffer, ); - self.wcm.get_pctx().air_instance_repo.add_air_instance(air_instance); + let pctx = self.wcm.get_pctx(); + pctx.air_instance_repo.add_air_instance(air_instance); } } diff --git a/state-machines/binary/src/binary_extension.rs b/state-machines/binary/src/binary_extension.rs index 039730cf..cac0ad19 100644 --- a/state-machines/binary/src/binary_extension.rs +++ b/state-machines/binary/src/binary_extension.rs @@ -12,7 +12,7 @@ use num_bigint::BigInt; use p3_field::PrimeField; use pil_std_lib::Std; use proofman::{WitnessComponent, WitnessManager}; -use proofman_common::{AirInstance, SetupCtx}; +use proofman_common::AirInstance; use proofman_util::{timer_start_debug, timer_stop_and_log_debug}; use rayon::Scope; use sm_common::{create_prover_buffer, OpResult, Provable, ThreadController}; @@ -39,9 +39,6 @@ pub struct BinaryExtensionSM { // STD std: Arc>, - // SetupCtx - sctx: Arc, - // Count of registered predecessors registered_predecessors: AtomicU32, @@ -66,7 +63,6 @@ impl BinaryExtensionSM { pub fn new( wcm: Arc>, std: Arc>, - sctx: Arc, binary_extension_table_sm: Arc>, airgroup_id: usize, air_ids: &[usize], @@ -74,7 +70,6 @@ impl BinaryExtensionSM { let binary_extension_sm = Self { wcm: wcm.clone(), std: std.clone(), - sctx: sctx.clone(), registered_predecessors: AtomicU32::new(0), threads_controller: Arc::new(ThreadController::new()), inputs: Mutex::new(Vec::new()), @@ -108,7 +103,7 @@ impl BinaryExtensionSM { self.binary_extension_table_sm.unregister_predecessor(scope); - self.std.unregister_predecessor(self.wcm.get_arc_pctx(), None); + self.std.unregister_predecessor(self.wcm.get_pctx(), None); } } @@ -401,12 +396,10 @@ impl BinaryExtensionSM { scope: &Scope, ) { timer_start_debug!(BINARY_EXTENSION_TRACE); - let air = wcm - .get_pctx() - .pilout - .get_air(BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]); - let air_binary_extension_table = wcm - .get_pctx() + let pctx = wcm.get_pctx(); + + let air = pctx.pilout.get_air(BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]); + let air_binary_extension_table = pctx .pilout .get_air(BINARY_EXTENSION_TABLE_AIRGROUP_ID, BINARY_EXTENSION_TABLE_AIR_IDS[0]); assert!(operations.len() <= air.num_rows()); @@ -482,11 +475,9 @@ impl Provable for BinaryExtensio if let Ok(mut inputs) = self.inputs.lock() { inputs.extend_from_slice(operations); - let air = self - .wcm - .get_pctx() - .pilout - .get_air(BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]); + let pctx = self.wcm.get_pctx(); + let air = + pctx.pilout.get_air(BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]); while inputs.len() >= air.num_rows() || (drain && !inputs.is_empty()) { let num_drained = std::cmp::min(air.num_rows(), inputs.len()); @@ -500,12 +491,13 @@ impl Provable for BinaryExtensio let std = self.std.clone(); - let sctx = self.sctx.clone(); + let sctx = self.wcm.get_sctx().clone(); + let pctx_cloned = pctx.clone(); scope.spawn(move |scope| { let (mut prover_buffer, offset) = create_prover_buffer( - wcm.get_ectx(), - wcm.get_sctx(), + &wcm.get_ectx(), + &wcm.get_sctx(), BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0], ); @@ -527,7 +519,7 @@ impl Provable for BinaryExtensio None, prover_buffer, ); - wcm.get_pctx().air_instance_repo.add_air_instance(air_instance); + pctx_cloned.air_instance_repo.add_air_instance(air_instance); thread_controller.remove_working_thread(); }); diff --git a/state-machines/binary/src/binary_extension_table.rs b/state-machines/binary/src/binary_extension_table.rs index 66cb26f1..d17fa624 100644 --- a/state-machines/binary/src/binary_extension_table.rs +++ b/state-machines/binary/src/binary_extension_table.rs @@ -6,7 +6,7 @@ use std::sync::{ use log::info; use p3_field::Field; use proofman::{WitnessComponent, WitnessManager}; -use proofman_common::{AirInstance, SetupCtx}; +use proofman_common::AirInstance; use rayon::{prelude::*, Scope}; use sm_common::create_prover_buffer; use zisk_core::{zisk_ops::ZiskOp, P2_11, P2_19, P2_8}; @@ -28,7 +28,6 @@ pub enum BinaryExtensionTableOp { pub struct BinaryExtensionTableSM { wcm: Arc>, - sctx: Arc, // Count of registered predecessors registered_predecessors: AtomicU32, @@ -46,20 +45,14 @@ pub enum ExtensionTableSMErr { impl BinaryExtensionTableSM { const MY_NAME: &'static str = "BinaryET"; - pub fn new( - wcm: Arc>, - sctx: Arc, - airgroup_id: usize, - air_ids: &[usize], - ) -> Arc { - let air = wcm - .get_pctx() + pub fn new(wcm: Arc>, airgroup_id: usize, air_ids: &[usize]) -> Arc { + let pctx = wcm.get_pctx(); + let air = pctx .pilout .get_air(BINARY_EXTENSION_TABLE_AIRGROUP_ID, BINARY_EXTENSION_TABLE_AIR_IDS[0]); let binary_extension_table = Self { wcm: wcm.clone(), - sctx, registered_predecessors: AtomicU32::new(0), num_rows: air.num_rows(), multiplicity: Mutex::new(vec![0; air.num_rows()]), @@ -78,8 +71,8 @@ impl BinaryExtensionTableSM { if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { // Create the prover buffer let (mut prover_buffer, offset) = create_prover_buffer( - self.wcm.get_ectx(), - self.wcm.get_sctx(), + &self.wcm.get_ectx(), + &self.wcm.get_sctx(), BINARY_EXTENSION_TABLE_AIRGROUP_ID, BINARY_EXTENSION_TABLE_AIR_IDS[0], ); @@ -98,13 +91,15 @@ impl BinaryExtensionTableSM { ); let air_instance = AirInstance::new( - self.sctx.clone(), + self.wcm.get_sctx().clone(), BINARY_EXTENSION_TABLE_AIRGROUP_ID, BINARY_EXTENSION_TABLE_AIR_IDS[0], None, prover_buffer, ); - self.wcm.get_pctx().air_instance_repo.add_air_instance(air_instance); + + let pctx = self.wcm.get_pctx(); + pctx.air_instance_repo.add_air_instance(air_instance); } } diff --git a/state-machines/mem/src/mem.rs b/state-machines/mem/src/mem.rs index f1182c01..aa286c95 100644 --- a/state-machines/mem/src/mem.rs +++ b/state-machines/mem/src/mem.rs @@ -30,11 +30,10 @@ pub struct MemSM { // Secondary State machines mem_aligned_sm: Arc, mem_unaligned_sm: Arc, - sctx: Arc, } impl MemSM { - pub fn new(wcm: Arc>, sctx: Arc) -> Arc { + pub fn new(wcm: Arc>) -> Arc { let mem_aligned_sm = MemAlignedSM::new(wcm.clone()); let mem_unaligned_sm = MemUnalignedSM::new(wcm.clone()); @@ -45,7 +44,6 @@ impl MemSM { inputs_unaligned: Mutex::new(Vec::new()), mem_aligned_sm: mem_aligned_sm.clone(), mem_unaligned_sm: mem_unaligned_sm.clone(), - sctx, }; let mem_sm = Arc::new(mem_sm); diff --git a/witness-computation/src/zisk_lib.rs b/witness-computation/src/zisk_lib.rs index c2650cb7..807eccd8 100644 --- a/witness-computation/src/zisk_lib.rs +++ b/witness-computation/src/zisk_lib.rs @@ -46,9 +46,9 @@ impl ZiskWitness { let std = Std::new(wcm.clone()); - let mem_sm = MemSM::new(wcm.clone(), sctx.clone()); - let binary_sm = BinarySM::new(wcm.clone(), std.clone(), sctx.clone()); - let arith_sm = ArithSM::new(wcm.clone(), sctx.clone()); + let mem_sm = MemSM::new(wcm.clone()); + let binary_sm = BinarySM::new(wcm.clone(), std.clone()); + let arith_sm = ArithSM::new(wcm.clone()); let main_sm = MainSM::new( self.rom_path.clone(), From f1c47b44c8a70477a0bb984594bc812e83a49f61 Mon Sep 17 00:00:00 2001 From: fractasy <89866610+fractasy@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:55:36 +0100 Subject: [PATCH 03/22] ROM SM and ROM merkelizer tool (#136) * Create ROM SM and ROM Merkle tool --------- Co-authored-by: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Co-authored-by: zkronos73 --- Cargo.lock | 73 +++++- Cargo.toml | 4 + core/src/zisk_definitions.rs | 23 ++ core/src/zisk_inst.rs | 22 +- core/src/zisk_inst_builder.rs | 2 +- core/src/zisk_required_operation.rs | 9 + core/src/zisk_rom.rs | 50 +--- emulator/src/emu.rs | 30 ++- emulator/src/emulator.rs | 21 +- pil/src/pil_helpers/pilout.rs | 24 +- pil/src/pil_helpers/traces.rs | 12 + pil/zisk.pil | 9 +- rom-merkle/Cargo.toml | 17 ++ rom-merkle/src/main.rs | 100 ++++++++ state-machines/main/Cargo.toml | 1 + state-machines/main/pil/main.pil | 64 ++--- state-machines/main/src/main_sm.rs | 29 ++- state-machines/rom/Cargo.toml | 23 ++ state-machines/rom/pil/rom.pil | 24 ++ state-machines/rom/src/lib.rs | 3 + state-machines/rom/src/rom.rs | 363 ++++++++++++++++++++++++++++ witness-computation/Cargo.toml | 1 + witness-computation/src/zisk_lib.rs | 5 +- 23 files changed, 807 insertions(+), 102 deletions(-) create mode 100644 rom-merkle/Cargo.toml create mode 100644 rom-merkle/src/main.rs create mode 100644 state-machines/rom/Cargo.toml create mode 100644 state-machines/rom/pil/rom.pil create mode 100644 state-machines/rom/src/lib.rs create mode 100644 state-machines/rom/src/rom.rs diff --git a/Cargo.lock b/Cargo.lock index ec4be183..7a376da7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1322,7 +1322,7 @@ dependencies = [ [[package]] name = "pil-std-lib" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "log", "num-bigint", @@ -1340,7 +1340,7 @@ dependencies = [ [[package]] name = "pilout" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "bytes", "log", @@ -1460,7 +1460,7 @@ dependencies = [ [[package]] name = "proofman" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "colored", "env_logger", @@ -1481,7 +1481,7 @@ dependencies = [ [[package]] name = "proofman-common" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "env_logger", "log", @@ -1499,7 +1499,7 @@ dependencies = [ [[package]] name = "proofman-hints" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "p3-field", "proofman-common", @@ -1509,7 +1509,7 @@ dependencies = [ [[package]] name = "proofman-macros" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "proc-macro2", "quote", @@ -1519,7 +1519,7 @@ dependencies = [ [[package]] name = "proofman-starks-lib-c" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "log", ] @@ -1527,10 +1527,10 @@ dependencies = [ [[package]] name = "proofman-util" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "colored", - "sysinfo", + "sysinfo 0.31.4", ] [[package]] @@ -1827,6 +1827,22 @@ dependencies = [ "json", ] +[[package]] +name = "rom-merkle" +version = "0.1.0" +dependencies = [ + "clap", + "colored", + "env_logger", + "log", + "p3-field", + "p3-goldilocks", + "proofman-common", + "sm-rom", + "stark", + "sysinfo 0.32.0", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -2058,6 +2074,7 @@ dependencies = [ "sm-binary", "sm-common", "sm-mem", + "sm-rom", "zisk-core", "zisk-pil", "ziskemu", @@ -2093,6 +2110,23 @@ dependencies = [ "zisk-pil", ] +[[package]] +name = "sm-rom" +version = "0.1.0" +dependencies = [ + "log", + "p3-field", + "proofman", + "proofman-common", + "proofman-macros", + "proofman-util", + "rayon", + "sm-common", + "zisk-core", + "zisk-pil", + "ziskemu", +] + [[package]] name = "smallvec" version = "1.13.2" @@ -2124,7 +2158,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stark" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "log", "p3-field", @@ -2220,6 +2254,20 @@ dependencies = [ "windows", ] +[[package]] +name = "sysinfo" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ae3f4f7d64646c46c4cae4e3f01d1c5d255c7406fdd7c7f999a94e488791" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "rayon", + "windows", +] + [[package]] name = "target-lexicon" version = "0.12.16" @@ -2419,7 +2467,7 @@ dependencies = [ [[package]] name = "transcript" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#0f8c16301e0930a6dce74ed6ac6ff993d75bbfb2" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" dependencies = [ "proofman-starks-lib-c", ] @@ -2981,6 +3029,7 @@ dependencies = [ "sm-main", "sm-mem", "sm-quick-ops", + "sm-rom", "zisk-pil", ] @@ -2994,7 +3043,7 @@ dependencies = [ "pprof", "rayon", "riscv", - "sysinfo", + "sysinfo 0.31.4", "vergen", "zisk-core", "zisk-pil", diff --git a/Cargo.toml b/Cargo.toml index 14f9ed48..8208fb92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,12 +5,14 @@ members = [ "emulator", "pil", "riscv", + "rom-merkle", "state-machines/arith", "state-machines/binary", "state-machines/common", "state-machines/freq-ops", "state-machines/main", "state-machines/mem", + "state-machines/rom", "witness-computation", "ziskos/entrypoint", ] @@ -29,12 +31,14 @@ proofman-macros = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git" proofman-util = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", branch ="develop" } proofman = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", branch ="develop" } pil-std-lib = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", branch ="develop" } +stark = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", branch ="develop" } #Local development # proofman-common = { path = "../pil2-proofman/common" } # proofman-macros = { path = "../pil2-proofman/macros" } # proofman-util = { path = "../pil2-proofman/util" } # proofman = { path = "../pil2-proofman/proofman" } # pil-std-lib = { path = "../pil2-proofman/pil2-components/lib/std/rs" } +# stark = { path = "../pil2-proofman/provers/stark" } p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } log = "0.4" diff --git a/core/src/zisk_definitions.rs b/core/src/zisk_definitions.rs index 238634e8..64e5be8a 100644 --- a/core/src/zisk_definitions.rs +++ b/core/src/zisk_definitions.rs @@ -1,3 +1,4 @@ +// a and b registers source types pub const SRC_C: u64 = 0; pub const SRC_MEM: u64 = 1; pub const SRC_IMM: u64 = 2; @@ -5,9 +6,31 @@ pub const SRC_STEP: u64 = 3; // #[cfg(feature = "sp")] // pub const SRC_SP: u64 = 4; pub const SRC_IND: u64 = 5; + +// c register store destination types pub const STORE_NONE: u64 = 0; pub const STORE_MEM: u64 = 1; pub const STORE_IND: u64 = 2; + +/* Memory map: + + |--------------- ROM_ENTRY (0x1000) + | (rom entry, calls program, ~BIOS) + |--------------- + ... + |--------------- ROM_ADDR (0x80000000) + | (rom program) + |--------------- INPUT_ADDR + | (input data) + |--------------- SYS_ADDR (= RAM_ADDR) + | (sys = 32 registers) + |--------------- OUTPUT_ADDR + | (output data) + |--------------- AVAILABLE_MEM_ADDR + | (program memory) + |--------------- + +*/ pub const ROM_ADDR: u64 = 0x80000000; pub const ROM_ADDR_MAX: u64 = INPUT_ADDR - 1; pub const INPUT_ADDR: u64 = 0x90000000; diff --git a/core/src/zisk_inst.rs b/core/src/zisk_inst.rs index 9254eefe..2df9ab35 100644 --- a/core/src/zisk_inst.rs +++ b/core/src/zisk_inst.rs @@ -1,4 +1,6 @@ -use crate::{source_to_str, store_to_str, InstContext}; +use crate::{ + source_to_str, store_to_str, InstContext, SRC_IMM, SRC_MEM, SRC_STEP, STORE_IND, STORE_MEM, +}; #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] #[repr(u32)] @@ -162,4 +164,22 @@ impl ZiskInst { } s } + + pub fn get_flags(&self) -> u64 { + let flags: u64 = 1 | + (((self.a_src == SRC_IMM) as u64) << 1) | + (((self.a_src == SRC_MEM) as u64) << 2) | + (((self.a_src == SRC_STEP) as u64) << 3) | + (((self.b_src == SRC_IMM) as u64) << 4) | + (((self.b_src == SRC_MEM) as u64) << 5) | + ((self.is_external_op as u64) << 6) | + ((self.store_ra as u64) << 7) | + (((self.store == STORE_MEM) as u64) << 8) | + (((self.store == STORE_IND) as u64) << 9) | + ((self.set_pc as u64) << 10) | + ((self.end as u64) << 11) | + ((self.m32 as u64) << 12); + + flags + } } diff --git a/core/src/zisk_inst_builder.rs b/core/src/zisk_inst_builder.rs index e94dada1..78e19f88 100644 --- a/core/src/zisk_inst_builder.rs +++ b/core/src/zisk_inst_builder.rs @@ -7,7 +7,7 @@ use crate::{ // #[cfg(feature = "sp")] // use crate::SRC_SP; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ZiskInstBuilder { ind_width_set: bool, pub i: ZiskInst, diff --git a/core/src/zisk_required_operation.rs b/core/src/zisk_required_operation.rs index d8eabe19..59a7aee6 100644 --- a/core/src/zisk_required_operation.rs +++ b/core/src/zisk_required_operation.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + #[derive(Clone)] pub struct ZiskRequiredOperation { pub step: u64, @@ -22,3 +24,10 @@ pub struct ZiskRequired { pub binary_extension: Vec, pub memory: Vec, } + +#[derive(Clone, Default)] +pub struct ZiskPcHistogram { + pub map: HashMap, + pub end_pc: u64, + pub steps: u64, +} diff --git a/core/src/zisk_rom.rs b/core/src/zisk_rom.rs index c4b1810f..4761feb8 100644 --- a/core/src/zisk_rom.rs +++ b/core/src/zisk_rom.rs @@ -1,15 +1,12 @@ use std::collections::HashMap; -use crate::{ - ZiskInst, ZiskInstBuilder, ROM_ADDR, ROM_ENTRY, SRC_IMM, SRC_IND, SRC_MEM, SRC_STEP, STORE_IND, - STORE_MEM, -}; +use crate::{ZiskInst, ZiskInstBuilder, ROM_ADDR, ROM_ENTRY, SRC_IND, SRC_STEP}; // #[cfg(feature = "sp")] // use crate::SRC_SP; /// RO data structure -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct RoData { pub from: u64, pub length: usize, @@ -25,7 +22,7 @@ impl RoData { } /// ZisK ROM data, including a map address to ZisK instruction -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub struct ZiskRom { pub next_init_inst_addr: u64, pub insts: HashMap, @@ -208,7 +205,7 @@ impl ZiskRom { // instruction for key in &keys { let i = &self.insts[key].i; - let rom_flags = self.get_rom_flags(i); + let rom_flags = i.get_flags(); // #[cfg(feature = "sp")] // { @@ -275,7 +272,7 @@ impl ZiskRom { for key in &keys { let mut aux: [u8; 8]; let i = &self.insts[key].i; - let rom_flags = self.get_rom_flags(i); + let rom_flags = i.get_flags(); aux = key.to_le_bytes(); v.extend(aux); aux = rom_flags.to_le_bytes(); @@ -353,41 +350,4 @@ impl ZiskRom { panic!("ZiskRom::save_to_bin_file() failed writing to file={}", file_name); } } - - pub fn get_rom_flags(&self, i: &ZiskInst) -> u64 { - // #[cfg(feature = "sp")] - // let rom_flags: u64 = ((i.a_src == SRC_IMM) as u64) | - // ((i.a_src == SRC_MEM) as u64) << 1 | - // ((i.b_src == SRC_IMM) as u64) << 2 | - // ((i.b_src == SRC_MEM) as u64) << 3 | - // (i.store_ra as u64) << 4 | - // ((i.store == STORE_MEM) as u64) << 5 | - // ((i.store == STORE_IND) as u64) << 6 | - // (i.set_pc as u64) << 7 | - // (i.m32 as u64) << 8 | - // (i.end as u64) << 9 | - // (i.is_external_op as u64) << 10 | - // ((i.a_src == SRC_SP) as u64) << 11 | - // (i.a_use_sp_imm1) << 12 | - // ((i.a_src == SRC_STEP) as u64) << 13 | - // ((i.b_src == SRC_IND) as u64) << 14 | - // (i.store_use_sp as u64) << 15; - - // #[cfg(not(feature = "sp"))] - let rom_flags: u64 = ((i.a_src == SRC_IMM) as u64) | - ((i.a_src == SRC_MEM) as u64) << 1 | - ((i.b_src == SRC_IMM) as u64) << 2 | - ((i.b_src == SRC_MEM) as u64) << 3 | - (i.store_ra as u64) << 4 | - ((i.store == STORE_MEM) as u64) << 5 | - ((i.store == STORE_IND) as u64) << 6 | - (i.set_pc as u64) << 7 | - (i.m32 as u64) << 8 | - (i.end as u64) << 9 | - (i.is_external_op as u64) << 10 | - ((i.a_src == SRC_STEP) as u64) << 13 | - ((i.b_src == SRC_IND) as u64) << 14; - - rom_flags - } } diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index ce397bb1..f76904e9 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -9,9 +9,9 @@ use riscv::RiscVRegisters; // #[cfg(feature = "sp")] // use zisk_core::SRC_SP; use zisk_core::{ - InstContext, ZiskInst, ZiskOperationType, ZiskRequiredOperation, ZiskRom, OUTPUT_ADDR, - ROM_ENTRY, SRC_C, SRC_IMM, SRC_IND, SRC_MEM, SRC_STEP, STORE_IND, STORE_MEM, STORE_NONE, - SYS_ADDR, ZISK_OPERATION_TYPE_VARIANTS, + InstContext, ZiskInst, ZiskOperationType, ZiskPcHistogram, ZiskRequiredOperation, ZiskRom, + OUTPUT_ADDR, ROM_ENTRY, SRC_C, SRC_IMM, SRC_IND, SRC_MEM, SRC_STEP, STORE_IND, STORE_MEM, + STORE_NONE, SYS_ADDR, ZISK_OPERATION_TYPE_VARIANTS, }; /// ZisK emulator structure, containing the ZisK rom, the list of ZisK operations, and the @@ -255,6 +255,30 @@ impl<'a> Emu<'a> { self.ctx.inst_ctx.step += 1; } + /// Run the whole program, getting pc histogram + #[inline(always)] + pub fn run_pc_histogram(&mut self, inputs: Vec, options: &EmuOptions) -> ZiskPcHistogram { + // Create an empty pc histogram + let mut histogram = ZiskPcHistogram::default(); + + // Context, where the state of the execution is stored and modified at every execution step + self.ctx = self.create_emu_context(inputs); + + // Run the steps + while !self.ctx.inst_ctx.end && (self.ctx.inst_ctx.step < options.max_steps) { + let count = histogram.map.entry(self.ctx.inst_ctx.pc).or_default(); + *count += 1; + //println!("Emu::run_pc_histogram() adding pc={}", self.ctx.inst_ctx.pc); + self.step_fast(); + if self.ctx.inst_ctx.end { + histogram.end_pc = self.ctx.inst_ctx.pc; + histogram.steps = self.ctx.inst_ctx.step; + } + } + + histogram + } + /// Run the whole program pub fn run( &mut self, diff --git a/emulator/src/emulator.rs b/emulator/src/emulator.rs index 05b33995..2a803851 100644 --- a/emulator/src/emulator.rs +++ b/emulator/src/emulator.rs @@ -11,7 +11,8 @@ use std::{ }; use sysinfo::System; use zisk_core::{ - Riscv2zisk, ZiskOperationType, ZiskRequiredOperation, ZiskRom, ZISK_OPERATION_TYPE_VARIANTS, + Riscv2zisk, ZiskOperationType, ZiskPcHistogram, ZiskRequiredOperation, ZiskRom, + ZISK_OPERATION_TYPE_VARIANTS, }; pub trait Emulator { @@ -162,6 +163,24 @@ impl ZiskEmulator { Ok(output) } + pub fn process_rom_pc_histogram( + rom: &ZiskRom, + inputs: &[u8], + options: &EmuOptions, + ) -> Result { + // Create a emulator instance with this rom and inputs + let mut emu = Emu::new(rom); + + // Run the emulation + let pc_histogram = emu.run_pc_histogram(inputs.to_owned(), options); + + if !emu.terminated() { + return Err(ZiskEmulatorErr::EmulationNoCompleted); + } + + Ok(pc_histogram) + } + pub fn par_process_rom( rom: &ZiskRom, inputs: &[u8], diff --git a/pil/src/pil_helpers/pilout.rs b/pil/src/pil_helpers/pilout.rs index 3032eb27..e371c7d6 100644 --- a/pil/src/pil_helpers/pilout.rs +++ b/pil/src/pil_helpers/pilout.rs @@ -8,20 +8,28 @@ pub const PILOUT_HASH: &[u8] = b"Zisk-hash"; pub const MAIN_AIRGROUP_ID: usize = 0; -pub const BINARY_AIRGROUP_ID: usize = 1; +pub const ROM_AIRGROUP_ID: usize = 1; -pub const BINARY_TABLE_AIRGROUP_ID: usize = 2; +pub const BINARY_AIRGROUP_ID: usize = 2; -pub const BINARY_EXTENSION_AIRGROUP_ID: usize = 3; +pub const BINARY_TABLE_AIRGROUP_ID: usize = 3; -pub const BINARY_EXTENSION_TABLE_AIRGROUP_ID: usize = 4; +pub const BINARY_EXTENSION_AIRGROUP_ID: usize = 4; -pub const SPECIFIED_RANGES_AIRGROUP_ID: usize = 5; +pub const BINARY_EXTENSION_TABLE_AIRGROUP_ID: usize = 5; + +pub const SPECIFIED_RANGES_AIRGROUP_ID: usize = 6; //AIR CONSTANTS pub const MAIN_AIR_IDS: &[usize] = &[0]; +pub const ROM_S_AIR_IDS: &[usize] = &[0]; + +pub const ROM_M_AIR_IDS: &[usize] = &[1]; + +pub const ROM_L_AIR_IDS: &[usize] = &[2]; + pub const BINARY_AIR_IDS: &[usize] = &[0]; pub const BINARY_TABLE_AIR_IDS: &[usize] = &[0]; @@ -42,6 +50,12 @@ impl Pilout { air_group.add_air(Some("Main"), 2097152); + let air_group = pilout.add_air_group(Some("Rom")); + + air_group.add_air(Some("RomS"), 65536); + air_group.add_air(Some("RomM"), 4194304); + air_group.add_air(Some("RomL"), 67108864); + let air_group = pilout.add_air_group(Some("Binary")); air_group.add_air(Some("Binary"), 2097152); diff --git a/pil/src/pil_helpers/traces.rs b/pil/src/pil_helpers/traces.rs index 2ea5b574..a3650c28 100644 --- a/pil/src/pil_helpers/traces.rs +++ b/pil/src/pil_helpers/traces.rs @@ -7,6 +7,18 @@ trace!(Main0Row, Main0Trace { a: [F; 2], b: [F; 2], c: [F; 2], last_c: [F; 2], flag: F, pc: F, a_src_imm: F, a_src_mem: F, a_offset_imm0: F, a_imm1: F, a_src_step: F, b_src_imm: F, b_src_mem: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, is_external_op: F, op: F, store_ra: F, store_mem: F, store_ind: F, store_offset: F, set_pc: F, jmp_offset1: F, jmp_offset2: F, end: F, m32: F, operation_bus_enabled: F, }); +trace!(RomS0Row, RomS0Trace { + line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, +}); + +trace!(RomM1Row, RomM1Trace { + line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, +}); + +trace!(RomL2Row, RomL2Trace { + line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, +}); + trace!(Binary0Row, Binary0Trace { m_op: F, mode32: F, free_in_a: [F; 8], free_in_b: [F; 8], free_in_c: [F; 8], carry: [F; 8], use_last_carry: F, op_is_min_max: F, multiplicity: F, main_step: F, }); diff --git a/pil/zisk.pil b/pil/zisk.pil index 59903524..fc90d2cc 100644 --- a/pil/zisk.pil +++ b/pil/zisk.pil @@ -1,5 +1,6 @@ + require "constants.pil" -// require "std_permutation.pil" +require "rom/pil/rom.pil" require "main/pil/main.pil" require "binary/pil/binary.pil" require "binary/pil/binary_table.pil" @@ -12,6 +13,12 @@ airgroup Main { Main(N: 2**21, RC: 2, operation_bus_id: OPERATION_BUS_ID); } +airgroup Rom { + Rom(N: 2**16) alias RomS; + Rom(N: 2**22) alias RomM; + Rom(N: 2**26) alias RomL; +} + // airgroup Mem { // Mem(N: 2**21, RC: 2); // } diff --git a/rom-merkle/Cargo.toml b/rom-merkle/Cargo.toml new file mode 100644 index 00000000..4558eda3 --- /dev/null +++ b/rom-merkle/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "rom-merkle" +version = "0.1.0" +edition = "2021" + +[dependencies] +sm-rom = { path = "../state-machines/rom" } +log = { workspace = true } +stark = { workspace = true } +proofman-common = { workspace = true } + +p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } +p3-field = { workspace = true } +clap = { version = "4.5.13", features = ["derive", "env"] } +env_logger = "0.11" +sysinfo = "0.32" +colored = "2" \ No newline at end of file diff --git a/rom-merkle/src/main.rs b/rom-merkle/src/main.rs new file mode 100644 index 00000000..d766a546 --- /dev/null +++ b/rom-merkle/src/main.rs @@ -0,0 +1,100 @@ +use clap::{Arg, Command}; +use colored::Colorize; +use p3_goldilocks::Goldilocks; +use proofman_common::{GlobalInfo, ProofType, SetupCtx}; +use sm_rom::RomSM; +use stark::StarkBufferAllocator; +use std::{path::Path, sync::Arc}; +use sysinfo::System; + +fn main() { + let matches = Command::new("ROM Handler") + .version("1.0") + .about("Compute the Merkle Root of a ROM file") + .arg(Arg::new("rom").value_name("FILE").help("The ROM file path").required(true).index(1)) + .arg( + Arg::new("proving_key") + .value_name("FILE") + .help("The proving key folder path") + .required(true) + .index(2), + ) + .arg( + Arg::new("global_info") + .value_name("FILE") + .help("The global info file path") + .required(true) + .index(3), + ) + .get_matches(); + + // Get the value of the `rom` argument as a path + let rom_path_str = matches.get_one::("rom").expect("ROM path is required"); + let rom_path = Path::new(rom_path_str); + let proving_key_path_str = + matches.get_one::("proving_key").expect("Proving key path is required"); + let proving_key_path = Path::new(proving_key_path_str); + let global_info_path_str = + matches.get_one::("global_info").expect("Global info path is required"); + let global_info_path = Path::new(global_info_path_str); + + env_logger::builder() + .format_timestamp(None) + .format_level(true) + .format_target(false) + .filter_level(log::LevelFilter::Info) + .init(); + + println!(); + println!( + " {}{}", + "Proofman by Polygon Labs v".bright_purple().bold(), + env!("CARGO_PKG_VERSION").bright_purple().bold() + ); + + let system_name = System::name().unwrap_or_else(|| "".to_owned()); + let system_kernel = System::kernel_version().unwrap_or_else(|| "".to_owned()); + let system_version = System::long_os_version().unwrap_or_else(|| "".to_owned()); + println!( + "{} {} {} ({})", + format!("{: >12}", "System").bright_green().bold(), + system_name, + system_kernel, + system_version + ); + let system_hostname = System::host_name().unwrap_or_else(|| "".to_owned()); + println!("{} {}", format!("{: >12}", "Hostname").bright_green().bold(), system_hostname); + println!(); + + // Check if the path exists + if !rom_path.exists() { + log::error!("Error: The specified ROM file does not exist: {}", rom_path_str); + std::process::exit(1); + } + + // Check if the path is a file and not a directory + if !rom_path.is_file() { + log::error!("Error: The specified ROM path is not a file: {}", rom_path_str); + std::process::exit(1); + } + + // If all checks pass, continue with the program + println!("ROM Path is valid: {}", rom_path.display()); + + let buffer_allocator: Arc = + Arc::new(StarkBufferAllocator::new(proving_key_path.to_path_buf())); + let global_info = GlobalInfo::new(global_info_path); + let sctx: Arc = Arc::new(SetupCtx::new(&global_info, &ProofType::Basic)); + + if let Err(e) = + RomSM::::compute_trace(rom_path.to_path_buf(), buffer_allocator, &sctx) + { + log::error!("Error: {}", e); + std::process::exit(1); + } + + // Compute LDE and Merkelize and get the root of the rom + // TODO: Implement the logic to compute the trace + + log::info!("ROM proof successful"); +} diff --git a/state-machines/main/Cargo.toml b/state-machines/main/Cargo.toml index 1434f441..abaf42e3 100644 --- a/state-machines/main/Cargo.toml +++ b/state-machines/main/Cargo.toml @@ -8,6 +8,7 @@ sm-arith = { path = "../arith" } sm-binary = { path = "../binary" } sm-mem = { path = "../mem" } sm-common = { path = "../common" } +sm-rom = { path = "../rom" } ziskemu = { path = "../../emulator" } zisk-core = { path = "../../core" } zisk-pil = { path = "../../pil" } diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 09689ec2..e6b06b2c 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -1,7 +1,4 @@ -// require "std_permutation.pil" -// require "std_lookup.pil" -// require "mem.pil" -// require "operation.pil" +require "std_lookup.pil" const int BOOT_ADDR = 0x1000; @@ -16,8 +13,8 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope airval main_last_segment; airval main_segment; - main_first_segment * (1 - main_first_segment) === 0; - main_last_segment * (1 - main_last_segment) === 0; + main_first_segment * (1 - main_first_segment) === 0; + main_last_segment * (1 - main_last_segment) === 0; main_first_segment * main_segment === 0; const expr L1 = SEGMENT_L1 * main_first_segment; @@ -41,7 +38,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // Instruction // a_src_step - // a_src_mem + // a_src_mem // a_src_imm // a_src_sp // b_src_mem @@ -106,7 +103,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope col witness jmp_offset1, jmp_offset2; // if flag, goto2, else goto 1 - col witness end; + col witness end; col witness m32; const expr addr_step = STEP * 3; @@ -126,21 +123,21 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope } // Mem.load - // mem_load(sel: a_src_mem, - // step: addr_step, + // mem_load(sel: a_src_mem, + // step: addr_step, // addr: addr[0], // value: a); // Mem.load // mem_load(sel: sel_mem_b, - // step: addr_step + 1, + // step: addr_step + 1, // bytes: ind_width, // addr: addr[1], // value: b); // Mem.store - // mem_store(sel: store_mem + store_ind, - // step: addr_step + 2, + // mem_store(sel: store_mem + store_ind, + // step: addr_step + 2, // bytes: ind_width, // addr: addr[2], // value: [store_ra*(pc + jmp_offset2 - c[0]) + c[0], (1 - store_ra) * c[1]]); @@ -202,8 +199,8 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // continuations // continuations_transition(pc, set_pc * (c[0] + jmp_offset1 - new_pc) + new_pc); - // continuations_transition(last_c[0], c[0]); // last_c[0]' = c[0]; - // continuations_transition(last_c[1], c[1]); // last_c[1]' = c[1]; + // continuations_transition(last_c[0], c[0]); // last_c[0]' = c[0]; + // continuations_transition(last_c[1], c[1]); // last_c[1]' = c[1]; // const expr new_pc = pc + flag*(jmp_offset1 - jmp_offset2) + jmp_offset2; // const expr next_pc = set_pc * (c[0] + jmp_offset1 - new_pc) + new_pc + end * L1' * (0x8000_0000 - (pc + jmp_offset1)); @@ -219,10 +216,10 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope const expr next_sp = set_sp * (c[0] - sp) + sp + inc_sp;; (1 - SEGMENT_LAST) * (sp' - next_sp) === 0; // permutation_proves(MAIN_CONTINUATION_ID, sel: SEGMENT_LAST, cols: [next_pc, ...c, next_sp]); - // permutation_assumes(MAIN_CONTINUATION_ID, sel: SEGMENT_L1, cols: [pc, ...last_c, sp]); + // permutation_assumes(MAIN_CONTINUATION_ID, sel: SEGMENT_L1, cols: [pc, ...last_c, sp]); } else { // permutation_proves(MAIN_CONTINUATION_ID, sel: SEGMENT_LAST, cols: [next_pc, ...c]); - // permutation_assumes(MAIN_CONTINUATION_ID, sel: SEGMENT_L1, cols: [pc, ...last_c]); + // permutation_assumes(MAIN_CONTINUATION_ID, sel: SEGMENT_L1, cols: [pc, ...last_c]); } // pc' === set_pc * ( c[0] + jmp_offset1 - new_pc) + new_pc + end * L1'*(0x8000_0000 - (pc + jmp_offset1 )); // Assume that when end=1 then set_pc = 0 and flag = 0 @@ -231,14 +228,27 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope flag * (1 - flag) === 0; - /* - if (stack_enabled) { - const expr rom_flags = a_src_imm + 2 * a_src_mem + 4 * b_src_imm + 8 * b_src_mem + 16 * store_ra + 32 * store_mem + 64 * store_ind + 128 * set_pc + 256 * m32 + 512 * end + 1024 * is_external_op + - 2**11 * a_src_sp + 2**12 * a_use_sp_imm1 + 2**13 * a_src_step + 2**14 * b_src_ind + 2**15 * store_use_sp; - // lookup_assumes(ROM_ID, cols: [pc, rom_flags, op, a_offset_imm0, b_offset_imm0, ind_width, store_offset, jmp_offset1, jmp_offset2, inc_sp, b_use_sp_imm1]); - } else { - const expr rom_flags = a_src_imm + 2 * a_src_mem + 4 * b_src_imm + 8 * b_src_mem + 16 * store_ra + 32 * store_mem + 64 * store_ind + 128 * set_pc + 256 * m32 + 512 * end + 1024 * is_external_op; - // lookup_assumes(ROM_ID, cols: [pc, rom_flags, op, a_offset_imm0, b_offset_imm0, ind_width, store_offset, jmp_offset1, jmp_offset2, a_src_step_imm1, b_src_ind_imm1]); - } - */ + + // set lsb of rom_flags always to 1 to force that padding rom rows (all values to zero), doesn't + // match with main trace. + const expr rom_flags = 1 + 2 * a_src_imm + 4 * a_src_mem + 8 * a_src_step + 16 * b_src_imm + 32 * b_src_mem + + 64 * is_external_op + 128 * store_ra + 256 * store_mem + 512 * store_ind + + + 1024 * set_pc + 2048 * end + 4096 * m32; + + a_src_imm * (1 - a_src_imm) === 0; + a_src_mem * (1 - a_src_mem) === 0; + a_src_step * (1 - a_src_step) === 0; + b_src_imm * (1 - b_src_imm) === 0; + b_src_mem * (1 - b_src_mem) === 0; + is_external_op * (1 - is_external_op) === 0; + store_ra * (1 - store_ra) === 0; + store_mem * (1 - store_mem) === 0; + store_ind * (1 - store_ind) === 0; + set_pc * (1 - set_pc) === 0; + end * (1 - end) === 0; + m32 * (1 - m32) === 0; + + lookup_assumes(ROM_BUS_ID, [pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, b_src_ind, ind_width, + op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1); + } \ No newline at end of file diff --git a/state-machines/main/src/main_sm.rs b/state-machines/main/src/main_sm.rs index e62e5717..d58b21fb 100644 --- a/state-machines/main/src/main_sm.rs +++ b/state-machines/main/src/main_sm.rs @@ -1,5 +1,6 @@ use log::info; use p3_field::PrimeField; +use sm_rom::RomSM; use core::panic; use proofman_util::{timer_start_debug, timer_stop_and_log_debug}; @@ -57,11 +58,12 @@ pub struct MainSM { zisk_rom_path: PathBuf, // State machines - mem_sm: Arc, - binary_sm: Arc>, arith_sm: Arc, sctx: Arc, + binary_sm: Arc>, + mem_sm: Arc, + rom_sm: Arc>, } impl MainSM { @@ -89,6 +91,7 @@ impl MainSM { rom_path: PathBuf, wcm: Arc>, sctx: Arc, + rom_sm: Arc>, mem_sm: Arc, binary_sm: Arc>, arith_sm: Arc, @@ -122,10 +125,11 @@ impl MainSM { let main_sm = Arc::new(Self { zisk_rom, zisk_rom_path: rom_path.to_path_buf(), - mem_sm: mem_sm.clone(), - binary_sm: binary_sm.clone(), - arith_sm: arith_sm.clone(), sctx, + arith_sm, + binary_sm, + mem_sm, + rom_sm, }); wcm.register_component(main_sm.clone(), Some(MAIN_AIRGROUP_ID), Some(MAIN_AIR_IDS)); @@ -191,6 +195,18 @@ impl MainSM { op_sizes[ZiskOperationType::BinaryE as usize] = air_binary_e.num_rows() as u64; pool.scope(|scope| { + // FIXME: This is a temporary solution to run the emulator in parallel with the ROM SM + // Spawn the ROM thread + let rom_sm = self.rom_sm.clone(); + let zisk_rom = self.zisk_rom.clone(); + let pc_histogram = ZiskEmulator::process_rom_pc_histogram( + &self.zisk_rom, + &public_inputs, + &emu_options, + ) + .expect("MainSM::execute() failed calling ZiskEmulator::process_rom_pc_histogram()"); + let handle_rom = std::thread::spawn(move || rom_sm.prove(&zisk_rom, pc_histogram)); + // Run the emulator in parallel n times to collect execution traces // and record the execution starting points for each AIR instance timer_start_debug!(PAR_PROCESS_ROM); @@ -206,6 +222,9 @@ impl MainSM { emu_slices.points.sort_by(|a, b| a.op_type.partial_cmp(&b.op_type).unwrap()); + // FIXME: This is a temporary solution to run the emulator in parallel with the ROM SM + handle_rom.join().unwrap().expect("Error during ROM witness computation"); + let mut instances_ctx: Vec> = Vec::with_capacity(emu_slices.points.len()); diff --git a/state-machines/rom/Cargo.toml b/state-machines/rom/Cargo.toml new file mode 100644 index 00000000..ae685530 --- /dev/null +++ b/state-machines/rom/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "sm-rom" +version = "0.1.0" +edition = "2021" + +[dependencies] +zisk-core = { path = "../../core" } +sm-common = { path = "../common" } +zisk-pil = { path = "../../pil" } +ziskemu = { path = "../../emulator" } + +p3-field = { workspace=true } +proofman-common = { workspace = true } +proofman-macros = { workspace = true } +proofman-util = { workspace = true } +proofman = { workspace = true } + +log = { workspace = true } +rayon = { workspace = true } + +[features] +default = [] +no_lib_link = ["proofman-common/no_lib_link", "proofman/no_lib_link"] \ No newline at end of file diff --git a/state-machines/rom/pil/rom.pil b/state-machines/rom/pil/rom.pil new file mode 100644 index 00000000..19afccc5 --- /dev/null +++ b/state-machines/rom/pil/rom.pil @@ -0,0 +1,24 @@ +require "std_lookup.pil" + +const int ROM_BUS_ID = 7890; + +airtemplate Rom(int N = 2**21, int stack_enabled = 0, const int rom_bus_id = ROM_BUS_ID) { + + col witness line; + col witness a_offset_imm0; + col witness a_imm1; + col witness b_offset_imm0; + col witness b_imm1; + col witness b_src_ind; + col witness ind_width; + col witness op; + col witness store_offset; + col witness jmp_offset1; + col witness jmp_offset2; + col witness flags; + + col witness multiplicity; + + lookup_proves(rom_bus_id, [line, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, b_src_ind, ind_width, + op, store_offset, jmp_offset1, jmp_offset2, flags], mul: multiplicity); +} \ No newline at end of file diff --git a/state-machines/rom/src/lib.rs b/state-machines/rom/src/lib.rs new file mode 100644 index 00000000..6c51134e --- /dev/null +++ b/state-machines/rom/src/lib.rs @@ -0,0 +1,3 @@ +mod rom; + +pub use rom::*; diff --git a/state-machines/rom/src/rom.rs b/state-machines/rom/src/rom.rs new file mode 100644 index 00000000..35c26212 --- /dev/null +++ b/state-machines/rom/src/rom.rs @@ -0,0 +1,363 @@ +use std::{path::PathBuf, sync::Arc}; + +use p3_field::Field; +use proofman::{WitnessComponent, WitnessManager}; +use proofman_common::{AirInstance, BufferAllocator, SetupCtx}; +use proofman_util::create_buffer_fast; + +use zisk_core::{Riscv2zisk, ZiskPcHistogram, ZiskRom, SRC_IMM, SRC_IND}; +use zisk_pil::{ + Pilout, RomL2Row, RomL2Trace, RomM1Row, RomM1Trace, RomS0Row, RomS0Trace, MAIN_AIRGROUP_ID, + MAIN_AIR_IDS, ROM_AIRGROUP_ID, ROM_L_AIR_IDS, ROM_M_AIR_IDS, ROM_S_AIR_IDS, +}; +//use ziskemu::ZiskEmulatorErr; +use std::error::Error; + +pub struct RomSM { + wcm: Arc>, +} + +impl RomSM { + pub fn new(wcm: Arc>) -> Arc { + let rom_sm = Self { wcm: wcm.clone() }; + let rom_sm = Arc::new(rom_sm); + + let rom_air_ids = &[ROM_S_AIR_IDS[0], ROM_M_AIR_IDS[0], ROM_L_AIR_IDS[0]]; + wcm.register_component(rom_sm.clone(), Some(ROM_AIRGROUP_ID), Some(rom_air_ids)); + + rom_sm + } + + pub fn prove( + &self, + rom: &ZiskRom, + pc_histogram: ZiskPcHistogram, + ) -> Result<(), Box> { + let buffer_allocator = self.wcm.get_ectx().buffer_allocator.clone(); + let sctx = self.wcm.get_sctx(); + + if pc_histogram.end_pc == 0 { + panic!("RomSM::prove() detected pc_histogram.end_pc == 0"); // TODO: return an error + } + + let main_trace_len = + self.wcm.get_pctx().pilout.get_air(MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]).num_rows() as u64; + + let (prover_buffer, _, air_id) = + Self::compute_trace_rom(rom, buffer_allocator, &sctx, pc_histogram, main_trace_len)?; + + let air_instance = + AirInstance::new(sctx.clone(), ROM_AIRGROUP_ID, air_id, None, prover_buffer); + self.wcm.get_pctx().air_instance_repo.add_air_instance(air_instance); + + Ok(()) + } + pub fn compute_trace( + rom_path: PathBuf, + buffer_allocator: Arc, + sctx: &SetupCtx, + ) -> Result<(Vec, u64, usize), Box> { + // Get the ELF file path as a string + let elf_filename: String = rom_path.to_str().unwrap().into(); + println!("Proving ROM for ELF file={}", elf_filename); + + // Load and parse the ELF file, and transpile it into a ZisK ROM using Riscv2zisk + + // Create an instance of the RISCV -> ZisK program converter + let riscv2zisk = Riscv2zisk::new(elf_filename, String::new(), String::new(), String::new()); + + // Convert program to rom + let rom_result = riscv2zisk.run(); + if rom_result.is_err() { + //return Err(ZiskEmulatorErr::Unknown(zisk_rom.err().unwrap().to_string())); + panic!("RomSM::prover() failed converting elf to rom"); + } + let rom = rom_result.unwrap(); + + let empty_pc_histogram = ZiskPcHistogram::default(); + + Self::compute_trace_rom(&rom, buffer_allocator, sctx, empty_pc_histogram, 0) + } + + pub fn compute_trace_rom( + rom: &ZiskRom, + buffer_allocator: Arc, + sctx: &SetupCtx, + pc_histogram: ZiskPcHistogram, + main_trace_len: u64, + ) -> Result<(Vec, u64, usize), Box> { + let pilout = Pilout::pilout(); + let sizes = ( + pilout.get_air(ROM_AIRGROUP_ID, ROM_S_AIR_IDS[0]).num_rows(), + pilout.get_air(ROM_AIRGROUP_ID, ROM_M_AIR_IDS[0]).num_rows(), + pilout.get_air(ROM_AIRGROUP_ID, ROM_L_AIR_IDS[0]).num_rows(), + ); + + let number_of_instructions = rom.insts.len(); + + match number_of_instructions { + n if n <= sizes.0 => Self::create_rom_s( + sizes.0, + rom, + n, + buffer_allocator, + sctx, + pc_histogram, + main_trace_len, + ), + n if n <= sizes.1 => Self::create_rom_m( + sizes.1, + rom, + n, + buffer_allocator, + sctx, + pc_histogram, + main_trace_len, + ), + n if n < sizes.2 => Self::create_rom_l( + sizes.2, + rom, + n, + buffer_allocator, + sctx, + pc_histogram, + main_trace_len, + ), + _ => panic!("RomSM::compute_trace() found rom too big size={}", number_of_instructions), + } + } + + fn create_rom_s( + rom_s_size: usize, + rom: &zisk_core::ZiskRom, + number_of_instructions: usize, + buffer_allocator: Arc, + sctx: &SetupCtx, + pc_histogram: ZiskPcHistogram, + main_trace_len: u64, + ) -> Result<(Vec, u64, usize), Box> { + // Set trace size + let trace_size = rom_s_size; + + // Allocate a prover buffer + let (buffer_size, offsets) = buffer_allocator + .get_buffer_info(sctx, ROM_AIRGROUP_ID, ROM_S_AIR_IDS[0]) + .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); + let mut prover_buffer = create_buffer_fast(buffer_size as usize); + + // Create an empty ROM trace + let mut rom_trace = + RomS0Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) + .expect("RomSM::compute_trace() failed mapping buffer to ROMS0Trace"); + + // For every instruction in the rom, fill its corresponding ROM trace + for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { + // Get the Zisk instruction + let inst = inst_builder.1.i; + + // Calculate the multiplicity, i.e. the number of times this pc is used in this + // execution + let mut multiplicity: u64; + if pc_histogram.map.is_empty() { + multiplicity = 1; // If the histogram is empty, we use 1 for all pc's + } else { + let counter = pc_histogram.map.get(&inst.paddr); + if counter.is_some() { + multiplicity = *counter.unwrap(); + if inst.paddr == pc_histogram.end_pc { + multiplicity += main_trace_len - (pc_histogram.steps % main_trace_len); + } + } else { + continue; // We skip those pc's that are not used in this execution + } + } + + // Fill the rom trace row fields + rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line + rom_trace[i].a_offset_imm0 = F::from_canonical_u64(inst.a_offset_imm0); + rom_trace[i].a_imm1 = + F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); + rom_trace[i].b_offset_imm0 = F::from_canonical_u64(inst.b_offset_imm0); + rom_trace[i].b_imm1 = + F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); + rom_trace[i].b_src_ind = + F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); + rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); + rom_trace[i].op = F::from_canonical_u8(inst.op); + rom_trace[i].store_offset = F::from_canonical_u64(inst.store_offset as u64); + rom_trace[i].jmp_offset1 = F::from_canonical_u64(inst.jmp_offset1 as u64); + rom_trace[i].jmp_offset2 = F::from_canonical_u64(inst.jmp_offset2 as u64); + rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); + rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); + /*println!( + "ROM SM [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}], {}", + inst.paddr, + inst.a_offset_imm0, + if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }, + inst.b_offset_imm0, + if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }, + if inst.b_src == SRC_IND { 1 } else { 0 }, + inst.ind_width, + inst.op, + inst.store_offset as u64, + inst.jmp_offset1 as u64, + inst.jmp_offset2 as u64, + inst.get_flags(), + multiplicity, + );*/ + } + + // Padd with zeroes + for i in number_of_instructions..trace_size { + rom_trace[i] = RomS0Row::default(); + } + + Ok((prover_buffer, offsets[0], ROM_S_AIR_IDS[0])) + } + + fn create_rom_m( + rom_m_size: usize, + rom: &zisk_core::ZiskRom, + number_of_instructions: usize, + buffer_allocator: Arc, + sctx: &SetupCtx, + pc_histogram: ZiskPcHistogram, + main_trace_len: u64, + ) -> Result<(Vec, u64, usize), Box> { + // Set trace size + let trace_size = rom_m_size; + + // Allocate a prover buffer + let (buffer_size, offsets) = buffer_allocator + .get_buffer_info(sctx, ROM_AIRGROUP_ID, ROM_M_AIR_IDS[0]) + .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); + let mut prover_buffer = create_buffer_fast(buffer_size as usize); + + // Create an empty ROM trace + let mut rom_trace = + RomM1Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) + .expect("RomSM::compute_trace() failed mapping buffer to ROMM0Trace"); + + // For every instruction in the rom, fill its corresponding ROM trace + for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { + // Get the Zisk instruction + let inst = inst_builder.1.i; + + // Calculate the multiplicity, i.e. the number of times this pc is used in this + // execution + let mut multiplicity: u64; + if pc_histogram.map.is_empty() { + multiplicity = 1; // If the histogram is empty, we use 1 for all pc's + } else { + let counter = pc_histogram.map.get(&inst.paddr); + if counter.is_some() { + multiplicity = *counter.unwrap(); + if inst.paddr == pc_histogram.end_pc { + multiplicity += main_trace_len - (pc_histogram.steps % main_trace_len); + } + } else { + continue; // We skip those pc's that are not used in this execution + } + } + + // Fill the rom trace row fields + rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line + rom_trace[i].a_offset_imm0 = F::from_canonical_u64(inst.a_offset_imm0); + rom_trace[i].a_imm1 = + F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); + rom_trace[i].b_offset_imm0 = F::from_canonical_u64(inst.b_offset_imm0); + rom_trace[i].b_imm1 = + F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); + rom_trace[i].b_src_ind = + F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); + rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); + rom_trace[i].op = F::from_canonical_u8(inst.op); + rom_trace[i].store_offset = F::from_canonical_u64(inst.store_offset as u64); + rom_trace[i].jmp_offset1 = F::from_canonical_u64(inst.jmp_offset1 as u64); + rom_trace[i].jmp_offset2 = F::from_canonical_u64(inst.jmp_offset2 as u64); + rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); + rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); + } + + // Padd with zeroes + for i in number_of_instructions..trace_size { + rom_trace[i] = RomM1Row::default(); + } + + Ok((prover_buffer, offsets[0], ROM_M_AIR_IDS[0])) + } + + fn create_rom_l( + rom_l_size: usize, + rom: &zisk_core::ZiskRom, + number_of_instructions: usize, + buffer_allocator: Arc, + sctx: &SetupCtx, + pc_histogram: ZiskPcHistogram, + main_trace_len: u64, + ) -> Result<(Vec, u64, usize), Box> { + // Set trace size + let trace_size = rom_l_size; + + // Allocate a prover buffer + let (buffer_size, offsets) = buffer_allocator + .get_buffer_info(sctx, ROM_AIRGROUP_ID, ROM_L_AIR_IDS[0]) + .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); + let mut prover_buffer = create_buffer_fast(buffer_size as usize); + + // Create an empty ROM trace + let mut rom_trace = + RomL2Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) + .expect("RomSM::compute_trace() failed mapping buffer to ROML0Trace"); + + // For every instruction in the rom, fill its corresponding ROM trace + for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { + // Get the Zisk instruction + let inst = inst_builder.1.i; + + // Calculate the multiplicity, i.e. the number of times this pc is used in this + // execution + let mut multiplicity: u64; + if pc_histogram.map.is_empty() { + multiplicity = 1; // If the histogram is empty, we use 1 for all pc's + } else { + let counter = pc_histogram.map.get(&inst.paddr); + if counter.is_some() { + multiplicity = *counter.unwrap(); + if inst.paddr == pc_histogram.end_pc { + multiplicity += main_trace_len - (pc_histogram.steps % main_trace_len); + } + } else { + continue; // We skip those pc's that are not used in this execution + } + } + + // Fill the rom trace row fields + rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line + rom_trace[i].a_offset_imm0 = F::from_canonical_u64(inst.a_offset_imm0); + rom_trace[i].a_imm1 = + F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); + rom_trace[i].b_offset_imm0 = F::from_canonical_u64(inst.b_offset_imm0); + rom_trace[i].b_imm1 = + F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); + rom_trace[i].b_src_ind = + F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); + rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); + rom_trace[i].op = F::from_canonical_u8(inst.op); + rom_trace[i].store_offset = F::from_canonical_u64(inst.store_offset as u64); + rom_trace[i].jmp_offset1 = F::from_canonical_u64(inst.jmp_offset1 as u64); + rom_trace[i].jmp_offset2 = F::from_canonical_u64(inst.jmp_offset2 as u64); + rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); + rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); + } + + // Padd with zeroes + for i in number_of_instructions..trace_size { + rom_trace[i] = RomL2Row::default(); + } + + Ok((prover_buffer, offsets[0], ROM_L_AIR_IDS[0])) + } +} + +impl WitnessComponent for RomSM {} diff --git a/witness-computation/Cargo.toml b/witness-computation/Cargo.toml index f2a4e229..89c97fa7 100644 --- a/witness-computation/Cargo.toml +++ b/witness-computation/Cargo.toml @@ -14,6 +14,7 @@ sm-freq-ops = { path = "../state-machines/freq-ops" } sm-main = { path = "../state-machines/main" } sm-mem = { path = "../state-machines/mem" } sm-quick-ops = { path = "../state-machines/quick-ops" } +sm-rom = { path = "../state-machines/rom" } zisk-pil = { path = "../pil" } proofman-common = { workspace = true } diff --git a/witness-computation/src/zisk_lib.rs b/witness-computation/src/zisk_lib.rs index 807eccd8..dd74be25 100644 --- a/witness-computation/src/zisk_lib.rs +++ b/witness-computation/src/zisk_lib.rs @@ -1,5 +1,6 @@ use pil_std_lib::Std; use proofman_util::{timer_start_info, timer_stop_and_log_info}; +use sm_rom::RomSM; use std::{error::Error, path::PathBuf, sync::Arc}; use zisk_pil::*; @@ -46,6 +47,7 @@ impl ZiskWitness { let std = Std::new(wcm.clone()); + let rom_sm = RomSM::new(wcm.clone()); let mem_sm = MemSM::new(wcm.clone()); let binary_sm = BinarySM::new(wcm.clone(), std.clone()); let arith_sm = ArithSM::new(wcm.clone()); @@ -53,7 +55,8 @@ impl ZiskWitness { let main_sm = MainSM::new( self.rom_path.clone(), wcm.clone(), - sctx.clone(), + sctx, + rom_sm, mem_sm, binary_sm, arith_sm, From 96de74c3e7f94c913839237acf0eedaff0042f09 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Mon, 28 Oct 2024 12:28:21 +0000 Subject: [PATCH 04/22] update main.pil --- state-machines/main/pil/main.pil | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 8e8dfcda..1f2e1f98 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -22,7 +22,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // // - it's possible reference previous row, but no next row. // - // - the first two rows has same STEP 0. + // - the first two rows has same SEGMENT_STEP 0. // // - global bus constraint with initial state of main (as initial PC) // [segment:0, is_last_segment: 0, pc: INITIAL_PC, a, b, c, flag] @@ -195,8 +195,8 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope a_src_sp * (a[index] - (index == 0 ? sp: 0 )) === 0; } a_src_step * (a[index] - (index == 0 ? STEP : 0)) === 0; - a_src_c * (a[index] - 'c[index]) === 0; - b_src_c * (b[index] - 'c[index]) === 0; + (1 - SEGMENT_L1) * a_src_c * (a[index] - 'c[index]) === 0; + (1 - SEGMENT_L1) * b_src_c * (b[index] - 'c[index]) === 0; a_src_imm * (a[index] - a_imm[index]) === 0; b_src_imm * (b[index] - b_imm[index]) === 0; @@ -242,7 +242,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // row = N-1 => bus_main_segment = 0 (proves) // - const expr bus_main_segment = main_segment - SEGMENT_LAST * (main_segment * main_last_segment + 1 - main_last_segment); + const expr bus_main_segment = main_segment - SEGMENT_LAST * (main_segment * main_last_segment - 1 + main_last_segment); permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, ...specific_registers, ...a, ...b, ...c, flag], sel: SEGMENT_LAST - SEGMENT_L1, name: PIOP_NAME_ISOLATED, bus_type: PIOP_BUS_SUM); @@ -271,7 +271,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope end * (1 - end) === 0; m32 * (1 - m32) === 0; - lookup_assumes(ROM_BUS_ID, [pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, b_src_ind, ind_width, + lookup_assumes(ROM_BUS_ID, [SEGMENT_L1 * (10000 - pc) + pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, b_src_ind, ind_width, op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1); } \ No newline at end of file From 5d94172517873c1dba83755cea8277eedc45fc92 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Mon, 28 Oct 2024 12:45:41 +0000 Subject: [PATCH 05/22] update pil, remove end column --- state-machines/main/pil/main.pil | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 1f2e1f98..09ed93b8 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -1,6 +1,9 @@ require "std_lookup.pil" const int BOOT_ADDR = 0x1000; +const int END_PC_ADDR = 0x2000; + +const int NOP_ROM_ADDR = 0x10000000; airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int operation_bus_id, int MAIN_CONTINUATION_ID = 1000) { @@ -106,7 +109,6 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope col witness jmp_offset1, jmp_offset2; // if flag, goto2, else goto 1 - col witness end; col witness m32; const expr addr_step = STEP * 3; @@ -222,8 +224,6 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope const expr next_pc = set_pc * (c[0] + jmp_offset1) + (1 - set_pc) * (pc + jmp_offset2) + flag * (jmp_offset1 - jmp_offset2); (1 - SEGMENT_L1') * (pc - 'next_pc) === 0; - // + end * L1' * (0x8000_0000 - (pc + jmp_offset1)); - const expr is_last_continuation = SEGMENT_LAST * main_last_segment; const expr specific_registers[stack_enabled ? 2:1]; specific_registers[0] = pc; @@ -246,9 +246,6 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, ...specific_registers, ...a, ...b, ...c, flag], sel: SEGMENT_LAST - SEGMENT_L1, name: PIOP_NAME_ISOLATED, bus_type: PIOP_BUS_SUM); - // BOOT_ADDR es called from - // L1 * (pc - BOOT_ADDR) === 0; // when end of program jump to this address - flag * (1 - flag) === 0; @@ -256,7 +253,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // match with main trace. const expr rom_flags = 1 + 2 * a_src_imm + 4 * a_src_mem + 8 * a_src_step + 16 * b_src_imm + 32 * b_src_mem + 64 * is_external_op + 128 * store_ra + 256 * store_mem + 512 * store_ind + - + 1024 * set_pc + 2048 * end + 4096 * m32; + + 1024 * set_pc + 2048 * m32; a_src_imm * (1 - a_src_imm) === 0; a_src_mem * (1 - a_src_mem) === 0; @@ -268,10 +265,10 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope store_mem * (1 - store_mem) === 0; store_ind * (1 - store_ind) === 0; set_pc * (1 - set_pc) === 0; - end * (1 - end) === 0; m32 * (1 - m32) === 0; - lookup_assumes(ROM_BUS_ID, [SEGMENT_L1 * (10000 - pc) + pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, b_src_ind, ind_width, + + lookup_assumes(ROM_BUS_ID, [SEGMENT_L1 * (NOP_ROM_ADDR - pc) + pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, b_src_ind, ind_width, op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1); } \ No newline at end of file From 30f3124c6157d4cefa921a85b28ff857450526b5 Mon Sep 17 00:00:00 2001 From: Ricard Borrell <75077385+rickb80@users.noreply.github.com> Date: Mon, 28 Oct 2024 18:50:50 +0100 Subject: [PATCH 06/22] Distributed WC (#134) * Remove threads pool and unregistrations * Add distribution context * solve multiplicities par reduction * Added segment id * remove old threads_controller code --------- Co-authored-by: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> --- Cargo.lock | 38 ++-- Cargo.toml | 12 +- state-machines/arith/src/arith.rs | 26 +-- state-machines/binary/src/binary.rs | 41 +--- state-machines/binary/src/binary_basic.rs | 77 +++---- .../binary/src/binary_basic_table.rs | 80 ++++--- state-machines/binary/src/binary_extension.rs | 80 +++---- .../binary/src/binary_extension_table.rs | 87 +++++--- state-machines/common/src/lib.rs | 2 - .../common/src/thread_controller.rs | 59 ----- state-machines/main/src/main_sm.rs | 201 ++++++++++-------- state-machines/mem/src/mem.rs | 8 +- state-machines/rom/src/rom.rs | 9 +- 13 files changed, 318 insertions(+), 402 deletions(-) delete mode 100644 state-machines/common/src/thread_controller.rs diff --git a/Cargo.lock b/Cargo.lock index 7a376da7..3d02d119 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -770,9 +770,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", @@ -1322,7 +1322,7 @@ dependencies = [ [[package]] name = "pil-std-lib" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "log", "num-bigint", @@ -1340,7 +1340,7 @@ dependencies = [ [[package]] name = "pilout" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "bytes", "log", @@ -1460,7 +1460,7 @@ dependencies = [ [[package]] name = "proofman" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "colored", "env_logger", @@ -1481,7 +1481,7 @@ dependencies = [ [[package]] name = "proofman-common" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "env_logger", "log", @@ -1499,7 +1499,7 @@ dependencies = [ [[package]] name = "proofman-hints" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "p3-field", "proofman-common", @@ -1509,7 +1509,7 @@ dependencies = [ [[package]] name = "proofman-macros" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "proc-macro2", "quote", @@ -1519,7 +1519,7 @@ dependencies = [ [[package]] name = "proofman-starks-lib-c" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "log", ] @@ -1527,7 +1527,7 @@ dependencies = [ [[package]] name = "proofman-util" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "colored", "sysinfo 0.31.4", @@ -1870,9 +1870,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.15" +version = "0.23.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" +checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" dependencies = [ "once_cell", "ring", @@ -1937,18 +1937,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", @@ -2158,7 +2158,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stark" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "log", "p3-field", @@ -2467,7 +2467,7 @@ dependencies = [ [[package]] name = "transcript" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#3e90c1fb8a235ef37f236612d6127079f260b9b6" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#272603df3f069ef4965ed262e1d43d7ac2a83c12" dependencies = [ "proofman-starks-lib-c", ] diff --git a/Cargo.toml b/Cargo.toml index 8208fb92..a1029f64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,12 +33,12 @@ proofman = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", branc pil-std-lib = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", branch ="develop" } stark = { git = "https://github.com/0xPolygonHermez/pil2-proofman.git", branch ="develop" } #Local development -# proofman-common = { path = "../pil2-proofman/common" } -# proofman-macros = { path = "../pil2-proofman/macros" } -# proofman-util = { path = "../pil2-proofman/util" } -# proofman = { path = "../pil2-proofman/proofman" } -# pil-std-lib = { path = "../pil2-proofman/pil2-components/lib/std/rs" } -# stark = { path = "../pil2-proofman/provers/stark" } +#proofman-common = { path = "../pil2-proofman/common" } +#proofman-macros = { path = "../pil2-proofman/macros" } +#proofman-util = { path = "../pil2-proofman/util" } +#proofman = { path = "../pil2-proofman/proofman" } +#pil-std-lib = { path = "../pil2-proofman/pil2-components/lib/std/rs" } +#stark = { path = "../pil2-proofman/provers/stark" } p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } log = "0.4" diff --git a/state-machines/arith/src/arith.rs b/state-machines/arith/src/arith.rs index f26e6177..e0503bff 100644 --- a/state-machines/arith/src/arith.rs +++ b/state-machines/arith/src/arith.rs @@ -8,7 +8,7 @@ use p3_field::Field; use proofman::{WitnessComponent, WitnessManager}; use proofman_common::{ExecutionCtx, ProofCtx, SetupCtx}; use rayon::Scope; -use sm_common::{OpResult, Provable, ThreadController}; +use sm_common::{OpResult, Provable}; use zisk_core::{zisk_ops::ZiskOp, ZiskRequiredOperation}; const PROVE_CHUNK_SIZE: usize = 1 << 12; @@ -18,9 +18,6 @@ pub struct ArithSM { // Count of registered predecessors registered_predecessors: AtomicU32, - // Thread controller to manage the execution of the state machines - threads_controller: Arc, - // Inputs inputs32: Mutex>, inputs64: Mutex>, @@ -39,7 +36,6 @@ impl ArithSM { let arith_sm = Self { registered_predecessors: AtomicU32::new(0), - threads_controller: Arc::new(ThreadController::new()), inputs32: Mutex::new(Vec::new()), inputs64: Mutex::new(Vec::new()), arith32_sm, @@ -65,8 +61,6 @@ impl ArithSM { if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { >::prove(self, &[], true, scope); - self.threads_controller.wait_for_threads(); - self.arith3264_sm.unregister_predecessor::(scope); self.arith64_sm.unregister_predecessor::(scope); self.arith32_sm.unregister_predecessor::(scope); @@ -127,14 +121,7 @@ impl Provable for ArithSM { let drained_inputs32 = inputs32.drain(..num_drained32).collect::>(); let arith32_sm_cloned = self.arith32_sm.clone(); - self.threads_controller.add_working_thread(); - let thread_controller = self.threads_controller.clone(); - - scope.spawn(move |scope| { - arith32_sm_cloned.prove(&drained_inputs32, drain, scope); - - thread_controller.remove_working_thread(); - }); + arith32_sm_cloned.prove(&drained_inputs32, drain, scope); } drop(inputs32); @@ -150,14 +137,7 @@ impl Provable for ArithSM { let drained_inputs64 = inputs64.drain(..num_drained64).collect::>(); let arith64_sm_cloned = self.arith64_sm.clone(); - self.threads_controller.add_working_thread(); - let thread_controller = self.threads_controller.clone(); - - scope.spawn(move |scope| { - arith64_sm_cloned.prove(&drained_inputs64, drain, scope); - - thread_controller.remove_working_thread(); - }); + arith64_sm_cloned.prove(&drained_inputs64, drain, scope); } drop(inputs64); } diff --git a/state-machines/binary/src/binary.rs b/state-machines/binary/src/binary.rs index 57bb7e6a..0acc615d 100644 --- a/state-machines/binary/src/binary.rs +++ b/state-machines/binary/src/binary.rs @@ -8,7 +8,7 @@ use p3_field::PrimeField; use pil_std_lib::Std; use proofman::{WitnessComponent, WitnessManager}; use rayon::Scope; -use sm_common::{OpResult, Provable, ThreadController}; +use sm_common::{OpResult, Provable}; use zisk_core::ZiskRequiredOperation; use zisk_pil::{ BINARY_AIRGROUP_ID, BINARY_AIR_IDS, BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS, @@ -23,9 +23,6 @@ pub struct BinarySM { // Count of registered predecessors registered_predecessors: AtomicU32, - // Thread controller to manage the execution of the state machines - threads_controller: Arc, - // Inputs inputs_basic: Mutex>, inputs_extension: Mutex>, @@ -61,7 +58,6 @@ impl BinarySM { let binary_sm = Self { registered_predecessors: AtomicU32::new(0), - threads_controller: Arc::new(ThreadController::new()), inputs_basic: Mutex::new(Vec::new()), inputs_extension: Mutex::new(Vec::new()), binary_basic_sm, @@ -81,18 +77,18 @@ impl BinarySM { self.registered_predecessors.fetch_add(1, Ordering::SeqCst); } - pub fn unregister_predecessor(&self, scope: &Scope) { + pub fn unregister_predecessor(&self) { if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { - as Provable>::prove( + /* as Provable>::prove( self, &[], true, scope, - ); - self.threads_controller.wait_for_threads(); + );*/ + //self.threads_controller.wait_for_threads(); - self.binary_basic_sm.unregister_predecessor(scope); - self.binary_extension_sm.unregister_predecessor(scope); + self.binary_basic_sm.unregister_predecessor(); + self.binary_extension_sm.unregister_predecessor(); } } @@ -102,12 +98,11 @@ impl BinarySM { is_extension: bool, prover_buffer: &mut [F], offset: u64, - scope: &Scope, ) { if !is_extension { - self.binary_basic_sm.prove_instance(operations, prover_buffer, offset, scope); + self.binary_basic_sm.prove_instance(operations, prover_buffer, offset); } else { - self.binary_extension_sm.prove_instance(operations, prover_buffer, offset, scope); + self.binary_extension_sm.prove_instance(operations, prover_buffer, offset); } } } @@ -142,14 +137,7 @@ impl Provable for BinarySM { let binary_basic_sm_cloned = self.binary_basic_sm.clone(); - self.threads_controller.add_working_thread(); - let thread_controller = self.threads_controller.clone(); - - scope.spawn(move |scope| { - binary_basic_sm_cloned.prove(&drained_inputs_basic, false, scope); - - thread_controller.remove_working_thread(); - }); + binary_basic_sm_cloned.prove(&drained_inputs_basic, false, scope); } drop(inputs_basic); @@ -163,14 +151,7 @@ impl Provable for BinarySM { inputs_extension.drain(..num_drained_extension).collect::>(); let binary_extension_sm_cloned = self.binary_extension_sm.clone(); - self.threads_controller.add_working_thread(); - let thread_controller = self.threads_controller.clone(); - - scope.spawn(move |scope| { - binary_extension_sm_cloned.prove(&drained_inputs_extension, false, scope); - - thread_controller.remove_working_thread(); - }); + binary_extension_sm_cloned.prove(&drained_inputs_extension, false, scope); } drop(inputs_extension); } diff --git a/state-machines/binary/src/binary_basic.rs b/state-machines/binary/src/binary_basic.rs index b1d368ac..444dd19b 100644 --- a/state-machines/binary/src/binary_basic.rs +++ b/state-machines/binary/src/binary_basic.rs @@ -9,7 +9,7 @@ use proofman::{WitnessComponent, WitnessManager}; use proofman_common::AirInstance; use proofman_util::{timer_start_trace, timer_stop_and_log_trace}; use rayon::Scope; -use sm_common::{create_prover_buffer, OpResult, Provable, ThreadController}; +use sm_common::{create_prover_buffer, OpResult, Provable}; use std::cmp::Ordering as CmpOrdering; use zisk_core::{zisk_ops::ZiskOp, ZiskRequiredOperation}; use zisk_pil::*; @@ -22,9 +22,6 @@ pub struct BinaryBasicSM { // Count of registered predecessors registered_predecessors: AtomicU32, - // Thread controller to manage the execution of the state machines - threads_controller: Arc, - // Inputs inputs: Mutex>, @@ -49,7 +46,6 @@ impl BinaryBasicSM { let binary_basic = Self { wcm: wcm.clone(), registered_predecessors: AtomicU32::new(0), - threads_controller: Arc::new(ThreadController::new()), inputs: Mutex::new(Vec::new()), binary_basic_table_sm, }; @@ -66,18 +62,16 @@ impl BinaryBasicSM { self.registered_predecessors.fetch_add(1, Ordering::SeqCst); } - pub fn unregister_predecessor(&self, scope: &Scope) { + pub fn unregister_predecessor(&self) { if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { - as Provable>::prove( + /* as Provable>::prove( self, &[], true, scope, - ); - - self.threads_controller.wait_for_threads(); + );*/ - self.binary_basic_table_sm.unregister_predecessor(scope); + self.binary_basic_table_sm.unregister_predecessor(); } } @@ -651,7 +645,6 @@ impl BinaryBasicSM { operations: Vec, prover_buffer: &mut [F], offset: u64, - scope: &Scope, ) { Self::prove_internal( &self.wcm, @@ -659,7 +652,6 @@ impl BinaryBasicSM { operations, prover_buffer, offset, - scope, ); } @@ -669,7 +661,6 @@ impl BinaryBasicSM { operations: Vec, prover_buffer: &mut [F], offset: u64, - scope: &Scope, ) { timer_start_trace!(BINARY_TRACE); let pctx = wcm.get_pctx(); @@ -730,7 +721,7 @@ impl BinaryBasicSM { binary_basic_table_sm.process_slice(&multiplicity_table); timer_stop_and_log_trace!(BINARY_TABLE); - scope.spawn(|_| { + std::thread::spawn(move || { drop(operations); drop(multiplicity_table); }); @@ -740,7 +731,7 @@ impl BinaryBasicSM { impl WitnessComponent for BinaryBasicSM {} impl Provable for BinaryBasicSM { - fn prove(&self, operations: &[ZiskRequiredOperation], drain: bool, scope: &Scope) { + fn prove(&self, operations: &[ZiskRequiredOperation], drain: bool, _scope: &Scope) { if let Ok(mut inputs) = self.inputs.lock() { inputs.extend_from_slice(operations); @@ -754,39 +745,31 @@ impl Provable for BinaryBasicSM { let binary_basic_table_sm = self.binary_basic_table_sm.clone(); let wcm = self.wcm.clone(); - self.threads_controller.add_working_thread(); - let thread_controller = self.threads_controller.clone(); - let sctx = self.wcm.get_sctx().clone(); - scope.spawn(move |scope| { - let (mut prover_buffer, offset) = create_prover_buffer( - &wcm.get_ectx(), - &wcm.get_sctx(), - BINARY_AIRGROUP_ID, - BINARY_AIR_IDS[0], - ); - - Self::prove_internal( - &wcm, - &binary_basic_table_sm, - drained_inputs, - &mut prover_buffer, - offset, - scope, - ); - - let air_instance = AirInstance::new( - sctx, - BINARY_AIRGROUP_ID, - BINARY_AIR_IDS[0], - None, - prover_buffer, - ); - wcm.get_pctx().air_instance_repo.add_air_instance(air_instance); - - thread_controller.remove_working_thread(); - }); + let (mut prover_buffer, offset) = create_prover_buffer( + &wcm.get_ectx(), + &wcm.get_sctx(), + BINARY_AIRGROUP_ID, + BINARY_AIR_IDS[0], + ); + + Self::prove_internal( + &wcm, + &binary_basic_table_sm, + drained_inputs, + &mut prover_buffer, + offset, + ); + + let air_instance = AirInstance::new( + sctx, + BINARY_AIRGROUP_ID, + BINARY_AIR_IDS[0], + None, + prover_buffer, + ); + wcm.get_pctx().air_instance_repo.add_air_instance(air_instance, None); } } } diff --git a/state-machines/binary/src/binary_basic_table.rs b/state-machines/binary/src/binary_basic_table.rs index 02b51888..df028e77 100644 --- a/state-machines/binary/src/binary_basic_table.rs +++ b/state-machines/binary/src/binary_basic_table.rs @@ -7,7 +7,7 @@ use log::info; use p3_field::Field; use proofman::{WitnessComponent, WitnessManager}; use proofman_common::AirInstance; -use rayon::{prelude::*, Scope}; +use rayon::prelude::*; use sm_common::create_prover_buffer; use zisk_core::{zisk_ops::ZiskOp, P2_16, P2_17, P2_18, P2_19, P2_8}; use zisk_pil::{BINARY_TABLE_AIRGROUP_ID, BINARY_TABLE_AIR_IDS}; @@ -71,38 +71,9 @@ impl BinaryBasicTableSM { self.registered_predecessors.fetch_add(1, Ordering::SeqCst); } - pub fn unregister_predecessor(&self, _: &Scope) { + pub fn unregister_predecessor(&self) { if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { - // Create the prover buffer - let (mut prover_buffer, offset) = create_prover_buffer( - &self.wcm.get_ectx(), - &self.wcm.get_sctx(), - BINARY_TABLE_AIRGROUP_ID, - BINARY_TABLE_AIR_IDS[0], - ); - - let multiplicity = self.multiplicity.lock().unwrap(); - - prover_buffer[offset as usize..offset as usize + self.num_rows] - .par_iter_mut() - .enumerate() - .for_each(|(i, input)| *input = F::from_canonical_u64(multiplicity[i])); - - info!( - "{}: ··· Creating Binary basic table instance [{} rows filled 100%]", - Self::MY_NAME, - self.num_rows, - ); - - let air_instance = AirInstance::new( - self.wcm.get_sctx().clone(), - BINARY_TABLE_AIRGROUP_ID, - BINARY_TABLE_AIR_IDS[0], - None, - prover_buffer, - ); - let pctx = self.wcm.get_pctx(); - pctx.air_instance_repo.add_air_instance(air_instance); + self.create_air_instance(); } } @@ -243,6 +214,51 @@ impl BinaryBasicTableSM { //_ => panic!("BinaryBasicTableSM::offset_opcode() got invalid opcode={:?}", opcode), } } + + pub fn create_air_instance(&self) { + let ectx = self.wcm.get_ectx(); + let mut dctx: std::sync::RwLockWriteGuard<'_, proofman_common::DistributionCtx> = + ectx.dctx.write().unwrap(); + let mut multiplicity = self.multiplicity.lock().unwrap(); + + let (is_myne, instance_global_idx) = + dctx.add_instance(BINARY_TABLE_AIRGROUP_ID, BINARY_TABLE_AIR_IDS[0], 1); + let owner: usize = dctx.owner(instance_global_idx); + + let mut multiplicity_ = std::mem::take(&mut *multiplicity); + dctx.distribute_multiplicity(&mut multiplicity_, owner); + + if is_myne { + // Create the prover buffer + let (mut prover_buffer, offset) = create_prover_buffer( + &self.wcm.get_ectx(), + &self.wcm.get_sctx(), + BINARY_TABLE_AIRGROUP_ID, + BINARY_TABLE_AIR_IDS[0], + ); + prover_buffer[offset as usize..offset as usize + self.num_rows] + .par_iter_mut() + .enumerate() + .for_each(|(i, input)| *input = F::from_canonical_u64(multiplicity_[i])); + + info!( + "{}: ··· Creating Binary basic table instance [{} rows filled 100%]", + Self::MY_NAME, + self.num_rows, + ); + let air_instance = AirInstance::new( + self.wcm.get_sctx(), + BINARY_TABLE_AIRGROUP_ID, + BINARY_TABLE_AIR_IDS[0], + None, + prover_buffer, + ); + self.wcm + .get_pctx() + .air_instance_repo + .add_air_instance(air_instance, Some(instance_global_idx)); + } + } } impl WitnessComponent for BinaryBasicTableSM {} diff --git a/state-machines/binary/src/binary_extension.rs b/state-machines/binary/src/binary_extension.rs index cac0ad19..dbd8f409 100644 --- a/state-machines/binary/src/binary_extension.rs +++ b/state-machines/binary/src/binary_extension.rs @@ -15,7 +15,7 @@ use proofman::{WitnessComponent, WitnessManager}; use proofman_common::AirInstance; use proofman_util::{timer_start_debug, timer_stop_and_log_debug}; use rayon::Scope; -use sm_common::{create_prover_buffer, OpResult, Provable, ThreadController}; +use sm_common::{create_prover_buffer, OpResult, Provable}; use zisk_core::{zisk_ops::ZiskOp, ZiskRequiredOperation}; use zisk_pil::*; @@ -42,9 +42,6 @@ pub struct BinaryExtensionSM { // Count of registered predecessors registered_predecessors: AtomicU32, - // Thread controller to manage the execution of the state machines - threads_controller: Arc, - // Inputs inputs: Mutex>, @@ -71,7 +68,6 @@ impl BinaryExtensionSM { wcm: wcm.clone(), std: std.clone(), registered_predecessors: AtomicU32::new(0), - threads_controller: Arc::new(ThreadController::new()), inputs: Mutex::new(Vec::new()), binary_extension_table_sm, }; @@ -90,18 +86,16 @@ impl BinaryExtensionSM { self.registered_predecessors.fetch_add(1, Ordering::SeqCst); } - pub fn unregister_predecessor(&self, scope: &Scope) { + pub fn unregister_predecessor(&self) { if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { - as Provable>::prove( + /* as Provable>::prove( self, &[], true, scope, - ); + );*/ - self.threads_controller.wait_for_threads(); - - self.binary_extension_table_sm.unregister_predecessor(scope); + self.binary_extension_table_sm.unregister_predecessor(); self.std.unregister_predecessor(self.wcm.get_pctx(), None); } @@ -373,7 +367,6 @@ impl BinaryExtensionSM { operations: Vec, prover_buffer: &mut [F], offset: u64, - scope: &Scope, ) { Self::prove_internal( &self.wcm, @@ -382,7 +375,6 @@ impl BinaryExtensionSM { operations, prover_buffer, offset, - scope, ); } @@ -393,7 +385,6 @@ impl BinaryExtensionSM { operations: Vec, prover_buffer: &mut [F], offset: u64, - scope: &Scope, ) { timer_start_debug!(BINARY_EXTENSION_TRACE); let pctx = wcm.get_pctx(); @@ -460,7 +451,7 @@ impl BinaryExtensionSM { } timer_stop_and_log_debug!(BINARY_EXTENSION_RANGE); - scope.spawn(|_| { + std::thread::spawn(move || { drop(operations); drop(multiplicity_table); drop(range_check); @@ -471,7 +462,7 @@ impl BinaryExtensionSM { impl WitnessComponent for BinaryExtensionSM {} impl Provable for BinaryExtensionSM { - fn prove(&self, operations: &[ZiskRequiredOperation], drain: bool, scope: &Scope) { + fn prove(&self, operations: &[ZiskRequiredOperation], drain: bool, _scope: &Scope) { if let Ok(mut inputs) = self.inputs.lock() { inputs.extend_from_slice(operations); @@ -486,43 +477,34 @@ impl Provable for BinaryExtensio let binary_extension_table_sm = self.binary_extension_table_sm.clone(); let wcm = self.wcm.clone(); - self.threads_controller.add_working_thread(); - let thread_controller = self.threads_controller.clone(); - let std = self.std.clone(); let sctx = self.wcm.get_sctx().clone(); - let pctx_cloned = pctx.clone(); - scope.spawn(move |scope| { - let (mut prover_buffer, offset) = create_prover_buffer( - &wcm.get_ectx(), - &wcm.get_sctx(), - BINARY_EXTENSION_AIRGROUP_ID, - BINARY_EXTENSION_AIR_IDS[0], - ); - - Self::prove_internal( - &wcm, - &binary_extension_table_sm, - &std, - drained_inputs, - &mut prover_buffer, - offset, - scope, - ); - - let air_instance = AirInstance::new( - sctx, - BINARY_EXTENSION_AIRGROUP_ID, - BINARY_EXTENSION_AIR_IDS[0], - None, - prover_buffer, - ); - pctx_cloned.air_instance_repo.add_air_instance(air_instance); - - thread_controller.remove_working_thread(); - }); + let (mut prover_buffer, offset) = create_prover_buffer( + &wcm.get_ectx(), + &wcm.get_sctx(), + BINARY_EXTENSION_AIRGROUP_ID, + BINARY_EXTENSION_AIR_IDS[0], + ); + + Self::prove_internal( + &wcm, + &binary_extension_table_sm, + &std, + drained_inputs, + &mut prover_buffer, + offset, + ); + + let air_instance = AirInstance::new( + sctx, + BINARY_EXTENSION_AIRGROUP_ID, + BINARY_EXTENSION_AIR_IDS[0], + None, + prover_buffer, + ); + wcm.get_pctx().air_instance_repo.add_air_instance(air_instance, None); } } } diff --git a/state-machines/binary/src/binary_extension_table.rs b/state-machines/binary/src/binary_extension_table.rs index d17fa624..8c88018b 100644 --- a/state-machines/binary/src/binary_extension_table.rs +++ b/state-machines/binary/src/binary_extension_table.rs @@ -7,7 +7,7 @@ use log::info; use p3_field::Field; use proofman::{WitnessComponent, WitnessManager}; use proofman_common::AirInstance; -use rayon::{prelude::*, Scope}; +use rayon::prelude::*; use sm_common::create_prover_buffer; use zisk_core::{zisk_ops::ZiskOp, P2_11, P2_19, P2_8}; use zisk_pil::{BINARY_EXTENSION_TABLE_AIRGROUP_ID, BINARY_EXTENSION_TABLE_AIR_IDS}; @@ -67,39 +67,9 @@ impl BinaryExtensionTableSM { self.registered_predecessors.fetch_add(1, Ordering::SeqCst); } - pub fn unregister_predecessor(&self, _: &Scope) { + pub fn unregister_predecessor(&self) { if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { - // Create the prover buffer - let (mut prover_buffer, offset) = create_prover_buffer( - &self.wcm.get_ectx(), - &self.wcm.get_sctx(), - BINARY_EXTENSION_TABLE_AIRGROUP_ID, - BINARY_EXTENSION_TABLE_AIR_IDS[0], - ); - - let multiplicity = self.multiplicity.lock().unwrap(); - - prover_buffer[offset as usize..offset as usize + self.num_rows] - .par_iter_mut() - .enumerate() - .for_each(|(i, input)| *input = F::from_canonical_u64(multiplicity[i])); - - info!( - "{}: ··· Creating Binary extension table instance [{} rows filled 100%]", - Self::MY_NAME, - self.num_rows, - ); - - let air_instance = AirInstance::new( - self.wcm.get_sctx().clone(), - BINARY_EXTENSION_TABLE_AIRGROUP_ID, - BINARY_EXTENSION_TABLE_AIR_IDS[0], - None, - prover_buffer, - ); - - let pctx = self.wcm.get_pctx(); - pctx.air_instance_repo.add_air_instance(air_instance); + self.create_air_instance(); } } @@ -152,6 +122,57 @@ impl BinaryExtensionTableSM { //_ => panic!("BinaryExtensionTableSM::offset_opcode() got invalid opcode={:?}", opcode), } } + + pub fn create_air_instance(&self) { + let ectx = self.wcm.get_ectx(); + let mut dctx: std::sync::RwLockWriteGuard<'_, proofman_common::DistributionCtx> = + ectx.dctx.write().unwrap(); + + let mut multiplicity = self.multiplicity.lock().unwrap(); + + let (is_myne, instance_global_idx) = dctx.add_instance( + BINARY_EXTENSION_TABLE_AIRGROUP_ID, + BINARY_EXTENSION_TABLE_AIR_IDS[0], + 1, + ); + let owner = dctx.owner(instance_global_idx); + + let mut multiplicity_ = std::mem::take(&mut *multiplicity); + dctx.distribute_multiplicity(&mut multiplicity_, owner); + + if is_myne { + // Create the prover buffer + let (mut prover_buffer, offset) = create_prover_buffer( + &self.wcm.get_ectx(), + &self.wcm.get_sctx(), + BINARY_EXTENSION_TABLE_AIRGROUP_ID, + BINARY_EXTENSION_TABLE_AIR_IDS[0], + ); + + prover_buffer[offset as usize..offset as usize + self.num_rows] + .par_iter_mut() + .enumerate() + .for_each(|(i, input)| *input = F::from_canonical_u64(multiplicity_[i])); + + info!( + "{}: ··· Creating Binary extension table instance [{} rows filled 100%]", + Self::MY_NAME, + self.num_rows, + ); + + let air_instance = AirInstance::new( + self.wcm.get_sctx(), + BINARY_EXTENSION_TABLE_AIRGROUP_ID, + BINARY_EXTENSION_TABLE_AIR_IDS[0], + None, + prover_buffer, + ); + self.wcm + .get_pctx() + .air_instance_repo + .add_air_instance(air_instance, Some(instance_global_idx)); + } + } } impl WitnessComponent for BinaryExtensionTableSM {} diff --git a/state-machines/common/src/lib.rs b/state-machines/common/src/lib.rs index 4072c7bd..01104c8c 100644 --- a/state-machines/common/src/lib.rs +++ b/state-machines/common/src/lib.rs @@ -2,7 +2,6 @@ mod operations; mod provable; mod session; mod temp; -mod thread_controller; mod worker; pub use operations::*; @@ -11,7 +10,6 @@ use proofman_util::create_buffer_fast; pub use provable::*; pub use session::*; pub use temp::*; -pub use thread_controller::*; pub use worker::*; pub fn create_prover_buffer( diff --git a/state-machines/common/src/thread_controller.rs b/state-machines/common/src/thread_controller.rs deleted file mode 100644 index a312a269..00000000 --- a/state-machines/common/src/thread_controller.rs +++ /dev/null @@ -1,59 +0,0 @@ -use std::sync::{ - atomic::{AtomicU32, Ordering}, - Condvar, Mutex, -}; - -/// A struct to track the number of active threads and allows waiting for all threads to complete -/// before proceeding with further operations. -pub struct ThreadController { - // An atomic counter for tracking the number of active working threads. - working_threads: AtomicU32, - - // A mutex used to synchronize access to the condition variable. - mutex: Mutex<()>, - - // A condition variable used to notify waiting threads when all working threads are done. - condvar: Condvar, -} - -impl Default for ThreadController { - fn default() -> Self { - Self::new() - } -} - -impl ThreadController { - pub fn new() -> ThreadController { - ThreadController { - working_threads: AtomicU32::new(0), - mutex: Mutex::new(()), - condvar: Condvar::new(), - } - } - - /// Blocks the calling thread until all working threads have completed. - /// This is done by waiting on a condition variable, which will be signaled when - /// the number of working threads reaches zero. - pub fn wait_for_threads(&self) { - let mut guard = self.mutex.lock().unwrap(); - - while self.working_threads.load(Ordering::Acquire) > 0 { - guard = self.condvar.wait(guard).unwrap(); - } - } - - /// Increments the count of active working threads. This is typically called - /// when a new thread is started and begins performing work. - pub fn add_working_thread(&self) { - self.working_threads.fetch_add(1, Ordering::Release); - } - - /// Decrements the count of active working threads. If this brings the count - /// to zero, it notifies any threads waiting for all work to complete. - pub fn remove_working_thread(&self) { - if self.working_threads.fetch_sub(1, Ordering::Release) == 1 { - let _guard = self.mutex.lock().unwrap(); - self.condvar.notify_all(); - } - } -} diff --git a/state-machines/main/src/main_sm.rs b/state-machines/main/src/main_sm.rs index d58b21fb..9bdc4647 100644 --- a/state-machines/main/src/main_sm.rs +++ b/state-machines/main/src/main_sm.rs @@ -4,7 +4,7 @@ use sm_rom::RomSM; use core::panic; use proofman_util::{timer_start_debug, timer_stop_and_log_debug}; -use rayon::{prelude::*, ThreadPoolBuilder}; +use rayon::prelude::*; use sm_binary::BinarySM; use std::{ fs, @@ -33,6 +33,8 @@ pub struct InstanceExtensionCtx { pub offset: u64, pub op_type: ZiskOperationType, pub emu_trace_start: EmuTraceStart, + pub segment_id: Option, + pub instance_global_idx: usize, pub air_instance: Option>, } @@ -42,9 +44,19 @@ impl InstanceExtensionCtx { offset: u64, op_type: ZiskOperationType, emu_trace_start: EmuTraceStart, + segment_id: Option, + instance_global_idx: usize, air_instance: Option>, ) -> Self { - Self { prover_buffer, offset, op_type, emu_trace_start, air_instance } + Self { + prover_buffer, + offset, + op_type, + emu_trace_start, + instance_global_idx, + segment_id, + air_instance, + } } } /// This is a multithreaded implementation of the Zisk MainSM state machine. @@ -159,7 +171,6 @@ impl MainSM { ) { // Create a thread pool to manage the execution of all the state machines related to the // execution process - let pool = ThreadPoolBuilder::new().build().unwrap(); // Prepare the settings for the emulator let emu_options = EmuOptions { @@ -194,104 +205,110 @@ impl MainSM { op_sizes[ZiskOperationType::Binary as usize] = air_binary.num_rows() as u64; op_sizes[ZiskOperationType::BinaryE as usize] = air_binary_e.num_rows() as u64; - pool.scope(|scope| { - // FIXME: This is a temporary solution to run the emulator in parallel with the ROM SM - // Spawn the ROM thread - let rom_sm = self.rom_sm.clone(); - let zisk_rom = self.zisk_rom.clone(); - let pc_histogram = ZiskEmulator::process_rom_pc_histogram( - &self.zisk_rom, - &public_inputs, - &emu_options, - ) - .expect("MainSM::execute() failed calling ZiskEmulator::process_rom_pc_histogram()"); - let handle_rom = std::thread::spawn(move || rom_sm.prove(&zisk_rom, pc_histogram)); - - // Run the emulator in parallel n times to collect execution traces - // and record the execution starting points for each AIR instance - timer_start_debug!(PAR_PROCESS_ROM); - let (emu_traces, mut emu_slices) = ZiskEmulator::par_process_rom::( - &self.zisk_rom, - &public_inputs, - &emu_options, - Self::NUM_THREADS, - op_sizes, - ) - .expect("Error during emulator execution"); - timer_stop_and_log_debug!(PAR_PROCESS_ROM); - - emu_slices.points.sort_by(|a, b| a.op_type.partial_cmp(&b.op_type).unwrap()); - - // FIXME: This is a temporary solution to run the emulator in parallel with the ROM SM - handle_rom.join().unwrap().expect("Error during ROM witness computation"); - - let mut instances_ctx: Vec> = - Vec::with_capacity(emu_slices.points.len()); - - let mut dctx = ectx.dctx.write().unwrap(); - for (idx, emu_slice) in emu_slices.points.iter().enumerate() { - let (airgroup_id, air_id) = match emu_slice.op_type { - ZiskOperationType::None => (MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]), - ZiskOperationType::Binary => (BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]), - ZiskOperationType::BinaryE => { - (BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]) - } - _ => panic!("Invalid operation type"), - }; - dctx.add_instance(airgroup_id, air_id, idx, 1); - - if dctx.is_my_instance(idx) { - let (buffer, offset) = - create_prover_buffer::(&ectx, &sctx, airgroup_id, air_id); - instances_ctx.push(InstanceExtensionCtx::new( - buffer, - offset, - emu_slice.op_type, - emu_slice.emu_trace_start.clone(), - None, - )); - } - } - drop(dctx); - - instances_ctx.par_iter_mut().enumerate().for_each(|(idx, iectx)| match iectx.op_type { - ZiskOperationType::None => { - self.prove_main(&emu_traces, idx, iectx, &pctx); - } - ZiskOperationType::Binary => { - self.prove_binary(&emu_traces, idx, iectx, &pctx, scope); - } + // FIXME: This is a temporary solution to run the emulator in parallel with the ROM SM + // Spawn the ROM thread + let rom_sm = self.rom_sm.clone(); + let zisk_rom = self.zisk_rom.clone(); + let pc_histogram = + ZiskEmulator::process_rom_pc_histogram(&self.zisk_rom, &public_inputs, &emu_options) + .expect( + "MainSM::execute() failed calling ZiskEmulator::process_rom_pc_histogram()", + ); + let handle_rom = std::thread::spawn(move || rom_sm.prove(&zisk_rom, pc_histogram)); + + // Run the emulator in parallel n times to collect execution traces + // and record the execution starting points for each AIR instance + timer_start_debug!(PAR_PROCESS_ROM); + let (emu_traces, mut emu_slices) = ZiskEmulator::par_process_rom::( + &self.zisk_rom, + &public_inputs, + &emu_options, + Self::NUM_THREADS, + op_sizes, + ) + .expect("Error during emulator execution"); + timer_stop_and_log_debug!(PAR_PROCESS_ROM); + + emu_slices.points.sort_by(|a, b| a.op_type.partial_cmp(&b.op_type).unwrap()); + + // FIXME: This is a temporary solution to run the emulator in parallel with the ROM SM + handle_rom.join().unwrap().expect("Error during ROM witness computation"); + + let mut instances_extension_ctx: Vec> = + Vec::with_capacity(emu_slices.points.len()); + + let mut dctx = ectx.dctx.write().unwrap(); + let mut main_segnent_id = 0; + for emu_slice in emu_slices.points.iter() { + let (airgroup_id, air_id) = match emu_slice.op_type { + ZiskOperationType::None => (MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]), + ZiskOperationType::Binary => (BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]), ZiskOperationType::BinaryE => { - self.prove_binary_extension(&emu_traces, idx, iectx, &pctx, scope); + (BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]) } _ => panic!("Invalid operation type"), - }); - - timer_start_debug!(ADD_INSTANCES_TO_THE_REPO); - for iectx in instances_ctx { - if let Some(air_instance) = iectx.air_instance { - pctx.air_instance_repo.add_air_instance(air_instance); + }; + let segmen_id = match emu_slice.op_type { + ZiskOperationType::None => { + main_segnent_id += 1; + Some(main_segnent_id - 1) } + _ => None, + }; + + if let (true, global_idx) = dctx.add_instance(airgroup_id, air_id, 1) { + let (buffer, offset) = create_prover_buffer::(&ectx, &sctx, airgroup_id, air_id); + instances_extension_ctx.push(InstanceExtensionCtx::new( + buffer, + offset, + emu_slice.op_type, + emu_slice.emu_trace_start.clone(), + segmen_id, + global_idx, + None, + )); } - timer_stop_and_log_debug!(ADD_INSTANCES_TO_THE_REPO); - - std::thread::spawn(move || { - drop(emu_traces); - }); + } + drop(dctx); - // self.mem_sm.unregister_predecessor(scope); - self.binary_sm.unregister_predecessor(scope); - // self.arith_sm.register_predecessor(scope); + instances_extension_ctx.par_iter_mut().for_each(|iectx| match iectx.op_type { + ZiskOperationType::None => { + self.prove_main(&emu_traces, iectx, &pctx); + } + ZiskOperationType::Binary => { + self.prove_binary(&emu_traces, iectx, &pctx); + } + ZiskOperationType::BinaryE => { + self.prove_binary_extension(&emu_traces, iectx, &pctx); + } + _ => panic!("Invalid operation type"), + }); + // Drop the emulator traces concurrently + std::thread::spawn(move || { + drop(emu_traces); }); + + timer_start_debug!(ADD_INSTANCES_TO_THE_REPO); + for iectx in instances_extension_ctx { + if let Some(air_instance) = iectx.air_instance { + pctx.air_instance_repo + .add_air_instance(air_instance, Some(iectx.instance_global_idx)); + } + } + timer_stop_and_log_debug!(ADD_INSTANCES_TO_THE_REPO); + + // self.mem_sm.unregister_predecessor(scope); + self.binary_sm.unregister_predecessor(); + // self.arith_sm.register_predecessor(scope); } fn prove_main( &self, vec_traces: &[EmuTrace], - segment_id: usize, iectx: &mut InstanceExtensionCtx, pctx: &ProofCtx, ) { + let segment_id = iectx.segment_id.unwrap(); let segment_trace = &vec_traces[segment_id]; let offset = iectx.offset; @@ -362,10 +379,8 @@ impl MainSM { fn prove_binary( &self, vec_traces: &[EmuTrace], - segment_id: usize, iectx: &mut InstanceExtensionCtx, pctx: &ProofCtx, - scope: &rayon::Scope, ) { let air = pctx.pilout.get_air(BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]); @@ -380,7 +395,7 @@ impl MainSM { timer_stop_and_log_debug!(PROCESS_BINARY); timer_start_debug!(PROVE_BINARY); - self.binary_sm.prove_instance(inputs, false, &mut iectx.prover_buffer, iectx.offset, scope); + self.binary_sm.prove_instance(inputs, false, &mut iectx.prover_buffer, iectx.offset); timer_stop_and_log_debug!(PROVE_BINARY); timer_start_debug!(CREATE_AIR_INSTANCE); @@ -389,7 +404,7 @@ impl MainSM { self.sctx.clone(), BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0], - Some(segment_id), + None, buffer, )); timer_stop_and_log_debug!(CREATE_AIR_INSTANCE); @@ -398,10 +413,8 @@ impl MainSM { fn prove_binary_extension( &self, vec_traces: &[EmuTrace], - segment_id: usize, iectx: &mut InstanceExtensionCtx, pctx: &ProofCtx, - scope: &rayon::Scope, ) { let air = pctx.pilout.get_air(BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]); @@ -413,14 +426,14 @@ impl MainSM { air.num_rows(), ); - self.binary_sm.prove_instance(inputs, true, &mut iectx.prover_buffer, iectx.offset, scope); + self.binary_sm.prove_instance(inputs, true, &mut iectx.prover_buffer, iectx.offset); let buffer = std::mem::take(&mut iectx.prover_buffer); iectx.air_instance = Some(AirInstance::new( self.sctx.clone(), BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0], - Some(segment_id), + None, buffer, )); } diff --git a/state-machines/mem/src/mem.rs b/state-machines/mem/src/mem.rs index aa286c95..065b1841 100644 --- a/state-machines/mem/src/mem.rs +++ b/state-machines/mem/src/mem.rs @@ -6,7 +6,7 @@ use std::sync::{ use crate::{MemAlignedSM, MemUnalignedSM}; use p3_field::Field; use rayon::Scope; -use sm_common::{MemOp, MemUnalignedOp, OpResult, Provable, ThreadController}; +use sm_common::{MemOp, MemUnalignedOp, OpResult, Provable}; use zisk_core::ZiskRequiredMemory; use proofman::{WitnessComponent, WitnessManager}; @@ -20,9 +20,6 @@ pub struct MemSM { // Count of registered predecessors registered_predecessors: AtomicU32, - // Thread controller to manage the execution of the state machines - threads_controller: Arc, - // Inputs inputs_aligned: Mutex>, inputs_unaligned: Mutex>, @@ -39,7 +36,6 @@ impl MemSM { let mem_sm = Self { registered_predecessors: AtomicU32::new(0), - threads_controller: Arc::new(ThreadController::new()), inputs_aligned: Mutex::new(Vec::new()), inputs_unaligned: Mutex::new(Vec::new()), mem_aligned_sm: mem_aligned_sm.clone(), @@ -64,8 +60,6 @@ impl MemSM { if self.registered_predecessors.fetch_sub(1, Ordering::SeqCst) == 1 { >::prove(self, &[], true, scope); - self.threads_controller.remove_working_thread(); - self.mem_aligned_sm.unregister_predecessor::(scope); self.mem_unaligned_sm.unregister_predecessor::(scope); } diff --git a/state-machines/rom/src/rom.rs b/state-machines/rom/src/rom.rs index 35c26212..7a0ee637 100644 --- a/state-machines/rom/src/rom.rs +++ b/state-machines/rom/src/rom.rs @@ -48,7 +48,14 @@ impl RomSM { let air_instance = AirInstance::new(sctx.clone(), ROM_AIRGROUP_ID, air_id, None, prover_buffer); - self.wcm.get_pctx().air_instance_repo.add_air_instance(air_instance); + let (is_mine, instance_gid) = + self.wcm.get_ectx().dctx.write().unwrap().add_instance(ROM_AIRGROUP_ID, air_id, 1); + if is_mine { + self.wcm + .get_pctx() + .air_instance_repo + .add_air_instance(air_instance, Some(instance_gid)); + } Ok(()) } From 7dda331f83c0ed2509d9463bfb9fac77e3ceafc6 Mon Sep 17 00:00:00 2001 From: fractasy Date: Mon, 28 Oct 2024 17:56:48 +0000 Subject: [PATCH 07/22] Backup changes to support main continuations --- emulator/src/emu.rs | 47 ++++++++++++++++++++------------ pil/src/pil_helpers/traces.rs | 2 +- pil/zisk.pil | 14 ++++++---- state-machines/main/pil/main.pil | 28 +++++++++---------- state-machines/mem/pil/mem.pil | 27 ++++++++---------- 5 files changed, 64 insertions(+), 54 deletions(-) diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index c1a07e54..05de283d 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -799,23 +799,27 @@ impl<'a> Emu<'a> { last_c: u64, last_pc: u64, ) -> EmuFullTraceStep { + // Calculate intermediate values + let a = [inst_ctx.a & 0xFFFFFFFF, (inst_ctx.a >> 32) & 0xFFFFFFFF]; + let b = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.b >> 32) & 0xFFFFFFFF]; + let c = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.c >> 32) & 0xFFFFFFFF]; + let hi_a = a[1] * (1 - inst.m32 as u64); + let hi_b = b[1] * (1 - inst.m32 as u64); + let store_value = [ + (inst.store_ra as i64) * (last_pc as i64 + inst.jmp_offset2 - c[0] as i64) + + c[0] as i64, + (1 - (inst.store_ra as i64)) * c[1] as i64, + ]; + + let addr1 = inst.b_offset_imm0 + if inst.b_src == SRC_IND { inst_ctx.a } else { 0 }; + let addr2 = + (inst.store_offset + if inst.store == STORE_IND { a[0] as i64 } else { 0 }) as u64; + EmuFullTraceStep { - a: [ - F::from_canonical_u64(inst_ctx.a & 0xFFFFFFFF), - F::from_canonical_u64((inst_ctx.a >> 32) & 0xFFFFFFFF), - ], - b: [ - F::from_canonical_u64(inst_ctx.b & 0xFFFFFFFF), - F::from_canonical_u64((inst_ctx.b >> 32) & 0xFFFFFFFF), - ], - c: [ - F::from_canonical_u64(inst_ctx.c & 0xFFFFFFFF), - F::from_canonical_u64((inst_ctx.c >> 32) & 0xFFFFFFFF), - ], - last_c: [ - F::from_canonical_u64(last_c & 0xFFFFFFFF), - F::from_canonical_u64((last_c >> 32) & 0xFFFFFFFF), - ], + a: [F::from_canonical_u64(a[0]), F::from_canonical_u64(a[1])], + b: [F::from_canonical_u64(b[0]), F::from_canonical_u64(b[1])], + c: [F::from_canonical_u64(c[0]), F::from_canonical_u64(c[1])], + flag: F::from_bool(inst_ctx.flag), pc: F::from_canonical_u64(last_pc), a_src_imm: F::from_bool(inst.a_src == SRC_IMM), @@ -854,12 +858,19 @@ impl<'a> Emu<'a> { // inc_sp: F::from_canonical_u64(inst.inc_sp), jmp_offset1: F::from_canonical_u64(inst.jmp_offset1 as u64), jmp_offset2: F::from_canonical_u64(inst.jmp_offset2 as u64), - end: F::from_bool(inst_ctx.end), m32: F::from_bool(inst.m32), - operation_bus_enabled: F::from_bool( + addr1: F::from_canonical_u64(addr1), + addr2: F::from_canonical_u64(addr2), + store_value: [ + F::from_canonical_u64(store_value[0] as u64), + F::from_canonical_u64(store_value[0] as u64), + ], + __debug_operation_bus_enabled: F::from_bool( inst.op_type == ZiskOperationType::Binary || inst.op_type == ZiskOperationType::BinaryE, ), + hi_a: F::from_canonical_u64(hi_a), + hi_b: F::from_canonical_u64(hi_b), } } diff --git a/pil/src/pil_helpers/traces.rs b/pil/src/pil_helpers/traces.rs index a3650c28..38938e53 100644 --- a/pil/src/pil_helpers/traces.rs +++ b/pil/src/pil_helpers/traces.rs @@ -4,7 +4,7 @@ use proofman_common as common; pub use proofman_macros::trace; trace!(Main0Row, Main0Trace { - a: [F; 2], b: [F; 2], c: [F; 2], last_c: [F; 2], flag: F, pc: F, a_src_imm: F, a_src_mem: F, a_offset_imm0: F, a_imm1: F, a_src_step: F, b_src_imm: F, b_src_mem: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, is_external_op: F, op: F, store_ra: F, store_mem: F, store_ind: F, store_offset: F, set_pc: F, jmp_offset1: F, jmp_offset2: F, end: F, m32: F, operation_bus_enabled: F, + a: [F; 2], b: [F; 2], c: [F; 2], flag: F, pc: F, a_src_imm: F, a_src_mem: F, a_offset_imm0: F, a_imm1: F, a_src_step: F, b_src_imm: F, b_src_mem: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, is_external_op: F, op: F, store_ra: F, store_mem: F, store_ind: F, store_offset: F, set_pc: F, jmp_offset1: F, jmp_offset2: F, m32: F, addr1: F, addr2: F, store_value: [F; 2], __debug_operation_bus_enabled: F, hi_a: F, hi_b: F, }); trace!(RomS0Row, RomS0Trace { diff --git a/pil/zisk.pil b/pil/zisk.pil index b8199c94..1c06c309 100644 --- a/pil/zisk.pil +++ b/pil/zisk.pil @@ -6,7 +6,7 @@ require "binary/pil/binary.pil" require "binary/pil/binary_table.pil" require "binary/pil/binary_extension.pil" require "binary/pil/binary_extension_table.pil" -require "mem/pil/mem.pil" +// require "mem/pil/mem.pil" const int OPERATION_BUS_ID = 5000; airgroup Main { @@ -14,12 +14,14 @@ airgroup Main { } airgroup Rom { - Rom(N: 2**23); + Rom(N: 2**16) alias RomS; + Rom(N: 2**22) alias RomM; + Rom(N: 2**26) alias RomL; } -airgroup Mem { - Mem(N: 2**21, RC: 2); -} +// airgroup Mem { +// Mem(N: 2**21, RC: 2); +// } airgroup Binary { Binary(N: 2**21, operation_bus_id: OPERATION_BUS_ID); @@ -35,4 +37,4 @@ airgroup BinaryExtension { airgroup BinaryExtensionTable { BinaryExtensionTable(disable_fixed: 0); -} +} \ No newline at end of file diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 09ed93b8..242544c7 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -136,28 +136,28 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // Mem.load - mem_load(sel: a_src_mem, - step: addr_step, - addr: addr0, - value: a); + //mem_load(sel: a_src_mem, + // step: addr_step, + // addr: addr0, + // value: a); // Mem.load - mem_load(sel: sel_mem_b, - step: addr_step + 1, - bytes: ind_width, - addr: addr1, - value: b); + //mem_load(sel: sel_mem_b, + // step: addr_step + 1, + // bytes: ind_width, + // addr: addr1, + // value: b); col witness store_value[2]; store_value[0] === store_ra*(pc + jmp_offset2 - c[0]) + c[0]; store_value[1] === (1 - store_ra) * c[1]; // Mem.store - mem_store(sel: store_mem + store_ind, - step: addr_step + 2, - bytes: ind_width, - addr: addr2, - value: store_value); + //mem_store(sel: store_mem + store_ind, + // step: addr_step + 2, + // bytes: ind_width, + // addr: addr2, + // value: store_value); // Operation.assume => how organize software diff --git a/state-machines/mem/pil/mem.pil b/state-machines/mem/pil/mem.pil index 143e552c..50bd652e 100644 --- a/state-machines/mem/pil/mem.pil +++ b/state-machines/mem/pil/mem.pil @@ -14,8 +14,8 @@ airtemplate Mem (int N = 2**21, int RC = 2, int id = MEMORY_ID, int MAX_STEP = 2 col fixed SEGMENT_L1 = [1,0...]; const expr SEGMENT_LAST = SEGMENT_L1'; - airval mem_segment; - airval mem_last_segment; + airval mem_segment; + airval mem_last_segment; col witness addr; // n-byte address, real address = addr * MEM_BYTES col witness step; @@ -35,11 +35,8 @@ airtemplate Mem (int N = 2**21, int RC = 2, int id = MEMORY_ID, int MAX_STEP = 2 addr_changes * (1 - addr_changes) === 0; - col witness range_to_check; - range_to_check === addr_changes * (addr - 'addr - step + 'step) + step - 'step; - // check increment of memory - range_check(sel: (1 - SEGMENT_L1), colu:range_to_check, min: 1, max: MEMORY_MAX_DIFF); + range_check(sel: (1 - SEGMENT_L1), colu: addr_changes * (addr - 'addr - step + 'step) + step - 'step, min: 1, max: MEMORY_MAX_DIFF); // PADDING: At end of memory fill with same addr, incrementing step, same value, sel = 0, rd = 1, wr = 0 // setting mem_last_segment = 1 @@ -59,16 +56,16 @@ airtemplate Mem (int N = 2**21, int RC = 2, int id = MEMORY_ID, int MAX_STEP = 2 } // CONTINUATIONS - // + // // segments: S, S+1 - // + // // CASE: last row of segment is read - // + // // S[n-1] wr = 0, sel = 1, addr, step, value => BUS.proves(MEM_CONT_ID, S+1, addr, step-1, value) // S+1[0] wr = 0, sel = 0, addr, step, value => BUS.assumes(MEM_CONT_ID, S, addr, step, value) // // CASE: last row of segment is write - // + // // S[n-1] wr = 1, sel = 1, addr, step, value => BUS.proves(MEM_CONT_ID, S+1, addr, step-1, value) // S+1[0] wr = 0, sel = 0, addr, step, value => BUS.assumes(MEM_CONT_ID, S, addr, step, value) // @@ -76,19 +73,19 @@ airtemplate Mem (int N = 2**21, int RC = 2, int id = MEMORY_ID, int MAX_STEP = 2 // on row = 0 forced by constraint that sel = 0 => wr = 0. // on S+1[0].step = S[n-1].step - 1; // - // FIRST SEGMENT: + // FIRST SEGMENT: // the BUS.proves needed by BUS.assumes of the first segment it's generated by global constraint to avoid // generate more than one cycle of memory. In this constraint we could force the initial address (to split // in two memories, one register-memory and other standard-memory). // - // LAST SEGMENT: + // LAST SEGMENT: // the last not used rows are filled with last addr and value and sel = 0 and wr = 0 incrementing steps. // last BUS.proves not it's generated to avoid generate more than one memory cycle. // permutation_proves(MEMORY_CONT_ID, [(mem_segment + 1), addr, step, ...value], sel: mem_last_segment * 'SEGMENT_L1); // last row // permutation_assumes(MEMORY_CONT_ID, [mem_segment, 0, addr, step, ...value], sel: SEGMENT_L1); // first row - permutation_proves(MEMORY_ID, cols: [wr, addr * MEM_BYTES, step, MEM_BYTES, ...value], sel: sel, bus_type: PIOP_BUS_SUM); + permutation_proves(MEMORY_ID, cols: [wr, addr * MEM_BYTES, step, MEM_BYTES, ...value], sel: sel); } // TODO: detect non default value but not called, mandatory parameter. @@ -97,7 +94,7 @@ function mem_load(int id = MEMORY_ID, expr sel = 1, expr addr, expr step, expr s error("max step_offset ${step_offset} is greater than max value ${MAX_MEM_STEP_OFFSET}"); } // adding one for first continuation - permutation_assumes(id, [MEMORY_LOAD_OP, addr, 1 + ((MAX_MEM_STEP_OFFSET + 1) * step) + step_offset, bytes, ...value], sel:sel, bus_type: PIOP_BUS_SUM); + permutation_assumes(id, [MEMORY_LOAD_OP, addr, 1 + ((MAX_MEM_STEP_OFFSET + 1) * step) + step_offset, bytes, ...value], sel:sel); } function mem_store(int id = MEMORY_ID, expr sel = 1, expr addr, expr step, expr step_offset = 0, expr bytes = 8, expr value[]) { @@ -105,5 +102,5 @@ function mem_store(int id = MEMORY_ID, expr sel = 1, expr addr, expr step, expr error("max step_offset ${step_offset} is greater than max value ${MAX_MEM_STEP_OFFSET}"); } // adding one for first continuation - permutation_assumes(id, [MEMORY_STORE_OP, addr, 1 + ((MAX_MEM_STEP_OFFSET + 1) * step), bytes, ...value], sel:sel, bus_type: PIOP_BUS_SUM); + permutation_assumes(id, [MEMORY_STORE_OP, addr, 1 + ((MAX_MEM_STEP_OFFSET + 1) * step), bytes, ...value], sel:sel); } \ No newline at end of file From 685c0402b9568ab01a74ee2373d310a52af822ee Mon Sep 17 00:00:00 2001 From: fractasy Date: Tue, 29 Oct 2024 16:46:49 +0000 Subject: [PATCH 08/22] Fix most constraints, except the last one --- emulator/src/emu.rs | 62 +++++++++++++++++++++++------- state-machines/main/pil/main.pil | 2 +- state-machines/main/src/main_sm.rs | 1 - 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index 05de283d..a76b3d9f 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -802,29 +802,65 @@ impl<'a> Emu<'a> { // Calculate intermediate values let a = [inst_ctx.a & 0xFFFFFFFF, (inst_ctx.a >> 32) & 0xFFFFFFFF]; let b = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.b >> 32) & 0xFFFFFFFF]; - let c = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.c >> 32) & 0xFFFFFFFF]; + let c = [inst_ctx.c & 0xFFFFFFFF, (inst_ctx.c >> 32) & 0xFFFFFFFF]; let hi_a = a[1] * (1 - inst.m32 as u64); let hi_b = b[1] * (1 - inst.m32 as u64); let store_value = [ - (inst.store_ra as i64) * (last_pc as i64 + inst.jmp_offset2 - c[0] as i64) - + c[0] as i64, - (1 - (inst.store_ra as i64)) * c[1] as i64, + if inst.store_ra { (inst.paddr as i64 + inst.jmp_offset2) as u64 } else { c[0] }, + if inst.store_ra { 0 } else { c[1] }, ]; - let addr1 = inst.b_offset_imm0 + if inst.b_src == SRC_IND { inst_ctx.a } else { 0 }; + let addr1 = (inst.b_offset_imm0 as i64 + + if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64; let addr2 = (inst.store_offset + if inst.store == STORE_IND { a[0] as i64 } else { 0 }) as u64; + let jmp_offset1 = if inst.jmp_offset1 >= 0 { + F::from_canonical_u64(inst.jmp_offset1 as u64) + } else { + F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) + }; + + let jmp_offset2 = if inst.jmp_offset2 >= 0 { + F::from_canonical_u64(inst.jmp_offset2 as u64) + } else { + F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) + }; + + let store_offset = if inst.store_offset >= 0 { + F::from_canonical_u64(inst.store_offset as u64) + } else { + F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) + }; + + let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { + F::from_canonical_u64(inst.a_offset_imm0) + } else { + F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) + }; + + let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { + F::from_canonical_u64(inst.b_offset_imm0 as u64) + } else { + F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) + }; + + if inst_ctx.step < 100 { + let inst_string = inst.to_text(); + println! {"MAIN step={} pc={} last_pc={} a={:x} b={:x} c={:x} m32={} store_ra={} store_value=[{},{}] jmp_offset1={} jmp_offset2={} flag={} addr1={} addr2={} inst={:?}", + inst_ctx.step, inst.paddr, last_pc, inst_ctx.a, inst_ctx.b, inst_ctx.c, inst.m32, inst.store_ra, store_value[0], store_value[1], inst.jmp_offset1, inst.jmp_offset2, inst_ctx.flag, addr1, addr2, inst_string}; + } + EmuFullTraceStep { a: [F::from_canonical_u64(a[0]), F::from_canonical_u64(a[1])], b: [F::from_canonical_u64(b[0]), F::from_canonical_u64(b[1])], c: [F::from_canonical_u64(c[0]), F::from_canonical_u64(c[1])], flag: F::from_bool(inst_ctx.flag), - pc: F::from_canonical_u64(last_pc), + pc: F::from_canonical_u64(inst.paddr), a_src_imm: F::from_bool(inst.a_src == SRC_IMM), a_src_mem: F::from_bool(inst.a_src == SRC_MEM), - a_offset_imm0: F::from_canonical_u64(inst.a_offset_imm0), + a_offset_imm0, // #[cfg(not(feature = "sp"))] a_imm1: F::from_canonical_u64(inst.a_use_sp_imm1), // #[cfg(feature = "sp")] @@ -836,7 +872,7 @@ impl<'a> Emu<'a> { a_src_step: F::from_bool(inst.a_src == SRC_STEP), b_src_imm: F::from_bool(inst.b_src == SRC_IMM), b_src_mem: F::from_bool(inst.b_src == SRC_MEM), - b_offset_imm0: F::from_canonical_u64(inst.b_offset_imm0), + b_offset_imm0, // #[cfg(not(feature = "sp"))] b_imm1: F::from_canonical_u64(inst.b_use_sp_imm1), // #[cfg(feature = "sp")] @@ -848,7 +884,7 @@ impl<'a> Emu<'a> { store_ra: F::from_bool(inst.store_ra), store_mem: F::from_bool(inst.store == STORE_MEM), store_ind: F::from_bool(inst.store == STORE_IND), - store_offset: F::from_canonical_u64(inst.store_offset as u64), + store_offset, set_pc: F::from_bool(inst.set_pc), // #[cfg(feature = "sp")] // store_use_sp: F::from_bool(inst.store_use_sp), @@ -856,14 +892,14 @@ impl<'a> Emu<'a> { // set_sp: F::from_bool(inst.set_sp), // #[cfg(feature = "sp")] // inc_sp: F::from_canonical_u64(inst.inc_sp), - jmp_offset1: F::from_canonical_u64(inst.jmp_offset1 as u64), - jmp_offset2: F::from_canonical_u64(inst.jmp_offset2 as u64), + jmp_offset1, + jmp_offset2, m32: F::from_bool(inst.m32), addr1: F::from_canonical_u64(addr1), addr2: F::from_canonical_u64(addr2), store_value: [ - F::from_canonical_u64(store_value[0] as u64), - F::from_canonical_u64(store_value[0] as u64), + F::from_canonical_u64(store_value[0]), + F::from_canonical_u64(store_value[1]), ], __debug_operation_bus_enabled: F::from_bool( inst.op_type == ZiskOperationType::Binary diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 242544c7..9b021cb6 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -222,7 +222,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope flag * set_pc === 0; const expr next_pc = set_pc * (c[0] + jmp_offset1) + (1 - set_pc) * (pc + jmp_offset2) + flag * (jmp_offset1 - jmp_offset2); - (1 - SEGMENT_L1') * (pc - 'next_pc) === 0; + (1 - SEGMENT_L1) * (pc - 'next_pc) === 0; const expr is_last_continuation = SEGMENT_LAST * main_last_segment; const expr specific_registers[stack_enabled ? 2:1]; diff --git a/state-machines/main/src/main_sm.rs b/state-machines/main/src/main_sm.rs index 9bdc4647..358d6212 100644 --- a/state-machines/main/src/main_sm.rs +++ b/state-machines/main/src/main_sm.rs @@ -369,7 +369,6 @@ impl MainSM { let main_last_segment = F::from_bool(segment_id == vec_traces.len() - 1); let main_segment = F::from_canonical_usize(segment_id); - air_instance.set_airvalue(&self.sctx, "Main.main_first_segment", main_first_segment); air_instance.set_airvalue(&self.sctx, "Main.main_last_segment", main_last_segment); air_instance.set_airvalue(&self.sctx, "Main.main_segment", main_segment); From 9e045f8d57ef935335af54dbbba798d33456fb38 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Tue, 29 Oct 2024 18:21:22 +0000 Subject: [PATCH 09/22] update pil with last continuations contraints --- state-machines/main/pil/main.pil | 96 ++++++++++++++++---------------- state-machines/rom/pil/rom.pil | 4 +- 2 files changed, 49 insertions(+), 51 deletions(-) diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 9b021cb6..9a590a18 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -114,7 +114,6 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope const expr addr_step = STEP * 3; const expr sel_mem_b; - const expr addr[3]; sel_mem_b = b_src_mem + b_src_ind; if (stack_enabled) { @@ -128,47 +127,41 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope } else { const expr air.addr0; col witness air.addr1; - col witness air.addr2; + const expr air.addr2; addr0 = a_offset_imm0; addr1 === b_offset_imm0 + b_src_ind * (a[0] + 2**32 * a[1]); - addr2 === store_offset + store_ind * a[0]; + addr2 = store_offset + store_ind * a[0]; } - // Mem.load - //mem_load(sel: a_src_mem, - // step: addr_step, - // addr: addr0, - // value: a); + mem_load(sel: a_src_mem, + step: addr_step, + addr: addr0, + value: a); // Mem.load - //mem_load(sel: sel_mem_b, - // step: addr_step + 1, - // bytes: ind_width, - // addr: addr1, - // value: b); + mem_load(sel: sel_mem_b, + step: addr_step + 1, + bytes: ind_width, + addr: addr1, + value: b); - col witness store_value[2]; + const expr store_value[2]; - store_value[0] === store_ra*(pc + jmp_offset2 - c[0]) + c[0]; - store_value[1] === (1 - store_ra) * c[1]; - // Mem.store - //mem_store(sel: store_mem + store_ind, - // step: addr_step + 2, - // bytes: ind_width, - // addr: addr2, - // value: store_value); + store_value[0] = store_ra*(pc + jmp_offset2 - c[0]) + c[0]; + store_value[1] = (1 - store_ra) * c[1]; + // Mem.store + mem_store(sel: store_mem + store_ind, + step: addr_step + 2, + bytes: ind_width, + addr: addr2, + value: store_value); // Operation.assume => how organize software - col witness __debug_operation_bus_enabled; - col witness hi_a; - col witness hi_b; + // col witness __debug_operation_bus_enabled; - hi_a === a[1] * (1 - m32); - hi_b === b[1] * (1 - m32); - lookup_assumes(operation_bus_id, [STEP, op, a[0], hi_a, b[0], hi_b, ...c, flag], sel: is_external_op * __debug_operation_bus_enabled, name: PIOP_NAME_ISOLATED); - // lookup_assumes(operation_bus_id, [STEP, op, a[0], (1 - m32) * a[1], b[0], (1 - m32) * b[1], ...c, flag], sel: is_external_op * (1 - SEGMENT_L1), name: PIOP_NAME_ISOLATED); + lookup_assumes(operation_bus_id, [STEP, op, a[0], (1 - m32) * a[1], b[0], (1 - m32) * b[1], ...c, flag], sel: is_external_op, name: PIOP_NAME_ISOLATED); const expr a_src_c; const expr b_src_c; @@ -197,8 +190,8 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope a_src_sp * (a[index] - (index == 0 ? sp: 0 )) === 0; } a_src_step * (a[index] - (index == 0 ? STEP : 0)) === 0; - (1 - SEGMENT_L1) * a_src_c * (a[index] - 'c[index]) === 0; - (1 - SEGMENT_L1) * b_src_c * (b[index] - 'c[index]) === 0; + a_src_c * (a[index] - 'c[index]) === 0; + b_src_c * (b[index] - 'c[index]) === 0; a_src_imm * (a[index] - a_imm[index]) === 0; b_src_imm * (b[index] - b_imm[index]) === 0; @@ -243,7 +236,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // const expr bus_main_segment = main_segment - SEGMENT_LAST * (main_segment * main_last_segment - 1 + main_last_segment); - permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, ...specific_registers, ...a, ...b, ...c, flag], + permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, ...specific_registers, ...a, ...c], sel: SEGMENT_LAST - SEGMENT_L1, name: PIOP_NAME_ISOLATED, bus_type: PIOP_BUS_SUM); flag * (1 - flag) === 0; @@ -253,22 +246,27 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // match with main trace. const expr rom_flags = 1 + 2 * a_src_imm + 4 * a_src_mem + 8 * a_src_step + 16 * b_src_imm + 32 * b_src_mem + 64 * is_external_op + 128 * store_ra + 256 * store_mem + 512 * store_ind + - + 1024 * set_pc + 2048 * m32; - - a_src_imm * (1 - a_src_imm) === 0; - a_src_mem * (1 - a_src_mem) === 0; - a_src_step * (1 - a_src_step) === 0; - b_src_imm * (1 - b_src_imm) === 0; - b_src_mem * (1 - b_src_mem) === 0; - is_external_op * (1 - is_external_op) === 0; - store_ra * (1 - store_ra) === 0; - store_mem * (1 - store_mem) === 0; - store_ind * (1 - store_ind) === 0; - set_pc * (1 - set_pc) === 0; - m32 * (1 - m32) === 0; - - - lookup_assumes(ROM_BUS_ID, [SEGMENT_L1 * (NOP_ROM_ADDR - pc) + pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, b_src_ind, ind_width, - op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1); + + 1024 * set_pc + 2048 * m32 + 4096 * b_src_ind; + + + // SETTINGS ROW 0 + // ----------------------------------------------------- + // b_offset_imm0 = b[0] = c[0] <== c[0] previous segment + // b_imm1 = b[1] = c[1] <== c[1] previous segment + // a_offset_imm0 = a[0] <== a[0] previous segment + // a_imm1 = a[1] <== a[1] previous segment + // op = 1 + // pc <== pc previous segment + // jmp_offset1 = jmp_offset2 = 0 + // flag = 0 + // a_src_imm = b_src_imm = 1 (rest flags to 0) + + SEGMENT_L1 * jmp_offset1 === 0; + SEGMENT_L1 * jmp_offset2 === 0; + SEGMENT_L1 * (rom_flags - 18) === 0; // 18 = a_src_imm(2) + b_src_imm(16) + SEGMENT_L1 * (op - 1) === 0; + + lookup_assumes(ROM_BUS_ID, [pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, ind_width, + op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1 - SEGMENT_L1); } \ No newline at end of file diff --git a/state-machines/rom/pil/rom.pil b/state-machines/rom/pil/rom.pil index 19afccc5..2c2011e0 100644 --- a/state-machines/rom/pil/rom.pil +++ b/state-machines/rom/pil/rom.pil @@ -9,7 +9,6 @@ airtemplate Rom(int N = 2**21, int stack_enabled = 0, const int rom_bus_id = ROM col witness a_imm1; col witness b_offset_imm0; col witness b_imm1; - col witness b_src_ind; col witness ind_width; col witness op; col witness store_offset; @@ -17,8 +16,9 @@ airtemplate Rom(int N = 2**21, int stack_enabled = 0, const int rom_bus_id = ROM col witness jmp_offset2; col witness flags; + col witness multiplicity; - lookup_proves(rom_bus_id, [line, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, b_src_ind, ind_width, + lookup_proves(rom_bus_id, [line, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, ind_width, op, store_offset, jmp_offset1, jmp_offset2, flags], mul: multiplicity); } \ No newline at end of file From 78d60f24552d59c7f65ef4a45603c377d643971a Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Wed, 30 Oct 2024 08:34:46 +0100 Subject: [PATCH 10/22] Feature/executor (#140) --- Cargo.lock | 20 +- state-machines/common/Cargo.toml | 3 + state-machines/main/src/instance_extension.rs | 35 ++ state-machines/main/src/lib.rs | 2 + state-machines/main/src/main_sm.rs | 305 +++--------------- witness-computation/Cargo.toml | 6 +- witness-computation/src/executor.rs | 242 ++++++++++++++ witness-computation/src/lib.rs | 2 + witness-computation/src/zisk_lib.rs | 63 ++-- 9 files changed, 375 insertions(+), 303 deletions(-) create mode 100644 state-machines/main/src/instance_extension.rs create mode 100644 witness-computation/src/executor.rs diff --git a/Cargo.lock b/Cargo.lock index 3d02d119..ef662b99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -213,6 +213,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "ciborium" version = "0.2.2" @@ -1632,10 +1638,11 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +checksum = "e346e016eacfff12233c243718197ca12f148c84e1e84268a896699b41c71780" dependencies = [ + "cfg_aliases", "libc", "once_cell", "socket2", @@ -1753,9 +1760,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.8" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64", "bytes", @@ -2044,6 +2051,8 @@ dependencies = [ "proofman-common", "proofman-util", "rayon", + "zisk-core", + "ziskemu", ] [[package]] @@ -3022,6 +3031,7 @@ dependencies = [ "proofman", "proofman-common", "proofman-util", + "rayon", "sm-arith", "sm-binary", "sm-common", @@ -3030,7 +3040,9 @@ dependencies = [ "sm-mem", "sm-quick-ops", "sm-rom", + "zisk-core", "zisk-pil", + "ziskemu", ] [[package]] diff --git a/state-machines/common/Cargo.toml b/state-machines/common/Cargo.toml index 91ce51a7..d0b716b8 100644 --- a/state-machines/common/Cargo.toml +++ b/state-machines/common/Cargo.toml @@ -4,6 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] +ziskemu = { path = "../../emulator" } +zisk-core = { path = "../../core" } + proofman-common = { workspace = true } proofman-util = { workspace = true } diff --git a/state-machines/main/src/instance_extension.rs b/state-machines/main/src/instance_extension.rs new file mode 100644 index 00000000..42aea872 --- /dev/null +++ b/state-machines/main/src/instance_extension.rs @@ -0,0 +1,35 @@ +use proofman_common::AirInstance; +use zisk_core::ZiskOperationType; +use ziskemu::EmuTraceStart; + +pub struct InstanceExtensionCtx { + pub prover_buffer: Vec, + pub offset: u64, + pub op_type: ZiskOperationType, + pub emu_trace_start: EmuTraceStart, + pub segment_id: Option, + pub instance_global_idx: usize, + pub air_instance: Option>, +} + +impl InstanceExtensionCtx { + pub fn new( + prover_buffer: Vec, + offset: u64, + op_type: ZiskOperationType, + emu_trace_start: EmuTraceStart, + segment_id: Option, + instance_global_idx: usize, + air_instance: Option>, + ) -> Self { + Self { + prover_buffer, + offset, + op_type, + emu_trace_start, + instance_global_idx, + segment_id, + air_instance, + } + } +} diff --git a/state-machines/main/src/lib.rs b/state-machines/main/src/lib.rs index 500eeac5..d4e2d658 100644 --- a/state-machines/main/src/lib.rs +++ b/state-machines/main/src/lib.rs @@ -1,3 +1,5 @@ +mod instance_extension; mod main_sm; +pub use instance_extension::*; pub use main_sm::*; diff --git a/state-machines/main/src/main_sm.rs b/state-machines/main/src/main_sm.rs index 9bdc4647..e8d3629e 100644 --- a/state-machines/main/src/main_sm.rs +++ b/state-machines/main/src/main_sm.rs @@ -1,148 +1,64 @@ use log::info; use p3_field::PrimeField; -use sm_rom::RomSM; -use core::panic; +use crate::InstanceExtensionCtx; use proofman_util::{timer_start_debug, timer_stop_and_log_debug}; -use rayon::prelude::*; use sm_binary::BinarySM; -use std::{ - fs, - path::{Path, PathBuf}, - sync::Arc, -}; -use zisk_core::{Riscv2zisk, ZiskOperationType, ZiskRom, ZISK_OPERATION_TYPE_VARIANTS}; +use std::sync::Arc; +use zisk_core::ZiskRom; use proofman::WitnessManager; -use proofman_common::{AirInstance, ExecutionCtx, ProofCtx, SetupCtx}; +use proofman_common::{AirInstance, ProofCtx}; +use proofman::WitnessComponent; +use sm_arith::ArithSM; +use sm_mem::MemSM; use zisk_pil::{ Main0Row, Main0Trace, BINARY_AIRGROUP_ID, BINARY_AIR_IDS, BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS, MAIN_AIRGROUP_ID, MAIN_AIR_IDS, }; -use ziskemu::{Emu, EmuOptions, EmuTrace, EmuTraceStart, ZiskEmulator}; - -//use process::Command; -use proofman::WitnessComponent; -use sm_arith::ArithSM; -use sm_common::create_prover_buffer; -use sm_mem::MemSM; - -pub struct InstanceExtensionCtx { - pub prover_buffer: Vec, - pub offset: u64, - pub op_type: ZiskOperationType, - pub emu_trace_start: EmuTraceStart, - pub segment_id: Option, - pub instance_global_idx: usize, - pub air_instance: Option>, -} +use ziskemu::{Emu, EmuTrace, ZiskEmulator}; -impl InstanceExtensionCtx { - pub fn new( - prover_buffer: Vec, - offset: u64, - op_type: ZiskOperationType, - emu_trace_start: EmuTraceStart, - segment_id: Option, - instance_global_idx: usize, - air_instance: Option>, - ) -> Self { - Self { - prover_buffer, - offset, - op_type, - emu_trace_start, - instance_global_idx, - segment_id, - air_instance, - } - } -} /// This is a multithreaded implementation of the Zisk MainSM state machine. /// /// The MainSM state machine is responsible for orchestrating the execution of the program and /// processing the inputs generated by the emulator. The MainSM state machine interacts with the /// secondary state machines to process the inputs generated by the emulator. pub struct MainSM { - // Zisk ROM - zisk_rom: ZiskRom, - zisk_rom_path: PathBuf, + /// Witness computation manager + wcm: Arc>, - // State machines + /// Arithmetic state machine arith_sm: Arc, - sctx: Arc, + /// Binary state machine binary_sm: Arc>, + + /// Memory state machine mem_sm: Arc, - rom_sm: Arc>, } impl MainSM { const MY_NAME: &'static str = "MainSM "; - /// Default number of inputs of the main state machine that are accumulated before being - /// processed - const BLOCK_SIZE: usize = 2usize.pow(21); - const NUM_THREADS: usize = 8; - /// Constructor for the MainSM state machine /// Registers the state machine at the WCManager and stores references to the secondary state /// machines that directly interact with the MainSM /// Returns an Arc to the MainSM state machine /// # Arguments - /// * `rom_path` - Path to the ROM file /// * `wcm` - Witness computation manager to register the state machine - /// * `mem_sm` - Arc to the MemSM state machine - /// * `binary_sm` - Arc to the BinarySM state machine /// * `arith_sm` - Arc to the ArithSM state machine - /// * `air_ids` - Array of Main Air IDs extracted from the pilout + /// * `binary_sm` - Arc to the BinarySM state machine + /// * `mem_sm` - Arc to the MemSM state machine /// # Returns /// * Arc to the MainSM state machine pub fn new( - rom_path: PathBuf, wcm: Arc>, - sctx: Arc, - rom_sm: Arc>, - mem_sm: Arc, - binary_sm: Arc>, arith_sm: Arc, + binary_sm: Arc>, + mem_sm: Arc, ) -> Arc { - // If rom_path has an .elf extension it must be converted to a ZisK ROM - let zisk_rom = if rom_path.extension().unwrap() == "elf" { - // Create an instance of the RISCV -> ZisK program converter - let rv2zk = Riscv2zisk::new( - rom_path.display().to_string(), - String::new(), - String::new(), - String::new(), - ); - - // Convert program to rom - match rv2zk.run() { - Ok(rom) => rom, - Err(e) => { - panic!("Application error: {}", e); - } - } - } else { - // TODO - Remove this when the ZisK ROM is able to be loaded from a file - panic!("ROM file must be an ELF file"); - }; - - // TODO - Compute MAX_ACCUMULATED having the num_rows of the Main AIR - // TODO - If there is more than one Main AIR available, the MAX_ACCUMULATED will be the one - // with the highest num_rows. It has to be a power of 2. - - let main_sm = Arc::new(Self { - zisk_rom, - zisk_rom_path: rom_path.to_path_buf(), - sctx, - arith_sm, - binary_sm, - mem_sm, - rom_sm, - }); + let main_sm = Arc::new(Self { wcm: wcm.clone(), arith_sm, binary_sm, mem_sm }); wcm.register_component(main_sm.clone(), Some(MAIN_AIRGROUP_ID), Some(MAIN_AIR_IDS)); @@ -154,156 +70,9 @@ impl MainSM { main_sm } - /// Executes the MainSM state machine and processes the inputs in batches when the maximum - /// number of accumulated inputs is reached. The MainSM state machine uses the emulator to - /// execute the a program and using a callback the main state machine receives batches of - /// inputs generated by the emulator. The inputs are processed in batches when the maximum - /// number of accumulated inputs is reached - /// # Arguments - /// * `pctx` - Proof context to interact with the proof system - /// * `ectx` - Execution context to interact with the execution environment - pub fn execute( - &self, - public_inputs_path: &Path, - pctx: Arc>, - ectx: Arc, - sctx: Arc, - ) { - // Create a thread pool to manage the execution of all the state machines related to the - // execution process - - // Prepare the settings for the emulator - let emu_options = EmuOptions { - elf: Some(self.zisk_rom_path.clone().display().to_string()), - inputs: Some(public_inputs_path.display().to_string()), - trace_steps: Some(Self::BLOCK_SIZE as u64), - ..EmuOptions::default() - }; - - // Call emulate with these options - let public_inputs = { - // Read inputs data from the provided inputs path - let path = PathBuf::from(public_inputs_path.display().to_string()); - fs::read(path).expect("Could not read inputs file") - }; - - // During ROM processing, we gather execution data necessary for creating the AIR instances. - // This data is collected by the emulator and includes the minimal execution trace, - // along with essential state information of the processor. This ensures that the execution - // can be reproduced from specific points in the trace to generate the inputs for each state - // machine. We aim to track the starting point of execution for every N instructions - // across different operation types. Currently, we are only collecting data for - // Binary and BinaryE operations. - let air_main = pctx.pilout.get_air(MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]); - let air_binary = pctx.pilout.get_air(BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]); - let air_binary_e = - pctx.pilout.get_air(BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]); - - let mut op_sizes = [0u64; ZISK_OPERATION_TYPE_VARIANTS]; - // The starting points for the Main is allocated using None operation - op_sizes[ZiskOperationType::None as usize] = air_main.num_rows() as u64; - op_sizes[ZiskOperationType::Binary as usize] = air_binary.num_rows() as u64; - op_sizes[ZiskOperationType::BinaryE as usize] = air_binary_e.num_rows() as u64; - - // FIXME: This is a temporary solution to run the emulator in parallel with the ROM SM - // Spawn the ROM thread - let rom_sm = self.rom_sm.clone(); - let zisk_rom = self.zisk_rom.clone(); - let pc_histogram = - ZiskEmulator::process_rom_pc_histogram(&self.zisk_rom, &public_inputs, &emu_options) - .expect( - "MainSM::execute() failed calling ZiskEmulator::process_rom_pc_histogram()", - ); - let handle_rom = std::thread::spawn(move || rom_sm.prove(&zisk_rom, pc_histogram)); - - // Run the emulator in parallel n times to collect execution traces - // and record the execution starting points for each AIR instance - timer_start_debug!(PAR_PROCESS_ROM); - let (emu_traces, mut emu_slices) = ZiskEmulator::par_process_rom::( - &self.zisk_rom, - &public_inputs, - &emu_options, - Self::NUM_THREADS, - op_sizes, - ) - .expect("Error during emulator execution"); - timer_stop_and_log_debug!(PAR_PROCESS_ROM); - - emu_slices.points.sort_by(|a, b| a.op_type.partial_cmp(&b.op_type).unwrap()); - - // FIXME: This is a temporary solution to run the emulator in parallel with the ROM SM - handle_rom.join().unwrap().expect("Error during ROM witness computation"); - - let mut instances_extension_ctx: Vec> = - Vec::with_capacity(emu_slices.points.len()); - - let mut dctx = ectx.dctx.write().unwrap(); - let mut main_segnent_id = 0; - for emu_slice in emu_slices.points.iter() { - let (airgroup_id, air_id) = match emu_slice.op_type { - ZiskOperationType::None => (MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]), - ZiskOperationType::Binary => (BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]), - ZiskOperationType::BinaryE => { - (BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]) - } - _ => panic!("Invalid operation type"), - }; - let segmen_id = match emu_slice.op_type { - ZiskOperationType::None => { - main_segnent_id += 1; - Some(main_segnent_id - 1) - } - _ => None, - }; - - if let (true, global_idx) = dctx.add_instance(airgroup_id, air_id, 1) { - let (buffer, offset) = create_prover_buffer::(&ectx, &sctx, airgroup_id, air_id); - instances_extension_ctx.push(InstanceExtensionCtx::new( - buffer, - offset, - emu_slice.op_type, - emu_slice.emu_trace_start.clone(), - segmen_id, - global_idx, - None, - )); - } - } - drop(dctx); - - instances_extension_ctx.par_iter_mut().for_each(|iectx| match iectx.op_type { - ZiskOperationType::None => { - self.prove_main(&emu_traces, iectx, &pctx); - } - ZiskOperationType::Binary => { - self.prove_binary(&emu_traces, iectx, &pctx); - } - ZiskOperationType::BinaryE => { - self.prove_binary_extension(&emu_traces, iectx, &pctx); - } - _ => panic!("Invalid operation type"), - }); - // Drop the emulator traces concurrently - std::thread::spawn(move || { - drop(emu_traces); - }); - - timer_start_debug!(ADD_INSTANCES_TO_THE_REPO); - for iectx in instances_extension_ctx { - if let Some(air_instance) = iectx.air_instance { - pctx.air_instance_repo - .add_air_instance(air_instance, Some(iectx.instance_global_idx)); - } - } - timer_stop_and_log_debug!(ADD_INSTANCES_TO_THE_REPO); - - // self.mem_sm.unregister_predecessor(scope); - self.binary_sm.unregister_predecessor(); - // self.arith_sm.register_predecessor(scope); - } - - fn prove_main( + pub fn prove_main( &self, + zisk_rom: &ZiskRom, vec_traces: &[EmuTrace], iectx: &mut InstanceExtensionCtx, pctx: &ProofCtx, @@ -323,7 +92,7 @@ impl MainSM { filled as f64 / air.num_rows() as f64 * 100.0 ); - let mut emu = Emu::from_emu_trace_start(&self.zisk_rom, &segment_trace.start); + let mut emu = Emu::from_emu_trace_start(zisk_rom, &segment_trace.start); let total_steps = segment_trace.steps.len(); const CHUNK_SIZE: usize = 4096; @@ -358,7 +127,7 @@ impl MainSM { let buffer = std::mem::take(&mut iectx.prover_buffer); let mut air_instance = AirInstance::new( - self.sctx.clone(), + self.wcm.get_sctx(), MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0], Some(segment_id), @@ -369,15 +138,24 @@ impl MainSM { let main_last_segment = F::from_bool(segment_id == vec_traces.len() - 1); let main_segment = F::from_canonical_usize(segment_id); - air_instance.set_airvalue(&self.sctx, "Main.main_first_segment", main_first_segment); - air_instance.set_airvalue(&self.sctx, "Main.main_last_segment", main_last_segment); - air_instance.set_airvalue(&self.sctx, "Main.main_segment", main_segment); + air_instance.set_airvalue( + &self.wcm.get_sctx(), + "Main.main_first_segment", + main_first_segment, + ); + air_instance.set_airvalue( + &self.wcm.get_sctx(), + "Main.main_last_segment", + main_last_segment, + ); + air_instance.set_airvalue(&self.wcm.get_sctx(), "Main.main_segment", main_segment); iectx.air_instance = Some(air_instance); } - fn prove_binary( + pub fn prove_binary( &self, + zisk_rom: &ZiskRom, vec_traces: &[EmuTrace], iectx: &mut InstanceExtensionCtx, pctx: &ProofCtx, @@ -386,7 +164,7 @@ impl MainSM { timer_start_debug!(PROCESS_BINARY); let inputs = ZiskEmulator::process_slice_required::( - &self.zisk_rom, + zisk_rom, vec_traces, iectx.op_type, &iectx.emu_trace_start, @@ -401,7 +179,7 @@ impl MainSM { timer_start_debug!(CREATE_AIR_INSTANCE); let buffer = std::mem::take(&mut iectx.prover_buffer); iectx.air_instance = Some(AirInstance::new( - self.sctx.clone(), + self.wcm.get_sctx(), BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0], None, @@ -410,8 +188,9 @@ impl MainSM { timer_stop_and_log_debug!(CREATE_AIR_INSTANCE); } - fn prove_binary_extension( + pub fn prove_binary_extension( &self, + zisk_rom: &ZiskRom, vec_traces: &[EmuTrace], iectx: &mut InstanceExtensionCtx, pctx: &ProofCtx, @@ -419,7 +198,7 @@ impl MainSM { let air = pctx.pilout.get_air(BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]); let inputs = ZiskEmulator::process_slice_required::( - &self.zisk_rom, + zisk_rom, vec_traces, iectx.op_type, &iectx.emu_trace_start, @@ -430,7 +209,7 @@ impl MainSM { let buffer = std::mem::take(&mut iectx.prover_buffer); iectx.air_instance = Some(AirInstance::new( - self.sctx.clone(), + self.wcm.get_sctx(), BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0], None, diff --git a/witness-computation/Cargo.toml b/witness-computation/Cargo.toml index 89c97fa7..8540e2a0 100644 --- a/witness-computation/Cargo.toml +++ b/witness-computation/Cargo.toml @@ -16,16 +16,20 @@ sm-mem = { path = "../state-machines/mem" } sm-quick-ops = { path = "../state-machines/quick-ops" } sm-rom = { path = "../state-machines/rom" } zisk-pil = { path = "../pil" } +ziskemu = { path = "../emulator" } +zisk-core = { path = "../core" } + proofman-common = { workspace = true } proofman-util = { workspace = true } proofman = { workspace = true } p3-field = { workspace=true } pil-std-lib = { workspace = true } - log = { workspace = true } + env_logger = "0.11" p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } +rayon = { workspace = true } [features] default = [] diff --git a/witness-computation/src/executor.rs b/witness-computation/src/executor.rs new file mode 100644 index 00000000..7be4d77a --- /dev/null +++ b/witness-computation/src/executor.rs @@ -0,0 +1,242 @@ +use p3_field::PrimeField; +use pil_std_lib::Std; +use proofman::WitnessManager; +use proofman_common::{ExecutionCtx, ProofCtx, SetupCtx}; +use proofman_util::{timer_start_debug, timer_stop_and_log_debug}; + +use rayon::prelude::*; + +use sm_arith::ArithSM; +use sm_binary::BinarySM; +use sm_common::create_prover_buffer; +use sm_main::{InstanceExtensionCtx, MainSM}; +use sm_mem::MemSM; +use sm_rom::RomSM; +use std::{ + fs, + path::{Path, PathBuf}, + sync::Arc, +}; +use zisk_core::{Riscv2zisk, ZiskOperationType, ZiskRom, ZISK_OPERATION_TYPE_VARIANTS}; +use zisk_pil::{ + BINARY_AIRGROUP_ID, BINARY_AIR_IDS, BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS, + MAIN_AIRGROUP_ID, MAIN_AIR_IDS, +}; +use ziskemu::{EmuOptions, ZiskEmulator}; + +pub struct ZiskExecutor { + /// ZisK ROM, a binary file that contains the ZisK program to be executed + pub zisk_rom: ZiskRom, + + /// Main State Machine + pub main_sm: Arc>, + + /// ROM State Machine + pub rom_sm: Arc>, + + /// Memory State Machine + pub mem_sm: Arc, + + /// Binary State Machine + pub binary_sm: Arc>, + + /// Arithmetic State Machine + pub arith_sm: Arc, +} + +impl ZiskExecutor { + const BLOCK_SIZE: usize = 2usize.pow(21); + const NUM_THREADS: usize = 8; + + pub fn new(wcm: Arc>, rom_path: PathBuf) -> Self { + let std = Std::new(wcm.clone()); + + let rom_sm = RomSM::new(wcm.clone()); + let mem_sm = MemSM::new(wcm.clone()); + let binary_sm = BinarySM::new(wcm.clone(), std.clone()); + let arith_sm = ArithSM::new(wcm.clone()); + + // If rom_path has an .elf extension it must be converted to a ZisK ROM + let zisk_rom = if rom_path.extension().unwrap() == "elf" { + // Create an instance of the RISCV -> ZisK program converter + let rv2zk = Riscv2zisk::new( + rom_path.display().to_string(), + String::new(), + String::new(), + String::new(), + ); + + // Convert program to rom + match rv2zk.run() { + Ok(rom) => rom, + Err(e) => { + panic!("Application error: {}", e); + } + } + } else { + // TODO - Remove this when the ZisK ROM is able to be loaded from a file + panic!("ROM file must be an ELF file"); + }; + + // TODO - Compute MAX_ACCUMULATED having the num_rows of the Main AIR + // TODO - If there is more than one Main AIR available, the MAX_ACCUMULATED will be the one + // with the highest num_rows. It has to be a power of 2. + + let main_sm = MainSM::new(wcm.clone(), arith_sm.clone(), binary_sm.clone(), mem_sm.clone()); + + Self { zisk_rom, main_sm, rom_sm, mem_sm, binary_sm, arith_sm } + } + + /// Executes the MainSM state machine and processes the inputs in batches when the maximum + /// number of accumulated inputs is reached. The MainSM state machine uses the emulator to + /// execute the a program and using a callback the main state machine receives batches of + /// inputs generated by the emulator. The inputs are processed in batches when the maximum + /// number of accumulated inputs is reached + /// # Arguments + /// * `pctx` - Proof context to interact with the proof system + /// * `ectx` - Execution context to interact with the execution environment + pub fn execute( + &self, + rom_path: &Path, + public_inputs_path: &Path, + pctx: Arc>, + ectx: Arc, + sctx: Arc, + ) { + // Create a thread pool to manage the execution of all the state machines related to the + // execution process + + // Prepare the settings for the emulator + let emu_options = EmuOptions { + elf: Some(rom_path.to_path_buf().display().to_string()), + inputs: Some(public_inputs_path.display().to_string()), + trace_steps: Some(Self::BLOCK_SIZE as u64), + ..EmuOptions::default() + }; + + // Call emulate with these options + let public_inputs = { + // Read inputs data from the provided inputs path + let path = PathBuf::from(public_inputs_path.display().to_string()); + fs::read(path).expect("Could not read inputs file") + }; + + // During ROM processing, we gather execution data necessary for creating the AIR instances. + // This data is collected by the emulator and includes the minimal execution trace, + // along with essential state information of the processor. This ensures that the execution + // can be reproduced from specific points in the trace to generate the inputs for each state + // machine. We aim to track the starting point of execution for every N instructions + // across different operation types. Currently, we are only collecting data for + // Binary and BinaryE operations. + let air_main = pctx.pilout.get_air(MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]); + let air_binary = pctx.pilout.get_air(BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]); + let air_binary_e = + pctx.pilout.get_air(BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]); + + let mut op_sizes = [0u64; ZISK_OPERATION_TYPE_VARIANTS]; + // The starting points for the Main is allocated using None operation + op_sizes[ZiskOperationType::None as usize] = air_main.num_rows() as u64; + op_sizes[ZiskOperationType::Binary as usize] = air_binary.num_rows() as u64; + op_sizes[ZiskOperationType::BinaryE as usize] = air_binary_e.num_rows() as u64; + + // ROM State Machine + // ---------------------------------------------- + // Run the ROM to compute the ROM witness + let rom_sm = self.rom_sm.clone(); + let zisk_rom = self.zisk_rom.clone(); + let pc_histogram = + ZiskEmulator::process_rom_pc_histogram(&self.zisk_rom, &public_inputs, &emu_options) + .expect( + "MainSM::execute() failed calling ZiskEmulator::process_rom_pc_histogram()", + ); + let handle_rom = std::thread::spawn(move || rom_sm.prove(&zisk_rom, pc_histogram)); + + // Main, Binary and Arith State Machines + // ---------------------------------------------- + // Run the emulator in parallel n times to collect execution traces + // and record the execution starting points for each AIR instance + timer_start_debug!(PAR_PROCESS_ROM); + let (emu_traces, mut emu_slices) = ZiskEmulator::par_process_rom::( + &self.zisk_rom, + &public_inputs, + &emu_options, + Self::NUM_THREADS, + op_sizes, + ) + .expect("Error during emulator execution"); + timer_stop_and_log_debug!(PAR_PROCESS_ROM); + + emu_slices.points.sort_by(|a, b| a.op_type.partial_cmp(&b.op_type).unwrap()); + + // Join threads to synchronize the execution + handle_rom.join().unwrap().expect("Error during ROM witness computation"); + + // FIXME: Move InstanceExtensionCtx form main SM to another place + let mut instances_extension_ctx: Vec> = + Vec::with_capacity(emu_slices.points.len()); + + let mut dctx = ectx.dctx.write().unwrap(); + let mut main_segnent_id = 0; + for emu_slice in emu_slices.points.iter() { + let (airgroup_id, air_id) = match emu_slice.op_type { + ZiskOperationType::None => (MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]), + ZiskOperationType::Binary => (BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]), + ZiskOperationType::BinaryE => { + (BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]) + } + _ => panic!("Invalid operation type"), + }; + let segmen_id = match emu_slice.op_type { + ZiskOperationType::None => { + main_segnent_id += 1; + Some(main_segnent_id - 1) + } + _ => None, + }; + + if let (true, global_idx) = dctx.add_instance(airgroup_id, air_id, 1) { + let (buffer, offset) = create_prover_buffer::(&ectx, &sctx, airgroup_id, air_id); + instances_extension_ctx.push(InstanceExtensionCtx::new( + buffer, + offset, + emu_slice.op_type, + emu_slice.emu_trace_start.clone(), + segmen_id, + global_idx, + None, + )); + } + } + drop(dctx); + + instances_extension_ctx.par_iter_mut().for_each(|iectx| match iectx.op_type { + ZiskOperationType::None => { + self.main_sm.prove_main(&self.zisk_rom, &emu_traces, iectx, &pctx); + } + ZiskOperationType::Binary => { + self.main_sm.prove_binary(&self.zisk_rom, &emu_traces, iectx, &pctx); + } + ZiskOperationType::BinaryE => { + self.main_sm.prove_binary_extension(&self.zisk_rom, &emu_traces, iectx, &pctx); + } + _ => panic!("Invalid operation type"), + }); + // Drop the emulator traces concurrently + std::thread::spawn(move || { + drop(emu_traces); + }); + + timer_start_debug!(ADD_INSTANCES_TO_THE_REPO); + for iectx in instances_extension_ctx { + if let Some(air_instance) = iectx.air_instance { + pctx.air_instance_repo + .add_air_instance(air_instance, Some(iectx.instance_global_idx)); + } + } + timer_stop_and_log_debug!(ADD_INSTANCES_TO_THE_REPO); + + // self.mem_sm.unregister_predecessor(scope); + self.binary_sm.unregister_predecessor(); + // self.arith_sm.register_predecessor(scope); + } +} diff --git a/witness-computation/src/lib.rs b/witness-computation/src/lib.rs index 39ef75d6..9a41bb3d 100644 --- a/witness-computation/src/lib.rs +++ b/witness-computation/src/lib.rs @@ -1,3 +1,5 @@ +mod executor; mod zisk_lib; +pub use executor::*; pub use zisk_lib::*; diff --git a/witness-computation/src/zisk_lib.rs b/witness-computation/src/zisk_lib.rs index dd74be25..e830dd89 100644 --- a/witness-computation/src/zisk_lib.rs +++ b/witness-computation/src/zisk_lib.rs @@ -1,27 +1,26 @@ -use pil_std_lib::Std; use proofman_util::{timer_start_info, timer_stop_and_log_info}; -use sm_rom::RomSM; -use std::{error::Error, path::PathBuf, sync::Arc}; +use std::{cell::OnceCell, error::Error, path::PathBuf, sync::Arc}; use zisk_pil::*; use p3_field::PrimeField; use p3_goldilocks::Goldilocks; use proofman::{WitnessLibrary, WitnessManager}; use proofman_common::{initialize_logger, ExecutionCtx, ProofCtx, SetupCtx, WitnessPilout}; -use sm_arith::ArithSM; -use sm_binary::BinarySM; -use sm_main::MainSM; -use sm_mem::MemSM; + +use crate::ZiskExecutor; pub struct ZiskWitness { + /// Public inputs path pub public_inputs_path: PathBuf, + + /// ROM path pub rom_path: PathBuf, - // Witness computation manager - pub wcm: Option>>, + /// Witness computation manager + pub wcm: OnceCell>>, - // State machines - pub main_sm: Option>>, + /// Executor + pub executor: OnceCell>, } impl ZiskWitness { @@ -38,32 +37,20 @@ impl ZiskWitness { ); } - Ok(ZiskWitness { public_inputs_path, rom_path, wcm: None, main_sm: None }) + Ok(ZiskWitness { + public_inputs_path, + rom_path, + wcm: OnceCell::new(), + executor: OnceCell::new(), + }) } fn initialize(&mut self, pctx: Arc>, ectx: Arc, sctx: Arc) { let wcm = WitnessManager::new(pctx, ectx, sctx.clone()); let wcm = Arc::new(wcm); - let std = Std::new(wcm.clone()); - - let rom_sm = RomSM::new(wcm.clone()); - let mem_sm = MemSM::new(wcm.clone()); - let binary_sm = BinarySM::new(wcm.clone(), std.clone()); - let arith_sm = ArithSM::new(wcm.clone()); - - let main_sm = MainSM::new( - self.rom_path.clone(), - wcm.clone(), - sctx, - rom_sm, - mem_sm, - binary_sm, - arith_sm, - ); - - self.wcm = Some(wcm); - self.main_sm = Some(main_sm); + self.wcm.set(wcm.clone()).ok(); + self.executor.set(ZiskExecutor::new(wcm, self.rom_path.clone())).ok(); } } @@ -76,15 +63,21 @@ impl WitnessLibrary for ZiskWitness { ) { self.initialize(pctx.clone(), ectx.clone(), sctx.clone()); - self.wcm.as_ref().unwrap().start_proof(pctx, ectx, sctx); + self.wcm.get().unwrap().start_proof(pctx, ectx, sctx); } fn end_proof(&mut self) { - self.wcm.as_ref().unwrap().end_proof(); + self.wcm.get().unwrap().end_proof(); } fn execute(&self, pctx: Arc>, ectx: Arc, sctx: Arc) { timer_start_info!(EXECUTE); - self.main_sm.as_ref().unwrap().execute(&self.public_inputs_path, pctx, ectx, sctx); + self.executor.get().unwrap().execute( + &self.rom_path, + &self.public_inputs_path, + pctx, + ectx, + sctx, + ); timer_stop_and_log_info!(EXECUTE); } @@ -95,7 +88,7 @@ impl WitnessLibrary for ZiskWitness { ectx: Arc, sctx: Arc, ) { - self.wcm.as_ref().unwrap().calculate_witness(stage, pctx, ectx, sctx); + self.wcm.get().unwrap().calculate_witness(stage, pctx, ectx, sctx); } fn pilout(&self) -> WitnessPilout { From 46481c45587753061a150de0f4f080ceb4f22045 Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Wed, 30 Oct 2024 07:48:31 +0000 Subject: [PATCH 11/22] fix doc --- book/getting_started/quickstart_dev.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/book/getting_started/quickstart_dev.md b/book/getting_started/quickstart_dev.md index 30ee12dd..ac2fdad1 100644 --- a/book/getting_started/quickstart_dev.md +++ b/book/getting_started/quickstart_dev.md @@ -20,8 +20,6 @@ git clone -b develop https://github.com/0xPolygonHermez/pil2-compiler.git git clone -b develop https://github.com/0xPolygonHermez/zisk.git git clone -b develop https://github.com/0xPolygonHermez/pil2-proofman.git git clone -b develop https://github.com/0xPolygonHermez/pil2-stark-js.git - -git clone --recursive -b develop https://github.com/0xPolygonHermez/pil2-stark.git git clone -b feature/setup https://github.com/0xPolygonHermez/pil2-proofman-js ``` @@ -116,7 +114,7 @@ node ../pil2-compiler/src/pil.js pil/zisk.pil -I pil,../pil2-components/lib/std_ ### Compile the PIl2 Stark C++ Library (run only once): ```bash -(cd ../pil2-stark && git submodule init && git submodule update && make clean && make -j starks_lib && make -j bctree) +(cd ../pil2-proofman/pil2-stark && git submodule init && git submodule update && make clean && make -j starks_lib && make -j bctree) ``` ### Generate PIL-Helpers Rust Code @@ -140,7 +138,7 @@ cargo build --release > If you get a library not found error, set the path manually: > ```bash -> export RUSTFLAGS="-L native=/home/{path to your pil2-stark folder}/lib" +> export RUSTFLAGS="-L native={path to your pil2-stark folder}/pil2-stark/lib" > ``` ## Generate & Verify Proofs From 61117ea19127db3cd3ea78aa5699e80791cb12fe Mon Sep 17 00:00:00 2001 From: fractasy Date: Wed, 30 Oct 2024 09:26:50 +0000 Subject: [PATCH 12/22] Compile new main.pil and fix Emu accordingly --- core/src/zisk_inst.rs | 29 +++++++++++++++-------------- emulator/src/emu.rs | 10 +++++----- pil/src/pil_helpers/traces.rs | 8 ++++---- state-machines/main/pil/main.pil | 28 ++++++++++++++-------------- state-machines/rom/src/rom.rs | 12 ++++++------ 5 files changed, 44 insertions(+), 43 deletions(-) diff --git a/core/src/zisk_inst.rs b/core/src/zisk_inst.rs index 2df9ab35..fd83e4cd 100644 --- a/core/src/zisk_inst.rs +++ b/core/src/zisk_inst.rs @@ -1,5 +1,6 @@ use crate::{ - source_to_str, store_to_str, InstContext, SRC_IMM, SRC_MEM, SRC_STEP, STORE_IND, STORE_MEM, + source_to_str, store_to_str, InstContext, SRC_IMM, SRC_IND, SRC_MEM, SRC_STEP, STORE_IND, + STORE_MEM, }; #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] @@ -166,19 +167,19 @@ impl ZiskInst { } pub fn get_flags(&self) -> u64 { - let flags: u64 = 1 | - (((self.a_src == SRC_IMM) as u64) << 1) | - (((self.a_src == SRC_MEM) as u64) << 2) | - (((self.a_src == SRC_STEP) as u64) << 3) | - (((self.b_src == SRC_IMM) as u64) << 4) | - (((self.b_src == SRC_MEM) as u64) << 5) | - ((self.is_external_op as u64) << 6) | - ((self.store_ra as u64) << 7) | - (((self.store == STORE_MEM) as u64) << 8) | - (((self.store == STORE_IND) as u64) << 9) | - ((self.set_pc as u64) << 10) | - ((self.end as u64) << 11) | - ((self.m32 as u64) << 12); + let flags: u64 = 1 + | (((self.a_src == SRC_IMM) as u64) << 1) + | (((self.a_src == SRC_MEM) as u64) << 2) + | (((self.a_src == SRC_STEP) as u64) << 3) + | (((self.b_src == SRC_IMM) as u64) << 4) + | (((self.b_src == SRC_MEM) as u64) << 5) + | ((self.is_external_op as u64) << 6) + | ((self.store_ra as u64) << 7) + | (((self.store == STORE_MEM) as u64) << 8) + | (((self.store == STORE_IND) as u64) << 9) + | ((self.set_pc as u64) << 10) + | ((self.m32 as u64) << 11) + | (((self.b_src == SRC_IND) as u64) << 12); flags } diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index a76b3d9f..7f2e83af 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -896,17 +896,17 @@ impl<'a> Emu<'a> { jmp_offset2, m32: F::from_bool(inst.m32), addr1: F::from_canonical_u64(addr1), - addr2: F::from_canonical_u64(addr2), - store_value: [ + //addr2: F::from_canonical_u64(addr2), + /*store_value: [ F::from_canonical_u64(store_value[0]), F::from_canonical_u64(store_value[1]), ], __debug_operation_bus_enabled: F::from_bool( inst.op_type == ZiskOperationType::Binary || inst.op_type == ZiskOperationType::BinaryE, - ), - hi_a: F::from_canonical_u64(hi_a), - hi_b: F::from_canonical_u64(hi_b), + ),*/ + //hi_a: F::from_canonical_u64(hi_a), + //hi_b: F::from_canonical_u64(hi_b), } } diff --git a/pil/src/pil_helpers/traces.rs b/pil/src/pil_helpers/traces.rs index 38938e53..c9c3bcdb 100644 --- a/pil/src/pil_helpers/traces.rs +++ b/pil/src/pil_helpers/traces.rs @@ -4,19 +4,19 @@ use proofman_common as common; pub use proofman_macros::trace; trace!(Main0Row, Main0Trace { - a: [F; 2], b: [F; 2], c: [F; 2], flag: F, pc: F, a_src_imm: F, a_src_mem: F, a_offset_imm0: F, a_imm1: F, a_src_step: F, b_src_imm: F, b_src_mem: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, is_external_op: F, op: F, store_ra: F, store_mem: F, store_ind: F, store_offset: F, set_pc: F, jmp_offset1: F, jmp_offset2: F, m32: F, addr1: F, addr2: F, store_value: [F; 2], __debug_operation_bus_enabled: F, hi_a: F, hi_b: F, + a: [F; 2], b: [F; 2], c: [F; 2], flag: F, pc: F, a_src_imm: F, a_src_mem: F, a_offset_imm0: F, a_imm1: F, a_src_step: F, b_src_imm: F, b_src_mem: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, is_external_op: F, op: F, store_ra: F, store_mem: F, store_ind: F, store_offset: F, set_pc: F, jmp_offset1: F, jmp_offset2: F, m32: F, addr1: F, }); trace!(RomS0Row, RomS0Trace { - line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, + line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, }); trace!(RomM1Row, RomM1Trace { - line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, + line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, }); trace!(RomL2Row, RomL2Trace { - line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, + line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, }); trace!(Binary0Row, Binary0Trace { diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 9a590a18..ee23b6ae 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -134,17 +134,17 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope } // Mem.load - mem_load(sel: a_src_mem, - step: addr_step, - addr: addr0, - value: a); + //mem_load(sel: a_src_mem, + // step: addr_step, + // addr: addr0, + // value: a); // Mem.load - mem_load(sel: sel_mem_b, - step: addr_step + 1, - bytes: ind_width, - addr: addr1, - value: b); + //mem_load(sel: sel_mem_b, + // step: addr_step + 1, + // bytes: ind_width, + // addr: addr1, + // value: b); const expr store_value[2]; @@ -152,11 +152,11 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope store_value[1] = (1 - store_ra) * c[1]; // Mem.store - mem_store(sel: store_mem + store_ind, - step: addr_step + 2, - bytes: ind_width, - addr: addr2, - value: store_value); + //mem_store(sel: store_mem + store_ind, + // step: addr_step + 2, + // bytes: ind_width, + // addr: addr2, + // value: store_value); // Operation.assume => how organize software // col witness __debug_operation_bus_enabled; diff --git a/state-machines/rom/src/rom.rs b/state-machines/rom/src/rom.rs index 7a0ee637..3cf76a57 100644 --- a/state-machines/rom/src/rom.rs +++ b/state-machines/rom/src/rom.rs @@ -187,8 +187,8 @@ impl RomSM { rom_trace[i].b_offset_imm0 = F::from_canonical_u64(inst.b_offset_imm0); rom_trace[i].b_imm1 = F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); - rom_trace[i].b_src_ind = - F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); + //rom_trace[i].b_src_ind = + // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); rom_trace[i].op = F::from_canonical_u8(inst.op); rom_trace[i].store_offset = F::from_canonical_u64(inst.store_offset as u64); @@ -275,8 +275,8 @@ impl RomSM { rom_trace[i].b_offset_imm0 = F::from_canonical_u64(inst.b_offset_imm0); rom_trace[i].b_imm1 = F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); - rom_trace[i].b_src_ind = - F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); + //rom_trace[i].b_src_ind = + // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); rom_trace[i].op = F::from_canonical_u8(inst.op); rom_trace[i].store_offset = F::from_canonical_u64(inst.store_offset as u64); @@ -347,8 +347,8 @@ impl RomSM { rom_trace[i].b_offset_imm0 = F::from_canonical_u64(inst.b_offset_imm0); rom_trace[i].b_imm1 = F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); - rom_trace[i].b_src_ind = - F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); + //rom_trace[i].b_src_ind = + // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); rom_trace[i].op = F::from_canonical_u8(inst.op); rom_trace[i].store_offset = F::from_canonical_u64(inst.store_offset as u64); From 5b45ab2ec5a67e65590c6b6d6d1d61852f24c849 Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:52:02 +0000 Subject: [PATCH 13/22] binary continuations working except global constraints --- emulator/src/emu.rs | 31 ++----------------- state-machines/main/pil/main.pil | 14 ++++++--- state-machines/main/src/main_sm.rs | 48 ++++++++++++++++++++++++++---- state-machines/rom/src/rom.rs | 2 +- 4 files changed, 56 insertions(+), 39 deletions(-) diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index 7f2e83af..fdc61369 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -796,24 +796,16 @@ impl<'a> Emu<'a> { pub fn build_full_trace_step( inst: &ZiskInst, inst_ctx: &InstContext, - last_c: u64, - last_pc: u64, + _last_c: u64, // TODO! Check if it's necessay + _last_pc: u64, ) -> EmuFullTraceStep { // Calculate intermediate values let a = [inst_ctx.a & 0xFFFFFFFF, (inst_ctx.a >> 32) & 0xFFFFFFFF]; let b = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.b >> 32) & 0xFFFFFFFF]; let c = [inst_ctx.c & 0xFFFFFFFF, (inst_ctx.c >> 32) & 0xFFFFFFFF]; - let hi_a = a[1] * (1 - inst.m32 as u64); - let hi_b = b[1] * (1 - inst.m32 as u64); - let store_value = [ - if inst.store_ra { (inst.paddr as i64 + inst.jmp_offset2) as u64 } else { c[0] }, - if inst.store_ra { 0 } else { c[1] }, - ]; - + let addr1 = (inst.b_offset_imm0 as i64 + if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64; - let addr2 = - (inst.store_offset + if inst.store == STORE_IND { a[0] as i64 } else { 0 }) as u64; let jmp_offset1 = if inst.jmp_offset1 >= 0 { F::from_canonical_u64(inst.jmp_offset1 as u64) @@ -845,12 +837,6 @@ impl<'a> Emu<'a> { F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) }; - if inst_ctx.step < 100 { - let inst_string = inst.to_text(); - println! {"MAIN step={} pc={} last_pc={} a={:x} b={:x} c={:x} m32={} store_ra={} store_value=[{},{}] jmp_offset1={} jmp_offset2={} flag={} addr1={} addr2={} inst={:?}", - inst_ctx.step, inst.paddr, last_pc, inst_ctx.a, inst_ctx.b, inst_ctx.c, inst.m32, inst.store_ra, store_value[0], store_value[1], inst.jmp_offset1, inst.jmp_offset2, inst_ctx.flag, addr1, addr2, inst_string}; - } - EmuFullTraceStep { a: [F::from_canonical_u64(a[0]), F::from_canonical_u64(a[1])], b: [F::from_canonical_u64(b[0]), F::from_canonical_u64(b[1])], @@ -896,17 +882,6 @@ impl<'a> Emu<'a> { jmp_offset2, m32: F::from_bool(inst.m32), addr1: F::from_canonical_u64(addr1), - //addr2: F::from_canonical_u64(addr2), - /*store_value: [ - F::from_canonical_u64(store_value[0]), - F::from_canonical_u64(store_value[1]), - ], - __debug_operation_bus_enabled: F::from_bool( - inst.op_type == ZiskOperationType::Binary - || inst.op_type == ZiskOperationType::BinaryE, - ),*/ - //hi_a: F::from_canonical_u64(hi_a), - //hi_b: F::from_canonical_u64(hi_b), } } diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index ee23b6ae..968ea659 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -1,4 +1,5 @@ require "std_lookup.pil" +require "std_common.pil" const int BOOT_ADDR = 0x1000; const int END_PC_ADDR = 0x2000; @@ -214,8 +215,11 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope flag * set_pc === 0; - const expr next_pc = set_pc * (c[0] + jmp_offset1) + (1 - set_pc) * (pc + jmp_offset2) + flag * (jmp_offset1 - jmp_offset2); - (1 - SEGMENT_L1) * (pc - 'next_pc) === 0; + // TODO! The following constraint is correct but something is not working in the compiler + + // const expr next_pc = set_pc * (c[0] + jmp_offset1) + (1 - set_pc) * (pc + jmp_offset2) + flag * (jmp_offset1 - jmp_offset2); + const expr next_pc = 'set_pc * ('c[0] + 'jmp_offset1) + (1 - 'set_pc) * ('pc + 'jmp_offset2) + 'flag * ('jmp_offset1 - 'jmp_offset2); + (1 - SEGMENT_L1) * (pc - next_pc) === 0; const expr is_last_continuation = SEGMENT_LAST * main_last_segment; const expr specific_registers[stack_enabled ? 2:1]; @@ -236,7 +240,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // const expr bus_main_segment = main_segment - SEGMENT_LAST * (main_segment * main_last_segment - 1 + main_last_segment); - permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, ...specific_registers, ...a, ...c], + permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, ...specific_registers, c[0] * (1 - main_last_segment), c[1] * (1 - main_last_segment)], sel: SEGMENT_LAST - SEGMENT_L1, name: PIOP_NAME_ISOLATED, bus_type: PIOP_BUS_SUM); flag * (1 - flag) === 0; @@ -263,10 +267,12 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope SEGMENT_L1 * jmp_offset1 === 0; SEGMENT_L1 * jmp_offset2 === 0; - SEGMENT_L1 * (rom_flags - 18) === 0; // 18 = a_src_imm(2) + b_src_imm(16) + SEGMENT_L1 * (rom_flags - 19) === 0; // 19 = 1 + a_src_imm(2) + b_src_imm(16) SEGMENT_L1 * (op - 1) === 0; lookup_assumes(ROM_BUS_ID, [pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, ind_width, op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1 - SEGMENT_L1); + direct_update(MAIN_CONTINUATION_ID, cols: [0, 0, 4096, 0, 0], bus_type: PIOP_BUS_SUM); + direct_update(MAIN_CONTINUATION_ID, cols: [0, 1, 8192, 0, 0], bus_type: PIOP_BUS_SUM); } \ No newline at end of file diff --git a/state-machines/main/src/main_sm.rs b/state-machines/main/src/main_sm.rs index 358d6212..df1d70d6 100644 --- a/state-machines/main/src/main_sm.rs +++ b/state-machines/main/src/main_sm.rs @@ -11,7 +11,10 @@ use std::{ path::{Path, PathBuf}, sync::Arc, }; -use zisk_core::{Riscv2zisk, ZiskOperationType, ZiskRom, ZISK_OPERATION_TYPE_VARIANTS}; +use zisk_core::{ + zisk_ops::ZiskOp, Riscv2zisk, ZiskOperationType, ZiskRom, ROM_ENTRY, + ZISK_OPERATION_TYPE_VARIANTS, +}; use proofman::WitnessManager; use proofman_common::{AirInstance, ExecutionCtx, ProofCtx, SetupCtx}; @@ -201,7 +204,7 @@ impl MainSM { let mut op_sizes = [0u64; ZISK_OPERATION_TYPE_VARIANTS]; // The starting points for the Main is allocated using None operation - op_sizes[ZiskOperationType::None as usize] = air_main.num_rows() as u64; + op_sizes[ZiskOperationType::None as usize] = air_main.num_rows() as u64 - 1; op_sizes[ZiskOperationType::Binary as usize] = air_binary.num_rows() as u64; op_sizes[ZiskOperationType::BinaryE as usize] = air_binary_e.num_rows() as u64; @@ -330,10 +333,44 @@ impl MainSM { let mut tmp_trace = Main0Trace::::new(CHUNK_SIZE); let mut last_row = Main0Row::::default(); - for chunk_start in (0..air.num_rows()).step_by(CHUNK_SIZE) { + + // Set row 0 + let row0 = if segment_id == 0 { + Main0Row:: { + pc: F::from_canonical_u64(ROM_ENTRY), + op: F::from_canonical_u8(ZiskOp::CopyB.code()), + a_src_imm: F::one(), + b_src_imm: F::one(), + ..Main0Row::default() + } + } else { + let emu_trace_previous = vec_traces[segment_id - 1].steps.last().unwrap(); + let row_previous = emu.step_slice_full_trace(emu_trace_previous); + + Main0Row:: { + a: row_previous.a, + b: row_previous.c, + c: row_previous.c, + a_offset_imm0: row_previous.a[0], + b_offset_imm0: row_previous.c[0], + a_imm1: row_previous.a[1], + b_imm1: row_previous.c[1], + op: F::from_canonical_u8(ZiskOp::CopyB.code()), + pc: row_previous.pc, + a_src_imm: F::one(), + b_src_imm: F::one(), + ..Main0Row::default() + } + }; + + iectx.prover_buffer[offset as usize..(offset as usize + Main0Row::::ROW_SIZE)].copy_from_slice(row0.as_slice()); + + // Set row 1..n + for chunk_start in (0..(air.num_rows())).step_by(CHUNK_SIZE) { // process the steps of the chunk let start_pos_abs = std::cmp::min(chunk_start, total_steps); - let end_pos_abs = (chunk_start + CHUNK_SIZE).min(total_steps); + let end_pos_abs = std::cmp::min(chunk_start + CHUNK_SIZE, total_steps); + for (i, step) in segment_trace.steps[start_pos_abs..end_pos_abs].iter().enumerate() { tmp_trace[i] = emu.step_slice_full_trace(step); } @@ -351,7 +388,7 @@ impl MainSM { //copy the chunk to the prover buffer let tmp_buffer = tmp_trace.buffer.as_mut().unwrap(); - let buffer_offset_chunk = offset as usize + chunk_start * Main0Row::::ROW_SIZE; + let buffer_offset_chunk = offset as usize + (chunk_start + 1) * Main0Row::::ROW_SIZE; iectx.prover_buffer[buffer_offset_chunk..buffer_offset_chunk + tmp_buffer.len()] .copy_from_slice(tmp_buffer); } @@ -365,7 +402,6 @@ impl MainSM { buffer, ); - let main_first_segment = F::from_bool(segment_id == 0); let main_last_segment = F::from_bool(segment_id == vec_traces.len() - 1); let main_segment = F::from_canonical_usize(segment_id); diff --git a/state-machines/rom/src/rom.rs b/state-machines/rom/src/rom.rs index 3cf76a57..6d04570f 100644 --- a/state-machines/rom/src/rom.rs +++ b/state-machines/rom/src/rom.rs @@ -5,7 +5,7 @@ use proofman::{WitnessComponent, WitnessManager}; use proofman_common::{AirInstance, BufferAllocator, SetupCtx}; use proofman_util::create_buffer_fast; -use zisk_core::{Riscv2zisk, ZiskPcHistogram, ZiskRom, SRC_IMM, SRC_IND}; +use zisk_core::{Riscv2zisk, ZiskPcHistogram, ZiskRom, SRC_IMM}; use zisk_pil::{ Pilout, RomL2Row, RomL2Trace, RomM1Row, RomM1Trace, RomS0Row, RomS0Trace, MAIN_AIRGROUP_ID, MAIN_AIR_IDS, ROM_AIRGROUP_ID, ROM_L_AIR_IDS, ROM_M_AIR_IDS, ROM_S_AIR_IDS, From 60cb3ae26f94352dc1cd6eb698703c84fa0c6a4e Mon Sep 17 00:00:00 2001 From: fractasy Date: Wed, 30 Oct 2024 17:37:43 +0000 Subject: [PATCH 14/22] Fixes to RomSM assume/prove --- core/src/zisk_definitions.rs | 20 +++--- emulator/src/emu.rs | 6 +- pil/src/pil_helpers/traces.rs | 2 +- state-machines/main/pil/main.pil | 12 ++-- state-machines/rom/src/rom.rs | 117 ++++++++++++++++++++++++++----- 5 files changed, 122 insertions(+), 35 deletions(-) diff --git a/core/src/zisk_definitions.rs b/core/src/zisk_definitions.rs index 64e5be8a..7f6c9669 100644 --- a/core/src/zisk_definitions.rs +++ b/core/src/zisk_definitions.rs @@ -14,21 +14,22 @@ pub const STORE_IND: u64 = 2; /* Memory map: - |--------------- ROM_ENTRY (0x1000) - | (rom entry, calls program, ~BIOS) - |--------------- + |--------------- ROM_ENTRY first instruction (0x1000) + | calls program at ROM_ADDR, then returns + | kind of a BIOS + |--------------- ROM_EXIT last instruction (0x4000) ... - |--------------- ROM_ADDR (0x80000000) + |--------------- ROM_ADDR (0x80000000) | (rom program) - |--------------- INPUT_ADDR + |--------------- INPUT_ADDR (0x90000000) | (input data) - |--------------- SYS_ADDR (= RAM_ADDR) + |--------------- SYS_ADDR (= RAM_ADDR) (0xa0000000) | (sys = 32 registers) - |--------------- OUTPUT_ADDR + |--------------- OUTPUT_ADDR (0xa0010000) | (output data) - |--------------- AVAILABLE_MEM_ADDR + |--------------- AVAILABLE_MEM_ADDR (0xa0020000) | (program memory) - |--------------- + |--------------- (0xb0000000) */ pub const ROM_ADDR: u64 = 0x80000000; @@ -44,6 +45,7 @@ pub const OUTPUT_MAX_SIZE: u64 = 0x10000; // 64K pub const AVAILABLE_MEM_ADDR: u64 = OUTPUT_ADDR + OUTPUT_MAX_SIZE; pub const AVAILABLE_MEM_SIZE: u64 = RAM_SIZE - OUTPUT_MAX_SIZE - SYS_SIZE; pub const ROM_ENTRY: u64 = 0x1000; +pub const ROM_EXIT: u64 = 0x4000; pub const ARCH_ID_ZISK: u64 = 0xFFFEEEE; pub const UART_ADDR: u64 = SYS_ADDR + 512; diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index fdc61369..fe821001 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -803,7 +803,7 @@ impl<'a> Emu<'a> { let a = [inst_ctx.a & 0xFFFFFFFF, (inst_ctx.a >> 32) & 0xFFFFFFFF]; let b = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.b >> 32) & 0xFFFFFFFF]; let c = [inst_ctx.c & 0xFFFFFFFF, (inst_ctx.c >> 32) & 0xFFFFFFFF]; - + let addr1 = (inst.b_offset_imm0 as i64 + if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64; @@ -882,6 +882,10 @@ impl<'a> Emu<'a> { jmp_offset2, m32: F::from_bool(inst.m32), addr1: F::from_canonical_u64(addr1), + __debug_operation_bus_enabled: F::from_bool( + inst.op_type == ZiskOperationType::Binary + || inst.op_type == ZiskOperationType::BinaryE, + ), } } diff --git a/pil/src/pil_helpers/traces.rs b/pil/src/pil_helpers/traces.rs index c9c3bcdb..580c4244 100644 --- a/pil/src/pil_helpers/traces.rs +++ b/pil/src/pil_helpers/traces.rs @@ -4,7 +4,7 @@ use proofman_common as common; pub use proofman_macros::trace; trace!(Main0Row, Main0Trace { - a: [F; 2], b: [F; 2], c: [F; 2], flag: F, pc: F, a_src_imm: F, a_src_mem: F, a_offset_imm0: F, a_imm1: F, a_src_step: F, b_src_imm: F, b_src_mem: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, is_external_op: F, op: F, store_ra: F, store_mem: F, store_ind: F, store_offset: F, set_pc: F, jmp_offset1: F, jmp_offset2: F, m32: F, addr1: F, + a: [F; 2], b: [F; 2], c: [F; 2], flag: F, pc: F, a_src_imm: F, a_src_mem: F, a_offset_imm0: F, a_imm1: F, a_src_step: F, b_src_imm: F, b_src_mem: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, is_external_op: F, op: F, store_ra: F, store_mem: F, store_ind: F, store_offset: F, set_pc: F, jmp_offset1: F, jmp_offset2: F, m32: F, addr1: F, __debug_operation_bus_enabled: F, }); trace!(RomS0Row, RomS0Trace { diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 968ea659..c9aa840f 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -160,9 +160,9 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // value: store_value); // Operation.assume => how organize software - // col witness __debug_operation_bus_enabled; + col witness __debug_operation_bus_enabled; - lookup_assumes(operation_bus_id, [STEP, op, a[0], (1 - m32) * a[1], b[0], (1 - m32) * b[1], ...c, flag], sel: is_external_op, name: PIOP_NAME_ISOLATED); + lookup_assumes(operation_bus_id, [STEP, op, a[0], (1 - m32) * a[1], b[0], (1 - m32) * b[1], ...c, flag], sel: is_external_op * __debug_operation_bus_enabled, name: PIOP_NAME_ISOLATED); const expr a_src_c; const expr b_src_c; @@ -259,8 +259,8 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // b_imm1 = b[1] = c[1] <== c[1] previous segment // a_offset_imm0 = a[0] <== a[0] previous segment // a_imm1 = a[1] <== a[1] previous segment - // op = 1 - // pc <== pc previous segment + // op = 1 (copyb: c=b, flag=0) + // pc <== pc previous segment (start of program at first segment; it needs to be equal to pc of row 1) // jmp_offset1 = jmp_offset2 = 0 // flag = 0 // a_src_imm = b_src_imm = 1 (rest flags to 0) @@ -273,6 +273,6 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope lookup_assumes(ROM_BUS_ID, [pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, ind_width, op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1 - SEGMENT_L1); - direct_update(MAIN_CONTINUATION_ID, cols: [0, 0, 4096, 0, 0], bus_type: PIOP_BUS_SUM); - direct_update(MAIN_CONTINUATION_ID, cols: [0, 1, 8192, 0, 0], bus_type: PIOP_BUS_SUM); + //direct_update(MAIN_CONTINUATION_ID, cols: [0, 0, 4096, 0, 0], bus_type: PIOP_BUS_SUM); + //direct_update(MAIN_CONTINUATION_ID, cols: [0, 1, 8192, 0, 0], bus_type: PIOP_BUS_SUM); } \ No newline at end of file diff --git a/state-machines/rom/src/rom.rs b/state-machines/rom/src/rom.rs index 6d04570f..e1cfffce 100644 --- a/state-machines/rom/src/rom.rs +++ b/state-machines/rom/src/rom.rs @@ -172,28 +172,55 @@ impl RomSM { if counter.is_some() { multiplicity = *counter.unwrap(); if inst.paddr == pc_histogram.end_pc { - multiplicity += main_trace_len - (pc_histogram.steps % main_trace_len); + multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); } } else { continue; // We skip those pc's that are not used in this execution } } + // Convert the i64 offsets to F + let jmp_offset1 = if inst.jmp_offset1 >= 0 { + F::from_canonical_u64(inst.jmp_offset1 as u64) + } else { + F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) + }; + let jmp_offset2 = if inst.jmp_offset2 >= 0 { + F::from_canonical_u64(inst.jmp_offset2 as u64) + } else { + F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) + }; + let store_offset = if inst.store_offset >= 0 { + F::from_canonical_u64(inst.store_offset as u64) + } else { + F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) + }; + let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { + F::from_canonical_u64(inst.a_offset_imm0) + } else { + F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) + }; + let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { + F::from_canonical_u64(inst.b_offset_imm0 as u64) + } else { + F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) + }; + // Fill the rom trace row fields rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line - rom_trace[i].a_offset_imm0 = F::from_canonical_u64(inst.a_offset_imm0); + rom_trace[i].a_offset_imm0 = a_offset_imm0; rom_trace[i].a_imm1 = F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); - rom_trace[i].b_offset_imm0 = F::from_canonical_u64(inst.b_offset_imm0); + rom_trace[i].b_offset_imm0 = b_offset_imm0; rom_trace[i].b_imm1 = F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); //rom_trace[i].b_src_ind = // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); rom_trace[i].op = F::from_canonical_u8(inst.op); - rom_trace[i].store_offset = F::from_canonical_u64(inst.store_offset as u64); - rom_trace[i].jmp_offset1 = F::from_canonical_u64(inst.jmp_offset1 as u64); - rom_trace[i].jmp_offset2 = F::from_canonical_u64(inst.jmp_offset2 as u64); + rom_trace[i].store_offset = store_offset; + rom_trace[i].jmp_offset1 = jmp_offset1; + rom_trace[i].jmp_offset2 = jmp_offset2; rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); /*println!( @@ -260,28 +287,55 @@ impl RomSM { if counter.is_some() { multiplicity = *counter.unwrap(); if inst.paddr == pc_histogram.end_pc { - multiplicity += main_trace_len - (pc_histogram.steps % main_trace_len); + multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); } } else { continue; // We skip those pc's that are not used in this execution } } + // Convert the i64 offsets to F + let jmp_offset1 = if inst.jmp_offset1 >= 0 { + F::from_canonical_u64(inst.jmp_offset1 as u64) + } else { + F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) + }; + let jmp_offset2 = if inst.jmp_offset2 >= 0 { + F::from_canonical_u64(inst.jmp_offset2 as u64) + } else { + F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) + }; + let store_offset = if inst.store_offset >= 0 { + F::from_canonical_u64(inst.store_offset as u64) + } else { + F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) + }; + let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { + F::from_canonical_u64(inst.a_offset_imm0) + } else { + F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) + }; + let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { + F::from_canonical_u64(inst.b_offset_imm0 as u64) + } else { + F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) + }; + // Fill the rom trace row fields rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line - rom_trace[i].a_offset_imm0 = F::from_canonical_u64(inst.a_offset_imm0); + rom_trace[i].a_offset_imm0 = a_offset_imm0; rom_trace[i].a_imm1 = F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); - rom_trace[i].b_offset_imm0 = F::from_canonical_u64(inst.b_offset_imm0); + rom_trace[i].b_offset_imm0 = b_offset_imm0; rom_trace[i].b_imm1 = F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); //rom_trace[i].b_src_ind = // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); rom_trace[i].op = F::from_canonical_u8(inst.op); - rom_trace[i].store_offset = F::from_canonical_u64(inst.store_offset as u64); - rom_trace[i].jmp_offset1 = F::from_canonical_u64(inst.jmp_offset1 as u64); - rom_trace[i].jmp_offset2 = F::from_canonical_u64(inst.jmp_offset2 as u64); + rom_trace[i].store_offset = store_offset; + rom_trace[i].jmp_offset1 = jmp_offset1; + rom_trace[i].jmp_offset2 = jmp_offset2; rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); } @@ -332,28 +386,55 @@ impl RomSM { if counter.is_some() { multiplicity = *counter.unwrap(); if inst.paddr == pc_histogram.end_pc { - multiplicity += main_trace_len - (pc_histogram.steps % main_trace_len); + multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); } } else { continue; // We skip those pc's that are not used in this execution } } + // Convert the i64 offsets to F + let jmp_offset1 = if inst.jmp_offset1 >= 0 { + F::from_canonical_u64(inst.jmp_offset1 as u64) + } else { + F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) + }; + let jmp_offset2 = if inst.jmp_offset2 >= 0 { + F::from_canonical_u64(inst.jmp_offset2 as u64) + } else { + F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) + }; + let store_offset = if inst.store_offset >= 0 { + F::from_canonical_u64(inst.store_offset as u64) + } else { + F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) + }; + let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { + F::from_canonical_u64(inst.a_offset_imm0) + } else { + F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) + }; + let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { + F::from_canonical_u64(inst.b_offset_imm0 as u64) + } else { + F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) + }; + // Fill the rom trace row fields rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line - rom_trace[i].a_offset_imm0 = F::from_canonical_u64(inst.a_offset_imm0); + rom_trace[i].a_offset_imm0 = a_offset_imm0; rom_trace[i].a_imm1 = F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); - rom_trace[i].b_offset_imm0 = F::from_canonical_u64(inst.b_offset_imm0); + rom_trace[i].b_offset_imm0 = b_offset_imm0; rom_trace[i].b_imm1 = F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); //rom_trace[i].b_src_ind = // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); rom_trace[i].op = F::from_canonical_u8(inst.op); - rom_trace[i].store_offset = F::from_canonical_u64(inst.store_offset as u64); - rom_trace[i].jmp_offset1 = F::from_canonical_u64(inst.jmp_offset1 as u64); - rom_trace[i].jmp_offset2 = F::from_canonical_u64(inst.jmp_offset2 as u64); + rom_trace[i].store_offset = store_offset; + rom_trace[i].jmp_offset1 = jmp_offset1; + rom_trace[i].jmp_offset2 = jmp_offset2; rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); } From e73f4128efc8cd285603427308f14f8f71bfae51 Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:46:38 +0000 Subject: [PATCH 15/22] cargo fmt & clippy --- core/src/zisk_inst.rs | 26 +++++++++++++------------- emulator/src/emu.rs | 30 +++++++++++++++--------------- state-machines/rom/src/rom.rs | 6 +++--- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/core/src/zisk_inst.rs b/core/src/zisk_inst.rs index fd83e4cd..4c2d0043 100644 --- a/core/src/zisk_inst.rs +++ b/core/src/zisk_inst.rs @@ -167,19 +167,19 @@ impl ZiskInst { } pub fn get_flags(&self) -> u64 { - let flags: u64 = 1 - | (((self.a_src == SRC_IMM) as u64) << 1) - | (((self.a_src == SRC_MEM) as u64) << 2) - | (((self.a_src == SRC_STEP) as u64) << 3) - | (((self.b_src == SRC_IMM) as u64) << 4) - | (((self.b_src == SRC_MEM) as u64) << 5) - | ((self.is_external_op as u64) << 6) - | ((self.store_ra as u64) << 7) - | (((self.store == STORE_MEM) as u64) << 8) - | (((self.store == STORE_IND) as u64) << 9) - | ((self.set_pc as u64) << 10) - | ((self.m32 as u64) << 11) - | (((self.b_src == SRC_IND) as u64) << 12); + let flags: u64 = 1 | + (((self.a_src == SRC_IMM) as u64) << 1) | + (((self.a_src == SRC_MEM) as u64) << 2) | + (((self.a_src == SRC_STEP) as u64) << 3) | + (((self.b_src == SRC_IMM) as u64) << 4) | + (((self.b_src == SRC_MEM) as u64) << 5) | + ((self.is_external_op as u64) << 6) | + ((self.store_ra as u64) << 7) | + (((self.store == STORE_MEM) as u64) << 8) | + (((self.store == STORE_IND) as u64) << 9) | + ((self.set_pc as u64) << 10) | + ((self.m32 as u64) << 11) | + (((self.b_src == SRC_IND) as u64) << 12); flags } diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index fe821001..84dcecfe 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -335,9 +335,9 @@ impl<'a> Emu<'a> { } // Log emulation step, if requested - if options.print_step.is_some() - && (options.print_step.unwrap() != 0) - && ((self.ctx.inst_ctx.step % options.print_step.unwrap()) == 0) + if options.print_step.is_some() && + (options.print_step.unwrap() != 0) && + ((self.ctx.inst_ctx.step % options.print_step.unwrap()) == 0) { println!("step={}", self.ctx.inst_ctx.step); } @@ -517,9 +517,9 @@ impl<'a> Emu<'a> { // Increment step counter self.ctx.inst_ctx.step += 1; - if self.ctx.inst_ctx.end - || ((self.ctx.inst_ctx.step - self.ctx.last_callback_step) - == self.ctx.callback_steps) + if self.ctx.inst_ctx.end || + ((self.ctx.inst_ctx.step - self.ctx.last_callback_step) == + self.ctx.callback_steps) { // In run() we have checked the callback consistency with ctx.do_callback let callback = callback.as_ref().unwrap(); @@ -689,11 +689,11 @@ impl<'a> Emu<'a> { let mut current_box_id = 0; let mut current_step_idx = loop { - if current_box_id == vec_traces.len() - 1 - || vec_traces[current_box_id + 1].start.step >= emu_trace_start.step + if current_box_id == vec_traces.len() - 1 || + vec_traces[current_box_id + 1].start.step >= emu_trace_start.step { - break emu_trace_start.step as usize - - vec_traces[current_box_id].start.step as usize; + break emu_trace_start.step as usize - + vec_traces[current_box_id].start.step as usize; } current_box_id += 1; }; @@ -804,8 +804,8 @@ impl<'a> Emu<'a> { let b = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.b >> 32) & 0xFFFFFFFF]; let c = [inst_ctx.c & 0xFFFFFFFF, (inst_ctx.c >> 32) & 0xFFFFFFFF]; - let addr1 = (inst.b_offset_imm0 as i64 - + if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64; + let addr1 = (inst.b_offset_imm0 as i64 + + if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64; let jmp_offset1 = if inst.jmp_offset1 >= 0 { F::from_canonical_u64(inst.jmp_offset1 as u64) @@ -832,7 +832,7 @@ impl<'a> Emu<'a> { }; let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { - F::from_canonical_u64(inst.b_offset_imm0 as u64) + F::from_canonical_u64(inst.b_offset_imm0) } else { F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) }; @@ -883,8 +883,8 @@ impl<'a> Emu<'a> { m32: F::from_bool(inst.m32), addr1: F::from_canonical_u64(addr1), __debug_operation_bus_enabled: F::from_bool( - inst.op_type == ZiskOperationType::Binary - || inst.op_type == ZiskOperationType::BinaryE, + inst.op_type == ZiskOperationType::Binary || + inst.op_type == ZiskOperationType::BinaryE, ), } } diff --git a/state-machines/rom/src/rom.rs b/state-machines/rom/src/rom.rs index e1cfffce..7a112201 100644 --- a/state-machines/rom/src/rom.rs +++ b/state-machines/rom/src/rom.rs @@ -201,7 +201,7 @@ impl RomSM { F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) }; let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { - F::from_canonical_u64(inst.b_offset_imm0 as u64) + F::from_canonical_u64(inst.b_offset_imm0) } else { F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) }; @@ -316,7 +316,7 @@ impl RomSM { F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) }; let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { - F::from_canonical_u64(inst.b_offset_imm0 as u64) + F::from_canonical_u64(inst.b_offset_imm0) } else { F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) }; @@ -415,7 +415,7 @@ impl RomSM { F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) }; let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { - F::from_canonical_u64(inst.b_offset_imm0 as u64) + F::from_canonical_u64(inst.b_offset_imm0) } else { F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) }; From da14564729bdb24b6b978234d3cdd9628a4791f7 Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Wed, 30 Oct 2024 19:41:37 +0000 Subject: [PATCH 16/22] improve code --- state-machines/main/src/main_sm.rs | 62 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/state-machines/main/src/main_sm.rs b/state-machines/main/src/main_sm.rs index 493fb224..bae63ae4 100644 --- a/state-machines/main/src/main_sm.rs +++ b/state-machines/main/src/main_sm.rs @@ -94,13 +94,7 @@ impl MainSM { let mut emu = Emu::from_emu_trace_start(zisk_rom, &segment_trace.start); - let total_steps = segment_trace.steps.len(); - const CHUNK_SIZE: usize = 4096; - let mut tmp_trace = Main0Trace::::new(CHUNK_SIZE); - - let mut last_row = Main0Row::::default(); - - // Set row 0 + // Set Row 0 of the current segment let row0 = if segment_id == 0 { Main0Row:: { pc: F::from_canonical_u64(ROM_ENTRY), @@ -129,40 +123,48 @@ impl MainSM { } }; - iectx.prover_buffer[offset as usize..(offset as usize + Main0Row::::ROW_SIZE)] - .copy_from_slice(row0.as_slice()); + let rng = offset as usize..(offset as usize + Main0Row::::ROW_SIZE); + iectx.prover_buffer[rng].copy_from_slice(row0.as_slice()); + + // Set Rows 1 to N of the current segment (N = maximum number of air rows) + let total_rows = segment_trace.steps.len(); + const SLICE_ROWS: usize = 4096; + let mut partial_trace = Main0Trace::::new(SLICE_ROWS); - // Set row 1..n - for chunk_start in (0..(air.num_rows())).step_by(CHUNK_SIZE) { + let mut last_row = Main0Row::::default(); + for slice in (0..(air.num_rows())).step_by(SLICE_ROWS) { // process the steps of the chunk - let start_pos_abs = std::cmp::min(chunk_start, total_steps); - let end_pos_abs = std::cmp::min(chunk_start + CHUNK_SIZE, total_steps); + let slice_start = std::cmp::min(slice, total_rows); + let slice_end = std::cmp::min(slice + SLICE_ROWS, total_rows); - for (i, step) in segment_trace.steps[start_pos_abs..end_pos_abs].iter().enumerate() { - tmp_trace[i] = emu.step_slice_full_trace(step); + for (i, emu_trace_step) in + segment_trace.steps[slice_start..slice_end].iter().enumerate() + { + partial_trace[i] = emu.step_slice_full_trace(emu_trace_step); } // if there are steps in the chunk update last row - if end_pos_abs - start_pos_abs > 0 { - last_row = tmp_trace[end_pos_abs - start_pos_abs - 1]; + if slice_end - slice_start > 0 { + last_row = partial_trace[slice_end - slice_start - 1]; } - // if there are less steps than the chunk size, fill the rest with the - // last row - for i in (end_pos_abs - start_pos_abs)..CHUNK_SIZE { - tmp_trace[i] = last_row; + // if there are less steps than the chunk size, fill the rest with the last row + for i in (slice_end - slice_start)..SLICE_ROWS { + partial_trace[i] = last_row; } //copy the chunk to the prover buffer - let tmp_buffer = tmp_trace.buffer.as_mut().unwrap(); - let buffer_offset_chunk = offset as usize + (chunk_start + 1) * Main0Row::::ROW_SIZE; - iectx.prover_buffer[buffer_offset_chunk..buffer_offset_chunk + tmp_buffer.len()] - .copy_from_slice(tmp_buffer); + let partial_buffer = partial_trace.buffer.as_ref().unwrap(); + let buffer_offset_slice = offset as usize + (slice + 1) * Main0Row::::ROW_SIZE; + + let rng = buffer_offset_slice..buffer_offset_slice + partial_buffer.len(); + iectx.prover_buffer[rng].copy_from_slice(partial_buffer); } let buffer = std::mem::take(&mut iectx.prover_buffer); + let sctx = self.wcm.get_sctx(); let mut air_instance = AirInstance::new( - self.wcm.get_sctx(), + sctx.clone(), MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0], Some(segment_id), @@ -172,12 +174,8 @@ impl MainSM { let main_last_segment = F::from_bool(segment_id == vec_traces.len() - 1); let main_segment = F::from_canonical_usize(segment_id); - air_instance.set_airvalue( - &self.wcm.get_sctx(), - "Main.main_last_segment", - main_last_segment, - ); - air_instance.set_airvalue(&self.wcm.get_sctx(), "Main.main_segment", main_segment); + air_instance.set_airvalue(&sctx, "Main.main_last_segment", main_last_segment); + air_instance.set_airvalue(&sctx, "Main.main_segment", main_segment); iectx.air_instance = Some(air_instance); } From ed47f7940410113d1a6a1ac579e0b2427c3353d8 Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Thu, 31 Oct 2024 15:04:59 +0000 Subject: [PATCH 17/22] wip main continuations --- Cargo.lock | 10 - emulator/src/emu.rs | 53 ++-- emulator/src/emu_trace.rs | 3 +- emulator/src/emulator.rs | 14 +- pil/src/pil_helpers/pilout.rs | 14 +- pil/src/pil_helpers/traces.rs | 10 +- pil/zisk.pil | 4 +- state-machines/main/pil/main.pil | 4 +- state-machines/main/src/main_sm.rs | 13 +- state-machines/rom/src/rom.rs | 474 ++++++++++++++-------------- witness-computation/src/executor.rs | 11 +- witness-computation/src/zisk_lib.rs | 2 +- 12 files changed, 305 insertions(+), 307 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b518eec7..f35546e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1328,7 +1328,6 @@ dependencies = [ [[package]] name = "pil-std-lib" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "log", "num-bigint", @@ -1346,7 +1345,6 @@ dependencies = [ [[package]] name = "pilout" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "bytes", "log", @@ -1466,7 +1464,6 @@ dependencies = [ [[package]] name = "proofman" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "colored", "env_logger", @@ -1487,7 +1484,6 @@ dependencies = [ [[package]] name = "proofman-common" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "env_logger", "log", @@ -1505,7 +1501,6 @@ dependencies = [ [[package]] name = "proofman-hints" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "p3-field", "proofman-common", @@ -1515,7 +1510,6 @@ dependencies = [ [[package]] name = "proofman-macros" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "proc-macro2", "quote", @@ -1525,7 +1519,6 @@ dependencies = [ [[package]] name = "proofman-starks-lib-c" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "log", ] @@ -1533,7 +1526,6 @@ dependencies = [ [[package]] name = "proofman-util" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "colored", "sysinfo 0.31.4", @@ -2167,7 +2159,6 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stark" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "log", "p3-field", @@ -2476,7 +2467,6 @@ dependencies = [ [[package]] name = "transcript" version = "0.1.0" -source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#42c646972e91fba0e89834cb4b1c3309756727d9" dependencies = [ "proofman-starks-lib-c", ] diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index 84dcecfe..0a018514 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -309,7 +309,7 @@ impl<'a> Emu<'a> { self.ctx.trace.steps.reserve(self.ctx.callback_steps as usize); // Init pc to the rom entry address - self.ctx.trace.start.pc = ROM_ENTRY; + self.ctx.trace.start_state.pc = ROM_ENTRY; } // Call run_fast if only essential work is needed @@ -335,9 +335,9 @@ impl<'a> Emu<'a> { } // Log emulation step, if requested - if options.print_step.is_some() && - (options.print_step.unwrap() != 0) && - ((self.ctx.inst_ctx.step % options.print_step.unwrap()) == 0) + if options.print_step.is_some() + && (options.print_step.unwrap() != 0) + && ((self.ctx.inst_ctx.step % options.print_step.unwrap()) == 0) { println!("step={}", self.ctx.inst_ctx.step); } @@ -404,7 +404,7 @@ impl<'a> Emu<'a> { self.ctx = self.create_emu_context(inputs); // Init pc to the rom entry address - self.ctx.trace.start.pc = ROM_ENTRY; + self.ctx.trace.start_state.pc = ROM_ENTRY; // Store the stats option into the emulator context self.ctx.do_stats = options.stats; @@ -425,12 +425,13 @@ impl<'a> Emu<'a> { // Check if is the first step of a new block if self.ctx.inst_ctx.step % par_options.num_steps as u64 == 0 { emu_traces.push(EmuTrace { - start: EmuTraceStart { + start_state: EmuTraceStart { pc: self.ctx.inst_ctx.pc, sp: self.ctx.inst_ctx.sp, c: self.ctx.inst_ctx.c, step: self.ctx.inst_ctx.step, }, + last_state: EmuTraceStart::default(), steps: Vec::with_capacity(par_options.num_steps), end: EmuTraceEnd { end: false }, }); @@ -484,6 +485,7 @@ impl<'a> Emu<'a> { // If this is the last instruction, stop executing if instruction.end { self.ctx.inst_ctx.end = true; + println!("Emu::step() end of execution steps: {}", self.ctx.inst_ctx.step); if options.stats { self.ctx.stats.on_steps(self.ctx.inst_ctx.step); } @@ -517,9 +519,9 @@ impl<'a> Emu<'a> { // Increment step counter self.ctx.inst_ctx.step += 1; - if self.ctx.inst_ctx.end || - ((self.ctx.inst_ctx.step - self.ctx.last_callback_step) == - self.ctx.callback_steps) + if self.ctx.inst_ctx.end + || ((self.ctx.inst_ctx.step - self.ctx.last_callback_step) + == self.ctx.callback_steps) { // In run() we have checked the callback consistency with ctx.do_callback let callback = callback.as_ref().unwrap(); @@ -534,10 +536,10 @@ impl<'a> Emu<'a> { (callback)(trace); // Set the start-of-trace data - self.ctx.trace.start.pc = self.ctx.inst_ctx.pc; - self.ctx.trace.start.sp = self.ctx.inst_ctx.sp; - self.ctx.trace.start.c = self.ctx.inst_ctx.c; - self.ctx.trace.start.step = self.ctx.inst_ctx.step; + self.ctx.trace.start_state.pc = self.ctx.inst_ctx.pc; + self.ctx.trace.start_state.sp = self.ctx.inst_ctx.sp; + self.ctx.trace.start_state.c = self.ctx.inst_ctx.c; + self.ctx.trace.start_state.step = self.ctx.inst_ctx.step; // Increment the last callback step counter self.ctx.last_callback_step += self.ctx.callback_steps; @@ -562,6 +564,13 @@ impl<'a> Emu<'a> { let last_pc = self.ctx.inst_ctx.pc; let last_c = self.ctx.inst_ctx.c; + emu_full_trace_vec.last_state = EmuTraceStart { + pc: self.ctx.inst_ctx.pc, + sp: self.ctx.inst_ctx.sp, + c: self.ctx.inst_ctx.c, + step: self.ctx.inst_ctx.step, + }; + let instruction = self.rom.get_instruction(self.ctx.inst_ctx.pc); // Build the 'a' register value based on the source specified by the current instruction @@ -689,17 +698,17 @@ impl<'a> Emu<'a> { let mut current_box_id = 0; let mut current_step_idx = loop { - if current_box_id == vec_traces.len() - 1 || - vec_traces[current_box_id + 1].start.step >= emu_trace_start.step + if current_box_id == vec_traces.len() - 1 + || vec_traces[current_box_id + 1].start_state.step >= emu_trace_start.step { - break emu_trace_start.step as usize - - vec_traces[current_box_id].start.step as usize; + break emu_trace_start.step as usize + - vec_traces[current_box_id].start_state.step as usize; } current_box_id += 1; }; let last_trace = vec_traces.last().unwrap(); - let last_step = last_trace.start.step + last_trace.steps.len() as u64; + let last_step = last_trace.start_state.step + last_trace.steps.len() as u64; let mut current_step = emu_trace_start.step; while current_step < last_step && result.len() < num_rows { @@ -804,8 +813,8 @@ impl<'a> Emu<'a> { let b = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.b >> 32) & 0xFFFFFFFF]; let c = [inst_ctx.c & 0xFFFFFFFF, (inst_ctx.c >> 32) & 0xFFFFFFFF]; - let addr1 = (inst.b_offset_imm0 as i64 + - if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64; + let addr1 = (inst.b_offset_imm0 as i64 + + if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64; let jmp_offset1 = if inst.jmp_offset1 >= 0 { F::from_canonical_u64(inst.jmp_offset1 as u64) @@ -883,8 +892,8 @@ impl<'a> Emu<'a> { m32: F::from_bool(inst.m32), addr1: F::from_canonical_u64(addr1), __debug_operation_bus_enabled: F::from_bool( - inst.op_type == ZiskOperationType::Binary || - inst.op_type == ZiskOperationType::BinaryE, + inst.op_type == ZiskOperationType::Binary + || inst.op_type == ZiskOperationType::BinaryE, ), } } diff --git a/emulator/src/emu_trace.rs b/emulator/src/emu_trace.rs index 599f9a7f..0048a1c4 100644 --- a/emulator/src/emu_trace.rs +++ b/emulator/src/emu_trace.rs @@ -19,7 +19,8 @@ pub struct EmuTraceEnd { #[derive(Default, Debug, Clone)] pub struct EmuTrace { - pub start: EmuTraceStart, + pub start_state: EmuTraceStart, + pub last_state: EmuTraceStart, pub steps: Vec, pub end: EmuTraceEnd, } diff --git a/emulator/src/emulator.rs b/emulator/src/emulator.rs index 2a803851..8406bea4 100644 --- a/emulator/src/emulator.rs +++ b/emulator/src/emulator.rs @@ -195,7 +195,7 @@ impl ZiskEmulator { let par_emu_options = ParEmuOptions::new( num_threads, thread_id, - op_sizes[ZiskOperationType::None as usize] as usize, + options.trace_steps.unwrap() as usize, op_sizes, ); @@ -216,6 +216,10 @@ impl ZiskEmulator { } }); + println!("emu_traces[0][0].len={}", emu_traces[0][0].steps.len()); + println!("emu_traces[0][0].len={}", emu_traces[1][0].steps.len()); + println!("emu_slices={:?}", emu_slices.lock().unwrap()); + let capacity = emu_traces.iter().map(|trace| trace.len()).sum::(); let mut vec_traces = Vec::with_capacity(capacity); for i in 0..capacity { @@ -233,10 +237,10 @@ impl ZiskEmulator { for vec_trace in &vec_traces { emu_slices.add( ZiskOperationType::None, - vec_trace.start.pc, - vec_trace.start.sp, - vec_trace.start.c, - vec_trace.start.step, + vec_trace.start_state.pc, + vec_trace.start_state.sp, + vec_trace.start_state.c, + vec_trace.start_state.step, ); } diff --git a/pil/src/pil_helpers/pilout.rs b/pil/src/pil_helpers/pilout.rs index e371c7d6..e16e3936 100644 --- a/pil/src/pil_helpers/pilout.rs +++ b/pil/src/pil_helpers/pilout.rs @@ -2,7 +2,7 @@ // Manual modifications are not recommended and may be overwritten. use proofman_common::WitnessPilout; -pub const PILOUT_HASH: &[u8] = b"Zisk-hash"; +pub const PILOUT_HASH: &[u8] = b"ZiskContinuations1-hash"; //AIRGROUP CONSTANTS @@ -24,11 +24,7 @@ pub const SPECIFIED_RANGES_AIRGROUP_ID: usize = 6; pub const MAIN_AIR_IDS: &[usize] = &[0]; -pub const ROM_S_AIR_IDS: &[usize] = &[0]; - -pub const ROM_M_AIR_IDS: &[usize] = &[1]; - -pub const ROM_L_AIR_IDS: &[usize] = &[2]; +pub const ROM_AIR_IDS: &[usize] = &[0]; pub const BINARY_AIR_IDS: &[usize] = &[0]; @@ -44,7 +40,7 @@ pub struct Pilout; impl Pilout { pub fn pilout() -> WitnessPilout { - let mut pilout = WitnessPilout::new("Zisk", 2, PILOUT_HASH.to_vec()); + let mut pilout = WitnessPilout::new("ZiskContinuations1", 2, PILOUT_HASH.to_vec()); let air_group = pilout.add_air_group(Some("Main")); @@ -52,9 +48,7 @@ impl Pilout { let air_group = pilout.add_air_group(Some("Rom")); - air_group.add_air(Some("RomS"), 65536); - air_group.add_air(Some("RomM"), 4194304); - air_group.add_air(Some("RomL"), 67108864); + air_group.add_air(Some("Rom"), 1048576); let air_group = pilout.add_air_group(Some("Binary")); diff --git a/pil/src/pil_helpers/traces.rs b/pil/src/pil_helpers/traces.rs index 580c4244..67d7db98 100644 --- a/pil/src/pil_helpers/traces.rs +++ b/pil/src/pil_helpers/traces.rs @@ -7,15 +7,7 @@ trace!(Main0Row, Main0Trace { a: [F; 2], b: [F; 2], c: [F; 2], flag: F, pc: F, a_src_imm: F, a_src_mem: F, a_offset_imm0: F, a_imm1: F, a_src_step: F, b_src_imm: F, b_src_mem: F, b_offset_imm0: F, b_imm1: F, b_src_ind: F, ind_width: F, is_external_op: F, op: F, store_ra: F, store_mem: F, store_ind: F, store_offset: F, set_pc: F, jmp_offset1: F, jmp_offset2: F, m32: F, addr1: F, __debug_operation_bus_enabled: F, }); -trace!(RomS0Row, RomS0Trace { - line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, -}); - -trace!(RomM1Row, RomM1Trace { - line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, -}); - -trace!(RomL2Row, RomL2Trace { +trace!(Rom0Row, Rom0Trace { line: F, a_offset_imm0: F, a_imm1: F, b_offset_imm0: F, b_imm1: F, ind_width: F, op: F, store_offset: F, jmp_offset1: F, jmp_offset2: F, flags: F, multiplicity: F, }); diff --git a/pil/zisk.pil b/pil/zisk.pil index 1c06c309..69cd09bb 100644 --- a/pil/zisk.pil +++ b/pil/zisk.pil @@ -14,9 +14,7 @@ airgroup Main { } airgroup Rom { - Rom(N: 2**16) alias RomS; - Rom(N: 2**22) alias RomM; - Rom(N: 2**26) alias RomL; + Rom(N: 2**20); } // airgroup Mem { diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index c9aa840f..90860ef7 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -273,6 +273,6 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope lookup_assumes(ROM_BUS_ID, [pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, ind_width, op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1 - SEGMENT_L1); - //direct_update(MAIN_CONTINUATION_ID, cols: [0, 0, 4096, 0, 0], bus_type: PIOP_BUS_SUM); - //direct_update(MAIN_CONTINUATION_ID, cols: [0, 1, 8192, 0, 0], bus_type: PIOP_BUS_SUM); + direct_update(MAIN_CONTINUATION_ID, cols: [0, 0, 4096, 0, 0], bus_type: PIOP_BUS_SUM); + direct_update(MAIN_CONTINUATION_ID, cols: [0, 1, 4312, 0, 0], bus_type: PIOP_BUS_SUM); } \ No newline at end of file diff --git a/state-machines/main/src/main_sm.rs b/state-machines/main/src/main_sm.rs index bae63ae4..41a3191e 100644 --- a/state-machines/main/src/main_sm.rs +++ b/state-machines/main/src/main_sm.rs @@ -82,7 +82,7 @@ impl MainSM { let offset = iectx.offset; let air = pctx.pilout.get_air(MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]); - let filled = segment_trace.steps.len(); + let filled = segment_trace.steps.len() + 1; info!( "{}: ··· Creating Main segment #{} [{} / {} rows filled {:.2}%]", Self::MY_NAME, @@ -92,8 +92,6 @@ impl MainSM { filled as f64 / air.num_rows() as f64 * 100.0 ); - let mut emu = Emu::from_emu_trace_start(zisk_rom, &segment_trace.start); - // Set Row 0 of the current segment let row0 = if segment_id == 0 { Main0Row:: { @@ -105,6 +103,7 @@ impl MainSM { } } else { let emu_trace_previous = vec_traces[segment_id - 1].steps.last().unwrap(); + let mut emu = Emu::from_emu_trace_start(zisk_rom, &vec_traces[segment_id - 1].last_state); let row_previous = emu.step_slice_full_trace(emu_trace_previous); Main0Row:: { @@ -123,6 +122,14 @@ impl MainSM { } }; + if segment_id == 1 { + // "INFO 19: 20 77 main/pil/main.pil:222 (1-Main.SEGMENT_L1)*(Main.pc-((('Main.set_pc*('Main.c[0]+'Main.jmp_offset1))+((1-'Main.set_pc)*('Main.pc+'Main.jmp_offset2)))+('Main.flag*('Main.jmp_offset1-'Main.jmp_offset2)))) == 0" + //row0: Main0Row { a: [27, 0], b: [452984832, 0], c: [452984832, 0], flag: 0, pc: 2147486932, a_src_imm: 1, a_src_mem: 0, a_offset_imm0: 27, a_imm1: 0, a_src_step: 0, b_src_imm: 1, b_src_mem: 0, b_offset_imm0: 452984832, b_imm1: 0, b_src_ind: 0, ind_width: 0, is_external_op: 0, op: 1, store_ra: 0, store_mem: 0, store_ind: 0, store_offset: 0, set_pc: 0, jmp_offset1: 0, jmp_offset2: 0, m32: 0, addr1: 0, __debug_operation_bus_enabled: 0 } + println!("row0: {:?}", row0); + } + + let mut emu = Emu::from_emu_trace_start(zisk_rom, &segment_trace.start_state); + let rng = offset as usize..(offset as usize + Main0Row::::ROW_SIZE); iectx.prover_buffer[rng].copy_from_slice(row0.as_slice()); diff --git a/state-machines/rom/src/rom.rs b/state-machines/rom/src/rom.rs index 7a112201..b703c2f8 100644 --- a/state-machines/rom/src/rom.rs +++ b/state-machines/rom/src/rom.rs @@ -6,10 +6,7 @@ use proofman_common::{AirInstance, BufferAllocator, SetupCtx}; use proofman_util::create_buffer_fast; use zisk_core::{Riscv2zisk, ZiskPcHistogram, ZiskRom, SRC_IMM}; -use zisk_pil::{ - Pilout, RomL2Row, RomL2Trace, RomM1Row, RomM1Trace, RomS0Row, RomS0Trace, MAIN_AIRGROUP_ID, - MAIN_AIR_IDS, ROM_AIRGROUP_ID, ROM_L_AIR_IDS, ROM_M_AIR_IDS, ROM_S_AIR_IDS, -}; +use zisk_pil::{Pilout, Rom0Row, Rom0Trace, MAIN_AIRGROUP_ID, MAIN_AIR_IDS, ROM_AIRGROUP_ID, ROM_AIR_IDS}; //use ziskemu::ZiskEmulatorErr; use std::error::Error; @@ -22,7 +19,7 @@ impl RomSM { let rom_sm = Self { wcm: wcm.clone() }; let rom_sm = Arc::new(rom_sm); - let rom_air_ids = &[ROM_S_AIR_IDS[0], ROM_M_AIR_IDS[0], ROM_L_AIR_IDS[0]]; + let rom_air_ids = ROM_AIR_IDS; wcm.register_component(rom_sm.clone(), Some(ROM_AIRGROUP_ID), Some(rom_air_ids)); rom_sm @@ -95,43 +92,52 @@ impl RomSM { ) -> Result<(Vec, u64, usize), Box> { let pilout = Pilout::pilout(); let sizes = ( - pilout.get_air(ROM_AIRGROUP_ID, ROM_S_AIR_IDS[0]).num_rows(), - pilout.get_air(ROM_AIRGROUP_ID, ROM_M_AIR_IDS[0]).num_rows(), - pilout.get_air(ROM_AIRGROUP_ID, ROM_L_AIR_IDS[0]).num_rows(), + pilout.get_air(ROM_AIRGROUP_ID, ROM_AIR_IDS[0]).num_rows(), + // pilout.get_air(ROM_AIRGROUP_ID, ROM_M_AIR_IDS[0]).num_rows(), + // pilout.get_air(ROM_AIRGROUP_ID, ROM_L_AIR_IDS[0]).num_rows(), ); let number_of_instructions = rom.insts.len(); - match number_of_instructions { - n if n <= sizes.0 => Self::create_rom_s( + Self::create_rom_s( sizes.0, rom, - n, + number_of_instructions, buffer_allocator, sctx, pc_histogram, main_trace_len, - ), - n if n <= sizes.1 => Self::create_rom_m( - sizes.1, - rom, - n, - buffer_allocator, - sctx, - pc_histogram, - main_trace_len, - ), - n if n < sizes.2 => Self::create_rom_l( - sizes.2, - rom, - n, - buffer_allocator, - sctx, - pc_histogram, - main_trace_len, - ), - _ => panic!("RomSM::compute_trace() found rom too big size={}", number_of_instructions), - } + ) + // match number_of_instructions { + // n if n <= sizes.0 => Self::create_rom_s( + // sizes.0, + // rom, + // n, + // buffer_allocator, + // sctx, + // pc_histogram, + // main_trace_len, + // ), + // n if n <= sizes.1 => Self::create_rom_m( + // sizes.1, + // rom, + // n, + // buffer_allocator, + // sctx, + // pc_histogram, + // main_trace_len, + // ), + // n if n < sizes.2 => Self::create_rom_l( + // sizes.2, + // rom, + // n, + // buffer_allocator, + // sctx, + // pc_histogram, + // main_trace_len, + // ), + // _ => panic!("RomSM::compute_trace() found rom too big size={}", number_of_instructions), + // } } fn create_rom_s( @@ -148,13 +154,13 @@ impl RomSM { // Allocate a prover buffer let (buffer_size, offsets) = buffer_allocator - .get_buffer_info(sctx, ROM_AIRGROUP_ID, ROM_S_AIR_IDS[0]) + .get_buffer_info(sctx, ROM_AIRGROUP_ID, ROM_AIR_IDS[0]) .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); let mut prover_buffer = create_buffer_fast(buffer_size as usize); // Create an empty ROM trace let mut rom_trace = - RomS0Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) + Rom0Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) .expect("RomSM::compute_trace() failed mapping buffer to ROMS0Trace"); // For every instruction in the rom, fill its corresponding ROM trace @@ -172,7 +178,7 @@ impl RomSM { if counter.is_some() { multiplicity = *counter.unwrap(); if inst.paddr == pc_histogram.end_pc { - multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); + multiplicity += main_trace_len - 1 - (pc_histogram.steps % (main_trace_len - 1)); } } else { continue; // We skip those pc's that are not used in this execution @@ -243,209 +249,209 @@ impl RomSM { // Padd with zeroes for i in number_of_instructions..trace_size { - rom_trace[i] = RomS0Row::default(); - } - - Ok((prover_buffer, offsets[0], ROM_S_AIR_IDS[0])) - } - - fn create_rom_m( - rom_m_size: usize, - rom: &zisk_core::ZiskRom, - number_of_instructions: usize, - buffer_allocator: Arc, - sctx: &SetupCtx, - pc_histogram: ZiskPcHistogram, - main_trace_len: u64, - ) -> Result<(Vec, u64, usize), Box> { - // Set trace size - let trace_size = rom_m_size; - - // Allocate a prover buffer - let (buffer_size, offsets) = buffer_allocator - .get_buffer_info(sctx, ROM_AIRGROUP_ID, ROM_M_AIR_IDS[0]) - .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); - let mut prover_buffer = create_buffer_fast(buffer_size as usize); - - // Create an empty ROM trace - let mut rom_trace = - RomM1Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) - .expect("RomSM::compute_trace() failed mapping buffer to ROMM0Trace"); - - // For every instruction in the rom, fill its corresponding ROM trace - for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { - // Get the Zisk instruction - let inst = inst_builder.1.i; - - // Calculate the multiplicity, i.e. the number of times this pc is used in this - // execution - let mut multiplicity: u64; - if pc_histogram.map.is_empty() { - multiplicity = 1; // If the histogram is empty, we use 1 for all pc's - } else { - let counter = pc_histogram.map.get(&inst.paddr); - if counter.is_some() { - multiplicity = *counter.unwrap(); - if inst.paddr == pc_histogram.end_pc { - multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); - } - } else { - continue; // We skip those pc's that are not used in this execution - } - } - - // Convert the i64 offsets to F - let jmp_offset1 = if inst.jmp_offset1 >= 0 { - F::from_canonical_u64(inst.jmp_offset1 as u64) - } else { - F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) - }; - let jmp_offset2 = if inst.jmp_offset2 >= 0 { - F::from_canonical_u64(inst.jmp_offset2 as u64) - } else { - F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) - }; - let store_offset = if inst.store_offset >= 0 { - F::from_canonical_u64(inst.store_offset as u64) - } else { - F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) - }; - let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { - F::from_canonical_u64(inst.a_offset_imm0) - } else { - F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) - }; - let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { - F::from_canonical_u64(inst.b_offset_imm0) - } else { - F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) - }; - - // Fill the rom trace row fields - rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line - rom_trace[i].a_offset_imm0 = a_offset_imm0; - rom_trace[i].a_imm1 = - F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); - rom_trace[i].b_offset_imm0 = b_offset_imm0; - rom_trace[i].b_imm1 = - F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); - //rom_trace[i].b_src_ind = - // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); - rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); - rom_trace[i].op = F::from_canonical_u8(inst.op); - rom_trace[i].store_offset = store_offset; - rom_trace[i].jmp_offset1 = jmp_offset1; - rom_trace[i].jmp_offset2 = jmp_offset2; - rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); - rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); - } - - // Padd with zeroes - for i in number_of_instructions..trace_size { - rom_trace[i] = RomM1Row::default(); + rom_trace[i] = Rom0Row::default(); } - Ok((prover_buffer, offsets[0], ROM_M_AIR_IDS[0])) + Ok((prover_buffer, offsets[0], ROM_AIR_IDS[0])) } - fn create_rom_l( - rom_l_size: usize, - rom: &zisk_core::ZiskRom, - number_of_instructions: usize, - buffer_allocator: Arc, - sctx: &SetupCtx, - pc_histogram: ZiskPcHistogram, - main_trace_len: u64, - ) -> Result<(Vec, u64, usize), Box> { - // Set trace size - let trace_size = rom_l_size; - - // Allocate a prover buffer - let (buffer_size, offsets) = buffer_allocator - .get_buffer_info(sctx, ROM_AIRGROUP_ID, ROM_L_AIR_IDS[0]) - .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); - let mut prover_buffer = create_buffer_fast(buffer_size as usize); - - // Create an empty ROM trace - let mut rom_trace = - RomL2Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) - .expect("RomSM::compute_trace() failed mapping buffer to ROML0Trace"); - - // For every instruction in the rom, fill its corresponding ROM trace - for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { - // Get the Zisk instruction - let inst = inst_builder.1.i; - - // Calculate the multiplicity, i.e. the number of times this pc is used in this - // execution - let mut multiplicity: u64; - if pc_histogram.map.is_empty() { - multiplicity = 1; // If the histogram is empty, we use 1 for all pc's - } else { - let counter = pc_histogram.map.get(&inst.paddr); - if counter.is_some() { - multiplicity = *counter.unwrap(); - if inst.paddr == pc_histogram.end_pc { - multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); - } - } else { - continue; // We skip those pc's that are not used in this execution - } - } - - // Convert the i64 offsets to F - let jmp_offset1 = if inst.jmp_offset1 >= 0 { - F::from_canonical_u64(inst.jmp_offset1 as u64) - } else { - F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) - }; - let jmp_offset2 = if inst.jmp_offset2 >= 0 { - F::from_canonical_u64(inst.jmp_offset2 as u64) - } else { - F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) - }; - let store_offset = if inst.store_offset >= 0 { - F::from_canonical_u64(inst.store_offset as u64) - } else { - F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) - }; - let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { - F::from_canonical_u64(inst.a_offset_imm0) - } else { - F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) - }; - let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { - F::from_canonical_u64(inst.b_offset_imm0) - } else { - F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) - }; - - // Fill the rom trace row fields - rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line - rom_trace[i].a_offset_imm0 = a_offset_imm0; - rom_trace[i].a_imm1 = - F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); - rom_trace[i].b_offset_imm0 = b_offset_imm0; - rom_trace[i].b_imm1 = - F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); - //rom_trace[i].b_src_ind = - // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); - rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); - rom_trace[i].op = F::from_canonical_u8(inst.op); - rom_trace[i].store_offset = store_offset; - rom_trace[i].jmp_offset1 = jmp_offset1; - rom_trace[i].jmp_offset2 = jmp_offset2; - rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); - rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); - } - - // Padd with zeroes - for i in number_of_instructions..trace_size { - rom_trace[i] = RomL2Row::default(); - } - - Ok((prover_buffer, offsets[0], ROM_L_AIR_IDS[0])) - } + // fn create_rom_m( + // rom_m_size: usize, + // rom: &zisk_core::ZiskRom, + // number_of_instructions: usize, + // buffer_allocator: Arc, + // sctx: &SetupCtx, + // pc_histogram: ZiskPcHistogram, + // main_trace_len: u64, + // ) -> Result<(Vec, u64, usize), Box> { + // // Set trace size + // let trace_size = rom_m_size; + + // // Allocate a prover buffer + // let (buffer_size, offsets) = buffer_allocator + // .get_buffer_info(sctx, ROM_AIRGROUP_ID, ROM_M_AIR_IDS[0]) + // .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); + // let mut prover_buffer = create_buffer_fast(buffer_size as usize); + + // // Create an empty ROM trace + // let mut rom_trace = + // RomM1Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) + // .expect("RomSM::compute_trace() failed mapping buffer to ROMM0Trace"); + + // // For every instruction in the rom, fill its corresponding ROM trace + // for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { + // // Get the Zisk instruction + // let inst = inst_builder.1.i; + + // // Calculate the multiplicity, i.e. the number of times this pc is used in this + // // execution + // let mut multiplicity: u64; + // if pc_histogram.map.is_empty() { + // multiplicity = 1; // If the histogram is empty, we use 1 for all pc's + // } else { + // let counter = pc_histogram.map.get(&inst.paddr); + // if counter.is_some() { + // multiplicity = *counter.unwrap(); + // if inst.paddr == pc_histogram.end_pc { + // multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); + // } + // } else { + // continue; // We skip those pc's that are not used in this execution + // } + // } + + // // Convert the i64 offsets to F + // let jmp_offset1 = if inst.jmp_offset1 >= 0 { + // F::from_canonical_u64(inst.jmp_offset1 as u64) + // } else { + // F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) + // }; + // let jmp_offset2 = if inst.jmp_offset2 >= 0 { + // F::from_canonical_u64(inst.jmp_offset2 as u64) + // } else { + // F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) + // }; + // let store_offset = if inst.store_offset >= 0 { + // F::from_canonical_u64(inst.store_offset as u64) + // } else { + // F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) + // }; + // let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { + // F::from_canonical_u64(inst.a_offset_imm0) + // } else { + // F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) + // }; + // let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { + // F::from_canonical_u64(inst.b_offset_imm0) + // } else { + // F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) + // }; + + // // Fill the rom trace row fields + // rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line + // rom_trace[i].a_offset_imm0 = a_offset_imm0; + // rom_trace[i].a_imm1 = + // F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); + // rom_trace[i].b_offset_imm0 = b_offset_imm0; + // rom_trace[i].b_imm1 = + // F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); + // //rom_trace[i].b_src_ind = + // // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); + // rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); + // rom_trace[i].op = F::from_canonical_u8(inst.op); + // rom_trace[i].store_offset = store_offset; + // rom_trace[i].jmp_offset1 = jmp_offset1; + // rom_trace[i].jmp_offset2 = jmp_offset2; + // rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); + // rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); + // } + + // // Padd with zeroes + // for i in number_of_instructions..trace_size { + // rom_trace[i] = RomM1Row::default(); + // } + + // Ok((prover_buffer, offsets[0], ROM_M_AIR_IDS[0])) + // } + + // fn create_rom_l( + // rom_l_size: usize, + // rom: &zisk_core::ZiskRom, + // number_of_instructions: usize, + // buffer_allocator: Arc, + // sctx: &SetupCtx, + // pc_histogram: ZiskPcHistogram, + // main_trace_len: u64, + // ) -> Result<(Vec, u64, usize), Box> { + // // Set trace size + // let trace_size = rom_l_size; + + // // Allocate a prover buffer + // let (buffer_size, offsets) = buffer_allocator + // .get_buffer_info(sctx, ROM_AIRGROUP_ID, ROM_L_AIR_IDS[0]) + // .unwrap_or_else(|err| panic!("Error getting buffer info: {}", err)); + // let mut prover_buffer = create_buffer_fast(buffer_size as usize); + + // // Create an empty ROM trace + // let mut rom_trace = + // RomL2Trace::::map_buffer(&mut prover_buffer, trace_size, offsets[0] as usize) + // .expect("RomSM::compute_trace() failed mapping buffer to ROML0Trace"); + + // // For every instruction in the rom, fill its corresponding ROM trace + // for (i, inst_builder) in rom.insts.clone().into_iter().enumerate() { + // // Get the Zisk instruction + // let inst = inst_builder.1.i; + + // // Calculate the multiplicity, i.e. the number of times this pc is used in this + // // execution + // let mut multiplicity: u64; + // if pc_histogram.map.is_empty() { + // multiplicity = 1; // If the histogram is empty, we use 1 for all pc's + // } else { + // let counter = pc_histogram.map.get(&inst.paddr); + // if counter.is_some() { + // multiplicity = *counter.unwrap(); + // if inst.paddr == pc_histogram.end_pc { + // multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); + // } + // } else { + // continue; // We skip those pc's that are not used in this execution + // } + // } + + // // Convert the i64 offsets to F + // let jmp_offset1 = if inst.jmp_offset1 >= 0 { + // F::from_canonical_u64(inst.jmp_offset1 as u64) + // } else { + // F::neg(F::from_canonical_u64((-inst.jmp_offset1) as u64)) + // }; + // let jmp_offset2 = if inst.jmp_offset2 >= 0 { + // F::from_canonical_u64(inst.jmp_offset2 as u64) + // } else { + // F::neg(F::from_canonical_u64((-inst.jmp_offset2) as u64)) + // }; + // let store_offset = if inst.store_offset >= 0 { + // F::from_canonical_u64(inst.store_offset as u64) + // } else { + // F::neg(F::from_canonical_u64((-inst.store_offset) as u64)) + // }; + // let a_offset_imm0 = if inst.a_offset_imm0 as i64 >= 0 { + // F::from_canonical_u64(inst.a_offset_imm0) + // } else { + // F::neg(F::from_canonical_u64((-(inst.a_offset_imm0 as i64)) as u64)) + // }; + // let b_offset_imm0 = if inst.b_offset_imm0 as i64 >= 0 { + // F::from_canonical_u64(inst.b_offset_imm0) + // } else { + // F::neg(F::from_canonical_u64((-(inst.b_offset_imm0 as i64)) as u64)) + // }; + + // // Fill the rom trace row fields + // rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line + // rom_trace[i].a_offset_imm0 = a_offset_imm0; + // rom_trace[i].a_imm1 = + // F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); + // rom_trace[i].b_offset_imm0 = b_offset_imm0; + // rom_trace[i].b_imm1 = + // F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); + // //rom_trace[i].b_src_ind = + // // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); + // rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); + // rom_trace[i].op = F::from_canonical_u8(inst.op); + // rom_trace[i].store_offset = store_offset; + // rom_trace[i].jmp_offset1 = jmp_offset1; + // rom_trace[i].jmp_offset2 = jmp_offset2; + // rom_trace[i].flags = F::from_canonical_u64(inst.get_flags()); + // rom_trace[i].multiplicity = F::from_canonical_u64(multiplicity); + // } + + // // Padd with zeroes + // for i in number_of_instructions..trace_size { + // rom_trace[i] = RomL2Row::default(); + // } + + // Ok((prover_buffer, offsets[0], ROM_L_AIR_IDS[0])) + // } } impl WitnessComponent for RomSM {} diff --git a/witness-computation/src/executor.rs b/witness-computation/src/executor.rs index 7be4d77a..69e2d247 100644 --- a/witness-computation/src/executor.rs +++ b/witness-computation/src/executor.rs @@ -45,7 +45,6 @@ pub struct ZiskExecutor { } impl ZiskExecutor { - const BLOCK_SIZE: usize = 2usize.pow(21); const NUM_THREADS: usize = 8; pub fn new(wcm: Arc>, rom_path: PathBuf) -> Self { @@ -103,14 +102,13 @@ impl ZiskExecutor { ectx: Arc, sctx: Arc, ) { - // Create a thread pool to manage the execution of all the state machines related to the - // execution process + let air_main = pctx.pilout.get_air(MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]); // Prepare the settings for the emulator let emu_options = EmuOptions { elf: Some(rom_path.to_path_buf().display().to_string()), inputs: Some(public_inputs_path.display().to_string()), - trace_steps: Some(Self::BLOCK_SIZE as u64), + trace_steps: Some(air_main.num_rows() as u64 - 1), ..EmuOptions::default() }; @@ -128,7 +126,6 @@ impl ZiskExecutor { // machine. We aim to track the starting point of execution for every N instructions // across different operation types. Currently, we are only collecting data for // Binary and BinaryE operations. - let air_main = pctx.pilout.get_air(MAIN_AIRGROUP_ID, MAIN_AIR_IDS[0]); let air_binary = pctx.pilout.get_air(BINARY_AIRGROUP_ID, BINARY_AIR_IDS[0]); let air_binary_e = pctx.pilout.get_air(BINARY_EXTENSION_AIRGROUP_ID, BINARY_EXTENSION_AIR_IDS[0]); @@ -186,7 +183,7 @@ impl ZiskExecutor { } _ => panic!("Invalid operation type"), }; - let segmen_id = match emu_slice.op_type { + let segment_id = match emu_slice.op_type { ZiskOperationType::None => { main_segnent_id += 1; Some(main_segnent_id - 1) @@ -201,7 +198,7 @@ impl ZiskExecutor { offset, emu_slice.op_type, emu_slice.emu_trace_start.clone(), - segmen_id, + segment_id, global_idx, None, )); diff --git a/witness-computation/src/zisk_lib.rs b/witness-computation/src/zisk_lib.rs index e830dd89..5dbb9fe9 100644 --- a/witness-computation/src/zisk_lib.rs +++ b/witness-computation/src/zisk_lib.rs @@ -46,7 +46,7 @@ impl ZiskWitness { } fn initialize(&mut self, pctx: Arc>, ectx: Arc, sctx: Arc) { - let wcm = WitnessManager::new(pctx, ectx, sctx.clone()); + let wcm = WitnessManager::new(pctx, ectx, sctx); let wcm = Arc::new(wcm); self.wcm.set(wcm.clone()).ok(); From 6e714dda923d7b73a5b4931779b86ff511131be1 Mon Sep 17 00:00:00 2001 From: fractasy Date: Thu, 31 Oct 2024 18:47:43 +0000 Subject: [PATCH 18/22] Stats per register usage. Remove debug asserts from binary SM. --- core/src/inst_context.rs | 5 ++ core/src/mem.rs | 5 +- emulator/src/stats.rs | 69 +++++++++++++------ state-machines/binary/src/binary_basic.rs | 83 +++++++++++------------ 4 files changed, 96 insertions(+), 66 deletions(-) diff --git a/core/src/inst_context.rs b/core/src/inst_context.rs index 41ca1218..c08f8a22 100644 --- a/core/src/inst_context.rs +++ b/core/src/inst_context.rs @@ -29,6 +29,11 @@ impl InstContext { end: false, } } + pub fn to_text(&self) -> String { + let s: String; + s = format! {"a={:x} b={:x} c={:x} flag={} sp={} pc={} step={} end={}", self.a, self.b, self.c, self.flag, self.sp, self.pc, self.step, self.end}; + s + } } impl Default for InstContext { diff --git a/core/src/mem.rs b/core/src/mem.rs index cf118090..5660b6df 100644 --- a/core/src/mem.rs +++ b/core/src/mem.rs @@ -151,7 +151,10 @@ impl Mem { // Check that the address and width fall into this section address range if (addr < section.start) || ((addr + width) > section.end) { - panic!("Mem::write_silent() invalid addr={}", addr); + panic!( + "Mem::write_silent() invalid addr={}={:x} write section start={:x} end={:x}", + addr, addr, section.start, section.end + ); } // Calculate the write position diff --git a/emulator/src/stats.rs b/emulator/src/stats.rs index 4332cd9c..afb26baa 100644 --- a/emulator/src/stats.rs +++ b/emulator/src/stats.rs @@ -32,6 +32,8 @@ pub struct Stats { usual: u64, steps: u64, ops: [u64; 256], + reg_writes: [u64; 32], + reg_reads: [u64; 32], } /// Default constructor for Stats structure @@ -43,6 +45,8 @@ impl Default for Stats { usual: 0, steps: 0, ops: [0; 256], + reg_writes: [0; 32], + reg_reads: [0; 32], } } } @@ -60,6 +64,7 @@ impl Stats { } if (REG_FIRST..=REG_LAST).contains(&address) { self.rops.reads += 1; + self.reg_reads[((address - REG_FIRST) / 8) as usize] += 1; } } @@ -75,6 +80,7 @@ impl Stats { } if (REG_FIRST..=REG_LAST).contains(&address) { self.rops.writes += 1; + self.reg_writes[((address - REG_FIRST) / 8) as usize] += 1; } } @@ -108,22 +114,22 @@ impl Stats { output += &format!(" COST_USUAL: {:02} sec\n", COST_USUAL); output += &format!(" COST_STEP: {:02} sec\n", COST_STEP); - let total_mem_ops = self.mops.mread_na1 + - self.mops.mread_na2 + - self.mops.mread_a + - self.mops.mwrite_na1 + - self.mops.mwrite_na2 + - self.mops.mwrite_a; - let total_mem_align_steps = self.mops.mread_na1 + - self.mops.mread_na2 * 2 + - self.mops.mwrite_na1 * 2 + - self.mops.mwrite_na2 * 4; + let total_mem_ops = self.mops.mread_na1 + + self.mops.mread_na2 + + self.mops.mread_a + + self.mops.mwrite_na1 + + self.mops.mwrite_na2 + + self.mops.mwrite_a; + let total_mem_align_steps = self.mops.mread_na1 + + self.mops.mread_na2 * 2 + + self.mops.mwrite_na1 * 2 + + self.mops.mwrite_na2 * 4; let cost_mem = total_mem_ops as f64 * COST_MEM; - let cost_mem_align = self.mops.mread_na1 as f64 * COST_MEMA_R1 + - self.mops.mread_na2 as f64 * COST_MEMA_R2 + - self.mops.mwrite_na1 as f64 * COST_MEMA_W1 + - self.mops.mwrite_na2 as f64 * COST_MEMA_W2; + let cost_mem_align = self.mops.mread_na1 as f64 * COST_MEMA_R1 + + self.mops.mread_na2 as f64 * COST_MEMA_R2 + + self.mops.mwrite_na1 as f64 * COST_MEMA_W1 + + self.mops.mwrite_na2 as f64 * COST_MEMA_W2; let mut total_opcodes: u64 = 0; let mut opcode_steps: [u64; 256] = [0; 256]; @@ -167,6 +173,9 @@ impl Stats { total_opcode_cost, total_opcode_steps, total_opcodes ); output += &format!(" Usual: {:.2} sec {} steps\n", cost_usual, self.usual); + let memory_reads = self.mops.mread_a + self.mops.mread_na1 + self.mops.mread_na2; + let memory_writes = self.mops.mwrite_a + self.mops.mwrite_na1 + self.mops.mwrite_na2; + let memory_total = memory_reads + memory_writes; output += &format!( " Memory: {} a reads + {} na1 reads + {} na2 reads + {} a writes + {} na1 writes + {} na2 writes = {} reads + {} writes = {} r/w\n", self.mops.mread_a, @@ -175,18 +184,38 @@ impl Stats { self.mops.mwrite_a, self.mops.mwrite_na1, self.mops.mwrite_na2, - self.mops.mread_a + self.mops.mread_na1 + self.mops.mread_na2, - self.mops.mwrite_a + self.mops.mwrite_na1 + self.mops.mwrite_na2, - self.mops.mread_a + self.mops.mread_na1 + self.mops.mread_na2 + - self.mops.mwrite_a + self.mops.mwrite_na1 + self.mops.mwrite_na2, + memory_reads, + memory_writes, + memory_total ); + let reg_reads_percentage = (self.rops.reads * 100) / memory_reads; + let reg_writes_percentage = (self.rops.writes * 100) / memory_writes; + let reg_total = self.rops.reads + self.rops.writes; + let reg_total_percentage = (reg_total * 100) / memory_total; + output += &format!( - " Registy: {} reads + {} writes = {} r/w\n", + " Registy: reads={}={}% writes={}={}% total={}={}% r/w\n", self.rops.reads, + reg_reads_percentage, self.rops.writes, - self.rops.reads + self.rops.writes + reg_writes_percentage, + reg_total, + reg_total_percentage ); + for reg in 0..32 { + let reads = self.reg_reads[reg]; + let writes = self.reg_writes[reg]; + let rw = reads + writes; + let reads_percentage = (reads * 100) / self.rops.reads; + let writes_percentage = (reads * 100) / self.rops.writes; + let rw_percentage = (rw * 100) / (self.rops.reads + self.rops.writes); + output += &format!( + " Reg {} reads={}={}% writes={}={}% r/w={}={}%\n", + reg, reads, reads_percentage, writes, writes_percentage, rw, rw_percentage + ); + } + output += "\nOpcodes:\n"; for opcode in 0..256 { diff --git a/state-machines/binary/src/binary_basic.rs b/state-machines/binary/src/binary_basic.rs index 444dd19b..da1e3bf8 100644 --- a/state-machines/binary/src/binary_basic.rs +++ b/state-machines/binary/src/binary_basic.rs @@ -109,32 +109,32 @@ impl BinaryBasicSM { fn opcode_is_32_bits(opcode: ZiskOp) -> bool { match opcode { - ZiskOp::Add | - ZiskOp::Sub | - ZiskOp::Ltu | - ZiskOp::Lt | - ZiskOp::Leu | - ZiskOp::Le | - ZiskOp::Eq | - ZiskOp::Minu | - ZiskOp::Min | - ZiskOp::Maxu | - ZiskOp::Max | - ZiskOp::And | - ZiskOp::Or | - ZiskOp::Xor => false, - - ZiskOp::AddW | - ZiskOp::SubW | - ZiskOp::LtuW | - ZiskOp::LtW | - ZiskOp::LeuW | - ZiskOp::LeW | - ZiskOp::EqW | - ZiskOp::MinuW | - ZiskOp::MinW | - ZiskOp::MaxuW | - ZiskOp::MaxW => true, + ZiskOp::Add + | ZiskOp::Sub + | ZiskOp::Ltu + | ZiskOp::Lt + | ZiskOp::Leu + | ZiskOp::Le + | ZiskOp::Eq + | ZiskOp::Minu + | ZiskOp::Min + | ZiskOp::Maxu + | ZiskOp::Max + | ZiskOp::And + | ZiskOp::Or + | ZiskOp::Xor => false, + + ZiskOp::AddW + | ZiskOp::SubW + | ZiskOp::LtuW + | ZiskOp::LtW + | ZiskOp::LeuW + | ZiskOp::LeW + | ZiskOp::EqW + | ZiskOp::MinuW + | ZiskOp::MinW + | ZiskOp::MaxuW + | ZiskOp::MaxW => true, _ => panic!("Binary basic opcode_is_32_bits() got invalid opcode={:?}", opcode), } @@ -206,7 +206,6 @@ impl BinaryBasicSM { // Calculate carry let previous_cin = cin; let result = cin + a_bytes[i] as u64 + b_bytes[i] as u64; - debug_assert!((result & 0xff) == c_bytes[i] as u64); cout = result >> 8; cin = if i == carry_byte { 0 } else { cout }; row.carry[i] = F::from_canonical_u64(cin); @@ -248,10 +247,6 @@ impl BinaryBasicSM { // Calculate carry let previous_cin = cin; cout = if a_bytes[i] as u64 >= (b_bytes[i] as u64 + cin) { 0 } else { 1 }; - debug_assert!( - (256 * cout + a_bytes[i] as u64 - cin - b_bytes[i] as u64) == - c_bytes[i] as u64 - ); cin = if i == carry_byte { 0 } else { cout }; row.carry[i] = F::from_canonical_u64(cin); @@ -308,9 +303,9 @@ impl BinaryBasicSM { } // If the chunk is signed, then the result is the sign of a - if (binary_basic_table_op.eq(&BinaryBasicTableOp::Lt)) && - (plast[i] == 1) && - (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) + if (binary_basic_table_op.eq(&BinaryBasicTableOp::Lt)) + && (plast[i] == 1) + && (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) { cout = if a_bytes[i] & 0x80 != 0 { 1 } else { 0 }; } @@ -357,9 +352,9 @@ impl BinaryBasicSM { if a_bytes[i] <= b_bytes[i] { cout = 1; } - if (binary_basic_table_op == BinaryBasicTableOp::Le) && - (plast[i] == 1) && - (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) + if (binary_basic_table_op == BinaryBasicTableOp::Le) + && (plast[i] == 1) + && (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) { cout = c; } @@ -400,10 +395,8 @@ impl BinaryBasicSM { let previous_cin = cin; if (a_bytes[i] == b_bytes[i]) && (cin == 0) { cout = 0; - debug_assert!(plast[i] == c_bytes[i] as u64); } else { cout = 1; - debug_assert!(0 == c_bytes[i] as u64); } if plast[i] == 1 { cout = 1 - cout; @@ -453,9 +446,9 @@ impl BinaryBasicSM { } // If the chunk is signed, then the result is the sign of a - if (binary_basic_table_op == BinaryBasicTableOp::Min) && - (plast[i] == 1) && - (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) + if (binary_basic_table_op == BinaryBasicTableOp::Min) + && (plast[i] == 1) + && (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) { cout = if a_bytes[i] & 0x80 != 0 { 1 } else { 0 }; } @@ -507,9 +500,9 @@ impl BinaryBasicSM { } // If the chunk is signed, then the result is the sign of a - if (binary_basic_table_op == BinaryBasicTableOp::Max) && - (plast[i] == 1) && - (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) + if (binary_basic_table_op == BinaryBasicTableOp::Max) + && (plast[i] == 1) + && (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) { cout = if a_bytes[i] & 0x80 != 0 { 1 } else { 0 }; } From 017906861f8d3dbbc4a695b5d19d489e670bf7a4 Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Fri, 1 Nov 2024 05:33:16 +0000 Subject: [PATCH 19/22] main continuations working --- Cargo.lock | 22 ++++++++++++++++------ emulator/src/emulator.rs | 4 ---- state-machines/main/pil/main.pil | 17 +++++++++-------- state-machines/main/src/main_sm.rs | 17 ++++++++++------- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f35546e4..dd7c1966 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1328,6 +1328,7 @@ dependencies = [ [[package]] name = "pil-std-lib" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "log", "num-bigint", @@ -1345,6 +1346,7 @@ dependencies = [ [[package]] name = "pilout" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "bytes", "log", @@ -1464,6 +1466,7 @@ dependencies = [ [[package]] name = "proofman" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "colored", "env_logger", @@ -1484,6 +1487,7 @@ dependencies = [ [[package]] name = "proofman-common" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "env_logger", "log", @@ -1501,6 +1505,7 @@ dependencies = [ [[package]] name = "proofman-hints" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "p3-field", "proofman-common", @@ -1510,6 +1515,7 @@ dependencies = [ [[package]] name = "proofman-macros" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "proc-macro2", "quote", @@ -1519,6 +1525,7 @@ dependencies = [ [[package]] name = "proofman-starks-lib-c" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "log", ] @@ -1526,6 +1533,7 @@ dependencies = [ [[package]] name = "proofman-util" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "colored", "sysinfo 0.31.4", @@ -2159,6 +2167,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stark" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "log", "p3-field", @@ -2222,9 +2231,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "e89275301d38033efb81a6e60e3497e734dfcc62571f2854bf4b16690398824c" dependencies = [ "proc-macro2", "quote", @@ -2289,18 +2298,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5" dependencies = [ "proc-macro2", "quote", @@ -2467,6 +2476,7 @@ dependencies = [ [[package]] name = "transcript" version = "0.1.0" +source = "git+https://github.com/0xPolygonHermez/pil2-proofman.git?branch=develop#2645c3a1695bad2007830f67a527cccb486815ce" dependencies = [ "proofman-starks-lib-c", ] diff --git a/emulator/src/emulator.rs b/emulator/src/emulator.rs index 8406bea4..6f7078f8 100644 --- a/emulator/src/emulator.rs +++ b/emulator/src/emulator.rs @@ -216,10 +216,6 @@ impl ZiskEmulator { } }); - println!("emu_traces[0][0].len={}", emu_traces[0][0].steps.len()); - println!("emu_traces[0][0].len={}", emu_traces[1][0].steps.len()); - println!("emu_slices={:?}", emu_slices.lock().unwrap()); - let capacity = emu_traces.iter().map(|trace| trace.len()).sum::(); let mut vec_traces = Vec::with_capacity(capacity); for i in 0..capacity { diff --git a/state-machines/main/pil/main.pil b/state-machines/main/pil/main.pil index 90860ef7..e4d406f9 100644 --- a/state-machines/main/pil/main.pil +++ b/state-machines/main/pil/main.pil @@ -240,12 +240,15 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // const expr bus_main_segment = main_segment - SEGMENT_LAST * (main_segment * main_last_segment - 1 + main_last_segment); - permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, ...specific_registers, c[0] * (1 - main_last_segment), c[1] * (1 - main_last_segment)], - sel: SEGMENT_LAST - SEGMENT_L1, name: PIOP_NAME_ISOLATED, bus_type: PIOP_BUS_SUM); + // permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, ...specific_registers, c[0] * (1 - main_last_segment), c[1] * (1 - main_last_segment)], + // sel: SEGMENT_LAST - SEGMENT_L1, name: PIOP_NAME_ISOLATED, bus_type: PIOP_BUS_SUM); + permutation_proves(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, pc, c[0], c[1], set_pc, jmp_offset1, flag * SEGMENT_LAST * (jmp_offset1 - jmp_offset2) + jmp_offset2], + sel: SEGMENT_LAST, name: PIOP_NAME_ISOLATED, bus_type: PIOP_BUS_SUM); + permutation_assumes(MAIN_CONTINUATION_ID, cols: [bus_main_segment, is_last_continuation, pc, c[0], c[1], set_pc, jmp_offset1, flag * SEGMENT_LAST * (jmp_offset1 - jmp_offset2) + jmp_offset2], + sel: SEGMENT_L1, name: PIOP_NAME_ISOLATED, bus_type: PIOP_BUS_SUM); flag * (1 - flag) === 0; - // set lsb of rom_flags always to 1 to force that padding rom rows (all values to zero), doesn't // match with main trace. const expr rom_flags = 1 + 2 * a_src_imm + 4 * a_src_mem + 8 * a_src_step + 16 * b_src_imm + 32 * b_src_mem @@ -265,14 +268,12 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope // flag = 0 // a_src_imm = b_src_imm = 1 (rest flags to 0) - SEGMENT_L1 * jmp_offset1 === 0; - SEGMENT_L1 * jmp_offset2 === 0; - SEGMENT_L1 * (rom_flags - 19) === 0; // 19 = 1 + a_src_imm(2) + b_src_imm(16) + SEGMENT_L1 * (rom_flags - 19 - set_pc * 1024) === 0; // 19 = 1 + a_src_imm(2) + b_src_imm(16) SEGMENT_L1 * (op - 1) === 0; lookup_assumes(ROM_BUS_ID, [pc, a_offset_imm0, a_imm1, b_offset_imm0, b_imm1, ind_width, op, store_offset, jmp_offset1, jmp_offset2, rom_flags], sel: 1 - SEGMENT_L1); - direct_update(MAIN_CONTINUATION_ID, cols: [0, 0, 4096, 0, 0], bus_type: PIOP_BUS_SUM); - direct_update(MAIN_CONTINUATION_ID, cols: [0, 1, 4312, 0, 0], bus_type: PIOP_BUS_SUM); + direct_update(MAIN_CONTINUATION_ID, cols: [0, 0, 4096, 0, 0], bus_type: PIOP_BUS_SUM, proves: 1); + direct_update(MAIN_CONTINUATION_ID, cols: [0, 1, 4312, 0, 0], bus_type: PIOP_BUS_SUM, proves: 0); } \ No newline at end of file diff --git a/state-machines/main/src/main_sm.rs b/state-machines/main/src/main_sm.rs index 41a3191e..0e2fe78f 100644 --- a/state-machines/main/src/main_sm.rs +++ b/state-machines/main/src/main_sm.rs @@ -103,15 +103,24 @@ impl MainSM { } } else { let emu_trace_previous = vec_traces[segment_id - 1].steps.last().unwrap(); - let mut emu = Emu::from_emu_trace_start(zisk_rom, &vec_traces[segment_id - 1].last_state); + let mut emu = + Emu::from_emu_trace_start(zisk_rom, &vec_traces[segment_id - 1].last_state); let row_previous = emu.step_slice_full_trace(emu_trace_previous); Main0Row:: { + set_pc: row_previous.set_pc, + jmp_offset1: row_previous.jmp_offset1, + jmp_offset2: if row_previous.flag == F::one() { + row_previous.jmp_offset1 + } else { + row_previous.jmp_offset2 + }, a: row_previous.a, b: row_previous.c, c: row_previous.c, a_offset_imm0: row_previous.a[0], b_offset_imm0: row_previous.c[0], + addr1: row_previous.c[0], a_imm1: row_previous.a[1], b_imm1: row_previous.c[1], op: F::from_canonical_u8(ZiskOp::CopyB.code()), @@ -122,12 +131,6 @@ impl MainSM { } }; - if segment_id == 1 { - // "INFO 19: 20 77 main/pil/main.pil:222 (1-Main.SEGMENT_L1)*(Main.pc-((('Main.set_pc*('Main.c[0]+'Main.jmp_offset1))+((1-'Main.set_pc)*('Main.pc+'Main.jmp_offset2)))+('Main.flag*('Main.jmp_offset1-'Main.jmp_offset2)))) == 0" - //row0: Main0Row { a: [27, 0], b: [452984832, 0], c: [452984832, 0], flag: 0, pc: 2147486932, a_src_imm: 1, a_src_mem: 0, a_offset_imm0: 27, a_imm1: 0, a_src_step: 0, b_src_imm: 1, b_src_mem: 0, b_offset_imm0: 452984832, b_imm1: 0, b_src_ind: 0, ind_width: 0, is_external_op: 0, op: 1, store_ra: 0, store_mem: 0, store_ind: 0, store_offset: 0, set_pc: 0, jmp_offset1: 0, jmp_offset2: 0, m32: 0, addr1: 0, __debug_operation_bus_enabled: 0 } - println!("row0: {:?}", row0); - } - let mut emu = Emu::from_emu_trace_start(zisk_rom, &segment_trace.start_state); let rng = offset as usize..(offset as usize + Main0Row::::ROW_SIZE); From 4abecee55b2c2281ae25fb07047bf70ebb952bfd Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Fri, 1 Nov 2024 05:37:40 +0000 Subject: [PATCH 20/22] cargo fmt&clippy --- core/src/inst_context.rs | 3 +- emulator/src/emu.rs | 28 ++++----- emulator/src/stats.rs | 28 ++++----- state-machines/binary/src/binary_basic.rs | 76 +++++++++++------------ state-machines/rom/src/rom.rs | 59 +++++++++--------- 5 files changed, 98 insertions(+), 96 deletions(-) diff --git a/core/src/inst_context.rs b/core/src/inst_context.rs index c08f8a22..38dabf5a 100644 --- a/core/src/inst_context.rs +++ b/core/src/inst_context.rs @@ -30,8 +30,7 @@ impl InstContext { } } pub fn to_text(&self) -> String { - let s: String; - s = format! {"a={:x} b={:x} c={:x} flag={} sp={} pc={} step={} end={}", self.a, self.b, self.c, self.flag, self.sp, self.pc, self.step, self.end}; + let s = format! {"a={:x} b={:x} c={:x} flag={} sp={} pc={} step={} end={}", self.a, self.b, self.c, self.flag, self.sp, self.pc, self.step, self.end}; s } } diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index 0a018514..353a72ab 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -335,9 +335,9 @@ impl<'a> Emu<'a> { } // Log emulation step, if requested - if options.print_step.is_some() - && (options.print_step.unwrap() != 0) - && ((self.ctx.inst_ctx.step % options.print_step.unwrap()) == 0) + if options.print_step.is_some() && + (options.print_step.unwrap() != 0) && + ((self.ctx.inst_ctx.step % options.print_step.unwrap()) == 0) { println!("step={}", self.ctx.inst_ctx.step); } @@ -519,9 +519,9 @@ impl<'a> Emu<'a> { // Increment step counter self.ctx.inst_ctx.step += 1; - if self.ctx.inst_ctx.end - || ((self.ctx.inst_ctx.step - self.ctx.last_callback_step) - == self.ctx.callback_steps) + if self.ctx.inst_ctx.end || + ((self.ctx.inst_ctx.step - self.ctx.last_callback_step) == + self.ctx.callback_steps) { // In run() we have checked the callback consistency with ctx.do_callback let callback = callback.as_ref().unwrap(); @@ -698,11 +698,11 @@ impl<'a> Emu<'a> { let mut current_box_id = 0; let mut current_step_idx = loop { - if current_box_id == vec_traces.len() - 1 - || vec_traces[current_box_id + 1].start_state.step >= emu_trace_start.step + if current_box_id == vec_traces.len() - 1 || + vec_traces[current_box_id + 1].start_state.step >= emu_trace_start.step { - break emu_trace_start.step as usize - - vec_traces[current_box_id].start_state.step as usize; + break emu_trace_start.step as usize - + vec_traces[current_box_id].start_state.step as usize; } current_box_id += 1; }; @@ -813,8 +813,8 @@ impl<'a> Emu<'a> { let b = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.b >> 32) & 0xFFFFFFFF]; let c = [inst_ctx.c & 0xFFFFFFFF, (inst_ctx.c >> 32) & 0xFFFFFFFF]; - let addr1 = (inst.b_offset_imm0 as i64 - + if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64; + let addr1 = (inst.b_offset_imm0 as i64 + + if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64; let jmp_offset1 = if inst.jmp_offset1 >= 0 { F::from_canonical_u64(inst.jmp_offset1 as u64) @@ -892,8 +892,8 @@ impl<'a> Emu<'a> { m32: F::from_bool(inst.m32), addr1: F::from_canonical_u64(addr1), __debug_operation_bus_enabled: F::from_bool( - inst.op_type == ZiskOperationType::Binary - || inst.op_type == ZiskOperationType::BinaryE, + inst.op_type == ZiskOperationType::Binary || + inst.op_type == ZiskOperationType::BinaryE, ), } } diff --git a/emulator/src/stats.rs b/emulator/src/stats.rs index afb26baa..fcc18a29 100644 --- a/emulator/src/stats.rs +++ b/emulator/src/stats.rs @@ -114,22 +114,22 @@ impl Stats { output += &format!(" COST_USUAL: {:02} sec\n", COST_USUAL); output += &format!(" COST_STEP: {:02} sec\n", COST_STEP); - let total_mem_ops = self.mops.mread_na1 - + self.mops.mread_na2 - + self.mops.mread_a - + self.mops.mwrite_na1 - + self.mops.mwrite_na2 - + self.mops.mwrite_a; - let total_mem_align_steps = self.mops.mread_na1 - + self.mops.mread_na2 * 2 - + self.mops.mwrite_na1 * 2 - + self.mops.mwrite_na2 * 4; + let total_mem_ops = self.mops.mread_na1 + + self.mops.mread_na2 + + self.mops.mread_a + + self.mops.mwrite_na1 + + self.mops.mwrite_na2 + + self.mops.mwrite_a; + let total_mem_align_steps = self.mops.mread_na1 + + self.mops.mread_na2 * 2 + + self.mops.mwrite_na1 * 2 + + self.mops.mwrite_na2 * 4; let cost_mem = total_mem_ops as f64 * COST_MEM; - let cost_mem_align = self.mops.mread_na1 as f64 * COST_MEMA_R1 - + self.mops.mread_na2 as f64 * COST_MEMA_R2 - + self.mops.mwrite_na1 as f64 * COST_MEMA_W1 - + self.mops.mwrite_na2 as f64 * COST_MEMA_W2; + let cost_mem_align = self.mops.mread_na1 as f64 * COST_MEMA_R1 + + self.mops.mread_na2 as f64 * COST_MEMA_R2 + + self.mops.mwrite_na1 as f64 * COST_MEMA_W1 + + self.mops.mwrite_na2 as f64 * COST_MEMA_W2; let mut total_opcodes: u64 = 0; let mut opcode_steps: [u64; 256] = [0; 256]; diff --git a/state-machines/binary/src/binary_basic.rs b/state-machines/binary/src/binary_basic.rs index da1e3bf8..ac4ddcb1 100644 --- a/state-machines/binary/src/binary_basic.rs +++ b/state-machines/binary/src/binary_basic.rs @@ -109,32 +109,32 @@ impl BinaryBasicSM { fn opcode_is_32_bits(opcode: ZiskOp) -> bool { match opcode { - ZiskOp::Add - | ZiskOp::Sub - | ZiskOp::Ltu - | ZiskOp::Lt - | ZiskOp::Leu - | ZiskOp::Le - | ZiskOp::Eq - | ZiskOp::Minu - | ZiskOp::Min - | ZiskOp::Maxu - | ZiskOp::Max - | ZiskOp::And - | ZiskOp::Or - | ZiskOp::Xor => false, - - ZiskOp::AddW - | ZiskOp::SubW - | ZiskOp::LtuW - | ZiskOp::LtW - | ZiskOp::LeuW - | ZiskOp::LeW - | ZiskOp::EqW - | ZiskOp::MinuW - | ZiskOp::MinW - | ZiskOp::MaxuW - | ZiskOp::MaxW => true, + ZiskOp::Add | + ZiskOp::Sub | + ZiskOp::Ltu | + ZiskOp::Lt | + ZiskOp::Leu | + ZiskOp::Le | + ZiskOp::Eq | + ZiskOp::Minu | + ZiskOp::Min | + ZiskOp::Maxu | + ZiskOp::Max | + ZiskOp::And | + ZiskOp::Or | + ZiskOp::Xor => false, + + ZiskOp::AddW | + ZiskOp::SubW | + ZiskOp::LtuW | + ZiskOp::LtW | + ZiskOp::LeuW | + ZiskOp::LeW | + ZiskOp::EqW | + ZiskOp::MinuW | + ZiskOp::MinW | + ZiskOp::MaxuW | + ZiskOp::MaxW => true, _ => panic!("Binary basic opcode_is_32_bits() got invalid opcode={:?}", opcode), } @@ -303,9 +303,9 @@ impl BinaryBasicSM { } // If the chunk is signed, then the result is the sign of a - if (binary_basic_table_op.eq(&BinaryBasicTableOp::Lt)) - && (plast[i] == 1) - && (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) + if (binary_basic_table_op.eq(&BinaryBasicTableOp::Lt)) && + (plast[i] == 1) && + (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) { cout = if a_bytes[i] & 0x80 != 0 { 1 } else { 0 }; } @@ -352,9 +352,9 @@ impl BinaryBasicSM { if a_bytes[i] <= b_bytes[i] { cout = 1; } - if (binary_basic_table_op == BinaryBasicTableOp::Le) - && (plast[i] == 1) - && (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) + if (binary_basic_table_op == BinaryBasicTableOp::Le) && + (plast[i] == 1) && + (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) { cout = c; } @@ -446,9 +446,9 @@ impl BinaryBasicSM { } // If the chunk is signed, then the result is the sign of a - if (binary_basic_table_op == BinaryBasicTableOp::Min) - && (plast[i] == 1) - && (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) + if (binary_basic_table_op == BinaryBasicTableOp::Min) && + (plast[i] == 1) && + (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) { cout = if a_bytes[i] & 0x80 != 0 { 1 } else { 0 }; } @@ -500,9 +500,9 @@ impl BinaryBasicSM { } // If the chunk is signed, then the result is the sign of a - if (binary_basic_table_op == BinaryBasicTableOp::Max) - && (plast[i] == 1) - && (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) + if (binary_basic_table_op == BinaryBasicTableOp::Max) && + (plast[i] == 1) && + (a_bytes[i] & 0x80) != (b_bytes[i] & 0x80) { cout = if a_bytes[i] & 0x80 != 0 { 1 } else { 0 }; } diff --git a/state-machines/rom/src/rom.rs b/state-machines/rom/src/rom.rs index b703c2f8..ac135e83 100644 --- a/state-machines/rom/src/rom.rs +++ b/state-machines/rom/src/rom.rs @@ -6,7 +6,9 @@ use proofman_common::{AirInstance, BufferAllocator, SetupCtx}; use proofman_util::create_buffer_fast; use zisk_core::{Riscv2zisk, ZiskPcHistogram, ZiskRom, SRC_IMM}; -use zisk_pil::{Pilout, Rom0Row, Rom0Trace, MAIN_AIRGROUP_ID, MAIN_AIR_IDS, ROM_AIRGROUP_ID, ROM_AIR_IDS}; +use zisk_pil::{ + Pilout, Rom0Row, Rom0Trace, MAIN_AIRGROUP_ID, MAIN_AIR_IDS, ROM_AIRGROUP_ID, ROM_AIR_IDS, +}; //use ziskemu::ZiskEmulatorErr; use std::error::Error; @@ -100,14 +102,14 @@ impl RomSM { let number_of_instructions = rom.insts.len(); Self::create_rom_s( - sizes.0, - rom, - number_of_instructions, - buffer_allocator, - sctx, - pc_histogram, - main_trace_len, - ) + sizes.0, + rom, + number_of_instructions, + buffer_allocator, + sctx, + pc_histogram, + main_trace_len, + ) // match number_of_instructions { // n if n <= sizes.0 => Self::create_rom_s( // sizes.0, @@ -136,8 +138,8 @@ impl RomSM { // pc_histogram, // main_trace_len, // ), - // _ => panic!("RomSM::compute_trace() found rom too big size={}", number_of_instructions), - // } + // _ => panic!("RomSM::compute_trace() found rom too big size={}", + // number_of_instructions), } } fn create_rom_s( @@ -178,7 +180,8 @@ impl RomSM { if counter.is_some() { multiplicity = *counter.unwrap(); if inst.paddr == pc_histogram.end_pc { - multiplicity += main_trace_len - 1 - (pc_histogram.steps % (main_trace_len - 1)); + multiplicity += + main_trace_len - 1 - (pc_histogram.steps % (main_trace_len - 1)); } } else { continue; // We skip those pc's that are not used in this execution @@ -293,8 +296,8 @@ impl RomSM { // if counter.is_some() { // multiplicity = *counter.unwrap(); // if inst.paddr == pc_histogram.end_pc { - // multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); - // } + // multiplicity += main_trace_len - 1 - (pc_histogram.steps % + // main_trace_len); } // } else { // continue; // We skip those pc's that are not used in this execution // } @@ -328,14 +331,14 @@ impl RomSM { // }; // // Fill the rom trace row fields - // rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line - // rom_trace[i].a_offset_imm0 = a_offset_imm0; + // rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, + // paddr, line rom_trace[i].a_offset_imm0 = a_offset_imm0; // rom_trace[i].a_imm1 = - // F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); - // rom_trace[i].b_offset_imm0 = b_offset_imm0; + // F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 + // }); rom_trace[i].b_offset_imm0 = b_offset_imm0; // rom_trace[i].b_imm1 = - // F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); - // //rom_trace[i].b_src_ind = + // F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 + // }); //rom_trace[i].b_src_ind = // // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); // rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); // rom_trace[i].op = F::from_canonical_u8(inst.op); @@ -392,8 +395,8 @@ impl RomSM { // if counter.is_some() { // multiplicity = *counter.unwrap(); // if inst.paddr == pc_histogram.end_pc { - // multiplicity += main_trace_len - 1 - (pc_histogram.steps % main_trace_len); - // } + // multiplicity += main_trace_len - 1 - (pc_histogram.steps % + // main_trace_len); } // } else { // continue; // We skip those pc's that are not used in this execution // } @@ -427,14 +430,14 @@ impl RomSM { // }; // // Fill the rom trace row fields - // rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, paddr, line - // rom_trace[i].a_offset_imm0 = a_offset_imm0; + // rom_trace[i].line = F::from_canonical_u64(inst.paddr); // TODO: unify names: pc, + // paddr, line rom_trace[i].a_offset_imm0 = a_offset_imm0; // rom_trace[i].a_imm1 = - // F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 }); - // rom_trace[i].b_offset_imm0 = b_offset_imm0; + // F::from_canonical_u64(if inst.a_src == SRC_IMM { inst.a_use_sp_imm1 } else { 0 + // }); rom_trace[i].b_offset_imm0 = b_offset_imm0; // rom_trace[i].b_imm1 = - // F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 }); - // //rom_trace[i].b_src_ind = + // F::from_canonical_u64(if inst.b_src == SRC_IMM { inst.b_use_sp_imm1 } else { 0 + // }); //rom_trace[i].b_src_ind = // // F::from_canonical_u64(if inst.b_src == SRC_IND { 1 } else { 0 }); // rom_trace[i].ind_width = F::from_canonical_u64(inst.ind_width); // rom_trace[i].op = F::from_canonical_u8(inst.op); From 35293e5b18a2e7c51edb797631ffc22faae390cf Mon Sep 17 00:00:00 2001 From: Xavier Pinsach <10213118+xavi-pinsach@users.noreply.github.com> Date: Sun, 3 Nov 2024 18:48:30 +0000 Subject: [PATCH 21/22] remove unnecessary println --- emulator/src/emu.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index 353a72ab..a42877cd 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -485,7 +485,6 @@ impl<'a> Emu<'a> { // If this is the last instruction, stop executing if instruction.end { self.ctx.inst_ctx.end = true; - println!("Emu::step() end of execution steps: {}", self.ctx.inst_ctx.step); if options.stats { self.ctx.stats.on_steps(self.ctx.inst_ctx.step); } From 3776e9852cb05c760d499394ac24d5ba909e982e Mon Sep 17 00:00:00 2001 From: fractasy Date: Mon, 4 Nov 2024 11:04:21 +0000 Subject: [PATCH 22/22] End zisk emulation in ROM_EXIT address --- core/src/zisk_definitions.rs | 6 +++--- core/src/zv2zisk.rs | 30 +++++++++++++++++++++--------- emulator/src/emu.rs | 4 +++- emulator/src/stats.rs | 18 ++++++++++++------ 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/core/src/zisk_definitions.rs b/core/src/zisk_definitions.rs index 7f6c9669..1c568108 100644 --- a/core/src/zisk_definitions.rs +++ b/core/src/zisk_definitions.rs @@ -14,10 +14,10 @@ pub const STORE_IND: u64 = 2; /* Memory map: - |--------------- ROM_ENTRY first instruction (0x1000) + |--------------- ROM_ENTRY first instr ( 0x1000) | calls program at ROM_ADDR, then returns | kind of a BIOS - |--------------- ROM_EXIT last instruction (0x4000) + |--------------- ROM_EXIT last instr (0x10000000) ... |--------------- ROM_ADDR (0x80000000) | (rom program) @@ -45,7 +45,7 @@ pub const OUTPUT_MAX_SIZE: u64 = 0x10000; // 64K pub const AVAILABLE_MEM_ADDR: u64 = OUTPUT_ADDR + OUTPUT_MAX_SIZE; pub const AVAILABLE_MEM_SIZE: u64 = RAM_SIZE - OUTPUT_MAX_SIZE - SYS_SIZE; pub const ROM_ENTRY: u64 = 0x1000; -pub const ROM_EXIT: u64 = 0x4000; +pub const ROM_EXIT: u64 = 0x10000000; pub const ARCH_ID_ZISK: u64 = 0xFFFEEEE; pub const UART_ADDR: u64 = SYS_ADDR + 512; diff --git a/core/src/zv2zisk.rs b/core/src/zv2zisk.rs index ac17d344..0179f25a 100644 --- a/core/src/zv2zisk.rs +++ b/core/src/zv2zisk.rs @@ -2,7 +2,7 @@ use riscv::{riscv_interpreter, RiscvInstruction}; use crate::{ convert_vector, read_u16_le, read_u32_le, read_u64_le, ZiskInstBuilder, ZiskRom, ARCH_ID_ZISK, - INPUT_ADDR, OUTPUT_ADDR, SYS_ADDR, + INPUT_ADDR, OUTPUT_ADDR, ROM_EXIT, SYS_ADDR, }; use std::collections::HashMap; @@ -1533,14 +1533,14 @@ pub fn add_entry_exit_jmp(rom: &mut ZiskRom, addr: u64) { rom.insts.insert(rom.next_init_inst_addr, zib); rom.next_init_inst_addr += 4; - // :0034 + // :0034 jump to end (success) let mut zib = ZiskInstBuilder::new(rom.next_init_inst_addr); zib.src_a("imm", 0, false); - zib.src_b("imm", 0, false); + zib.src_b("imm", ROM_EXIT, false); zib.op("copyb").unwrap(); - zib.end(); + zib.set_pc(); zib.j(0, 0); - zib.verbose("end"); + zib.verbose("jump to end successfully"); zib.build(); rom.insts.insert(rom.next_init_inst_addr, zib); rom.next_init_inst_addr += 4; @@ -1557,14 +1557,14 @@ pub fn add_entry_exit_jmp(rom: &mut ZiskRom, addr: u64) { rom.insts.insert(rom.next_init_inst_addr, zib); rom.next_init_inst_addr += 4; - // :003c + // :003c jump to END (error) let mut zib = ZiskInstBuilder::new(rom.next_init_inst_addr); zib.src_a("imm", 0, false); - zib.src_b("imm", 0, false); + zib.src_b("imm", ROM_EXIT, false); zib.op("copyb").unwrap(); - zib.end(); + zib.set_pc(); zib.j(0, 0); - zib.verbose("end"); + zib.verbose("jump to end due to error"); zib.build(); rom.insts.insert(rom.next_init_inst_addr, zib); rom.next_init_inst_addr += 4; @@ -1603,4 +1603,16 @@ pub fn add_entry_exit_jmp(rom: &mut ZiskRom, addr: u64) { zib.build(); rom.insts.insert(rom.next_init_inst_addr, zib); rom.next_init_inst_addr += 4; + + // END: all programs should exit here, regardless of the execution result + rom.next_init_inst_addr = ROM_EXIT; + let mut zib = ZiskInstBuilder::new(rom.next_init_inst_addr); + zib.src_a("imm", 0, false); + zib.src_b("imm", 0, false); + zib.op("copyb").unwrap(); + zib.end(); + zib.j(0, 0); + zib.verbose("end"); + zib.build(); + rom.insts.insert(rom.next_init_inst_addr, zib); } diff --git a/emulator/src/emu.rs b/emulator/src/emu.rs index 0a018514..afee5f3f 100644 --- a/emulator/src/emu.rs +++ b/emulator/src/emu.rs @@ -453,6 +453,7 @@ impl<'a> Emu<'a> { #[inline(always)] #[allow(unused_variables)] pub fn step(&mut self, options: &EmuOptions, callback: &Option) { + let pc = self.ctx.inst_ctx.pc; let instruction = self.rom.get_instruction(self.ctx.inst_ctx.pc); //println!("Emu::step() executing step={} pc={:x} inst={}", ctx.step, ctx.pc, @@ -495,8 +496,9 @@ impl<'a> Emu<'a> { #[cfg(debug_assertions)] if options.log_step { println!( - "step={} pc={} op={}={} a={} b={} c={} flag={} inst={}", + "step={} pc={} next={} op={}={} a={} b={} c={} flag={} inst={}", self.ctx.inst_ctx.step, + pc, self.ctx.inst_ctx.pc, instruction.op, instruction.op_str, diff --git a/emulator/src/stats.rs b/emulator/src/stats.rs index afb26baa..63173369 100644 --- a/emulator/src/stats.rs +++ b/emulator/src/stats.rs @@ -188,10 +188,13 @@ impl Stats { memory_writes, memory_total ); - let reg_reads_percentage = (self.rops.reads * 100) / memory_reads; - let reg_writes_percentage = (self.rops.writes * 100) / memory_writes; + let reg_reads_percentage = + if memory_reads != 0 { (self.rops.reads * 100) / memory_reads } else { 0 }; + let reg_writes_percentage = + if memory_writes != 0 { (self.rops.writes * 100) / memory_writes } else { 0 }; let reg_total = self.rops.reads + self.rops.writes; - let reg_total_percentage = (reg_total * 100) / memory_total; + let reg_total_percentage = + if memory_total != 0 { (reg_total * 100) / memory_total } else { 0 }; output += &format!( " Registy: reads={}={}% writes={}={}% total={}={}% r/w\n", @@ -207,9 +210,12 @@ impl Stats { let reads = self.reg_reads[reg]; let writes = self.reg_writes[reg]; let rw = reads + writes; - let reads_percentage = (reads * 100) / self.rops.reads; - let writes_percentage = (reads * 100) / self.rops.writes; - let rw_percentage = (rw * 100) / (self.rops.reads + self.rops.writes); + let reads_percentage = + if self.rops.reads != 0 { (reads * 100) / self.rops.reads } else { 0 }; + let writes_percentage = + if self.rops.writes != 0 { (reads * 100) / self.rops.writes } else { 0 }; + let total_rw = self.rops.reads + self.rops.writes; + let rw_percentage = if total_rw != 0 { (rw * 100) / total_rw } else { 0 }; output += &format!( " Reg {} reads={}={}% writes={}={}% r/w={}={}%\n", reg, reads, reads_percentage, writes, writes_percentage, rw, rw_percentage