mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-01-10 10:17:55 -05:00
Remove support for running stand-alone rust files (#1220)
Change both tests and CLI to only support running rust crates
This commit is contained in:
@@ -9,36 +9,13 @@ A [RISCV](https://riscv.org/technical/specifications/) frontend for powdr is alr
|
||||
rustup target add riscv32imac-unknown-none-elf
|
||||
# Run the compiler. It will generate files in /tmp/.
|
||||
# -i specifies the prover witness input (see below)
|
||||
powdr rust riscv/tests/riscv_data/sum.rs -o /tmp -f -i 10,2,4,6
|
||||
powdr rust riscv/tests/riscv_data/sum -o /tmp -f -i 10,2,4,6
|
||||
```
|
||||
|
||||
The following example Rust file verifies that a supplied list of integers sums up to a specified value.
|
||||
Note that this is the full and only input file you need for the whole process!
|
||||
The example Rust code verifies that a supplied list of integers sums up to a specified value.
|
||||
|
||||
```rust
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use runtime::get_prover_input;
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() {
|
||||
// This is the sum claimed by the prover.
|
||||
let proposed_sum = get_prover_input(0);
|
||||
// The number of integers we want to sum.
|
||||
let len = get_prover_input(1) as usize;
|
||||
// Read the numbers from the prover and store them
|
||||
// in a vector.
|
||||
let data: Vec<_> = (2..(len + 2))
|
||||
.map(|idx| get_prover_input(idx as u32))
|
||||
.collect();
|
||||
// Compute the sum.
|
||||
let sum: u32 = data.iter().sum();
|
||||
// Check that our sum matches the prover's.
|
||||
assert_eq!(sum, proposed_sum);
|
||||
}
|
||||
{{#include ../../../riscv/tests/riscv_data/sum/src/lib.rs}}
|
||||
```
|
||||
|
||||
The function `get_prover_input` reads a number from the list supplied with `-i`.
|
||||
|
||||
@@ -154,7 +154,7 @@ enum Commands {
|
||||
/// and finally to PIL and generates fixed and witness columns.
|
||||
/// Needs `rustup target add riscv32imac-unknown-none-elf`.
|
||||
Rust {
|
||||
/// Input file (rust source file) or directory (containing a crate).
|
||||
/// input rust code, points to a crate dir or its Cargo.toml file
|
||||
file: String,
|
||||
|
||||
/// The field to use
|
||||
|
||||
@@ -4,8 +4,8 @@ use powdr_number::{BigInt, FieldElement, GoldilocksField};
|
||||
|
||||
use powdr_pipeline::test_util::{evaluate_integer_function, std_analyzed};
|
||||
use powdr_riscv::{
|
||||
compile_rust_crate_to_riscv_asm, compile_rust_to_riscv_asm, compiler,
|
||||
continuations::bootloader::default_input, CoProcessors,
|
||||
compile_rust_crate_to_riscv_asm, compiler, continuations::bootloader::default_input,
|
||||
CoProcessors,
|
||||
};
|
||||
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
@@ -40,8 +40,10 @@ fn executor_benchmark(c: &mut Criterion) {
|
||||
group.bench_function("keccak", |b| b.iter(|| run_witgen(&pil, &fixed_cols, &[])));
|
||||
|
||||
// The first chunk of `many_chunks`, with Poseidon co-processor & bootloader
|
||||
let riscv_asm_files =
|
||||
compile_rust_to_riscv_asm("../riscv/tests/riscv_data/many_chunks.rs", &tmp_dir);
|
||||
let riscv_asm_files = compile_rust_crate_to_riscv_asm(
|
||||
"../riscv/tests/riscv_data/many_chunks/Cargo.toml",
|
||||
&tmp_dir,
|
||||
);
|
||||
let contents =
|
||||
compiler::compile::<T>(riscv_asm_files, &CoProcessors::base().with_poseidon(), true);
|
||||
let mut pipeline = Pipeline::<T>::default().from_asm_string(contents, None);
|
||||
|
||||
@@ -48,7 +48,7 @@ pub fn compile_rust<T: FieldElement>(
|
||||
} else if fs::metadata(file_name).unwrap().is_dir() {
|
||||
compile_rust_crate_to_riscv_asm(&format!("{file_name}/Cargo.toml"), output_dir)
|
||||
} else {
|
||||
compile_rust_to_riscv_asm(file_name, output_dir)
|
||||
panic!("input must be a crate directory or `Cargo.toml` file");
|
||||
};
|
||||
if !output_dir.exists() {
|
||||
fs::create_dir_all(output_dir).unwrap()
|
||||
@@ -138,37 +138,6 @@ pub fn compile_riscv_asm<T: FieldElement>(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn compile_rust_to_riscv_asm(input_file: &str, output_dir: &Path) -> BTreeMap<String, String> {
|
||||
let crate_dir = Temp::new_dir().unwrap();
|
||||
// TODO is there no easier way?
|
||||
let mut cargo_file = crate_dir.clone();
|
||||
cargo_file.push("Cargo.toml");
|
||||
|
||||
fs::write(
|
||||
&cargo_file,
|
||||
format!(
|
||||
r#"[package]
|
||||
name = "{}"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = {{ git = "https://github.com/powdr-labs/powdr", branch = "main" }}
|
||||
"#,
|
||||
Path::new(input_file).file_stem().unwrap().to_str().unwrap()
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut src_file = crate_dir.clone();
|
||||
src_file.push("src");
|
||||
fs::create_dir(&src_file).unwrap();
|
||||
src_file.push("lib.rs");
|
||||
fs::write(src_file, fs::read_to_string(input_file).unwrap()).unwrap();
|
||||
|
||||
compile_rust_crate_to_riscv_asm(cargo_file.to_str().unwrap(), output_dir)
|
||||
}
|
||||
|
||||
macro_rules! as_ref [
|
||||
($t:ty; $($x:expr),* $(,)?) => {
|
||||
[$(AsRef::<$t>::as_ref(&$x)),+]
|
||||
|
||||
@@ -4,7 +4,7 @@ use common::verify_riscv_asm_string;
|
||||
use mktemp::Temp;
|
||||
use powdr_backend::BackendType;
|
||||
use powdr_number::{FieldElement, GoldilocksField};
|
||||
use powdr_pipeline::{test_util::verify_asm_string, verify::verify, Pipeline};
|
||||
use powdr_pipeline::{verify::verify, Pipeline};
|
||||
use std::path::PathBuf;
|
||||
use test_log::test;
|
||||
|
||||
@@ -13,14 +13,15 @@ use powdr_riscv::{
|
||||
CoProcessors,
|
||||
};
|
||||
|
||||
/// Compiles and runs a rust file with continuations, runs the full
|
||||
/// Compiles and runs a rust program with continuations, runs the full
|
||||
/// witness generation & verifies it using Pilcom.
|
||||
pub fn test_continuations(case: &str) {
|
||||
let rust_file = format!("{case}.rs");
|
||||
let coprocessors = CoProcessors::base().with_poseidon();
|
||||
let temp_dir = Temp::new_dir().unwrap();
|
||||
let riscv_asm =
|
||||
powdr_riscv::compile_rust_to_riscv_asm(&format!("tests/riscv_data/{rust_file}"), &temp_dir);
|
||||
let riscv_asm = powdr_riscv::compile_rust_crate_to_riscv_asm(
|
||||
&format!("tests/riscv_data/{case}/Cargo.toml"),
|
||||
&temp_dir,
|
||||
);
|
||||
let powdr_asm =
|
||||
powdr_riscv::compiler::compile::<GoldilocksField>(riscv_asm, &coprocessors, true);
|
||||
|
||||
@@ -28,7 +29,7 @@ pub fn test_continuations(case: &str) {
|
||||
let tmp_dir = mktemp::Temp::new_dir().unwrap();
|
||||
|
||||
let mut pipeline = Pipeline::<GoldilocksField>::default()
|
||||
.from_asm_string(powdr_asm.clone(), Some(PathBuf::from(&rust_file)))
|
||||
.from_asm_string(powdr_asm.clone(), Some(PathBuf::from(&case)))
|
||||
.with_prover_inputs(Default::default())
|
||||
.with_output(tmp_dir.to_path_buf(), false);
|
||||
let pipeline_callback = |pipeline: Pipeline<GoldilocksField>| -> Result<(), ()> {
|
||||
@@ -46,22 +47,22 @@ pub fn test_continuations(case: &str) {
|
||||
#[test]
|
||||
#[ignore = "Too slow"]
|
||||
fn test_trivial() {
|
||||
let case = "trivial.rs";
|
||||
verify_riscv_file(case, Default::default(), &CoProcessors::base())
|
||||
let case = "trivial";
|
||||
verify_riscv_crate(case, Default::default(), &CoProcessors::base())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "Too slow"]
|
||||
fn test_zero_with_values() {
|
||||
let case = "zero_with_values.rs";
|
||||
verify_riscv_file(case, Default::default(), &CoProcessors::base())
|
||||
let case = "zero_with_values";
|
||||
verify_riscv_crate(case, Default::default(), &CoProcessors::base())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "Too slow"]
|
||||
fn test_poseidon_gl() {
|
||||
let case = "poseidon_gl_via_coprocessor.rs";
|
||||
verify_riscv_file(
|
||||
let case = "poseidon_gl_via_coprocessor";
|
||||
verify_riscv_crate(
|
||||
case,
|
||||
Default::default(),
|
||||
&CoProcessors::base().with_poseidon(),
|
||||
@@ -71,8 +72,8 @@ fn test_poseidon_gl() {
|
||||
#[test]
|
||||
#[ignore = "Too slow"]
|
||||
fn test_sum() {
|
||||
let case = "sum.rs";
|
||||
verify_riscv_file(
|
||||
let case = "sum";
|
||||
verify_riscv_crate(
|
||||
case,
|
||||
[16, 4, 1, 2, 8, 5].iter().map(|&x| x.into()).collect(),
|
||||
&CoProcessors::base(),
|
||||
@@ -82,8 +83,8 @@ fn test_sum() {
|
||||
#[test]
|
||||
#[ignore = "Too slow"]
|
||||
fn test_byte_access() {
|
||||
let case = "byte_access.rs";
|
||||
verify_riscv_file(
|
||||
let case = "byte_access";
|
||||
verify_riscv_crate(
|
||||
case,
|
||||
[0, 104, 707].iter().map(|&x| x.into()).collect(),
|
||||
&CoProcessors::base(),
|
||||
@@ -93,13 +94,13 @@ fn test_byte_access() {
|
||||
#[test]
|
||||
#[ignore = "Too slow"]
|
||||
fn test_double_word() {
|
||||
let case = "double_word.rs";
|
||||
let case = "double_word";
|
||||
let a0 = 0x01000000u32;
|
||||
let a1 = 0x010000ffu32;
|
||||
let b0 = 0xf100b00fu32;
|
||||
let b1 = 0x0100f0f0u32;
|
||||
let c = ((a0 as u64) | ((a1 as u64) << 32)).wrapping_mul((b0 as u64) | ((b1 as u64) << 32));
|
||||
verify_riscv_file(
|
||||
verify_riscv_crate(
|
||||
case,
|
||||
[
|
||||
a0,
|
||||
@@ -197,22 +198,26 @@ fn test_sum_serde() {
|
||||
|
||||
#[test]
|
||||
#[ignore = "Too slow"]
|
||||
#[should_panic(expected = "Witness generation failed.")]
|
||||
#[should_panic(
|
||||
expected = "called `Result::unwrap()` on an `Err` value: \"Error accessing prover inputs: Index 0 out of bounds 0\""
|
||||
)]
|
||||
fn test_print() {
|
||||
let case = "print.rs";
|
||||
verify_file(case, Default::default(), &CoProcessors::base());
|
||||
let case = "print";
|
||||
verify_riscv_crate(case, Default::default(), &CoProcessors::base());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_many_chunks_dry() {
|
||||
// Compiles and runs the many_chunks.rs example with continuations, just computing
|
||||
// Compiles and runs the many_chunks example with continuations, just computing
|
||||
// and validating the bootloader inputs.
|
||||
// Doesn't do a full witness generation, verification, or proving.
|
||||
let case = "many_chunks.rs";
|
||||
let case = "many_chunks";
|
||||
let coprocessors = CoProcessors::base().with_poseidon();
|
||||
let temp_dir = Temp::new_dir().unwrap();
|
||||
let riscv_asm =
|
||||
powdr_riscv::compile_rust_to_riscv_asm(&format!("tests/riscv_data/{case}"), &temp_dir);
|
||||
let riscv_asm = powdr_riscv::compile_rust_crate_to_riscv_asm(
|
||||
&format!("tests/riscv_data/{case}/Cargo.toml"),
|
||||
&temp_dir,
|
||||
);
|
||||
let powdr_asm =
|
||||
powdr_riscv::compiler::compile::<GoldilocksField>(riscv_asm, &coprocessors, true);
|
||||
|
||||
@@ -234,36 +239,6 @@ fn test_many_chunks_memory() {
|
||||
test_continuations("many_chunks_memory")
|
||||
}
|
||||
|
||||
fn verify_file(case: &str, inputs: Vec<GoldilocksField>, coprocessors: &CoProcessors) {
|
||||
let temp_dir = Temp::new_dir().unwrap();
|
||||
let riscv_asm =
|
||||
powdr_riscv::compile_rust_to_riscv_asm(&format!("tests/riscv_data/{case}"), &temp_dir);
|
||||
let powdr_asm =
|
||||
powdr_riscv::compiler::compile::<GoldilocksField>(riscv_asm, coprocessors, false);
|
||||
|
||||
verify_asm_string::<()>(&format!("{case}.asm"), &powdr_asm, inputs, vec![], None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "Too slow"]
|
||||
#[should_panic(
|
||||
expected = "called `Result::unwrap()` on an `Err` value: \"Error accessing prover inputs: Index 0 out of bounds 0\""
|
||||
)]
|
||||
fn test_print_rv32_executor() {
|
||||
let case = "print.rs";
|
||||
verify_riscv_file(case, Default::default(), &CoProcessors::base());
|
||||
}
|
||||
|
||||
fn verify_riscv_file(case: &str, inputs: Vec<GoldilocksField>, coprocessors: &CoProcessors) {
|
||||
let temp_dir = Temp::new_dir().unwrap();
|
||||
let riscv_asm =
|
||||
powdr_riscv::compile_rust_to_riscv_asm(&format!("tests/riscv_data/{case}"), &temp_dir);
|
||||
let powdr_asm =
|
||||
powdr_riscv::compiler::compile::<GoldilocksField>(riscv_asm, coprocessors, false);
|
||||
|
||||
verify_riscv_asm_string::<()>(&format!("{case}.asm"), &powdr_asm, inputs, None);
|
||||
}
|
||||
|
||||
fn verify_riscv_crate(case: &str, inputs: Vec<GoldilocksField>, coprocessors: &CoProcessors) {
|
||||
let powdr_asm = compile_riscv_crate::<GoldilocksField>(case, coprocessors);
|
||||
|
||||
|
||||
9
riscv/tests/riscv_data/byte_access/Cargo.toml
Normal file
9
riscv/tests/riscv_data/byte_access/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "byte_access"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = { path = "../../../../riscv-runtime" }
|
||||
|
||||
[workspace]
|
||||
4
riscv/tests/riscv_data/byte_access/rust-toolchain.toml
Normal file
4
riscv/tests/riscv_data/byte_access/rust-toolchain.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-02-01"
|
||||
targets = ["riscv32imac-unknown-none-elf"]
|
||||
profile = "minimal"
|
||||
9
riscv/tests/riscv_data/double_word/Cargo.toml
Normal file
9
riscv/tests/riscv_data/double_word/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "double_word"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = { path = "../../../../riscv-runtime" }
|
||||
|
||||
[workspace]
|
||||
4
riscv/tests/riscv_data/double_word/rust-toolchain.toml
Normal file
4
riscv/tests/riscv_data/double_word/rust-toolchain.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-02-01"
|
||||
targets = ["riscv32imac-unknown-none-elf"]
|
||||
profile = "minimal"
|
||||
9
riscv/tests/riscv_data/many_chunks/Cargo.toml
Normal file
9
riscv/tests/riscv_data/many_chunks/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "many_chunks"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = { path = "../../../../riscv-runtime" }
|
||||
|
||||
[workspace]
|
||||
4
riscv/tests/riscv_data/many_chunks/rust-toolchain.toml
Normal file
4
riscv/tests/riscv_data/many_chunks/rust-toolchain.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-02-01"
|
||||
targets = ["riscv32imac-unknown-none-elf"]
|
||||
profile = "minimal"
|
||||
9
riscv/tests/riscv_data/many_chunks_memory/Cargo.toml
Normal file
9
riscv/tests/riscv_data/many_chunks_memory/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "many_chunks_memory"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = { path = "../../../../riscv-runtime" }
|
||||
|
||||
[workspace]
|
||||
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-02-01"
|
||||
targets = ["riscv32imac-unknown-none-elf"]
|
||||
profile = "minimal"
|
||||
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "poseidon_gl_via_coprocessor"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = { path = "../../../../riscv-runtime" }
|
||||
|
||||
[workspace]
|
||||
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-02-01"
|
||||
targets = ["riscv32imac-unknown-none-elf"]
|
||||
profile = "minimal"
|
||||
9
riscv/tests/riscv_data/print/Cargo.toml
Normal file
9
riscv/tests/riscv_data/print/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "print"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = { path = "../../../../riscv-runtime" }
|
||||
|
||||
[workspace]
|
||||
4
riscv/tests/riscv_data/print/rust-toolchain.toml
Normal file
4
riscv/tests/riscv_data/print/rust-toolchain.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-02-01"
|
||||
targets = ["riscv32imac-unknown-none-elf"]
|
||||
profile = "minimal"
|
||||
9
riscv/tests/riscv_data/sum/Cargo.toml
Normal file
9
riscv/tests/riscv_data/sum/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "sum"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = { path = "../../../../riscv-runtime" }
|
||||
|
||||
[workspace]
|
||||
4
riscv/tests/riscv_data/sum/rust-toolchain.toml
Normal file
4
riscv/tests/riscv_data/sum/rust-toolchain.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-02-01"
|
||||
targets = ["riscv32imac-unknown-none-elf"]
|
||||
profile = "minimal"
|
||||
@@ -7,11 +7,17 @@ use powdr_riscv_runtime::get_prover_input;
|
||||
|
||||
#[no_mangle]
|
||||
pub fn main() {
|
||||
// This is the sum claimed by the prover.
|
||||
let proposed_sum = get_prover_input(0);
|
||||
// The number of integers we want to sum.
|
||||
let len = get_prover_input(1) as usize;
|
||||
// Read the numbers from the prover and store them
|
||||
// in a vector.
|
||||
let data: Vec<_> = (2..(len + 2))
|
||||
.map(|idx| get_prover_input(idx as u32))
|
||||
.collect();
|
||||
// Compute the sum.
|
||||
let sum: u32 = data.iter().sum();
|
||||
// Check that our sum matches the prover's.
|
||||
assert_eq!(sum, proposed_sum);
|
||||
}
|
||||
9
riscv/tests/riscv_data/trivial/Cargo.toml
Normal file
9
riscv/tests/riscv_data/trivial/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "trivial"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = { path = "../../../../riscv-runtime" }
|
||||
|
||||
[workspace]
|
||||
4
riscv/tests/riscv_data/trivial/rust-toolchain.toml
Normal file
4
riscv/tests/riscv_data/trivial/rust-toolchain.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-02-01"
|
||||
targets = ["riscv32imac-unknown-none-elf"]
|
||||
profile = "minimal"
|
||||
9
riscv/tests/riscv_data/zero_with_values/Cargo.toml
Normal file
9
riscv/tests/riscv_data/zero_with_values/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "zero_with_values"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
powdr-riscv-runtime = { path = "../../../../riscv-runtime" }
|
||||
|
||||
[workspace]
|
||||
@@ -0,0 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-02-01"
|
||||
targets = ["riscv32imac-unknown-none-elf"]
|
||||
profile = "minimal"
|
||||
Reference in New Issue
Block a user