From 0793ada8692435b46475c35ad4ed1714918d191c Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Tue, 11 Jan 2022 16:12:51 +0100 Subject: [PATCH] Implement benchmarks based on the Criterion crate (#323) * apply fmt to benches * add git submodule poiting to wasm_kernel * clean up benchmark .wat files * add v1::Module::engine method getter * remove built-in wasm-kernel We are now using this as a git submodule instead. * add new benchmarks, remove old ones * no longer deny warnings for cargo audit CI job This is due to the fact that the tools warns for unmaintained crates such as serde_cbor which usually is not a big deal and happens way too often to be a practical guard. --- .github/workflows/rust.yml | 2 +- .gitmodules | 3 + Cargo.toml | 12 +- benches/.gitignore | 3 - benches/Cargo.toml | 15 - benches/bench/mod.rs | 139 ++++ benches/benches.rs | 641 +++++++++++++++++++ benches/build.rs | 30 - benches/src/lib.rs | 738 ---------------------- benches/src/revcomp-input.txt | 171 ----- benches/src/revcomp-output.txt | 171 ----- benches/wasm-kernel/.gitignore | 1 - benches/wasm-kernel/Cargo.toml | 18 - benches/wasm-kernel/src/lib.rs | 132 ---- benches/wasm-kernel/src/regex_redux.rs | 17 - benches/wasm-kernel/src/rev_complement.rs | 164 ----- benches/wasm/wasm_kernel | 1 + benches/wat/host_calls.wat | 8 +- benches/wat/optimized_factorial.wat | 12 +- benches/wat/recursive_factorial.wat | 4 +- benches/wat/recursive_ok.wat | 4 +- benches/wat/recursive_trap.wat | 4 +- src/v1/module/mod.rs | 5 + 23 files changed, 817 insertions(+), 1478 deletions(-) delete mode 100644 benches/.gitignore delete mode 100644 benches/Cargo.toml create mode 100644 benches/bench/mod.rs create mode 100644 benches/benches.rs delete mode 100644 benches/build.rs delete mode 100644 benches/src/lib.rs delete mode 100644 benches/src/revcomp-input.txt delete mode 100644 benches/src/revcomp-output.txt delete mode 100644 benches/wasm-kernel/.gitignore delete mode 100644 benches/wasm-kernel/Cargo.toml delete mode 100644 benches/wasm-kernel/src/lib.rs delete mode 100644 benches/wasm-kernel/src/regex_redux.rs delete mode 100644 benches/wasm-kernel/src/rev_complement.rs create mode 160000 benches/wasm/wasm_kernel diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 9611b7c185..9114edff8a 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -122,7 +122,7 @@ jobs: - uses: actions-rs/cargo@v1 with: command: audit - args: --deny warnings + args: '' clippy: name: Clippy diff --git a/.gitmodules b/.gitmodules index 7da646be11..33342276f2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ [submodule "tests/spec/testsuite-v1"] path = tests/spec/testsuite-v1 url = https://github.com/WebAssembly/testsuite.git +[submodule "benches/wasm_kernel"] + path = benches/wasm/wasm_kernel + url = https://github.com/robbepop/wasm_kernel.git diff --git a/Cargo.toml b/Cargo.toml index ccbdb37cad..83531cc024 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ rand = "0.4.2" wabt = "0.9" wast = "39.0" anyhow = "1.0" +criterion = "0.3.5" [features] default = ["std"] @@ -56,4 +57,13 @@ reduced-stack-buffer = [ "parity-wasm/reduced-stack-buffer" ] [workspace] members = ["validation"] -exclude = ["benches"] +exclude = [] + +[[bench]] +name = "benches" +harness = false + +[profile.bench] +debug = true +lto = "fat" +codegen-units = 1 diff --git a/benches/.gitignore b/benches/.gitignore deleted file mode 100644 index ffc9328557..0000000000 --- a/benches/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target -*.trace - diff --git a/benches/Cargo.toml b/benches/Cargo.toml deleted file mode 100644 index d19f535bc8..0000000000 --- a/benches/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "benches" -version = "0.1.0" -authors = ["Sergey Pepyakin "] -edition = "2021" - -[dependencies] -wasmi = { path = ".." } -assert_matches = "1.2" -wabt = "0.9" - -[profile.bench] -debug = true -lto = "fat" -codegen-units = 1 diff --git a/benches/bench/mod.rs b/benches/bench/mod.rs new file mode 100644 index 0000000000..73c704c181 --- /dev/null +++ b/benches/bench/mod.rs @@ -0,0 +1,139 @@ +use super::{v0, v1}; +use std::{fs::File, io::Read as _}; + +/// Returns the Wasm binary at the given `file_name` as `Vec`. +/// +/// # Note +/// +/// This includes validation and compilation to `wasmi` bytecode. +/// +/// # Panics +/// +/// If the benchmark Wasm file could not be opened, read or parsed. +pub fn load_wasm_from_file(file_name: &str) -> Vec { + let mut file = File::open(file_name) + .unwrap_or_else(|error| panic!("could not open benchmark file {}: {}", file_name, error)); + let mut buffer = Vec::new(); + file.read_to_end(&mut buffer).unwrap_or_else(|error| { + panic!("could not read file at {} to buffer: {}", file_name, error) + }); + buffer +} + +/// Parses the Wasm binary at the given `file_name` into a `wasmi` module. +/// +/// # Note +/// +/// This includes validation and compilation to `wasmi` bytecode. +/// +/// # Panics +/// +/// If the benchmark Wasm file could not be opened, read or parsed. +pub fn load_module_from_file_v0(file_name: &str) -> v0::Module { + let wasm = load_wasm_from_file(file_name); + v0::Module::from_buffer(wasm).unwrap_or_else(|error| { + panic!( + "could not parse Wasm module from file {}: {}", + file_name, error + ) + }) +} + +/// Parses the Wasm binary at the given `file_name` into a `wasmi` module. +/// +/// # Note +/// +/// This includes validation and compilation to `wasmi` bytecode. +/// +/// # Panics +/// +/// If the benchmark Wasm file could not be opened, read or parsed. +pub fn load_module_from_file_v1(file_name: &str) -> v1::Module { + let wasm = load_wasm_from_file(file_name); + let engine = v1::Engine::default(); + v1::Module::new(&engine, wasm).unwrap_or_else(|error| { + panic!( + "could not parse Wasm module from file {}: {}", + file_name, error + ) + }) +} + +/// Parses the Wasm binary from the given `file_name` into a `wasmi` `v0` module. +/// +/// # Note +/// +/// This includes validation and compilation to `wasmi` bytecode. +/// +/// # Panics +/// +/// If the benchmark Wasm file could not be opened, read or parsed. +pub fn load_instance_from_file_v0(file_name: &str) -> v0::ModuleRef { + let module = load_module_from_file_v0(file_name); + v0::ModuleInstance::new(&module, &v0::ImportsBuilder::default()) + .expect("failed to instantiate wasm module") + .run_start(&mut v0::NopExternals) + .unwrap() +} + +/// Parses the Wasm binary from the given `file_name` into a `wasmi` `v1` module. +/// +/// # Note +/// +/// This includes validation and compilation to `wasmi` bytecode. +/// +/// # Panics +/// +/// If the benchmark Wasm file could not be opened, read or parsed. +pub fn load_instance_from_file_v1(file_name: &str) -> (v1::Store<()>, v1::Instance) { + let module = load_module_from_file_v1(file_name); + let mut linker = >::default(); + let mut store = v1::Store::new(module.engine(), ()); + let instance = linker + .instantiate(&mut store, &module) + .unwrap() + .start(&mut store) + .unwrap(); + (store, instance) +} + +/// Parses the Wasm source from the given `.wat` bytes into a `wasmi` `v0` module. +/// +/// # Note +/// +/// This includes validation and compilation to `wasmi` bytecode. +/// +/// # Panics +/// +/// If the benchmark Wasm file could not be opened, read or parsed. +pub fn load_instance_from_wat_v0(wat_bytes: &[u8]) -> v0::ModuleRef { + let wasm = wabt::wat2wasm(wat_bytes).unwrap(); + let module = v0::Module::from_buffer(&wasm).unwrap(); + v0::ModuleInstance::new(&module, &v0::ImportsBuilder::default()) + .expect("failed to instantiate wasm module") + .run_start(&mut v0::NopExternals) + .unwrap() +} + +/// Parses the Wasm source from the given `.wat` bytes into a `wasmi` `v0` module. +/// +/// # Note +/// +/// This includes validation and compilation to `wasmi` bytecode. +/// +/// # Panics +/// +/// If the benchmark Wasm file could not be opened, read or parsed. +pub fn load_instance_from_wat_v1(wat_bytes: &[u8]) -> (v1::Store<()>, v1::Instance) { + let wasm = wabt::wat2wasm(wat_bytes).unwrap(); + let engine = v1::Engine::default(); + let module = v1::Module::new(&engine, &wasm).unwrap(); + let mut linker = >::default(); + let mut store = v1::Store::new(&engine, ()); + let instance = linker + .instantiate(&mut store, &module) + .unwrap() + .start(&mut store) + .unwrap(); + (store, instance) +} diff --git a/benches/benches.rs b/benches/benches.rs new file mode 100644 index 0000000000..4adfb10a06 --- /dev/null +++ b/benches/benches.rs @@ -0,0 +1,641 @@ +mod bench; + +use self::bench::{ + load_instance_from_file_v0, + load_instance_from_file_v1, + load_instance_from_wat_v0, + load_instance_from_wat_v1, + load_module_from_file_v0, + load_module_from_file_v1, + load_wasm_from_file, +}; +use assert_matches::assert_matches; +use criterion::{criterion_group, criterion_main, Criterion}; +use std::slice; +use wasmi as v0; +use wasmi::{v1, Trap, Value}; + +const WASM_KERNEL: &str = + "benches/wasm/wasm_kernel/target/wasm32-unknown-unknown/release/wasm_kernel.wasm"; +const REVCOMP_INPUT: &[u8] = include_bytes!("wasm/wasm_kernel/res/revcomp-input.txt"); +const REVCOMP_OUTPUT: &[u8] = include_bytes!("wasm/wasm_kernel/res/revcomp-output.txt"); + +criterion_group!( + bench_compile_and_validate, + bench_compile_and_validate_v0, + bench_compile_and_validate_v1 +); +criterion_group!( + bench_instantiate, + bench_instantiate_v0, + bench_instantiate_v1 +); +criterion_group!( + bench_execute, + bench_execute_tiny_keccak_v0, + bench_execute_tiny_keccak_v1, + bench_execute_rev_comp_v0, + bench_execute_rev_comp_v1, + bench_execute_regex_redux_v0, + bench_execute_regex_redux_v1, + bench_execute_count_until_v0, + bench_execute_count_until_v1, + bench_execute_fac_recursive_v0, + bench_execute_fac_recursive_v1, + bench_execute_fac_opt_v0, + bench_execute_fac_opt_v1, + bench_execute_recursive_ok_v0, + bench_execute_recursive_ok_v1, + bench_execute_recursive_trap_v0, + bench_execute_recursive_trap_v1, + bench_execute_host_calls_v0, + bench_execute_host_calls_v1 +); +criterion_main!(bench_compile_and_validate, bench_instantiate, bench_execute); + +fn bench_compile_and_validate_v0(c: &mut Criterion) { + let wasm_bytes = load_wasm_from_file(WASM_KERNEL); + c.bench_function("compile_and_validate/v0", |b| { + b.iter(|| { + let _module = v0::Module::from_buffer(&wasm_bytes).unwrap(); + }) + }); +} + +fn bench_compile_and_validate_v1(c: &mut Criterion) { + let wasm_bytes = load_wasm_from_file(WASM_KERNEL); + c.bench_function("compile_and_validate/v1", |b| { + b.iter(|| { + let engine = v1::Engine::default(); + let _module = v1::Module::new(&engine, &wasm_bytes).unwrap(); + }) + }); +} + +fn bench_instantiate_v0(c: &mut Criterion) { + let wasm_kernel = load_module_from_file_v0(WASM_KERNEL); + + c.bench_function("instantiate/v0", |b| { + b.iter(|| { + let _instance = v0::ModuleInstance::new(&wasm_kernel, &v0::ImportsBuilder::default()) + .expect("failed to instantiate wasm module") + .assert_no_start(); + }) + }); +} + +fn bench_instantiate_v1(c: &mut Criterion) { + let module = load_module_from_file_v1(WASM_KERNEL); + let mut linker = >::default(); + + c.bench_function("instantiate/v1", |b| { + b.iter(|| { + let mut store = v1::Store::new(module.engine(), ()); + let _instance = linker.instantiate(&mut store, &module).unwrap(); + }) + }); +} + +fn bench_execute_tiny_keccak_v0(c: &mut Criterion) { + let instance = load_instance_from_file_v0(WASM_KERNEL); + + let test_data_ptr = assert_matches!( + instance.invoke_export("prepare_tiny_keccak", &[], &mut v0::NopExternals), + Ok(Some(v @ Value::I32(_))) => v + ); + + c.bench_function("execute/tiny_keccak/v0", |b| { + b.iter(|| { + instance + .invoke_export("bench_tiny_keccak", &[test_data_ptr], &mut v0::NopExternals) + .unwrap(); + }) + }); +} + +fn bench_execute_tiny_keccak_v1(c: &mut Criterion) { + let (mut store, instance) = load_instance_from_file_v1(WASM_KERNEL); + let prepare = instance + .get_export(&store, "prepare_tiny_keccak") + .and_then(v1::Extern::into_func) + .unwrap(); + let keccak = instance + .get_export(&store, "bench_tiny_keccak") + .and_then(v1::Extern::into_func) + .unwrap(); + let mut test_data_ptr = Value::I32(0); + prepare + .call(&mut store, &[], slice::from_mut(&mut test_data_ptr)) + .unwrap(); + assert_matches!(test_data_ptr, Value::I32(_)); + + c.bench_function("execute/tiny_keccak/v1", |b| { + b.iter(|| { + keccak + .call(&mut store, slice::from_ref(&test_data_ptr), &mut []) + .unwrap(); + }) + }); +} + +fn bench_execute_rev_comp_v0(c: &mut Criterion) { + let instance = load_instance_from_file_v0(WASM_KERNEL); + + // Allocate buffers for the input and output. + let test_data_ptr: Value = { + let input_size = Value::I32(REVCOMP_INPUT.len() as i32); + assert_matches!( + instance.invoke_export("prepare_rev_complement", &[input_size], &mut v0::NopExternals), + Ok(Some(v @ Value::I32(_))) => v, + "", + ) + }; + + // Get the pointer to the input buffer. + let input_data_mem_offset = assert_matches!( + instance.invoke_export("rev_complement_input_ptr", &[test_data_ptr], &mut v0::NopExternals), + Ok(Some(Value::I32(v))) => v as u32, + "", + ); + + // Copy test data inside the wasm memory. + let memory = instance + .export_by_name("memory") + .expect("Expected export with a name 'memory'") + .as_memory() + .expect("'memory' should be a memory instance") + .clone(); + memory + .set(input_data_mem_offset, REVCOMP_INPUT) + .expect("can't load test data into a wasm memory"); + + c.bench_function("execute/rev_complement/v0", |b| { + b.iter(|| { + instance + .invoke_export( + "bench_rev_complement", + &[test_data_ptr], + &mut v0::NopExternals, + ) + .unwrap(); + }) + }); + + // Verify the result. + let output_data_mem_offset = assert_matches!( + instance.invoke_export("rev_complement_output_ptr", &[test_data_ptr], &mut v0::NopExternals), + Ok(Some(Value::I32(v))) => v as u32, + "", + ); + let mut result = vec![0x00_u8; REVCOMP_OUTPUT.len()]; + memory + .get_into(output_data_mem_offset, &mut result) + .expect("can't get result data from a wasm memory"); + assert_eq!(&*result, REVCOMP_OUTPUT); +} + +fn bench_execute_rev_comp_v1(c: &mut Criterion) { + let (mut store, instance) = load_instance_from_file_v1(WASM_KERNEL); + + // Allocate buffers for the input and output. + let mut result = Value::I32(0); + let input_size = Value::I32(REVCOMP_INPUT.len() as i32); + let prepare_rev_complement = instance + .get_export(&store, "prepare_rev_complement") + .and_then(v1::Extern::into_func) + .unwrap(); + prepare_rev_complement + .call(&mut store, &[input_size], slice::from_mut(&mut result)) + .unwrap(); + let test_data_ptr = match result { + value @ Value::I32(_) => value, + _ => panic!("unexpected non-I32 result found for prepare_rev_complement"), + }; + + // Get the pointer to the input buffer. + let rev_complement_input_ptr = instance + .get_export(&store, "rev_complement_input_ptr") + .and_then(v1::Extern::into_func) + .unwrap(); + rev_complement_input_ptr + .call(&mut store, &[test_data_ptr], slice::from_mut(&mut result)) + .unwrap(); + let input_data_mem_offset = match result { + Value::I32(value) => value, + _ => panic!("unexpected non-I32 result found for prepare_rev_complement"), + }; + + // Copy test data inside the wasm memory. + let memory = instance + .get_export(&store, "memory") + .and_then(v1::Extern::into_memory) + .expect("failed to find 'memory' exported linear memory in instance"); + memory + .write(&mut store, input_data_mem_offset as usize, REVCOMP_INPUT) + .expect("failed to write test data into a wasm memory"); + + let bench_rev_complement = instance + .get_export(&store, "bench_rev_complement") + .and_then(v1::Extern::into_func) + .unwrap(); + + c.bench_function("execute/rev_complement/v1", |b| { + b.iter(|| { + bench_rev_complement + .call(&mut store, &[test_data_ptr], &mut []) + .unwrap(); + }) + }); + + // Get the pointer to the output buffer. + let rev_complement_output_ptr = instance + .get_export(&store, "rev_complement_output_ptr") + .and_then(v1::Extern::into_func) + .unwrap(); + rev_complement_output_ptr + .call(&mut store, &[test_data_ptr], slice::from_mut(&mut result)) + .unwrap(); + let output_data_mem_offset = match result { + Value::I32(value) => value, + _ => panic!("unexpected non-I32 result found for prepare_rev_complement"), + }; + + let mut revcomp_result = vec![0x00_u8; REVCOMP_OUTPUT.len()]; + memory + .read(&store, output_data_mem_offset as usize, &mut revcomp_result) + .expect("failed to read result data from a wasm memory"); + assert_eq!(&revcomp_result[..], REVCOMP_OUTPUT); +} + +fn bench_execute_regex_redux_v0(c: &mut Criterion) { + let instance = load_instance_from_file_v0(WASM_KERNEL); + + // Allocate buffers for the input and output. + let test_data_ptr: Value = { + let input_size = Value::I32(REVCOMP_INPUT.len() as i32); + assert_matches!( + instance.invoke_export("prepare_regex_redux", &[input_size], &mut v0::NopExternals), + Ok(Some(v @ Value::I32(_))) => v, + "", + ) + }; + + // Get the pointer to the input buffer. + let input_data_mem_offset = assert_matches!( + instance.invoke_export("regex_redux_input_ptr", &[test_data_ptr], &mut v0::NopExternals), + Ok(Some(Value::I32(v))) => v as u32, + "", + ); + + // Copy test data inside the wasm memory. + let memory = instance + .export_by_name("memory") + .expect("Expected export with a name 'memory'") + .as_memory() + .expect("'memory' should be a memory instance") + .clone(); + memory + .set(input_data_mem_offset, REVCOMP_INPUT) + .expect("can't load test data into a wasm memory"); + + c.bench_function("execute/regex_redux/v0", |b| { + b.iter(|| { + instance + .invoke_export("bench_regex_redux", &[test_data_ptr], &mut v0::NopExternals) + .unwrap(); + }) + }); +} + +fn bench_execute_regex_redux_v1(c: &mut Criterion) { + let (mut store, instance) = load_instance_from_file_v1(WASM_KERNEL); + + // Allocate buffers for the input and output. + let mut result = Value::I32(0); + let input_size = Value::I32(REVCOMP_INPUT.len() as i32); + let prepare_regex_redux = instance + .get_export(&store, "prepare_regex_redux") + .and_then(v1::Extern::into_func) + .unwrap(); + prepare_regex_redux + .call(&mut store, &[input_size], slice::from_mut(&mut result)) + .unwrap(); + let test_data_ptr = match result { + value @ Value::I32(_) => value, + _ => panic!("unexpected non-I32 result found for prepare_regex_redux"), + }; + + // Get the pointer to the input buffer. + let regex_redux_input_ptr = instance + .get_export(&store, "regex_redux_input_ptr") + .and_then(v1::Extern::into_func) + .unwrap(); + regex_redux_input_ptr + .call(&mut store, &[test_data_ptr], slice::from_mut(&mut result)) + .unwrap(); + let input_data_mem_offset = match result { + Value::I32(value) => value, + _ => panic!("unexpected non-I32 result found for regex_redux_input_ptr"), + }; + + // Copy test data inside the wasm memory. + let memory = instance + .get_export(&store, "memory") + .and_then(v1::Extern::into_memory) + .expect("failed to find 'memory' exported linear memory in instance"); + memory + .write(&mut store, input_data_mem_offset as usize, REVCOMP_INPUT) + .expect("failed to write test data into a wasm memory"); + + let bench_regex_redux = instance + .get_export(&store, "bench_regex_redux") + .and_then(v1::Extern::into_func) + .unwrap(); + + c.bench_function("execute/regex_redux/v1", |b| { + b.iter(|| { + bench_regex_redux + .call(&mut store, &[test_data_ptr], &mut []) + .unwrap(); + }) + }); +} + +const COUNT_UNTIL: i32 = 100_000; + +fn bench_execute_count_until_v0(c: &mut Criterion) { + let instance = load_instance_from_wat_v0(include_bytes!("wat/count_until.wat")); + c.bench_function("execute/count_until/v0", |b| { + b.iter(|| { + let value = instance.invoke_export( + "count_until", + &[Value::I32(COUNT_UNTIL)], + &mut v0::NopExternals, + ); + assert_matches!(value, Ok(Some(Value::I32(COUNT_UNTIL)))); + }) + }); +} + +fn bench_execute_count_until_v1(c: &mut Criterion) { + let (mut store, instance) = load_instance_from_wat_v1(include_bytes!("wat/count_until.wat")); + let count_until = instance + .get_export(&store, "count_until") + .and_then(v1::Extern::into_func) + .unwrap(); + let mut result = [Value::I32(0)]; + c.bench_function("execute/count_until/v1", |b| { + b.iter(|| { + count_until + .call(&mut store, &[Value::I32(COUNT_UNTIL)], &mut result) + .unwrap(); + assert_matches!(result, [Value::I32(COUNT_UNTIL)]); + }) + }); +} + +fn bench_execute_fac_recursive_v0(c: &mut Criterion) { + let instance = load_instance_from_wat_v0(include_bytes!("wat/recursive_factorial.wat")); + c.bench_function("execute/factorial_recursive/v0", |b| { + b.iter(|| { + let value = instance.invoke_export("fac-rec", &[Value::I64(25)], &mut v0::NopExternals); + assert_matches!(value, Ok(Some(Value::I64(7034535277573963776)))); + }) + }); +} + +fn bench_execute_fac_recursive_v1(c: &mut Criterion) { + let (mut store, instance) = + load_instance_from_wat_v1(include_bytes!("wat/recursive_factorial.wat")); + let fac = instance + .get_export(&store, "fac-rec") + .and_then(v1::Extern::into_func) + .unwrap(); + let mut result = [Value::I64(0)]; + c.bench_function("execute/factorial_recursive/v1", |b| { + b.iter(|| { + fac.call(&mut store, &[Value::I64(25)], &mut result) + .unwrap(); + assert_matches!(result, [Value::I64(7034535277573963776)]); + }) + }); +} + +fn bench_execute_fac_opt_v0(c: &mut Criterion) { + let instance = load_instance_from_wat_v0(include_bytes!("wat/optimized_factorial.wat")); + c.bench_function("execute/factorial_optimized/v0", |b| { + b.iter(|| { + let value = instance.invoke_export("fac-opt", &[Value::I64(25)], &mut v0::NopExternals); + assert_matches!(value, Ok(Some(Value::I64(7034535277573963776)))); + }) + }); +} + +fn bench_execute_fac_opt_v1(c: &mut Criterion) { + let (mut store, instance) = + load_instance_from_wat_v1(include_bytes!("wat/optimized_factorial.wat")); + let fac = instance + .get_export(&store, "fac-opt") + .and_then(v1::Extern::into_func) + .unwrap(); + let mut result = [Value::I64(0)]; + c.bench_function("execute/factorial_optimized/v1", |b| { + b.iter(|| { + fac.call(&mut store, &[Value::I64(25)], &mut result) + .unwrap(); + assert_matches!(result, [Value::I64(7034535277573963776)]); + }) + }); +} + +const RECURSIVE_DEPTH: i32 = 8000; + +fn bench_execute_recursive_ok_v0(c: &mut Criterion) { + let instance = load_instance_from_wat_v0(include_bytes!("wat/recursive_ok.wat")); + c.bench_function("execute/recursive_ok/v0", |b| { + b.iter(|| { + let value = instance.invoke_export( + "call", + &[Value::I32(RECURSIVE_DEPTH)], + &mut v0::NopExternals, + ); + assert_matches!(value, Ok(Some(Value::I32(0)))); + }) + }); +} + +fn bench_execute_recursive_ok_v1(c: &mut Criterion) { + let (mut store, instance) = load_instance_from_wat_v1(include_bytes!("wat/recursive_ok.wat")); + let bench_call = instance + .get_export(&store, "call") + .and_then(v1::Extern::into_func) + .unwrap(); + let mut result = [Value::I32(0)]; + c.bench_function("execute/recursive_ok/v1", |b| { + b.iter(|| { + bench_call + .call(&mut store, &[Value::I32(RECURSIVE_DEPTH)], &mut result) + .unwrap(); + assert_matches!(result, [Value::I32(0)]); + }) + }); +} + +fn bench_execute_recursive_trap_v0(c: &mut Criterion) { + let instance = load_instance_from_wat_v0(include_bytes!("wat/recursive_trap.wat")); + c.bench_function("execute/recursive_trap/v0", |b| { + b.iter(|| { + let value = instance.invoke_export("call", &[Value::I32(1000)], &mut v0::NopExternals); + assert_matches!(value, Err(_)); + }) + }); +} + +fn bench_execute_recursive_trap_v1(c: &mut Criterion) { + let (mut store, instance) = load_instance_from_wat_v1(include_bytes!("wat/recursive_trap.wat")); + let bench_call = instance + .get_export(&store, "call") + .and_then(v1::Extern::into_func) + .unwrap(); + let mut result = [Value::I32(0)]; + c.bench_function("execute/recursive_trap/v1", |b| { + b.iter(|| { + let result = bench_call.call(&mut store, &[Value::I32(1000)], &mut result); + assert_matches!(result, Err(_)); + }) + }); +} + +/// How often the `host_call` should be called per Wasm invocation. +const HOST_CALLS_REPETITIONS: i64 = 1000; + +fn bench_execute_host_calls_v0(c: &mut Criterion) { + let wasm = wabt::wat2wasm(include_bytes!("wat/host_calls.wat")).unwrap(); + let module = v0::Module::from_buffer(&wasm).unwrap(); + let instance = v0::ModuleInstance::new(&module, &BenchExternals) + .expect("failed to instantiate wasm module") + .assert_no_start(); + + /// The benchmark externals provider. + pub struct BenchExternals; + + /// The index of the host function that is about to be called a lot. + const HOST_CALL_INDEX: usize = 0; + + impl v0::Externals for BenchExternals { + fn invoke_index( + &mut self, + index: usize, + args: v0::RuntimeArgs, + ) -> Result, Trap> { + match index { + HOST_CALL_INDEX => { + let arg = args.nth_value_checked(0)?; + Ok(Some(arg)) + } + _ => panic!("BenchExternals do not provide function at index {}", index), + } + } + } + + impl v0::ImportResolver for BenchExternals { + fn resolve_func( + &self, + _module_name: &str, + field_name: &str, + func_type: &v0::Signature, + ) -> Result { + let index = match field_name { + "host_call" => HOST_CALL_INDEX, + _ => { + return Err(v0::Error::Instantiation(format!( + "Unknown host func import {}", + field_name + ))); + } + }; + // We skip signature checks in this benchmarks since we are + // not interested in testing this here. + let func = v0::FuncInstance::alloc_host(func_type.clone(), index); + Ok(func) + } + + fn resolve_global( + &self, + module_name: &str, + field_name: &str, + _global_type: &v0::GlobalDescriptor, + ) -> Result { + Err(v0::Error::Instantiation(format!( + "Export {}::{} not found", + module_name, field_name + ))) + } + + fn resolve_memory( + &self, + module_name: &str, + field_name: &str, + _memory_type: &v0::MemoryDescriptor, + ) -> Result { + Err(v0::Error::Instantiation(format!( + "Export {}::{} not found", + module_name, field_name + ))) + } + + fn resolve_table( + &self, + module_name: &str, + field_name: &str, + _table_type: &v0::TableDescriptor, + ) -> Result { + Err(v0::Error::Instantiation(format!( + "Export {}::{} not found", + module_name, field_name + ))) + } + } + c.bench_function("execute/host_calls/v0", |b| { + b.iter(|| { + let value = instance.invoke_export( + "call", + &[Value::I64(HOST_CALLS_REPETITIONS)], + &mut BenchExternals, + ); + assert_matches!(value, Ok(Some(Value::I64(0)))); + }) + }); +} + +fn bench_execute_host_calls_v1(c: &mut Criterion) { + let wasm = wabt::wat2wasm(include_bytes!("wat/host_calls.wat")).unwrap(); + let engine = v1::Engine::default(); + let module = v1::Module::new(&engine, &wasm).unwrap(); + let mut linker = >::default(); + let mut store = v1::Store::new(&engine, ()); + let host_call = v1::Func::wrap(&mut store, |value: i64| value); + linker.define("benchmark", "host_call", host_call).unwrap(); + let instance = linker + .instantiate(&mut store, &module) + .unwrap() + .ensure_no_start(&mut store) + .unwrap(); + let call = instance + .get_export(&store, "call") + .and_then(v1::Extern::into_func) + .unwrap(); + let mut result = [Value::I64(0)]; + + c.bench_function("execute/host_calls/v1", |b| { + b.iter(|| { + call.call( + &mut store, + &[Value::I64(HOST_CALLS_REPETITIONS)], + &mut result, + ) + .unwrap(); + assert_matches!(result, [Value::I64(0)]); + }) + }); +} diff --git a/benches/build.rs b/benches/build.rs deleted file mode 100644 index 921815bcef..0000000000 --- a/benches/build.rs +++ /dev/null @@ -1,30 +0,0 @@ -use std::{env, process}; - -fn main() { - println!("cargo:rerun-if-changed=./wasm-kernel/"); - - // The CARGO environment variable provides a path to the executable that - // runs this build process. - let cargo_bin = env::var("CARGO").expect("CARGO env variable should be defined"); - - // Build a release version of wasm-kernel. The code in the output wasm binary - // will be used in benchmarks. - let output = process::Command::new(cargo_bin) - .arg("build") - .arg("--target=wasm32-unknown-unknown") - .arg("--release") - .arg("--manifest-path=./wasm-kernel/Cargo.toml") - .arg("--verbose") - .output() - .expect("failed to execute `cargo`"); - - if !output.status.success() { - let msg = format!( - "status: {status}\nstdout: {stdout}\nstderr: {stderr}\n", - status = output.status, - stdout = String::from_utf8_lossy(&output.stdout), - stderr = String::from_utf8_lossy(&output.stderr), - ); - panic!("{}", msg); - } -} diff --git a/benches/src/lib.rs b/benches/src/lib.rs deleted file mode 100644 index f29e78bb76..0000000000 --- a/benches/src/lib.rs +++ /dev/null @@ -1,738 +0,0 @@ -#![feature(test)] - -extern crate test; - -#[macro_use] -extern crate assert_matches; - -use core::slice; -use std::{fs::File, io::Read as _}; -use test::Bencher; -use wasmi::{ - v1, - Error, - Externals, - FuncInstance, - FuncRef, - GlobalDescriptor, - GlobalRef, - ImportResolver, - ImportsBuilder, - MemoryDescriptor, - MemoryRef, - Module, - ModuleInstance, - NopExternals, - RuntimeArgs, - Value, - Signature, - TableDescriptor, - TableRef, - Trap, -}; - -/// Returns the Wasm binary at the given `file_name` as `Vec`. -/// -/// # Note -/// -/// This includes validation and compilation to `wasmi` bytecode. -/// -/// # Panics -/// -/// - If the benchmark Wasm file could not be opened, read or parsed. -fn load_file(file_name: &str) -> Vec { - let mut file = File::open(file_name) - .unwrap_or_else(|error| panic!("could not open benchmark file {}: {}", file_name, error)); - let mut buffer = Vec::new(); - file.read_to_end(&mut buffer).unwrap_or_else(|error| { - panic!("could not read file at {} to buffer: {}", file_name, error) - }); - buffer -} - -/// Parses the Wasm binary at the given `file_name` into a `wasmi` module. -/// -/// # Note -/// -/// This includes validation and compilation to `wasmi` bytecode. -/// -/// # Panics -/// -/// - If the benchmark Wasm file could not be opened, read or parsed. -fn load_module(file_name: &str) -> Module { - let buffer = load_file(file_name); - Module::from_buffer(buffer).unwrap_or_else(|error| { - panic!( - "could not parse Wasm module from file {}: {}", - file_name, error - ) - }) -} - -const WASM_KERNEL: &str = "wasm-kernel/target/wasm32-unknown-unknown/release/wasm_kernel.wasm"; -const REVCOMP_INPUT: &[u8] = include_bytes!("./revcomp-input.txt"); -const REVCOMP_OUTPUT: &[u8] = include_bytes!("./revcomp-output.txt"); - -#[bench] -fn bench_compile_and_validate(b: &mut Bencher) { - let wasm_bytes = load_file(WASM_KERNEL); - b.iter(|| { - let _module = Module::from_buffer(&wasm_bytes).unwrap(); - }); -} - -#[bench] -fn bench_compile_and_validate_v1(b: &mut Bencher) { - let wasm_bytes = load_file(WASM_KERNEL); - - b.iter(|| { - let engine = v1::Engine::default(); - let _module = v1::Module::new(&engine, &wasm_bytes).unwrap(); - }); -} - -#[bench] -fn bench_instantiate_module(b: &mut Bencher) { - let wasm_kernel = load_module(WASM_KERNEL); - - b.iter(|| { - let _instance = ModuleInstance::new(&wasm_kernel, &ImportsBuilder::default()) - .expect("failed to instantiate wasm module") - .assert_no_start(); - }); -} - -#[bench] -fn bench_instantiate_module_v1(b: &mut Bencher) { - let wasm_bytes = load_file(WASM_KERNEL); - let engine = v1::Engine::default(); - let mut linker = >::default(); - let module = v1::Module::new(&engine, &wasm_bytes).unwrap(); - - b.iter(|| { - let mut store = v1::Store::new(&engine, ()); - let _instance = linker.instantiate(&mut store, &module).unwrap(); - }); -} - -#[bench] -fn bench_tiny_keccak(b: &mut Bencher) { - let wasm_kernel = load_module(WASM_KERNEL); - let instance = ModuleInstance::new(&wasm_kernel, &ImportsBuilder::default()) - .expect("failed to instantiate wasm module") - .assert_no_start(); - let test_data_ptr = assert_matches!( - instance.invoke_export("prepare_tiny_keccak", &[], &mut NopExternals), - Ok(Some(v @ Value::I32(_))) => v - ); - - b.iter(|| { - instance - .invoke_export("bench_tiny_keccak", &[test_data_ptr], &mut NopExternals) - .unwrap(); - }); -} - -#[bench] -fn bench_tiny_keccak_v1(b: &mut Bencher) { - let wasm = load_file(WASM_KERNEL); - let engine = v1::Engine::default(); - let module = v1::Module::new(&engine, &wasm).unwrap(); - let mut linker = >::default(); - let mut store = v1::Store::new(&engine, ()); - let instance = linker - .instantiate(&mut store, &module) - .unwrap() - .ensure_no_start(&mut store) - .unwrap(); - let prepare = instance - .get_export(&store, "prepare_tiny_keccak") - .and_then(v1::Extern::into_func) - .unwrap(); - let keccak = instance - .get_export(&store, "bench_tiny_keccak") - .and_then(v1::Extern::into_func) - .unwrap(); - let mut test_data_ptr = Value::I32(0); - - prepare - .call(&mut store, &[], std::slice::from_mut(&mut test_data_ptr)) - .unwrap(); - assert!(matches!(test_data_ptr, Value::I32(_))); - b.iter(|| { - keccak - .call(&mut store, std::slice::from_ref(&test_data_ptr), &mut []) - .unwrap(); - }); -} - -#[bench] -fn bench_rev_comp(b: &mut Bencher) { - let wasm_kernel = load_module(WASM_KERNEL); - let instance = ModuleInstance::new(&wasm_kernel, &ImportsBuilder::default()) - .expect("failed to instantiate wasm module") - .assert_no_start(); - - // Allocate buffers for the input and output. - let test_data_ptr: Value = { - let input_size = Value::I32(REVCOMP_INPUT.len() as i32); - assert_matches!( - instance.invoke_export("prepare_rev_complement", &[input_size], &mut NopExternals), - Ok(Some(v @ Value::I32(_))) => v, - "", - ) - }; - - // Get the pointer to the input buffer. - let input_data_mem_offset = assert_matches!( - instance.invoke_export("rev_complement_input_ptr", &[test_data_ptr], &mut NopExternals), - Ok(Some(Value::I32(v))) => v as u32, - "", - ); - - // Copy test data inside the wasm memory. - let memory = instance - .export_by_name("memory") - .expect("Expected export with a name 'memory'") - .as_memory() - .expect("'memory' should be a memory instance") - .clone(); - memory - .set(input_data_mem_offset, REVCOMP_INPUT) - .expect("can't load test data into a wasm memory"); - - b.iter(|| { - instance - .invoke_export("bench_rev_complement", &[test_data_ptr], &mut NopExternals) - .unwrap(); - }); - - // Verify the result. - let output_data_mem_offset = assert_matches!( - instance.invoke_export("rev_complement_output_ptr", &[test_data_ptr], &mut NopExternals), - Ok(Some(Value::I32(v))) => v as u32, - "", - ); - let mut result = vec![0x00_u8; REVCOMP_OUTPUT.len()]; - memory - .get_into(output_data_mem_offset, &mut result) - .expect("can't get result data from a wasm memory"); - assert_eq!(&*result, REVCOMP_OUTPUT); -} - -#[bench] -fn bench_rev_comp_v1(b: &mut Bencher) { - let wasm = load_file(WASM_KERNEL); - let engine = v1::Engine::default(); - let module = v1::Module::new(&engine, &wasm).unwrap(); - let mut linker = >::default(); - let mut store = v1::Store::new(&engine, ()); - let instance = linker - .instantiate(&mut store, &module) - .unwrap() - .ensure_no_start(&mut store) - .unwrap(); - - // Allocate buffers for the input and output. - let mut result = RuntimeValue::I32(0); - let input_size = RuntimeValue::I32(REVCOMP_INPUT.len() as i32); - let prepare_rev_complement = instance - .get_export(&store, "prepare_rev_complement") - .and_then(v1::Extern::into_func) - .unwrap(); - prepare_rev_complement - .call(&mut store, &[input_size], slice::from_mut(&mut result)) - .unwrap(); - let test_data_ptr = match result { - value @ RuntimeValue::I32(_) => value, - _ => panic!("unexpected non-I32 result found for prepare_rev_complement"), - }; - - // Get the pointer to the input buffer. - let rev_complement_input_ptr = instance - .get_export(&store, "rev_complement_input_ptr") - .and_then(v1::Extern::into_func) - .unwrap(); - rev_complement_input_ptr - .call(&mut store, &[test_data_ptr], slice::from_mut(&mut result)) - .unwrap(); - let input_data_mem_offset = match result { - RuntimeValue::I32(value) => value, - _ => panic!("unexpected non-I32 result found for prepare_rev_complement"), - }; - - // Copy test data inside the wasm memory. - let memory = instance - .get_export(&store, "memory") - .and_then(v1::Extern::into_memory) - .expect("failed to find 'memory' exported linear memory in instance"); - memory - .write(&mut store, input_data_mem_offset as usize, REVCOMP_INPUT) - .expect("failed to write test data into a wasm memory"); - - let bench_rev_complement = instance - .get_export(&store, "bench_rev_complement") - .and_then(v1::Extern::into_func) - .unwrap(); - b.iter(|| { - bench_rev_complement - .call(&mut store, &[test_data_ptr], &mut []) - .unwrap(); - }); - - // Get the pointer to the output buffer. - let rev_complement_output_ptr = instance - .get_export(&store, "rev_complement_output_ptr") - .and_then(v1::Extern::into_func) - .unwrap(); - rev_complement_output_ptr - .call(&mut store, &[test_data_ptr], slice::from_mut(&mut result)) - .unwrap(); - let output_data_mem_offset = match result { - RuntimeValue::I32(value) => value, - _ => panic!("unexpected non-I32 result found for prepare_rev_complement"), - }; - - let mut revcomp_result = vec![0x00_u8; REVCOMP_OUTPUT.len()]; - memory - .read(&store, output_data_mem_offset as usize, &mut revcomp_result) - .expect("failed to read result data from a wasm memory"); - assert_eq!(&revcomp_result[..], REVCOMP_OUTPUT); -} - -#[bench] -fn bench_regex_redux(b: &mut Bencher) { - let wasm_kernel = load_module(WASM_KERNEL); - let instance = ModuleInstance::new(&wasm_kernel, &ImportsBuilder::default()) - .expect("failed to instantiate wasm module") - .assert_no_start(); - - // Allocate buffers for the input and output. - let test_data_ptr: Value = { - let input_size = Value::I32(REVCOMP_INPUT.len() as i32); - assert_matches!( - instance.invoke_export("prepare_regex_redux", &[input_size], &mut NopExternals), - Ok(Some(v @ Value::I32(_))) => v, - "", - ) - }; - - // Get the pointer to the input buffer. - let input_data_mem_offset = assert_matches!( - instance.invoke_export("regex_redux_input_ptr", &[test_data_ptr], &mut NopExternals), - Ok(Some(Value::I32(v))) => v as u32, - "", - ); - - // Copy test data inside the wasm memory. - let memory = instance - .export_by_name("memory") - .expect("Expected export with a name 'memory'") - .as_memory() - .expect("'memory' should be a memory instance") - .clone(); - memory - .set(input_data_mem_offset, REVCOMP_INPUT) - .expect("can't load test data into a wasm memory"); - - b.iter(|| { - instance - .invoke_export("bench_regex_redux", &[test_data_ptr], &mut NopExternals) - .unwrap(); - }); -} - -#[bench] -fn bench_regex_redux_v1(b: &mut Bencher) { - let wasm = load_file(WASM_KERNEL); - let engine = v1::Engine::default(); - let module = v1::Module::new(&engine, &wasm).unwrap(); - let mut linker = >::default(); - let mut store = v1::Store::new(&engine, ()); - let instance = linker - .instantiate(&mut store, &module) - .unwrap() - .ensure_no_start(&mut store) - .unwrap(); - - // Allocate buffers for the input and output. - let mut result = RuntimeValue::I32(0); - let input_size = RuntimeValue::I32(REVCOMP_INPUT.len() as i32); - let prepare_regex_redux = instance - .get_export(&store, "prepare_regex_redux") - .and_then(v1::Extern::into_func) - .unwrap(); - prepare_regex_redux - .call(&mut store, &[input_size], slice::from_mut(&mut result)) - .unwrap(); - let test_data_ptr = match result { - value @ RuntimeValue::I32(_) => value, - _ => panic!("unexpected non-I32 result found for prepare_regex_redux"), - }; - - // Get the pointer to the input buffer. - let regex_redux_input_ptr = instance - .get_export(&store, "regex_redux_input_ptr") - .and_then(v1::Extern::into_func) - .unwrap(); - regex_redux_input_ptr - .call(&mut store, &[test_data_ptr], slice::from_mut(&mut result)) - .unwrap(); - let input_data_mem_offset = match result { - RuntimeValue::I32(value) => value, - _ => panic!("unexpected non-I32 result found for regex_redux_input_ptr"), - }; - - // Copy test data inside the wasm memory. - let memory = instance - .get_export(&store, "memory") - .and_then(v1::Extern::into_memory) - .expect("failed to find 'memory' exported linear memory in instance"); - memory - .write(&mut store, input_data_mem_offset as usize, REVCOMP_INPUT) - .expect("failed to write test data into a wasm memory"); - - let bench_regex_redux = instance - .get_export(&store, "bench_regex_redux") - .and_then(v1::Extern::into_func) - .unwrap(); - b.iter(|| { - bench_regex_redux - .call(&mut store, &[test_data_ptr], &mut []) - .unwrap(); - }); -} - -#[bench] -fn count_until(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/count_until.wat")).unwrap(); - let module = Module::from_buffer(&wasm).unwrap(); - let instance = ModuleInstance::new(&module, &ImportsBuilder::default()) - .expect("failed to instantiate wasm module") - .assert_no_start(); - const REPETITIONS: i32 = 100_000; - b.iter(|| { - let value = instance.invoke_export( - "count_until", - &[Value::I32(REPETITIONS)], - &mut NopExternals, - ); - assert_matches!(value, Ok(Some(Value::I32(REPETITIONS)))); - }); -} - -#[bench] -fn count_until_v1(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/count_until.wat")).unwrap(); - let engine = v1::Engine::default(); - let module = v1::Module::new(&engine, &wasm).unwrap(); - let mut linker = >::default(); - let mut store = v1::Store::new(&engine, ()); - let instance = linker - .instantiate(&mut store, &module) - .unwrap() - .ensure_no_start(&mut store) - .unwrap(); - let count_until = instance - .get_export(&store, "count_until") - .and_then(v1::Extern::into_func) - .unwrap(); - const REPETITIONS: i32 = 100_000; - let mut result = [Value::I32(0)]; - b.iter(|| { - count_until - .call(&mut store, &[Value::I32(REPETITIONS)], &mut result) - .unwrap(); - assert_matches!(result, [Value::I32(REPETITIONS)]); - }); -} - -#[bench] -fn fac_recursive(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/recursive_factorial.wat")).unwrap(); - let module = Module::from_buffer(&wasm).unwrap(); - let instance = ModuleInstance::new(&module, &ImportsBuilder::default()) - .expect("failed to instantiate wasm module") - .assert_no_start(); - - b.iter(|| { - let value = instance.invoke_export("fac-rec", &[Value::I64(25)], &mut NopExternals); - assert_matches!(value, Ok(Some(Value::I64(7034535277573963776)))); - }); -} - -#[bench] -fn fac_recursive_v1(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/recursive_factorial.wat")).unwrap(); - let engine = v1::Engine::default(); - let module = v1::Module::new(&engine, &wasm).unwrap(); - let mut linker = >::default(); - let mut store = v1::Store::new(&engine, ()); - let instance = linker - .instantiate(&mut store, &module) - .unwrap() - .ensure_no_start(&mut store) - .unwrap(); - let fac = instance - .get_export(&store, "fac-rec") - .and_then(v1::Extern::into_func) - .unwrap(); - let mut result = [Value::I64(0)]; - - b.iter(|| { - fac.call(&mut store, &[Value::I64(25)], &mut result) - .unwrap(); - assert_matches!(result, [Value::I64(7034535277573963776)]); - }); -} - -#[bench] -fn fac_opt(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/optimized_factorial.wat")).unwrap(); - let module = Module::from_buffer(&wasm).unwrap(); - let instance = ModuleInstance::new(&module, &ImportsBuilder::default()) - .expect("failed to instantiate wasm module") - .assert_no_start(); - - b.iter(|| { - let value = instance.invoke_export("fac-opt", &[Value::I64(25)], &mut NopExternals); - assert_matches!(value, Ok(Some(Value::I64(7034535277573963776)))); - }); -} - -#[bench] -fn fac_opt_v1(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/optimized_factorial.wat")).unwrap(); - let engine = v1::Engine::default(); - let module = v1::Module::new(&engine, &wasm).unwrap(); - let mut linker = >::default(); - let mut store = v1::Store::new(&engine, ()); - let instance = linker - .instantiate(&mut store, &module) - .unwrap() - .ensure_no_start(&mut store) - .unwrap(); - let fac = instance - .get_export(&store, "fac-opt") - .and_then(v1::Extern::into_func) - .unwrap(); - let mut result = [Value::I64(0)]; - - b.iter(|| { - fac.call(&mut store, &[Value::I64(25)], &mut result) - .unwrap(); - assert_matches!(result, [Value::I64(7034535277573963776)]); - }); -} - -// This is used for testing overhead of a function call -// is not too large. -#[bench] -fn recursive_ok(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/recursive_ok.wat")).unwrap(); - let module = Module::from_buffer(&wasm).unwrap(); - let instance = ModuleInstance::new(&module, &ImportsBuilder::default()) - .expect("failed to instantiate wasm module") - .assert_no_start(); - - b.iter(|| { - let value = instance.invoke_export("call", &[Value::I32(8000)], &mut NopExternals); - assert_matches!(value, Ok(Some(Value::I32(0)))); - }); -} - -#[bench] -fn recursive_ok_v1(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/recursive_ok.wat")).unwrap(); - let engine = v1::Engine::default(); - let module = v1::Module::new(&engine, &wasm).unwrap(); - let mut linker = >::default(); - let mut store = v1::Store::new(&engine, ()); - let instance = linker - .instantiate(&mut store, &module) - .unwrap() - .ensure_no_start(&mut store) - .unwrap(); - let bench_call = instance - .get_export(&store, "call") - .and_then(v1::Extern::into_func) - .unwrap(); - let mut result = [Value::I32(0)]; - - b.iter(|| { - bench_call - .call(&mut store, &[Value::I32(8000)], &mut result) - .unwrap(); - assert_matches!(result, [Value::I32(0)]); - }); -} - -#[bench] -fn recursive_trap(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/recursive_trap.wat")).unwrap(); - let module = Module::from_buffer(&wasm).unwrap(); - let instance = ModuleInstance::new(&module, &ImportsBuilder::default()) - .expect("failed to instantiate wasm module") - .assert_no_start(); - - b.iter(|| { - let value = instance.invoke_export("call", &[Value::I32(1000)], &mut NopExternals); - assert_matches!(value, Err(_)); - }); -} - -#[bench] -fn recursive_trap_v1(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/recursive_trap.wat")).unwrap(); - let engine = v1::Engine::default(); - let module = v1::Module::new(&engine, &wasm).unwrap(); - let mut linker = >::default(); - let mut store = v1::Store::new(&engine, ()); - let instance = linker - .instantiate(&mut store, &module) - .unwrap() - .ensure_no_start(&mut store) - .unwrap(); - let bench_call = instance - .get_export(&store, "call") - .and_then(v1::Extern::into_func) - .unwrap(); - let mut result = [RuntimeValue::I32(0)]; - - b.iter(|| { - let result = bench_call.call(&mut store, &[RuntimeValue::I32(1000)], &mut result); - assert_matches!(result, Err(_)); - }); -} - -#[bench] -fn host_calls(b: &mut Bencher) { - let wasm = wabt::wat2wasm(include_bytes!("../wat/host_calls.wat")).unwrap(); - let module = Module::from_buffer(&wasm).unwrap(); - let instance = ModuleInstance::new(&module, &BenchExternals) - .expect("failed to instantiate wasm module") - .assert_no_start(); - - /// The benchmark externals provider. - pub struct BenchExternals; - - /// The index of the host function that is about to be called a lot. - const HOST_CALL_INDEX: usize = 0; - - /// How often the `host_call` should be called per Wasm invocation. - const REPETITIONS: i64 = 1000; - - impl Externals for BenchExternals { - fn invoke_index( - &mut self, - index: usize, - args: RuntimeArgs, - ) -> Result, Trap> { - match index { - HOST_CALL_INDEX => { - let arg = args.nth_value_checked(0)?; - Ok(Some(arg)) - } - _ => panic!("BenchExternals do not provide function at index {}", index), - } - } - } - - impl ImportResolver for BenchExternals { - fn resolve_func( - &self, - _module_name: &str, - field_name: &str, - func_type: &Signature, - ) -> Result { - let index = match field_name { - "host_call" => HOST_CALL_INDEX, - _ => { - return Err(Error::Instantiation(format!( - "Unknown host func import {}", - field_name - ))); - } - }; - // We skip signature checks in this benchmarks since we are - // not interested in testing this here. - let func = FuncInstance::alloc_host(func_type.clone(), index); - Ok(func) - } - - fn resolve_global( - &self, - module_name: &str, - field_name: &str, - _global_type: &GlobalDescriptor, - ) -> Result { - Err(Error::Instantiation(format!( - "Export {}::{} not found", - module_name, field_name - ))) - } - - fn resolve_memory( - &self, - module_name: &str, - field_name: &str, - _memory_type: &MemoryDescriptor, - ) -> Result { - Err(Error::Instantiation(format!( - "Export {}::{} not found", - module_name, field_name - ))) - } - - fn resolve_table( - &self, - module_name: &str, - field_name: &str, - _table_type: &TableDescriptor, - ) -> Result { - Err(Error::Instantiation(format!( - "Export {}::{} not found", - module_name, field_name - ))) - } - } - - b.iter(|| { - let value = instance.invoke_export( - "call", - &[Value::I64(REPETITIONS)], - &mut BenchExternals, - ); - assert_matches!(value, Ok(Some(Value::I64(0)))); - }); -} - -#[bench] -fn host_calls_v1(b: &mut Bencher) { - /// How often the `host_call` should be called per Wasm invocation. - const REPETITIONS: i64 = 1000; - - let wasm = wabt::wat2wasm(include_bytes!("../wat/host_calls.wat")).unwrap(); - let engine = v1::Engine::default(); - let module = v1::Module::new(&engine, &wasm).unwrap(); - let mut linker = >::default(); - let mut store = v1::Store::new(&engine, ()); - let host_call = v1::Func::wrap(&mut store, |value: i64| value); - linker.define("benchmark", "host_call", host_call).unwrap(); - let instance = linker - .instantiate(&mut store, &module) - .unwrap() - .ensure_no_start(&mut store) - .unwrap(); - let call = instance - .get_export(&store, "call") - .and_then(v1::Extern::into_func) - .unwrap(); - let mut result = [Value::I64(0)]; - - b.iter(|| { - call.call(&mut store, &[Value::I64(REPETITIONS)], &mut result) - .unwrap(); - assert_matches!(result, [Value::I64(0)]); - }); -} diff --git a/benches/src/revcomp-input.txt b/benches/src/revcomp-input.txt deleted file mode 100644 index f1caba0d62..0000000000 --- a/benches/src/revcomp-input.txt +++ /dev/null @@ -1,171 +0,0 @@ ->ONE Homo sapiens alu -GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA -TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT -AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG -GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG -CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT -GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA -GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA -TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG -AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA -GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT -AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC -AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG -GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC -CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG -AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT -TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA -TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT -GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG -TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT -CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG -CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG -TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA -CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG -AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG -GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC -TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA -TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA -GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT -GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC -ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT -TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC -CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG -CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG -GGCGACAGAGCGAGACTCCG ->TWO IUB ambiguity codes -cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg -tactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaa -NtactMcSMtYtcMgRtacttctWBacgaaatatagScDtttgaagacacatagtVgYgt -cattHWtMMWcStgttaggKtSgaYaaccWStcgBttgcgaMttBYatcWtgacaYcaga -gtaBDtRacttttcWatMttDBcatWtatcttactaBgaYtcttgttttttttYaaScYa -HgtgttNtSatcMtcVaaaStccRcctDaataataStcYtRDSaMtDttgttSagtRRca -tttHatSttMtWgtcgtatSSagactYaaattcaMtWatttaSgYttaRgKaRtccactt -tattRggaMcDaWaWagttttgacatgttctacaaaRaatataataaMttcgDacgaSSt -acaStYRctVaNMtMgtaggcKatcttttattaaaaagVWaHKYagtttttatttaacct -tacgtVtcVaattVMBcttaMtttaStgacttagattWWacVtgWYagWVRctDattBYt -gtttaagaagattattgacVatMaacattVctgtBSgaVtgWWggaKHaatKWcBScSWa -accRVacacaaactaccScattRatatKVtactatatttHttaagtttSKtRtacaaagt -RDttcaaaaWgcacatWaDgtDKacgaacaattacaRNWaatHtttStgttattaaMtgt -tgDcgtMgcatBtgcttcgcgaDWgagctgcgaggggVtaaScNatttacttaatgacag -cccccacatYScaMgtaggtYaNgttctgaMaacNaMRaacaaacaKctacatagYWctg -ttWaaataaaataRattagHacacaagcgKatacBttRttaagtatttccgatctHSaat -actcNttMaagtattMtgRtgaMgcataatHcMtaBSaRattagttgatHtMttaaKagg -YtaaBataSaVatactWtataVWgKgttaaaacagtgcgRatatacatVtHRtVYataSa -KtWaStVcNKHKttactatccctcatgWHatWaRcttactaggatctataDtDHBttata -aaaHgtacVtagaYttYaKcctattcttcttaataNDaaggaaaDYgcggctaaWSctBa -aNtgctggMBaKctaMVKagBaactaWaDaMaccYVtNtaHtVWtKgRtcaaNtYaNacg -gtttNattgVtttctgtBaWgtaattcaagtcaVWtactNggattctttaYtaaagccgc -tcttagHVggaYtgtNcDaVagctctctKgacgtatagYcctRYHDtgBattDaaDgccK -tcHaaStttMcctagtattgcRgWBaVatHaaaataYtgtttagMDMRtaataaggatMt -ttctWgtNtgtgaaaaMaatatRtttMtDgHHtgtcattttcWattRSHcVagaagtacg -ggtaKVattKYagactNaatgtttgKMMgYNtcccgSKttctaStatatNVataYHgtNa -BKRgNacaactgatttcctttaNcgatttctctataScaHtataRagtcRVttacDSDtt -aRtSatacHgtSKacYagttMHtWataggatgactNtatSaNctataVtttRNKtgRacc -tttYtatgttactttttcctttaaacatacaHactMacacggtWataMtBVacRaSaatc -cgtaBVttccagccBcttaRKtgtgcctttttRtgtcagcRttKtaaacKtaaatctcac -aattgcaNtSBaaccgggttattaaBcKatDagttactcttcattVtttHaaggctKKga -tacatcBggScagtVcacattttgaHaDSgHatRMaHWggtatatRgccDttcgtatcga -aacaHtaagttaRatgaVacttagattVKtaaYttaaatcaNatccRttRRaMScNaaaD -gttVHWgtcHaaHgacVaWtgttScactaagSgttatcttagggDtaccagWattWtRtg -ttHWHacgattBtgVcaYatcggttgagKcWtKKcaVtgaYgWctgYggVctgtHgaNcV -taBtWaaYatcDRaaRtSctgaHaYRttagatMatgcatttNattaDttaattgttctaa -ccctcccctagaWBtttHtBccttagaVaatMcBHagaVcWcagBVttcBtaYMccagat -gaaaaHctctaacgttagNWRtcggattNatcRaNHttcagtKttttgWatWttcSaNgg -gaWtactKKMaacatKatacNattgctWtatctaVgagctatgtRaHtYcWcttagccaa -tYttWttaWSSttaHcaaaaagVacVgtaVaRMgattaVcDactttcHHggHRtgNcctt -tYatcatKgctcctctatVcaaaaKaaaagtatatctgMtWtaaaacaStttMtcgactt -taSatcgDataaactaaacaagtaaVctaggaSccaatMVtaaSKNVattttgHccatca -cBVctgcaVatVttRtactgtVcaattHgtaaattaaattttYtatattaaRSgYtgBag -aHSBDgtagcacRHtYcBgtcacttacactaYcgctWtattgSHtSatcataaatataHt -cgtYaaMNgBaatttaRgaMaatatttBtttaaaHHKaatctgatWatYaacttMctctt -ttVctagctDaaagtaVaKaKRtaacBgtatccaaccactHHaagaagaaggaNaaatBW -attccgStaMSaMatBttgcatgRSacgttVVtaaDMtcSgVatWcaSatcttttVatag -ttactttacgatcaccNtaDVgSRcgVcgtgaacgaNtaNatatagtHtMgtHcMtagaa -attBgtataRaaaacaYKgtRccYtatgaagtaataKgtaaMttgaaRVatgcagaKStc -tHNaaatctBBtcttaYaBWHgtVtgacagcaRcataWctcaBcYacYgatDgtDHccta ->THREE Homo sapiens frequency -aacacttcaccaggtatcgtgaaggctcaagattacccagagaacctttgcaatataaga -atatgtatgcagcattaccctaagtaattatattctttttctgactcaaagtgacaagcc -ctagtgtatattaaatcggtatatttgggaaattcctcaaactatcctaatcaggtagcc -atgaaagtgatcaaaaaagttcgtacttataccatacatgaattctggccaagtaaaaaa -tagattgcgcaaaattcgtaccttaagtctctcgccaagatattaggatcctattactca -tatcgtgtttttctttattgccgccatccccggagtatctcacccatccttctcttaaag -gcctaatattacctatgcaaataaacatatattgttgaaaattgagaacctgatcgtgat -tcttatgtgtaccatatgtatagtaatcacgcgactatatagtgctttagtatcgcccgt -gggtgagtgaatattctgggctagcgtgagatagtttcttgtcctaatatttttcagatc -gaatagcttctatttttgtgtttattgacatatgtcgaaactccttactcagtgaaagtc -atgaccagatccacgaacaatcttcggaatcagtctcgttttacggcggaatcttgagtc -taacttatatcccgtcgcttactttctaacaccccttatgtatttttaaaattacgttta -ttcgaacgtacttggcggaagcgttattttttgaagtaagttacattgggcagactcttg -acattttcgatacgactttctttcatccatcacaggactcgttcgtattgatatcagaag -ctcgtgatgattagttgtcttctttaccaatactttgaggcctattctgcgaaatttttg -ttgccctgcgaacttcacataccaaggaacacctcgcaacatgccttcatatccatcgtt -cattgtaattcttacacaatgaatcctaagtaattacatccctgcgtaaaagatggtagg -ggcactgaggatatattaccaagcatttagttatgagtaatcagcaatgtttcttgtatt -aagttctctaaaatagttacatcgtaatgttatctcgggttccgcgaataaacgagatag -attcattatatatggccctaagcaaaaacctcctcgtattctgttggtaattagaatcac -acaatacgggttgagatattaattatttgtagtacgaagagatataaaaagatgaacaat -tactcaagtcaagatgtatacgggatttataataaaaatcgggtagagatctgctttgca -attcagacgtgccactaaatcgtaatatgtcgcgttacatcagaaagggtaactattatt -aattaataaagggcttaatcactacatattagatcttatccgatagtcttatctattcgt -tgtatttttaagcggttctaattcagtcattatatcagtgctccgagttctttattattg -ttttaaggatgacaaaatgcctcttgttataacgctgggagaagcagactaagagtcgga -gcagttggtagaatgaggctgcaaaagacggtctcgacgaatggacagactttactaaac -caatgaaagacagaagtagagcaaagtctgaagtggtatcagcttaattatgacaaccct -taatacttccctttcgccgaatactggcgtggaaaggttttaaaagtcgaagtagttaga -ggcatctctcgctcataaataggtagactactcgcaatccaatgtgactatgtaatactg -ggaacatcagtccgcgatgcagcgtgtttatcaaccgtccccactcgcctggggagacat -gagaccacccccgtggggattattagtccgcagtaatcgactcttgacaatccttttcga -ttatgtcatagcaatttacgacagttcagcgaagtgactactcggcgaaatggtattact -aaagcattcgaacccacatgaatgtgattcttggcaatttctaatccactaaagcttttc -cgttgaatctggttgtagatatttatataagttcactaattaagatcacggtagtatatt -gatagtgatgtctttgcaagaggttggccgaggaatttacggattctctattgatacaat -ttgtctggcttataactcttaaggctgaaccaggcgtttttagacgacttgatcagctgt -tagaatggtttggactccctctttcatgtcagtaacatttcagccgttattgttacgata -tgcttgaacaatattgatctaccacacacccatagtatattttataggtcatgctgttac -ctacgagcatggtattccacttcccattcaatgagtattcaacatcactagcctcagaga -tgatgacccacctctaataacgtcacgttgcggccatgtgaaacctgaacttgagtagac -gatatcaagcgctttaaattgcatataacatttgagggtaaagctaagcggatgctttat -ataatcaatactcaataataagatttgattgcattttagagttatgacacgacatagttc -actaacgagttactattcccagatctagactgaagtactgatcgagacgatccttacgtc -gatgatcgttagttatcgacttaggtcgggtctctagcggtattggtacttaaccggaca -ctatactaataacccatgatcaaagcataacagaatacagacgataatttcgccaacata -tatgtacagaccccaagcatgagaagctcattgaaagctatcattgaagtcccgctcaca -atgtgtcttttccagacggtttaactggttcccgggagtcctggagtttcgacttacata -aatggaaacaatgtattttgctaatttatctatagcgtcatttggaccaatacagaatat -tatgttgcctagtaatccactataacccgcaagtgctgatagaaaatttttagacgattt -ataaatgccccaagtatccctcccgtgaatcctccgttatactaattagtattcgttcat -acgtataccgcgcatatatgaacatttggcgataaggcgcgtgaattgttacgtgacaga -gatagcagtttcttgtgatatggttaacagacgtacatgaagggaaactttatatctata -gtgatgcttccgtagaaataccgccactggtctgccaatgatgaagtatgtagctttagg -tttgtactatgaggctttcgtttgtttgcagagtataacagttgcgagtgaaaaaccgac -gaatttatactaatacgctttcactattggctacaaaatagggaagagtttcaatcatga -gagggagtatatggatgctttgtagctaaaggtagaacgtatgtatatgctgccgttcat -tcttgaaagatacataagcgataagttacgacaattataagcaacatccctaccttcgta -acgatttcactgttactgcgcttgaaatacactatggggctattggcggagagaagcaga -tcgcgccgagcatatacgagacctataatgttgatgatagagaaggcgtctgaattgata -catcgaagtacactttctttcgtagtatctctcgtcctctttctatctccggacacaaga -attaagttatatatatagagtcttaccaatcatgttgaatcctgattctcagagttcttt -ggcgggccttgtgatgactgagaaacaatgcaatattgctccaaatttcctaagcaaatt -ctcggttatgttatgttatcagcaaagcgttacgttatgttatttaaatctggaatgacg -gagcgaagttcttatgtcggtgtgggaataattcttttgaagacagcactccttaaataa -tatcgctccgtgtttgtatttatcgaatgggtctgtaaccttgcacaagcaaatcggtgg -tgtatatatcggataacaattaatacgatgttcatagtgacagtatactgatcgagtcct -ctaaagtcaattacctcacttaacaatctcattgatgttgtgtcattcccggtatcgccc -gtagtatgtgctctgattgaccgagtgtgaaccaaggaacatctactaatgcctttgtta -ggtaagatctctctgaattccttcgtgccaacttaaaacattatcaaaatttcttctact -tggattaactacttttacgagcatggcaaattcccctgtggaagacggttcattattatc -ggaaaccttatagaaattgcgtgttgactgaaattagatttttattgtaagagttgcatc -tttgcgattcctctggtctagcttccaatgaacagtcctcccttctattcgacatcgggt -ccttcgtacatgtctttgcgatgtaataattaggttcggagtgtggccttaatgggtgca -actaggaatacaacgcaaatttgctgacatgatagcaaatcggtatgccggcaccaaaac -gtgctccttgcttagcttgtgaatgagactcagtagttaaataaatccatatctgcaatc -gattccacaggtattgtccactatctttgaactactctaagagatacaagcttagctgag -accgaggtgtatatgactacgctgatatctgtaaggtaccaatgcaggcaaagtatgcga -gaagctaataccggctgtttccagctttataagattaaaatttggctgtcctggcggcct -cagaattgttctatcgtaatcagttggttcattaattagctaagtacgaggtacaactta -tctgtcccagaacagctccacaagtttttttacagccgaaacccctgtgtgaatcttaat -atccaagcgcgttatctgattagagtttacaactcagtattttatcagtacgttttgttt -ccaacattacccggtatgacaaaatgacgccacgtgtcgaataatggtctgaccaatgta -ggaagtgaaaagataaatat diff --git a/benches/src/revcomp-output.txt b/benches/src/revcomp-output.txt deleted file mode 100644 index 14d792ade8..0000000000 --- a/benches/src/revcomp-output.txt +++ /dev/null @@ -1,171 +0,0 @@ ->ONE Homo sapiens alu -CGGAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTCACTGCAAC -CTCCGCCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACA -GGCGCGCGCCACCACGCCCGGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCAT -GTTGGCCAGGCTGGTCTCGAACTCCTGACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAA -AGTGCTGGGATTACAGGCGTGAGCCACCGCGCCCGGCCTTTTTGAGACGGAGTCTCGCTC -TGTCGCCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTCACTGCAACCTCCGCCTCCCGG -GTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACAGGCGCGCGCCACC -ACGCCCGGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGCCAGGCTG -GTCTCGAACTCCTGACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTA -CAGGCGTGAGCCACCGCGCCCGGCCTTTTTGAGACGGAGTCTCGCTCTGTCGCCCAGGCT -GGAGTGCAGTGGCGCGATCTCGGCTCACTGCAACCTCCGCCTCCCGGGTTCAAGCGATTC -TCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACAGGCGCGCGCCACCACGCCCGGCTAAT -TTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGCCAGGCTGGTCTCGAACTCCT -GACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCA -CCGCGCCCGGCCTTTTTGAGACGGAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGC -GCGATCTCGGCTCACTGCAACCTCCGCCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCC -TCCCGAGTAGCTGGGATTACAGGCGCGCGCCACCACGCCCGGCTAATTTTTGTATTTTTA -GTAGAGACGGGGTTTCACCATGTTGGCCAGGCTGGTCTCGAACTCCTGACCTCAGGTGAT -CCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCGCGCCCGGCCT -TTTTGAGACGGAGTCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTC -ACTGCAACCTCCGCCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTG -GGATTACAGGCGCGCGCCACCACGCCCGGCTAATTTTTGTATTTTTAGTAGAGACGGGGT -TTCACCATGTTGGCCAGGCTGGTCTCGAACTCCTGACCTCAGGTGATCCGCCCGCCTCGG -CCTCCCAAAGTGCTGGGATTACAGGCGTGAGCCACCGCGCCCGGCCTTTTTGAGACGGAG -TCTCGCTCTGTCGCCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTCACTGCAACCTCCG -CCTCCCGGGTTCAAGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACAGGCGC -GCGCCACCACGCCCGGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGG -CCAGGCTGGTCTCGAACTCCTGACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAAAGTGC -TGGGATTACAGGCGTGAGCCACCGCGCCCGGCCTTTTTGAGACGGAGTCTCGCTCTGTCG -CCCAGGCTGGAGTGCAGTGGCGCGATCTCGGCTCACTGCAACCTCCGCCTCCCGGGTTCA -AGCGATTCTCCTGCCTCAGCCTCCCGAGTAGCTGGGATTACAGGCGCGCGCCACCACGCC -CGGCTAATTTTTGTATTTTTAGTAGAGACGGGGTTTCACCATGTTGGCCAGGCTGGTCTC -GAACTCCTGACCTCAGGTGATCCGCCCGCCTCGGCCTCCCAAAGTGCTGGGATTACAGGC -GTGAGCCACCGCGCCCGGCC ->TWO IUB ambiguity codes -TAGGDHACHATCRGTRGVTGAGWTATGYTGCTGTCABACDWVTRTAAGAVVAGATTTNDA -GASMTCTGCATBYTTCAAKTTACMTATTACTTCATARGGYACMRTGTTTTYTATACVAAT -TTCTAKGDACKADACTATATNTANTCGTTCACGBCGYSCBHTANGGTGATCGTAAAGTAA -CTATBAAAAGATSTGWATBCSGAKHTTABBAACGTSYCATGCAAVATKTSKTASCGGAAT -WVATTTNTCCTTCTTCTTDDAGTGGTTGGATACVGTTAYMTMTBTACTTTHAGCTAGBAA -AAGAGKAAGTTRATWATCAGATTMDDTTTAAAVAAATATTKTCYTAAATTVCNKTTRACG -ADTATATTTATGATSADSCAATAWAGCGRTAGTGTAAGTGACVGRADYGTGCTACHVSDT -CTVCARCSYTTAATATARAAAATTTAATTTACDAATTGBACAGTAYAABATBTGCAGBVG -TGATGGDCAAAATBNMSTTABKATTGGSTCCTAGBTTACTTGTTTAGTTTATHCGATSTA -AAGTCGAKAAASTGTTTTAWAKCAGATATACTTTTMTTTTGBATAGAGGAGCMATGATRA -AAGGNCAYDCCDDGAAAGTHGBTAATCKYTBTACBGTBCTTTTTGDTAASSWTAAWAARA -TTGGCTAAGWGRADTYACATAGCTCBTAGATAWAGCAATNGTATMATGTTKMMAGTAWTC -CCNTSGAAWATWCAAAAMACTGAADNTYGATNAATCCGAYWNCTAACGTTAGAGDTTTTC -ATCTGGKRTAVGAABVCTGWGBTCTDVGKATTBTCTAAGGVADAAAVWTCTAGGGGAGGG -TTAGAACAATTAAHTAATNAAATGCATKATCTAAYRTDTCAGSAYTTYHGATRTTWAVTA -BGNTCDACAGBCCRCAGWCRTCABTGMMAWGMCTCAACCGATRTGBCAVAATCGTDWDAA -CAYAWAATWCTGGTAHCCCTAAGATAACSCTTAGTGSAACAWTBGTCDTTDGACWDBAAC -HTTTNGSKTYYAAYGGATNTGATTTAARTTAMBAATCTAAGTBTCATYTAACTTADTGTT -TCGATACGAAHGGCYATATACCWDTKYATDCSHTDTCAAAATGTGBACTGSCCVGATGTA -TCMMAGCCTTDAAABAATGAAGAGTAACTHATMGVTTAATAACCCGGTTVSANTGCAATT -GTGAGATTTAMGTTTAMAAYGCTGACAYAAAAAGGCACAMYTAAGVGGCTGGAABVTACG -GATTSTYGTBVAKTATWACCGTGTKAGTDTGTATGTTTAAAGGAAAAAGTAACATARAAA -GGTYCAMNYAAABTATAGNTSATANAGTCATCCTATWADKAACTRGTMSACDGTATSAYT -AAHSHGTAABYGACTYTATADTGSTATAGAGAAATCGNTAAAGGAAATCAGTTGTNCYMV -TNACDRTATBNATATASTAGAAMSCGGGANRCKKMCAAACATTNAGTCTRMAATBMTACC -CGTACTTCTBGDSYAATWGAAAATGACADDCHAKAAAYATATTKTTTTCACANACWAGAA -AKATCCTTATTAYKHKCTAAACARTATTTTDATBTVWCYGCAATACTAGGKAAASTTDGA -MGGCHTTHAATVCAHDRYAGGRCTATACGTCMAGAGAGCTBTHGNACARTCCBDCTAAGA -GCGGCTTTARTAAAGAATCCNAGTAWBTGACTTGAATTACWTVACAGAAABCAATNAAAC -CGTNTRANTTGAYCMAWBADTANABRGGTKTHTWTAGTTVCTMBKTAGMTVKCCAGCANT -TVAGSWTTAGCCGCRHTTTCCTTHNTATTAAGAAGAATAGGMTRAARTCTABGTACDTTT -TATAAVDHAHTATAGATCCTAGTAAGYTWATDWCATGAGGGATAGTAAMDMNGBASTWAM -TSTATRBAYDABATGTATATYCGCACTGTTTTAACMCWBTATAWAGTATBTSTATVTTAR -CCTMTTAAKADATCAACTAATYTSVTAKGDATTATGCKTCAYCAKAATACTTKAANGAGT -ATTSDAGATCGGAAATACTTAAYAAVGTATMCGCTTGTGTDCTAATYTATTTTATTTWAA -CAGWRCTATGTAGMTGTTTGTTYKTNGTTKTCAGAACNTRACCTACKTGSRATGTGGGGG -CTGTCATTAAGTAAATNGSTTABCCCCTCGCAGCTCWHTCGCGAAGCAVATGCKACGHCA -ACAKTTAATAACASAAADATTWNYTGTAATTGTTCGTMHACHTWATGTGCWTTTTGAAHY -ACTTTGTAYAMSAAACTTAADAAATATAGTABMATATYAATGSGGTAGTTTGTGTBYGGT -TWSGSVGWMATTDMTCCWWCABTCSVACAGBAATGTTKATBGTCAATAATCTTCTTAAAC -ARVAATHAGYBWCTRWCABGTWWAATCTAAGTCASTAAAKTAAGVKBAATTBGABACGTA -AGGTTAAATAAAAACTRMDTWBCTTTTTAATAAAAGATMGCCTACKAKNTBAGYRASTGT -ASSTCGTHCGAAKTTATTATATTYTTTGTAGAACATGTCAAAACTWTWTHGKTCCYAATA -AAGTGGAYTMCYTAARCSTAAATWAKTGAATTTRAGTCTSSATACGACWAKAASATDAAA -TGYYACTSAACAAHAKTSHYARGASTATTATTHAGGYGGASTTTBGAKGATSANAACACD -TRGSTTRAAAAAAAACAAGARTCVTAGTAAGATAWATGVHAAKATWGAAAAGTYAHVTAC -TCTGRTGTCAWGATRVAAKTCGCAAVCGASWGGTTRTCSAMCCTAACASGWKKAWDAATG -ACRCBACTATGTGTCTTCAAAHGSCTATATTTCGTVWAGAAGTAYCKGARAKSGKAGTAN -TTTCYACATWATGTCTAAAADMDTWCAATSTKDACAMAADADBSAAATAGGCTHAHAGTA -CGACVGAATTATAAAGAHCCVAYHGHTTTACATSTTTATGNCCMTAGCATATGATAVAAG ->THREE Homo sapiens frequency -ATATTTATCTTTTCACTTCCTACATTGGTCAGACCATTATTCGACACGTGGCGTCATTTT -GTCATACCGGGTAATGTTGGAAACAAAACGTACTGATAAAATACTGAGTTGTAAACTCTA -ATCAGATAACGCGCTTGGATATTAAGATTCACACAGGGGTTTCGGCTGTAAAAAAACTTG -TGGAGCTGTTCTGGGACAGATAAGTTGTACCTCGTACTTAGCTAATTAATGAACCAACTG -ATTACGATAGAACAATTCTGAGGCCGCCAGGACAGCCAAATTTTAATCTTATAAAGCTGG -AAACAGCCGGTATTAGCTTCTCGCATACTTTGCCTGCATTGGTACCTTACAGATATCAGC -GTAGTCATATACACCTCGGTCTCAGCTAAGCTTGTATCTCTTAGAGTAGTTCAAAGATAG -TGGACAATACCTGTGGAATCGATTGCAGATATGGATTTATTTAACTACTGAGTCTCATTC -ACAAGCTAAGCAAGGAGCACGTTTTGGTGCCGGCATACCGATTTGCTATCATGTCAGCAA -ATTTGCGTTGTATTCCTAGTTGCACCCATTAAGGCCACACTCCGAACCTAATTATTACAT -CGCAAAGACATGTACGAAGGACCCGATGTCGAATAGAAGGGAGGACTGTTCATTGGAAGC -TAGACCAGAGGAATCGCAAAGATGCAACTCTTACAATAAAAATCTAATTTCAGTCAACAC -GCAATTTCTATAAGGTTTCCGATAATAATGAACCGTCTTCCACAGGGGAATTTGCCATGC -TCGTAAAAGTAGTTAATCCAAGTAGAAGAAATTTTGATAATGTTTTAAGTTGGCACGAAG -GAATTCAGAGAGATCTTACCTAACAAAGGCATTAGTAGATGTTCCTTGGTTCACACTCGG -TCAATCAGAGCACATACTACGGGCGATACCGGGAATGACACAACATCAATGAGATTGTTA -AGTGAGGTAATTGACTTTAGAGGACTCGATCAGTATACTGTCACTATGAACATCGTATTA -ATTGTTATCCGATATATACACCACCGATTTGCTTGTGCAAGGTTACAGACCCATTCGATA -AATACAAACACGGAGCGATATTATTTAAGGAGTGCTGTCTTCAAAAGAATTATTCCCACA -CCGACATAAGAACTTCGCTCCGTCATTCCAGATTTAAATAACATAACGTAACGCTTTGCT -GATAACATAACATAACCGAGAATTTGCTTAGGAAATTTGGAGCAATATTGCATTGTTTCT -CAGTCATCACAAGGCCCGCCAAAGAACTCTGAGAATCAGGATTCAACATGATTGGTAAGA -CTCTATATATATAACTTAATTCTTGTGTCCGGAGATAGAAAGAGGACGAGAGATACTACG -AAAGAAAGTGTACTTCGATGTATCAATTCAGACGCCTTCTCTATCATCAACATTATAGGT -CTCGTATATGCTCGGCGCGATCTGCTTCTCTCCGCCAATAGCCCCATAGTGTATTTCAAG -CGCAGTAACAGTGAAATCGTTACGAAGGTAGGGATGTTGCTTATAATTGTCGTAACTTAT -CGCTTATGTATCTTTCAAGAATGAACGGCAGCATATACATACGTTCTACCTTTAGCTACA -AAGCATCCATATACTCCCTCTCATGATTGAAACTCTTCCCTATTTTGTAGCCAATAGTGA -AAGCGTATTAGTATAAATTCGTCGGTTTTTCACTCGCAACTGTTATACTCTGCAAACAAA -CGAAAGCCTCATAGTACAAACCTAAAGCTACATACTTCATCATTGGCAGACCAGTGGCGG -TATTTCTACGGAAGCATCACTATAGATATAAAGTTTCCCTTCATGTACGTCTGTTAACCA -TATCACAAGAAACTGCTATCTCTGTCACGTAACAATTCACGCGCCTTATCGCCAAATGTT -CATATATGCGCGGTATACGTATGAACGAATACTAATTAGTATAACGGAGGATTCACGGGA -GGGATACTTGGGGCATTTATAAATCGTCTAAAAATTTTCTATCAGCACTTGCGGGTTATA -GTGGATTACTAGGCAACATAATATTCTGTATTGGTCCAAATGACGCTATAGATAAATTAG -CAAAATACATTGTTTCCATTTATGTAAGTCGAAACTCCAGGACTCCCGGGAACCAGTTAA -ACCGTCTGGAAAAGACACATTGTGAGCGGGACTTCAATGATAGCTTTCAATGAGCTTCTC -ATGCTTGGGGTCTGTACATATATGTTGGCGAAATTATCGTCTGTATTCTGTTATGCTTTG -ATCATGGGTTATTAGTATAGTGTCCGGTTAAGTACCAATACCGCTAGAGACCCGACCTAA -GTCGATAACTAACGATCATCGACGTAAGGATCGTCTCGATCAGTACTTCAGTCTAGATCT -GGGAATAGTAACTCGTTAGTGAACTATGTCGTGTCATAACTCTAAAATGCAATCAAATCT -TATTATTGAGTATTGATTATATAAAGCATCCGCTTAGCTTTACCCTCAAATGTTATATGC -AATTTAAAGCGCTTGATATCGTCTACTCAAGTTCAGGTTTCACATGGCCGCAACGTGACG -TTATTAGAGGTGGGTCATCATCTCTGAGGCTAGTGATGTTGAATACTCATTGAATGGGAA -GTGGAATACCATGCTCGTAGGTAACAGCATGACCTATAAAATATACTATGGGTGTGTGGT -AGATCAATATTGTTCAAGCATATCGTAACAATAACGGCTGAAATGTTACTGACATGAAAG -AGGGAGTCCAAACCATTCTAACAGCTGATCAAGTCGTCTAAAAACGCCTGGTTCAGCCTT -AAGAGTTATAAGCCAGACAAATTGTATCAATAGAGAATCCGTAAATTCCTCGGCCAACCT -CTTGCAAAGACATCACTATCAATATACTACCGTGATCTTAATTAGTGAACTTATATAAAT -ATCTACAACCAGATTCAACGGAAAAGCTTTAGTGGATTAGAAATTGCCAAGAATCACATT -CATGTGGGTTCGAATGCTTTAGTAATACCATTTCGCCGAGTAGTCACTTCGCTGAACTGT -CGTAAATTGCTATGACATAATCGAAAAGGATTGTCAAGAGTCGATTACTGCGGACTAATA -ATCCCCACGGGGGTGGTCTCATGTCTCCCCAGGCGAGTGGGGACGGTTGATAAACACGCT -GCATCGCGGACTGATGTTCCCAGTATTACATAGTCACATTGGATTGCGAGTAGTCTACCT -ATTTATGAGCGAGAGATGCCTCTAACTACTTCGACTTTTAAAACCTTTCCACGCCAGTAT -TCGGCGAAAGGGAAGTATTAAGGGTTGTCATAATTAAGCTGATACCACTTCAGACTTTGC -TCTACTTCTGTCTTTCATTGGTTTAGTAAAGTCTGTCCATTCGTCGAGACCGTCTTTTGC -AGCCTCATTCTACCAACTGCTCCGACTCTTAGTCTGCTTCTCCCAGCGTTATAACAAGAG -GCATTTTGTCATCCTTAAAACAATAATAAAGAACTCGGAGCACTGATATAATGACTGAAT -TAGAACCGCTTAAAAATACAACGAATAGATAAGACTATCGGATAAGATCTAATATGTAGT -GATTAAGCCCTTTATTAATTAATAATAGTTACCCTTTCTGATGTAACGCGACATATTACG -ATTTAGTGGCACGTCTGAATTGCAAAGCAGATCTCTACCCGATTTTTATTATAAATCCCG -TATACATCTTGACTTGAGTAATTGTTCATCTTTTTATATCTCTTCGTACTACAAATAATT -AATATCTCAACCCGTATTGTGTGATTCTAATTACCAACAGAATACGAGGAGGTTTTTGCT -TAGGGCCATATATAATGAATCTATCTCGTTTATTCGCGGAACCCGAGATAACATTACGAT -GTAACTATTTTAGAGAACTTAATACAAGAAACATTGCTGATTACTCATAACTAAATGCTT -GGTAATATATCCTCAGTGCCCCTACCATCTTTTACGCAGGGATGTAATTACTTAGGATTC -ATTGTGTAAGAATTACAATGAACGATGGATATGAAGGCATGTTGCGAGGTGTTCCTTGGT -ATGTGAAGTTCGCAGGGCAACAAAAATTTCGCAGAATAGGCCTCAAAGTATTGGTAAAGA -AGACAACTAATCATCACGAGCTTCTGATATCAATACGAACGAGTCCTGTGATGGATGAAA -GAAAGTCGTATCGAAAATGTCAAGAGTCTGCCCAATGTAACTTACTTCAAAAAATAACGC -TTCCGCCAAGTACGTTCGAATAAACGTAATTTTAAAAATACATAAGGGGTGTTAGAAAGT -AAGCGACGGGATATAAGTTAGACTCAAGATTCCGCCGTAAAACGAGACTGATTCCGAAGA -TTGTTCGTGGATCTGGTCATGACTTTCACTGAGTAAGGAGTTTCGACATATGTCAATAAA -CACAAAAATAGAAGCTATTCGATCTGAAAAATATTAGGACAAGAAACTATCTCACGCTAG -CCCAGAATATTCACTCACCCACGGGCGATACTAAAGCACTATATAGTCGCGTGATTACTA -TACATATGGTACACATAAGAATCACGATCAGGTTCTCAATTTTCAACAATATATGTTTAT -TTGCATAGGTAATATTAGGCCTTTAAGAGAAGGATGGGTGAGATACTCCGGGGATGGCGG -CAATAAAGAAAAACACGATATGAGTAATAGGATCCTAATATCTTGGCGAGAGACTTAAGG -TACGAATTTTGCGCAATCTATTTTTTACTTGGCCAGAATTCATGTATGGTATAAGTACGA -ACTTTTTTGATCACTTTCATGGCTACCTGATTAGGATAGTTTGAGGAATTTCCCAAATAT -ACCGATTTAATATACACTAGGGCTTGTCACTTTGAGTCAGAAAAAGAATATAATTACTTA -GGGTAATGCTGCATACATATTCTTATATTGCAAAGGTTCTCTGGGTAATCTTGAGCCTTC -ACGATACCTGGTGAAGTGTT diff --git a/benches/wasm-kernel/.gitignore b/benches/wasm-kernel/.gitignore deleted file mode 100644 index ea8c4bf7f3..0000000000 --- a/benches/wasm-kernel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/benches/wasm-kernel/Cargo.toml b/benches/wasm-kernel/Cargo.toml deleted file mode 100644 index ab2d06fe3a..0000000000 --- a/benches/wasm-kernel/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "wasm-kernel" -version = "0.1.0" -authors = ["Sergey Pepyakin "] -edition = "2021" - -[lib] -crate-type = ["cdylib"] - -[dependencies] -tiny-keccak = "1.4.2" -regex = "0.2.10" -lazy_static = "1.0" - -[profile.release] -panic = "abort" -lto = true -opt-level = "z" diff --git a/benches/wasm-kernel/src/lib.rs b/benches/wasm-kernel/src/lib.rs deleted file mode 100644 index 9b69bb5365..0000000000 --- a/benches/wasm-kernel/src/lib.rs +++ /dev/null @@ -1,132 +0,0 @@ -extern crate regex; -extern crate tiny_keccak; -#[macro_use] -extern crate lazy_static; - -use std::mem::ManuallyDrop; -use tiny_keccak::Keccak; - -mod regex_redux; -mod rev_complement; - -pub struct TinyKeccakTestData { - data: &'static [u8], - result: &'static mut [u8], -} - -#[no_mangle] -pub extern "C" fn prepare_tiny_keccak() -> *const TinyKeccakTestData { - static DATA: [u8; 4096] = [254u8; 4096]; - static mut RESULT: [u8; 32] = [0u8; 32]; - - static mut TEST_DATA: Option = None; - - unsafe { - if TEST_DATA.is_none() { - TEST_DATA = Some(TinyKeccakTestData { - data: &DATA, - result: &mut RESULT, - }); - } - TEST_DATA.as_ref().unwrap() as *const TinyKeccakTestData - } -} - -/// Starts the `tiny_keccak` benchmark using the benchmark data. -/// -/// # Safety -/// -/// It is the caller's responsibility to provide a `test_data` pointer that -/// is guaranteed to be not `null`. -#[no_mangle] -pub unsafe extern "C" fn bench_tiny_keccak(test_data: *mut TinyKeccakTestData) { - let mut keccak = Keccak::new_keccak256(); - keccak.update((*test_data).data); - keccak.finalize((*test_data).result); -} - -pub struct RevComplementTestData { - input: ManuallyDrop>, - output: ManuallyDrop>, -} - -#[no_mangle] -pub extern "C" fn prepare_rev_complement(size: usize) -> *mut RevComplementTestData { - let input = vec![0; size]; - let output = vec![0; size]; - - let test_data = Box::new(RevComplementTestData { - input: ManuallyDrop::new(input.into_boxed_slice()), - output: ManuallyDrop::new(output.into_boxed_slice()), - }); - - // Basically leak the pointer to the test data. This shouldn't be harmful since `prepare` is called - // only once per bench run (not for the iteration), and afterwards whole memory instance is discarded. - Box::into_raw(test_data) -} - -/// # Safety -/// -/// It is the caller's responsibility to provide non `null` `test_data`. -#[no_mangle] -pub unsafe extern "C" fn rev_complement_input_ptr( - test_data: *mut RevComplementTestData, -) -> *mut u8 { - (*test_data).input.as_mut_ptr() -} - -/// # Safety -/// -/// It is the caller's responsibility to provide non `null` `test_data`. -#[no_mangle] -pub unsafe extern "C" fn rev_complement_output_ptr( - test_data: *mut RevComplementTestData, -) -> *const u8 { - (*test_data).output.as_ptr() -} - -/// # Safety -/// -/// It is the caller's responsibility to provide non `null` `test_data`. -#[no_mangle] -pub unsafe extern "C" fn bench_rev_complement(test_data: *mut RevComplementTestData) { - let result = rev_complement::run(&*(*test_data).input); - (*test_data).output.copy_from_slice(&result); -} - -pub struct RegexReduxTestData { - input: ManuallyDrop>, - output: Option, -} - -#[no_mangle] -pub extern "C" fn prepare_regex_redux(size: usize) -> *mut RegexReduxTestData { - regex_redux::prepare(); - - let input = vec![0; size]; - let test_data = Box::new(RegexReduxTestData { - input: ManuallyDrop::new(input.into_boxed_slice()), - output: None, - }); - - // Basically leak the pointer to the test data. This shouldn't be harmful since `prepare` is called - // only once per bench run (not for the iteration), and afterwards whole memory instance is discarded. - Box::into_raw(test_data) -} - -/// # Safety -/// -/// It is the caller's responsibility to provide non `null` `test_data`. -#[no_mangle] -pub unsafe extern "C" fn regex_redux_input_ptr(test_data: *mut RegexReduxTestData) -> *mut u8 { - (*test_data).input.as_mut_ptr() -} - -/// # Safety -/// -/// It is the caller's responsibility to provide non `null` `test_data`. -#[no_mangle] -pub unsafe extern "C" fn bench_regex_redux(test_data: *mut RegexReduxTestData) { - let result = regex_redux::run(&*(*test_data).input); - (*test_data).output = Some(result); -} diff --git a/benches/wasm-kernel/src/regex_redux.rs b/benches/wasm-kernel/src/regex_redux.rs deleted file mode 100644 index da2317e819..0000000000 --- a/benches/wasm-kernel/src/regex_redux.rs +++ /dev/null @@ -1,17 +0,0 @@ -//! Initially it supposed to be like [1]. However it turned out -//! that executing this code in wasmi way too slow. -//! -//! [1]: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/regexredux-rust-2.html - -lazy_static! { - static ref REGEX: ::regex::bytes::Regex = - ::regex::bytes::Regex::new("agggtaa[cgt]|[acg]ttaccct").unwrap(); -} - -pub fn prepare() { - ::lazy_static::initialize(®EX); -} - -pub fn run(seq: &[u8]) -> usize { - REGEX.find_iter(seq).count() -} diff --git a/benches/wasm-kernel/src/rev_complement.rs b/benches/wasm-kernel/src/rev_complement.rs deleted file mode 100644 index 1571f75509..0000000000 --- a/benches/wasm-kernel/src/rev_complement.rs +++ /dev/null @@ -1,164 +0,0 @@ -// Adapted version from benchmarks game. In particular -// rayon is removed. -// -// https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/revcomp-rust-3.html - -// The Computer Language Benchmarks Game -// https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ -// -// contributed by the Rust Project Developers -// contributed by Cristi Cobzarenco -// contributed by TeXitoi -// contributed by Matt Brubeck - -use std::io::BufRead; -use std::mem::{replace, take}; -use std::{cmp, io}; - -/// Lookup table to find the complement of a single FASTA code. -fn build_table() -> [u8; 256] { - let mut table = [0; 256]; - for (i, x) in table.iter_mut().enumerate() { - *x = match i as u8 as char { - 'A' | 'a' => 'T', - 'C' | 'c' => 'G', - 'G' | 'g' => 'C', - 'T' | 't' => 'A', - 'U' | 'u' => 'A', - 'M' | 'm' => 'K', - 'R' | 'r' => 'Y', - 'W' | 'w' => 'W', - 'S' | 's' => 'S', - 'Y' | 'y' => 'R', - 'K' | 'k' => 'M', - 'V' | 'v' => 'B', - 'H' | 'h' => 'D', - 'D' | 'd' => 'H', - 'B' | 'b' => 'V', - 'N' | 'n' => 'N', - i => i, - } as u8; - } - table -} - -/// Utilities for splitting chunks off of slices. -trait SplitOff { - fn split_off_left(&mut self, n: usize) -> Self; - fn split_off_right(&mut self, n: usize) -> Self; -} -impl<'a, T> SplitOff for &'a mut [T] { - /// Split the left `n` items from self and return them as a separate slice. - fn split_off_left(&mut self, n: usize) -> Self { - let n = cmp::min(self.len(), n); - let data = take(self); - let (left, data) = data.split_at_mut(n); - *self = data; - left - } - /// Split the right `n` items from self and return them as a separate slice. - fn split_off_right(&mut self, n: usize) -> Self { - let len = self.len(); - let n = cmp::min(len, n); - let data = take(self); - let (data, right) = data.split_at_mut(len - n); - *self = data; - right - } -} - -/// Length of a normal line including the terminating \n. -const LINE_LEN: usize = 61; - -/// Compute the reverse complement for two contiguous chunks without line breaks. -fn reverse_chunks(left: &mut [u8], right: &mut [u8], table: &[u8; 256]) { - for (x, y) in left.iter_mut().zip(right.iter_mut().rev()) { - *y = table[replace(x, table[*y as usize]) as usize]; - } -} - -/// Compute the reverse complement on chunks from opposite ends of a sequence. -/// -/// `left` must start at the beginning of a line. If there are an odd number of -/// bytes, `right` will initially be 1 byte longer than `left`; otherwise they -/// will have equal lengths. -fn reverse_complement_left_right( - mut left: &mut [u8], - mut right: &mut [u8], - trailing_len: usize, - table: &[u8; 256], -) { - // Each iteration swaps one line from the start of the sequence with one - // from the end. - while !left.is_empty() || !right.is_empty() { - // Get the chunk up to the newline in `right`. - let mut a = left.split_off_left(trailing_len); - let mut b = right.split_off_right(trailing_len); - right.split_off_right(1); // Skip the newline in `right`. - - // If we've reached the middle of the sequence here and there is an - // odd number of bytes remaining, the odd one will be on the right. - if b.len() > a.len() { - let mid = b.split_off_left(1); - mid[0] = table[mid[0] as usize]; - } - - reverse_chunks(a, b, table); - - // Get the chunk up to the newline in `left`. - let n = LINE_LEN - 1 - trailing_len; - a = left.split_off_left(n); - b = right.split_off_right(n); - left.split_off_left(1); // Skip the newline in `left`. - - // If we've reached the middle of the sequence and there is an odd - // number of bytes remaining, the odd one will now be on the left. - if a.len() > b.len() { - let mid = a.split_off_right(1); - mid[0] = table[mid[0] as usize] - } - - reverse_chunks(a, b, table); - } -} - -/// Compute the reverse complement of one sequence. -fn reverse_complement(seq: &mut [u8], table: &[u8; 256]) { - let len = seq.len() - 1; - let seq = &mut seq[..len]; // Drop the last newline - let trailing_len = len % LINE_LEN; - let (left, right) = seq.split_at_mut(len / 2); - reverse_complement_left_right(left, right, trailing_len, table); -} - -/// Read sequences from stdin and print the reverse complement to stdout. -pub fn run(input: &[u8]) -> Vec { - let mut buf = Vec::with_capacity(input.len()); - - let mut input = io::Cursor::new(input); - - // Read the first header line. - input.read_until(b'\n', &mut buf).unwrap(); - - // Read sequence data line-by-line, splitting on headers. - let mut line_start = buf.len(); - let mut seq_start = line_start; - let mut seqs = vec![]; - while input.read_until(b'\n', &mut buf).unwrap() > 0 { - if buf[line_start] == b'>' { - // Found the start of a new sequence. - seqs.push(seq_start..line_start); - seq_start = buf.len(); - } - line_start = buf.len(); - } - seqs.push(seq_start..buf.len()); - - // Compute the reverse complements of each sequence. - let table = build_table(); - for seq in seqs { - reverse_complement(&mut buf[seq], &table); - } - - buf -} diff --git a/benches/wasm/wasm_kernel b/benches/wasm/wasm_kernel new file mode 160000 index 0000000000..6abd5b38d9 --- /dev/null +++ b/benches/wasm/wasm_kernel @@ -0,0 +1 @@ +Subproject commit 6abd5b38d9775b3957087fd9b1e8cae9418602a0 diff --git a/benches/wat/host_calls.wat b/benches/wat/host_calls.wat index 4137060724..7cecc6d590 100644 --- a/benches/wat/host_calls.wat +++ b/benches/wat/host_calls.wat @@ -11,17 +11,17 @@ (loop (br_if 1 - (i64.eq (get_local 0) (i64.const 0)) + (i64.eq (local.get 0) (i64.const 0)) ) - (set_local 0 + (local.set 0 (i64.sub - (call $host_call (get_local 0)) + (call $host_call (local.get 0)) (i64.const 1) ) ) (br 0) ) ) - (get_local 0) + (local.get 0) ) ) diff --git a/benches/wat/optimized_factorial.wat b/benches/wat/optimized_factorial.wat index a2420bd829..3d015e0e27 100644 --- a/benches/wat/optimized_factorial.wat +++ b/benches/wat/optimized_factorial.wat @@ -1,14 +1,14 @@ ;; Optimized factorial function, does not use recursion. (func (export "fac-opt") (param i64) (result i64) (local i64) - (set_local 1 (i64.const 1)) + (local.set 1 (i64.const 1)) (block - (br_if 0 (i64.lt_s (get_local 0) (i64.const 2))) + (br_if 0 (i64.lt_s (local.get 0) (i64.const 2))) (loop - (set_local 1 (i64.mul (get_local 1) (get_local 0))) - (set_local 0 (i64.add (get_local 0) (i64.const -1))) - (br_if 0 (i64.gt_s (get_local 0) (i64.const 1))) + (local.set 1 (i64.mul (local.get 1) (local.get 0))) + (local.set 0 (i64.add (local.get 0) (i64.const -1))) + (br_if 0 (i64.gt_s (local.get 0) (i64.const 1))) ) ) - (get_local 1) + (local.get 1) ) diff --git a/benches/wat/recursive_factorial.wat b/benches/wat/recursive_factorial.wat index 414f04af4f..de02351f45 100644 --- a/benches/wat/recursive_factorial.wat +++ b/benches/wat/recursive_factorial.wat @@ -1,9 +1,9 @@ ;; Recursive trivial factorial function. (func (export "fac-rec") (param i64) (result i64) - (if (result i64) (i64.eq (get_local 0) (i64.const 0)) + (if (result i64) (i64.eq (local.get 0) (i64.const 0)) (then (i64.const 1)) (else - (i64.mul (get_local 0) (call 0 (i64.sub (get_local 0) (i64.const 1)))) + (i64.mul (local.get 0) (call 0 (i64.sub (local.get 0) (i64.const 1)))) ) ) ) diff --git a/benches/wat/recursive_ok.wat b/benches/wat/recursive_ok.wat index 8da8dbeba3..92feb02828 100644 --- a/benches/wat/recursive_ok.wat +++ b/benches/wat/recursive_ok.wat @@ -3,8 +3,8 @@ (module (func $call (export "call") (param i32) (result i32) block (result i32) - get_local 0 - get_local 0 + local.get 0 + local.get 0 i32.eqz br_if 0 diff --git a/benches/wat/recursive_trap.wat b/benches/wat/recursive_trap.wat index 3a31d98094..d0b94bf368 100644 --- a/benches/wat/recursive_trap.wat +++ b/benches/wat/recursive_trap.wat @@ -3,8 +3,8 @@ (module (func $call (export "call") (param i32) (result i32) block (result i32) - get_local 0 - get_local 0 + local.get 0 + local.get 0 i32.eqz br_if 0 diff --git a/src/v1/module/mod.rs b/src/v1/module/mod.rs index e32d3fb7a9..240a28d44c 100644 --- a/src/v1/module/mod.rs +++ b/src/v1/module/mod.rs @@ -85,4 +85,9 @@ impl Module { func_bodies, }) } + + /// Returns a shared reference to the [`Engine`] associated to the [`Module`]. + pub fn engine(&self) -> &Engine { + &self.engine + } }