Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 31 additions & 11 deletions crates/intrinsic-test/src/common/argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand Down Expand Up @@ -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<T>,
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]);`
Expand Down
65 changes: 43 additions & 22 deletions crates/intrinsic-test/src/common/gen_rust.rs
Original file line number Diff line number Diff line change
@@ -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"),
Expand Down Expand Up @@ -118,6 +125,20 @@ pub fn write_lib_rs<T: IntrinsicTypeDefinition>(

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)?;
}
Expand Down Expand Up @@ -232,23 +253,23 @@ pub fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
}
}

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,
)
}

Expand Down
4 changes: 4 additions & 0 deletions crates/intrinsic-test/src/common/indentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down