tasm_lib/traits/
closure.rsuse rand::prelude::*;
use triton_vm::prelude::*;
use super::basic_snippet::BasicSnippet;
use super::rust_shadow::RustShadow;
use crate::linker::execute_bench;
use crate::prelude::Tip5;
use crate::push_encodable;
use crate::snippet_bencher::write_benchmarks;
use crate::snippet_bencher::BenchmarkCase;
use crate::snippet_bencher::NamedBenchmarkResult;
use crate::test_helpers::test_rust_equivalence_given_complete_state;
pub trait Closure: BasicSnippet {
type Args: BFieldCodec;
fn rust_shadow(&self, stack: &mut Vec<BFieldElement>);
fn pseudorandom_args(&self, seed: [u8; 32], bench_case: Option<BenchmarkCase>) -> Self::Args;
fn corner_case_args(&self) -> Vec<Self::Args> {
vec![]
}
fn set_up_test_stack(&self, args: Self::Args) -> Vec<BFieldElement> {
let mut stack = self.init_stack_for_isolated_run();
push_encodable(&mut stack, &args);
stack
}
}
pub struct ShadowedClosure<C: Closure> {
closure: C,
}
impl<C: Closure> ShadowedClosure<C> {
pub fn new(closure: C) -> Self {
Self { closure }
}
}
impl<C: Closure> RustShadow for ShadowedClosure<C> {
fn inner(&self) -> &dyn BasicSnippet {
&self.closure
}
fn rust_shadow_wrapper(
&self,
_stdin: &[BFieldElement],
_nondeterminism: &NonDeterminism,
stack: &mut Vec<BFieldElement>,
_memory: &mut std::collections::HashMap<BFieldElement, BFieldElement>,
_sponge: &mut Option<Tip5>,
) -> Vec<BFieldElement> {
self.closure.rust_shadow(stack);
vec![]
}
fn test(&self) {
let num_states = 5;
let mut rng = rand::rng();
for args in self.closure.corner_case_args() {
test_rust_equivalence_given_complete_state(
self,
&self.closure.set_up_test_stack(args),
&[],
&NonDeterminism::default(),
&None,
None,
);
}
for _ in 0..num_states {
let seed: [u8; 32] = rng.random();
let args = self.closure.pseudorandom_args(seed, None);
let stack = self.closure.set_up_test_stack(args);
let stdin = vec![];
test_rust_equivalence_given_complete_state(
self,
&stack,
&stdin,
&NonDeterminism::default(),
&None,
None,
);
}
}
fn bench(&self) {
let mut rng = StdRng::from_seed(
hex::decode("73a24b6b8b32e4d7d563a4d9a85f476573a24b6b8b32e4d7d563a4d9a85f4765")
.unwrap()
.try_into()
.unwrap(),
);
let mut benchmarks = Vec::with_capacity(2);
for bench_case in [BenchmarkCase::CommonCase, BenchmarkCase::WorstCase] {
let args = self
.closure
.pseudorandom_args(rng.random(), Some(bench_case));
let stack = self.closure.set_up_test_stack(args);
let program = self.closure.link_for_isolated_run();
let benchmark =
execute_bench(&program, &stack, vec![], NonDeterminism::new(vec![]), None);
let benchmark = NamedBenchmarkResult {
name: self.closure.entrypoint(),
benchmark_result: benchmark,
case: bench_case,
};
benchmarks.push(benchmark);
}
write_benchmarks(benchmarks);
}
}