mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-04-20 03:03:25 -04:00
Merge pull request #293 from powdr-org/combine_pil_and_asm
Combine CLI for pil and asm compilation.
This commit is contained in:
@@ -18,6 +18,25 @@ pub fn no_callback<T>() -> Option<fn(&str) -> Option<T>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Compiles a .pil or .asm file and runs witness generation.
|
||||
/// If the file ends in .asm, converts it to .pil first.
|
||||
pub fn compile_pil_or_asm<T: FieldElement>(
|
||||
file_name: &str,
|
||||
inputs: Vec<T>,
|
||||
output_dir: &Path,
|
||||
force_overwrite: bool,
|
||||
) {
|
||||
if file_name.ends_with(".asm") {
|
||||
compile_asm(file_name, inputs, output_dir, force_overwrite)
|
||||
} else {
|
||||
compile_pil(
|
||||
Path::new(file_name),
|
||||
output_dir,
|
||||
Some(inputs_to_query_callback(inputs)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Compiles a .pil file to its json form and also tries to generate
|
||||
/// constants and committed polynomials.
|
||||
/// @returns true if all committed/witness and constant/fixed polynomials
|
||||
@@ -90,31 +109,11 @@ pub fn compile_asm_string<T: FieldElement>(
|
||||
}
|
||||
fs::write(pil_file_name.clone(), format!("{pil}")).unwrap();
|
||||
|
||||
let query_callback = |query: &str| -> Option<T> {
|
||||
let items = query.split(',').map(|s| s.trim()).collect::<Vec<_>>();
|
||||
match items[0] {
|
||||
"\"input\"" => {
|
||||
assert_eq!(items.len(), 2);
|
||||
let index = items[1].parse::<usize>().unwrap();
|
||||
let value = inputs.get(index).cloned();
|
||||
if let Some(value) = value {
|
||||
log::trace!("Input query: Index {index} -> {value}");
|
||||
}
|
||||
value
|
||||
}
|
||||
"\"print_char\"" => {
|
||||
assert_eq!(items.len(), 2);
|
||||
print!("{}", items[1].parse::<u8>().unwrap() as char);
|
||||
Some(0.into())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
compile_pil_ast(
|
||||
&pil,
|
||||
pil_file_name.file_name().unwrap(),
|
||||
output_dir,
|
||||
Some(query_callback),
|
||||
Some(inputs_to_query_callback(inputs)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -174,3 +173,26 @@ fn write_polys_file<T: FieldElement>(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn inputs_to_query_callback<T: FieldElement>(inputs: Vec<T>) -> impl Fn(&str) -> Option<T> {
|
||||
move |query: &str| -> Option<T> {
|
||||
let items = query.split(',').map(|s| s.trim()).collect::<Vec<_>>();
|
||||
match items[0] {
|
||||
"\"input\"" => {
|
||||
assert_eq!(items.len(), 2);
|
||||
let index = items[1].parse::<usize>().unwrap();
|
||||
let value = inputs.get(index).cloned();
|
||||
if let Some(value) = value {
|
||||
log::trace!("Input query: Index {index} -> {value}");
|
||||
}
|
||||
value
|
||||
}
|
||||
"\"print_char\"" => {
|
||||
assert_eq!(items.len(), 2);
|
||||
print!("{}", items[1].parse::<u8>().unwrap() as char);
|
||||
Some(0.into())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//! The powdr CLI tool
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use compiler::no_callback;
|
||||
use env_logger::{Builder, Target};
|
||||
use log::LevelFilter;
|
||||
use number::{FieldElement, GoldilocksField};
|
||||
@@ -16,6 +15,29 @@ struct Cli {
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Runs compilation and witness generation for .pil and .asm files.
|
||||
/// First converts .asm files to .pil, if needed.
|
||||
/// Then converts the .pil file to json and generates fixed and witness column data files.
|
||||
Pil {
|
||||
/// Input file
|
||||
file: String,
|
||||
|
||||
/// Output directory for the PIL file, json file and fixed and witness column data.
|
||||
#[arg(short, long)]
|
||||
#[arg(default_value_t = String::from("."))]
|
||||
output_directory: String,
|
||||
|
||||
/// Comma-separated list of free inputs (numbers). Assumes queries to have the form
|
||||
/// ("input", <index>).
|
||||
#[arg(short, long)]
|
||||
#[arg(default_value_t = String::new())]
|
||||
inputs: String,
|
||||
|
||||
/// Force overwriting of PIL output file.
|
||||
#[arg(short, long)]
|
||||
#[arg(default_value_t = false)]
|
||||
force: bool,
|
||||
},
|
||||
/// Compiles (no-std) rust code to riscv assembly, then to powdr assembly
|
||||
/// and finally to PIL and generates fixed and witness columns.
|
||||
/// Needs `rustup target add riscv32imc-unknown-none-elf`.
|
||||
@@ -61,42 +83,11 @@ enum Commands {
|
||||
force: bool,
|
||||
},
|
||||
|
||||
/// Compiles assembly to PIL and generates fixed and witness columns.
|
||||
Asm {
|
||||
/// Input file
|
||||
file: String,
|
||||
|
||||
/// Comma-separated list of free inputs (numbers).
|
||||
#[arg(short, long)]
|
||||
#[arg(default_value_t = String::new())]
|
||||
inputs: String,
|
||||
|
||||
/// Output directory for PIL file, json file and fixed and witness column data.
|
||||
#[arg(short, long)]
|
||||
#[arg(default_value_t = String::from("."))]
|
||||
output_directory: String,
|
||||
|
||||
/// Force overwriting of PIL output file.
|
||||
#[arg(short, long)]
|
||||
#[arg(default_value_t = false)]
|
||||
force: bool,
|
||||
},
|
||||
|
||||
/// Parses and prints the PIL file on stdout.
|
||||
Reformat {
|
||||
/// Input file
|
||||
file: String,
|
||||
},
|
||||
|
||||
/// Compiles the PIL file to json and generates fixed and witness columns.
|
||||
Compile {
|
||||
/// Input file
|
||||
file: String,
|
||||
/// Output directory for json file and fixed and witness column data.
|
||||
#[arg(short, long)]
|
||||
#[arg(default_value_t = String::from("."))]
|
||||
output_directory: String,
|
||||
},
|
||||
}
|
||||
|
||||
fn split_inputs<T: FieldElement>(inputs: &str) -> Vec<T> {
|
||||
@@ -146,19 +137,6 @@ fn main() {
|
||||
force,
|
||||
);
|
||||
}
|
||||
Commands::Asm {
|
||||
file,
|
||||
inputs,
|
||||
output_directory,
|
||||
force,
|
||||
} => {
|
||||
compiler::compile_asm::<GoldilocksField>(
|
||||
&file,
|
||||
split_inputs(&inputs),
|
||||
Path::new(&output_directory),
|
||||
force,
|
||||
);
|
||||
}
|
||||
Commands::Reformat { file } => {
|
||||
let contents = fs::read_to_string(&file).unwrap();
|
||||
match parser::parse::<GoldilocksField>(Some(&file), &contents) {
|
||||
@@ -166,14 +144,17 @@ fn main() {
|
||||
Err(err) => err.output_to_stderr(),
|
||||
}
|
||||
}
|
||||
Commands::Compile {
|
||||
Commands::Pil {
|
||||
file,
|
||||
output_directory,
|
||||
inputs,
|
||||
force,
|
||||
} => {
|
||||
compiler::compile_pil::<GoldilocksField>(
|
||||
Path::new(&file),
|
||||
compiler::compile_pil_or_asm::<GoldilocksField>(
|
||||
&file,
|
||||
split_inputs(&inputs),
|
||||
Path::new(&output_directory),
|
||||
no_callback(),
|
||||
force,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user