From 427d3934423be3817b1d7b6b251f5d225855ee3d Mon Sep 17 00:00:00 2001 From: Georg Wiese Date: Mon, 12 Feb 2024 11:24:27 +0100 Subject: [PATCH] Halo2 tests: Only run Mock prover in PR tests --- .github/workflows/nightly-tests.yml | 1 + pipeline/src/test_util.rs | 26 ++++++++++++ pipeline/tests/asm.rs | 66 ++++++++++++++--------------- pipeline/tests/pil.rs | 14 +++--- pipeline/tests/powdr_std.rs | 12 ++++-- 5 files changed, 76 insertions(+), 43 deletions(-) diff --git a/.github/workflows/nightly-tests.yml b/.github/workflows/nightly-tests.yml index 98d4cba68..e8e78be58 100644 --- a/.github/workflows/nightly-tests.yml +++ b/.github/workflows/nightly-tests.yml @@ -6,6 +6,7 @@ on: env: CARGO_TERM_COLOR: always + IS_NIGHTLY_TEST: true jobs: check_if_needs_running: diff --git a/pipeline/src/test_util.rs b/pipeline/src/test_util.rs index 57c20019c..cc3f4cffa 100644 --- a/pipeline/src/test_util.rs +++ b/pipeline/src/test_util.rs @@ -73,6 +73,32 @@ pub fn gen_estark_proof(file_name: &str, inputs: Vec) { .unwrap(); } +#[cfg(feature = "halo2")] +pub fn test_halo2(file_name: &str, inputs: Vec) { + use std::env; + + // Generate a mock proof (fast and has good error messages) + let full_file_name = format!("{}/../test_data/{file_name}", env!("CARGO_MANIFEST_DIR")); + Pipeline::default() + .from_file(PathBuf::from(full_file_name)) + .with_prover_inputs(inputs.clone()) + .with_backend(powdr_backend::BackendType::Halo2Mock) + .proof() + .unwrap(); + + // `gen_halo2_proof` is rather slow, because it computes two Halo2 proofs. + // Therefore, we only run it in the nightly tests. + let is_nightly_test = env::var("IS_NIGHTLY_TEST") + .map(|v| v == "true") + .unwrap_or(false); + if is_nightly_test { + gen_halo2_proof(file_name, inputs) + } +} + +#[cfg(not(feature = "halo2"))] +pub fn test_halo2(_file_name: &str, _inputs: Vec) {} + #[cfg(feature = "halo2")] pub fn gen_halo2_proof(file_name: &str, inputs: Vec) { use std::fs; diff --git a/pipeline/tests/asm.rs b/pipeline/tests/asm.rs index a1c9b2b45..d6ecca4a2 100644 --- a/pipeline/tests/asm.rs +++ b/pipeline/tests/asm.rs @@ -1,5 +1,5 @@ use powdr_number::{FieldElement, GoldilocksField}; -use powdr_pipeline::test_util::{gen_estark_proof, gen_halo2_proof, verify_test_file}; +use powdr_pipeline::test_util::{gen_estark_proof, test_halo2, verify_test_file}; use test_log::test; fn verify_asm(file_name: &str, inputs: Vec) { @@ -15,7 +15,7 @@ fn simple_sum_asm() { let f = "asm/simple_sum.asm"; let i = [16, 4, 1, 2, 8, 5]; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -23,7 +23,7 @@ fn simple_sum_asm() { fn secondary_block_machine_add2() { let f = "asm/secondary_block_machine_add2.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -31,7 +31,7 @@ fn secondary_block_machine_add2() { fn mem_write_once() { let f = "asm/mem_write_once.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -49,7 +49,7 @@ fn mem_write_once_external_write() { fn block_machine_cache_miss() { let f = "asm/block_machine_cache_miss.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -58,7 +58,7 @@ fn palindrome() { let f = "asm/palindrome.asm"; let i = [7, 1, 7, 3, 9, 3, 7, 1]; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); // currently starky leads to // thread 'functional_instructions' has overflowed its stack // leave it out until that's fixed @@ -70,7 +70,7 @@ fn single_function_vm() { let f = "asm/single_function_vm.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -79,7 +79,7 @@ fn empty() { let f = "asm/empty.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -88,7 +88,7 @@ fn single_operation() { let f = "asm/single_operation.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -97,7 +97,7 @@ fn empty_vm() { let f = "asm/empty_vm.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -106,7 +106,7 @@ fn vm_to_block_unique_interface() { let f = "asm/vm_to_block_unique_interface.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); // currently starky leads to // thread 'functional_instructions' has overflowed its stack // leave it out until that's fixed @@ -118,7 +118,7 @@ fn vm_to_block_to_block() { let f = "asm/vm_to_block_to_block.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); } #[test] @@ -126,7 +126,7 @@ fn block_to_block() { let f = "asm/block_to_block.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -135,7 +135,7 @@ fn vm_to_block_multiple_interfaces() { let f = "asm/vm_to_block_multiple_interfaces.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -144,7 +144,7 @@ fn vm_to_vm() { let f = "asm/vm_to_vm.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -153,7 +153,7 @@ fn vm_to_vm_dynamic_trace_length() { let f = "asm/vm_to_vm_dynamic_trace_length.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -162,7 +162,7 @@ fn vm_to_vm_to_block() { let f = "asm/vm_to_vm_to_block.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -171,7 +171,7 @@ fn vm_to_block_array() { let f = "asm/vm_to_block_array.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -180,7 +180,7 @@ fn vm_to_vm_to_vm() { let f = "asm/vm_to_vm_to_vm.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -188,7 +188,7 @@ fn vm_to_vm_to_vm() { fn test_mem_read_write() { let f = "asm/mem_read_write.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -196,7 +196,7 @@ fn test_mem_read_write() { fn test_mem_read_write_no_memory_accesses() { let f = "asm/mem_read_write_no_memory_accesses.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -204,7 +204,7 @@ fn test_mem_read_write_no_memory_accesses() { fn test_mem_read_write_with_bootloader() { let f = "asm/mem_read_write_with_bootloader.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -212,7 +212,7 @@ fn test_mem_read_write_with_bootloader() { fn test_mem_read_write_large_diffs() { let f = "asm/mem_read_write_large_diffs.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -221,7 +221,7 @@ fn test_multi_assign() { let f = "asm/multi_assign.asm"; let i = [7]; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, slice_to_vec(&i)); } @@ -230,7 +230,7 @@ fn test_multi_return() { let f = "asm/multi_return.asm"; let i = []; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); gen_estark_proof(f, Default::default()); } @@ -255,7 +255,7 @@ fn test_bit_access() { let f = "asm/bit_access.asm"; let i = [20]; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); // currently starky leads to // thread 'functional_instructions' has overflowed its stack // leave it out until that's fixed @@ -266,7 +266,7 @@ fn test_bit_access() { fn test_sqrt() { let f = "asm/sqrt.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -275,7 +275,7 @@ fn functional_instructions() { let f = "asm/functional_instructions.asm"; let i = [20]; verify_asm::(f, slice_to_vec(&i)); - gen_halo2_proof(f, slice_to_vec(&i)); + test_halo2(f, slice_to_vec(&i)); // currently starky leads to // thread 'functional_instructions' has overflowed its stack // leave it out until that's fixed @@ -286,7 +286,7 @@ fn functional_instructions() { fn full_pil_constant() { let f = "asm/full_pil_constant.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -294,7 +294,7 @@ fn full_pil_constant() { fn intermediate() { let f = "asm/intermediate.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -302,7 +302,7 @@ fn intermediate() { fn intermediate_nested() { let f = "asm/intermediate_nested.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -310,7 +310,7 @@ fn intermediate_nested() { fn pil_at_module_level() { let f = "asm/pil_at_module_level.asm"; verify_asm::(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -324,7 +324,7 @@ mod book { let i = [0]; verify_asm::(file, slice_to_vec(&i)); - gen_halo2_proof(file, slice_to_vec(&i)); + test_halo2(file, slice_to_vec(&i)); gen_estark_proof(file, slice_to_vec(&i)); } diff --git a/pipeline/tests/pil.rs b/pipeline/tests/pil.rs index a15cd44a5..8004fbc48 100644 --- a/pipeline/tests/pil.rs +++ b/pipeline/tests/pil.rs @@ -1,5 +1,5 @@ use powdr_number::GoldilocksField; -use powdr_pipeline::test_util::{gen_estark_proof, gen_halo2_proof, verify_test_file}; +use powdr_pipeline::test_util::{gen_estark_proof, test_halo2, verify_test_file}; use test_log::test; pub fn verify_pil(file_name: &str, inputs: Vec) { @@ -10,7 +10,7 @@ pub fn verify_pil(file_name: &str, inputs: Vec) { fn test_fibonacci() { let f = "pil/fibonacci.pil"; verify_pil(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -18,7 +18,7 @@ fn test_fibonacci() { fn test_constant_in_identity() { let f = "pil/constant_in_identity.pil"; verify_pil(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -26,7 +26,7 @@ fn test_constant_in_identity() { fn fib_arrays() { let f = "pil/fib_arrays.pil"; verify_pil(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -132,7 +132,7 @@ fn test_block_lookup_or() { fn test_halo_without_lookup() { let f = "pil/halo_without_lookup.pil"; verify_pil(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -178,7 +178,7 @@ fn conditional_fixed_constraints() { fn referencing_arrays() { let f = "pil/referencing_array.pil"; verify_pil(f, Default::default()); - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); gen_estark_proof(f, Default::default()); } @@ -188,7 +188,7 @@ mod book { fn run_book_test(file: &str) { verify_pil(file, Default::default()); - gen_halo2_proof(file, Default::default()); + test_halo2(file, Default::default()); gen_estark_proof(file, Default::default()); } diff --git a/pipeline/tests/powdr_std.rs b/pipeline/tests/powdr_std.rs index 8ebc249d5..b9d931473 100644 --- a/pipeline/tests/powdr_std.rs +++ b/pipeline/tests/powdr_std.rs @@ -1,7 +1,8 @@ use powdr_number::GoldilocksField; use powdr_pipeline::test_util::{ - evaluate_integer_function, gen_estark_proof, gen_halo2_proof, std_analyzed, verify_test_file, + evaluate_integer_function, gen_estark_proof, gen_halo2_proof, std_analyzed, test_halo2, + verify_test_file, }; use test_log::test; @@ -10,6 +11,11 @@ use num_traits::Num; #[test] fn poseidon_bn254_test() { let f = "std/poseidon_bn254_test.asm"; + test_halo2(f, Default::default()); + + // `test_halo2` only does a mock proof in the PR tests. + // This makes sure we test the whole proof generation for one example + // file even in the PR tests. gen_halo2_proof(f, Default::default()); } @@ -23,7 +29,7 @@ fn poseidon_gl_test() { #[test] fn split_bn254_test() { let f = "std/split_bn254_test.asm"; - gen_halo2_proof(f, Default::default()); + test_halo2(f, Default::default()); } #[test] @@ -40,7 +46,7 @@ fn arith_test() { verify_test_file::(f, Default::default(), vec![]); gen_estark_proof(f, Default::default()); // Halo2 test runs out of memory on CI - // gen_halo2_proof(f, Default::default()); + // test_halo2(f, Default::default()); } #[test]