mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-01-10 07:07:59 -05:00
Default pipeline with backend arguments (#2557)
Depends on #2535 and standardizes the backend argument in `Pipeline`: 1. `backend` now defaults to `BackendType::Mock` when constructing the pipeline. 2. For tests that only computes up to witgen without actually running the backend, `with_backend_factory` API is used instead of `with_backend`. - If the test doesn't care which backend the witgen is computed for, NO `with_backend_factory` is called, because the default pipeline already defaults to `BackendType::Mock`. - Note that `with_backend_factory(backend)` is equivalent to `with_backend(backend, None)`. 3. For tests that generate proof, `with_backend` API is used.
This commit is contained in:
@@ -17,9 +17,10 @@ use powdr_number::{DegreeType, FieldElement};
|
||||
use std::{collections::BTreeMap, io, path::PathBuf, sync::Arc};
|
||||
use strum::{Display, EnumString, EnumVariantNames};
|
||||
|
||||
#[derive(Clone, EnumString, EnumVariantNames, Display, Copy)]
|
||||
#[derive(Clone, Default, EnumString, EnumVariantNames, Display, Copy)]
|
||||
pub enum BackendType {
|
||||
#[strum(serialize = "mock")]
|
||||
#[default]
|
||||
Mock,
|
||||
#[cfg(feature = "halo2")]
|
||||
#[strum(serialize = "halo2")]
|
||||
|
||||
@@ -426,7 +426,7 @@ fn execute<F: FieldElement>(
|
||||
) -> Result<(), Vec<String>> {
|
||||
let mut pipeline = Pipeline::<F>::default()
|
||||
.from_asm_file(file_name.to_path_buf())
|
||||
.with_backend(backend, None)
|
||||
.with_backend_factory(backend)
|
||||
.with_prover_inputs(inputs)
|
||||
.with_output(output_dir.into(), true);
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use ::powdr_pipeline::Pipeline;
|
||||
use powdr_backend::BackendType;
|
||||
use powdr_number::GoldilocksField;
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
@@ -11,10 +10,8 @@ fn jit_witgen_benchmark(c: &mut Criterion) {
|
||||
group.sample_size(10);
|
||||
|
||||
// Poseidon benchmark
|
||||
let mut pipeline = Pipeline::<T>::default()
|
||||
.from_file("../test_data/std/poseidon_benchmark.asm".into())
|
||||
.with_backend(BackendType::Mock, None);
|
||||
// this `jit_witgen_benchmark` function will also require backend type
|
||||
let mut pipeline =
|
||||
Pipeline::<T>::default().from_file("../test_data/std/poseidon_benchmark.asm".into());
|
||||
pipeline.compute_backend_tuned_pil().unwrap();
|
||||
pipeline.compute_fixed_cols().unwrap();
|
||||
|
||||
|
||||
@@ -105,8 +105,8 @@ struct Arguments<T: FieldElement> {
|
||||
external_witness_values: Vec<(String, Vec<T>)>,
|
||||
/// Callback for queries for witness generation.
|
||||
query_callback: Option<Arc<dyn QueryCallback<T>>>,
|
||||
/// Backend to use for proving. If None, proving will fail.
|
||||
backend: Option<BackendType>,
|
||||
/// Backend to use for proving. Defaults to Mock Backend.
|
||||
backend: BackendType,
|
||||
/// Backend options
|
||||
backend_options: BackendOptions,
|
||||
/// Linker options
|
||||
@@ -365,19 +365,17 @@ impl<T: FieldElement> Pipeline<T> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_backend(mut self, backend: BackendType, options: Option<BackendOptions>) -> Self {
|
||||
self.arguments.backend = Some(backend);
|
||||
self.arguments.backend_options = options.unwrap_or_default();
|
||||
pub fn with_backend_factory(mut self, backend: BackendType) -> Self {
|
||||
self.arguments.backend = backend;
|
||||
self.artifact.backend = None;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_backend_if_none(&mut self, backend: BackendType, options: Option<BackendOptions>) {
|
||||
if self.arguments.backend.is_none() {
|
||||
self.arguments.backend = Some(backend);
|
||||
self.arguments.backend_options = options.unwrap_or_default();
|
||||
self.artifact.backend = None;
|
||||
}
|
||||
pub fn with_backend(mut self, backend: BackendType, options: Option<BackendOptions>) -> Self {
|
||||
self.arguments.backend = backend;
|
||||
self.arguments.backend_options = options.unwrap_or_default();
|
||||
self.artifact.backend = None;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_setup_file(mut self, setup_file: Option<PathBuf>) -> Self {
|
||||
@@ -1002,7 +1000,7 @@ impl<T: FieldElement> Pipeline<T> {
|
||||
|
||||
self.compute_optimized_pil()?;
|
||||
|
||||
let backend_type = self.arguments.backend.expect("no backend selected!");
|
||||
let backend_type = self.arguments.backend;
|
||||
|
||||
// If backend option is set, compute and cache the backend-tuned pil in artifacts and return backend-tuned pil.
|
||||
let optimized_pil = self.artifact.optimized_pil.clone().unwrap();
|
||||
@@ -1146,7 +1144,7 @@ impl<T: FieldElement> Pipeline<T> {
|
||||
let pil = self.compute_backend_tuned_pil()?; // will panic if backend type is not set yet
|
||||
let fixed_cols = self.compute_fixed_cols()?;
|
||||
|
||||
let backend = self.arguments.backend.expect("no backend selected!");
|
||||
let backend = self.arguments.backend;
|
||||
let factory = backend.factory::<T>();
|
||||
|
||||
// Opens the setup file, if set.
|
||||
|
||||
@@ -172,7 +172,7 @@ fn block_to_block_empty_submachine() {
|
||||
.iter()
|
||||
.for_each(|backend| {
|
||||
let mut pipeline = make_simple_prepared_pipeline::<GoldilocksField>(f, LinkerMode::Bus)
|
||||
.with_backend(*backend, None);
|
||||
.with_backend_factory(*backend);
|
||||
let witness_and_publics = pipeline.compute_witness().unwrap();
|
||||
let arith_size = witness_and_publics
|
||||
.0
|
||||
@@ -313,7 +313,7 @@ fn dynamic_vadcop() {
|
||||
// Witness generation require backend to be known
|
||||
for backend in [BackendType::Mock, BackendType::Plonky3].iter() {
|
||||
let mut pipeline = make_simple_prepared_pipeline::<GoldilocksField>(f, LinkerMode::Bus)
|
||||
.with_backend(*backend, None);
|
||||
.with_backend_factory(*backend);
|
||||
let witness = &pipeline.compute_witness().unwrap().0;
|
||||
let witness_by_name = witness
|
||||
.iter()
|
||||
@@ -890,7 +890,6 @@ fn expand_fixed_jit() {
|
||||
let file_name = "asm/expand_fixed.asm";
|
||||
|
||||
let mut pipeline = Pipeline::<GoldilocksField>::default()
|
||||
.with_backend(BackendType::Mock, None)
|
||||
.with_tmp_output()
|
||||
.from_file(resolve_test_file(file_name));
|
||||
let pil = pipeline.compute_backend_tuned_pil().unwrap();
|
||||
|
||||
@@ -5,7 +5,6 @@ use test_log::test;
|
||||
|
||||
fn run_witgen_pil<T: FieldElement>(pil: &str) -> Columns<T> {
|
||||
Pipeline::default()
|
||||
.with_backend(powdr_pipeline::BackendType::Mock, None)
|
||||
.from_pil_string(pil.to_string())
|
||||
.compute_witness()
|
||||
.unwrap()
|
||||
|
||||
@@ -16,8 +16,7 @@ fn fibonacci_wrong_initialization() {
|
||||
// Initializes y with 2 instead of 1
|
||||
// -> fails `ISLAST * (y' - 1) = 0;` in the last row
|
||||
let f = "pil/fibonacci.pil";
|
||||
let pipeline = make_simple_prepared_pipeline::<GoldilocksField>(f, LinkerMode::Bus)
|
||||
.with_backend(powdr_backend::BackendType::Mock, None);
|
||||
let pipeline = make_simple_prepared_pipeline::<GoldilocksField>(f, LinkerMode::Bus);
|
||||
let pipeline = pipeline.set_witness(vec![
|
||||
// This would be the correct witness:
|
||||
// col("Fibonacci::x", [1, 1, 2, 3]),
|
||||
@@ -36,8 +35,7 @@ fn block_to_block_wrong_connection() {
|
||||
// So, if we multiply all columns with a constant, the constraint
|
||||
// should still be satisfied, but the connection argument should fail.
|
||||
let f = "asm/block_to_block.asm";
|
||||
let mut pipeline = make_simple_prepared_pipeline::<GoldilocksField>(f, LinkerMode::Bus)
|
||||
.with_backend(powdr_backend::BackendType::Mock, None);
|
||||
let mut pipeline = make_simple_prepared_pipeline::<GoldilocksField>(f, LinkerMode::Bus);
|
||||
|
||||
pipeline.compute_witness().unwrap();
|
||||
|
||||
|
||||
@@ -110,12 +110,9 @@ fn fibonacci() {
|
||||
fn fibonacci_with_public() {
|
||||
// Public references are not supported by the backends yet, but we can test witness generation.
|
||||
let f = "pil/fibonacci_with_public.pil";
|
||||
let pipeline: Pipeline<GoldilocksField> =
|
||||
let mut pipeline: Pipeline<GoldilocksField> =
|
||||
make_prepared_pipeline(f, vec![], vec![], LinkerMode::Bus);
|
||||
pipeline
|
||||
.with_backend(powdr_backend::BackendType::Mock, None)
|
||||
.compute_witness()
|
||||
.unwrap();
|
||||
pipeline.compute_witness().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use ::powdr_pipeline::Pipeline;
|
||||
use powdr_backend::BackendType;
|
||||
use powdr_number::GoldilocksField;
|
||||
|
||||
use powdr_riscv::{compile_rust_crate_to_riscv, elf, CompilerOptions};
|
||||
@@ -19,9 +18,7 @@ fn executor_benchmark(c: &mut Criterion) {
|
||||
compile_rust_crate_to_riscv("./tests/riscv_data/keccak/Cargo.toml", &tmp_dir, None);
|
||||
let options = CompilerOptions::new_gl();
|
||||
let contents = elf::translate(&executable, options);
|
||||
let mut pipeline = Pipeline::<T>::default()
|
||||
.from_asm_string(contents, None)
|
||||
.with_backend(BackendType::Mock, None);
|
||||
let mut pipeline = Pipeline::<T>::default().from_asm_string(contents, None);
|
||||
pipeline.compute_backend_tuned_pil().unwrap();
|
||||
pipeline.compute_fixed_cols().unwrap();
|
||||
|
||||
|
||||
@@ -59,8 +59,6 @@ pub fn rust_continuations<F: FieldElement, PipelineCallback, E>(
|
||||
where
|
||||
PipelineCallback: Fn(&mut Pipeline<F>) -> Result<(), E>,
|
||||
{
|
||||
pipeline.with_backend_if_none(powdr_pipeline::BackendType::Mock, None);
|
||||
|
||||
let bootloader_inputs = dry_run_result.bootloader_inputs;
|
||||
let num_chunks = bootloader_inputs.len();
|
||||
|
||||
@@ -339,8 +337,6 @@ pub fn rust_continuations_dry_run<F: FieldElement>(
|
||||
pipeline: &mut Pipeline<F>,
|
||||
profiler_opt: Option<ProfilerOptions>,
|
||||
) -> DryRunResult<F> {
|
||||
pipeline.with_backend_if_none(powdr_pipeline::BackendType::Mock, None);
|
||||
|
||||
let field = F::known_field().unwrap();
|
||||
|
||||
// All inputs for all chunks.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use mktemp::Temp;
|
||||
use powdr_backend::BackendType;
|
||||
use powdr_number::{BabyBearField, FieldElement, GoldilocksField, KnownField, KoalaBearField};
|
||||
use powdr_pipeline::{
|
||||
test_util::{test_mock_backend, test_plonky3_pipeline},
|
||||
@@ -24,8 +23,7 @@ pub fn verify_riscv_asm_string<T: FieldElement, S: serde::Serialize + Send + Syn
|
||||
let mut pipeline = Pipeline::default()
|
||||
.with_prover_inputs(inputs.to_vec())
|
||||
.with_output(temp_dir.to_path_buf(), true)
|
||||
.from_asm_string(contents.to_string(), Some(PathBuf::from(file_name)))
|
||||
.with_backend(BackendType::Mock, None);
|
||||
.from_asm_string(contents.to_string(), Some(PathBuf::from(file_name)));
|
||||
|
||||
if let Some(data) = data {
|
||||
pipeline = pipeline.add_data_vec(data);
|
||||
|
||||
@@ -427,7 +427,6 @@ fn read_slice_with_options<T: FieldElement>(options: CompilerOptions) {
|
||||
|
||||
let mut pipeline = Pipeline::<T>::default()
|
||||
.from_asm_string(powdr_asm, Some(PathBuf::from(case)))
|
||||
.with_backend(powdr_backend::BackendType::Mock, None)
|
||||
.with_prover_inputs(vec![answer.into()])
|
||||
.with_prover_dict_inputs(d);
|
||||
|
||||
@@ -612,7 +611,6 @@ fn output_syscall_with_options<T: FieldElement>(options: CompilerOptions) {
|
||||
|
||||
let inputs = vec![1u32, 2, 3].into_iter().map(T::from).collect();
|
||||
let mut pipeline = Pipeline::<T>::default()
|
||||
.with_backend(powdr_backend::BackendType::Mock, None)
|
||||
.from_asm_string(powdr_asm, Some(PathBuf::from(case)))
|
||||
.with_prover_inputs(inputs);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user