diff --git a/crates/intrinsic-test/src/common/argument.rs b/crates/intrinsic-test/src/common/argument.rs index 5fb7d0f210..385cf32d3b 100644 --- a/crates/intrinsic-test/src/common/argument.rs +++ b/crates/intrinsic-test/src/common/argument.rs @@ -60,9 +60,15 @@ where } /// The name (e.g. "A_VALS" or "a_vals") for the array of possible test inputs. - fn rust_vals_array_name(&self) -> impl std::fmt::Display { + pub(crate) fn rust_vals_array_name(&self) -> impl std::fmt::Display { if self.ty.is_rust_vals_array_const() { - format!("{}_VALS", self.name.to_uppercase()) + let loads = crate::common::gen_rust::PASSES; + format!( + "{}_{ty}_{load_size}", + self.name.to_uppercase(), + ty = self.ty.rust_scalar_type(), + load_size = self.ty.num_lanes() * self.ty.num_vectors() + loads - 1, + ) } else { format!("{}_vals", self.name.to_lowercase()) } @@ -134,20 +140,34 @@ where loads: u32, ) -> std::io::Result<()> { for arg in self.iter().filter(|&arg| !arg.has_constraint()) { - writeln!( - w, - "{indentation}{bind} {name}: [{ty}; {load_size}] = {values};", - bind = arg.rust_vals_array_binding(), - name = arg.rust_vals_array_name(), - ty = arg.ty.rust_scalar_type(), - load_size = arg.ty.num_lanes() * arg.ty.num_vectors() + loads - 1, - values = arg.ty.populate_random(indentation, loads, &Language::Rust) - )? + // Constants are defined globally. + if arg.ty.is_rust_vals_array_const() { + continue; + } + + Self::gen_arg_rust(arg, w, indentation, loads)?; } Ok(()) } + pub fn gen_arg_rust( + arg: &Argument, + w: &mut impl std::io::Write, + indentation: Indentation, + loads: u32, + ) -> std::io::Result<()> { + writeln!( + w, + "{indentation}{bind} {name}: [{ty}; {load_size}] = {values};\n", + bind = arg.rust_vals_array_binding(), + name = arg.rust_vals_array_name(), + ty = arg.ty.rust_scalar_type(), + load_size = arg.ty.num_lanes() * arg.ty.num_vectors() + loads - 1, + values = arg.ty.populate_random(indentation, loads, &Language::Rust) + ) + } + /// Creates a line for each argument that initializes the argument from an array `[arg]_vals` at /// an offset `i` using a load intrinsic, in C. /// e.g `uint8x8_t a = vld1_u8(&a_vals[i]);` diff --git a/crates/intrinsic-test/src/common/gen_rust.rs b/crates/intrinsic-test/src/common/gen_rust.rs index 27f49a37b1..c8d815e46e 100644 --- a/crates/intrinsic-test/src/common/gen_rust.rs +++ b/crates/intrinsic-test/src/common/gen_rust.rs @@ -1,24 +1,31 @@ use itertools::Itertools; use std::process::Command; +use crate::common::argument::ArgumentList; use crate::common::intrinsic::Intrinsic; use super::indentation::Indentation; use super::intrinsic_helpers::IntrinsicTypeDefinition; // The number of times each intrinsic will be called. -const PASSES: u32 = 20; +pub(crate) const PASSES: u32 = 20; + +macro_rules! concatln { + ($($lines:expr),* $(,)?) => { + concat!($( $lines, "\n" ),*) + }; +} fn write_cargo_toml_header(w: &mut impl std::io::Write, name: &str) -> std::io::Result<()> { writeln!( w, - concat!( - "[package]\n", - "name = \"{name}\"\n", - "version = \"{version}\"\n", - "authors = [{authors}]\n", - "license = \"{license}\"\n", - "edition = \"2018\"\n", + concatln!( + "[package]", + "name = \"{name}\"", + "version = \"{version}\"", + "authors = [{authors}]", + "license = \"{license}\"", + "edition = \"2018\"", ), name = name, version = env!("CARGO_PKG_VERSION"), @@ -118,6 +125,20 @@ pub fn write_lib_rs( writeln!(w, "{definitions}")?; + let mut seen = std::collections::HashSet::new(); + + for intrinsic in intrinsics { + for arg in &intrinsic.arguments.args { + if !arg.has_constraint() && arg.ty.is_rust_vals_array_const() { + let name = arg.rust_vals_array_name().to_string(); + + if seen.insert(name) { + ArgumentList::gen_arg_rust(arg, w, Indentation::default(), PASSES)?; + } + } + } + } + for intrinsic in intrinsics { crate::common::gen_rust::create_rust_test_module(w, intrinsic)?; } @@ -232,23 +253,23 @@ pub fn generate_rust_test_loop( } } - let indentation2 = indentation.nested(); - let indentation3 = indentation2.nested(); - writeln!( + write!( w, - "\ - for (id, f) in specializations {{\n\ - for i in 0..{passes} {{\n\ - unsafe {{\n\ - {loaded_args}\ - let __return_value = f({args});\n\ - println!(\"Result {{id}}-{{}}: {{:?}}\", i + 1, {return_value});\n\ - }}\n\ - }}\n\ - }}", - loaded_args = intrinsic.arguments.load_values_rust(indentation3), + concatln!( + " for (id, f) in specializations {{", + " for i in 0..{passes} {{", + " unsafe {{", + "{loaded_args}", + " let __return_value = f({args});", + " println!(\"Result {{id}}-{{}}: {{:?}}\", i + 1, {return_value});", + " }}", + " }}", + " }}", + ), + loaded_args = intrinsic.arguments.load_values_rust(indentation.nest_by(4)), args = intrinsic.arguments.as_call_param_rust(), return_value = intrinsic.results.print_result_rust(), + passes = passes, ) } diff --git a/crates/intrinsic-test/src/common/indentation.rs b/crates/intrinsic-test/src/common/indentation.rs index 9ee331d7f7..9c2cc886e6 100644 --- a/crates/intrinsic-test/src/common/indentation.rs +++ b/crates/intrinsic-test/src/common/indentation.rs @@ -10,6 +10,10 @@ impl Indentation { pub fn nested(self) -> Self { Self(self.0 + 1) } + + pub fn nest_by(&self, additional_levels: u32) -> Self { + Self(self.0 + additional_levels) + } } impl std::fmt::Display for Indentation {