chore: code consolidation

This commit is contained in:
Madhav Madhusoodanan 2025-03-27 22:36:52 +04:00 committed by Amanieu d'Antras
parent 17277d71e8
commit c862432cfd
14 changed files with 145 additions and 162 deletions

View file

@ -1,9 +1,8 @@
use std::ops::Range;
use super::format::Indentation;
use super::json_parser::ArgPrep;
use super::types::{IntrinsicType, TypeKind};
use crate::common::types::Language;
use std::ops::Range;
/// An argument for the intrinsic.
#[derive(Debug, PartialEq, Clone)]

View file

@ -8,8 +8,7 @@ pub fn build_notices(line_prefix: &str) -> String {
)
}
pub const POLY128_OSTREAM_DEF: &str =
r#"std::ostream& operator<<(std::ostream& os, poly128_t value) {
pub const POLY128_OSTREAM_DEF: &str = r#"std::ostream& operator<<(std::ostream& os, poly128_t value) {
std::stringstream temp;
do {
int n = value % 10;

View file

@ -1,13 +1,12 @@
use itertools::Itertools;
use rayon::prelude::*;
use std::io::Write;
use super::argument::Argument;
use super::config::{AARCH_CONFIGURATIONS, POLY128_OSTREAM_DEF, build_notices};
use super::format::Indentation;
use super::intrinsic::Intrinsic;
use crate::common::gen_c::{compile_c, create_c_files, generate_c_program};
use crate::common::gen_rust::{compile_rust, create_rust_files, generate_rust_program};
use itertools::Itertools;
use rayon::prelude::*;
use std::io::Write;
// The number of times each intrinsic will be called.
const PASSES: u32 = 20;
@ -156,7 +155,7 @@ fn compile_c_arm(
cxx_toolchain_dir: Option<&str>,
) -> bool {
let compiler_commands = intrinsics_name_list.iter().map(|intrinsic_name|{
let c_filename = format!(r#"c_programs/{}.cpp"#, intrinsic_name);
let c_filename = format!(r#"c_programs/{intrinsic_name}.cpp"#);
let flags = std::env::var("CPPFLAGS").unwrap_or("".into());
let arch_flags = if target.contains("v7") {
"-march=armv8.6-a+crypto+crc+dotprod+fp16"

View file

@ -1,8 +1,7 @@
use super::argument::ArgumentList;
use super::format::Indentation;
use super::types::{IntrinsicType, TypeKind};
use super::argument::ArgumentList;
/// An intrinsic
#[derive(Debug, PartialEq, Clone)]
pub struct Intrinsic {
@ -82,8 +81,6 @@ impl Intrinsic {
String::from("")
},
close = if self.results.is_simd() { ")" } else { "" },
lanes = lanes,
additional = additional,
)
}
@ -146,7 +143,6 @@ impl Intrinsic {
intrinsic_call = self.name,
const = constraints,
args = self.arguments.as_call_param_rust(),
additional = additional,
)
}
}

View file

@ -1,11 +1,9 @@
use std::collections::HashMap;
use std::path::Path;
use serde::Deserialize;
use super::argument::{Argument, ArgumentList};
use super::intrinsic::Intrinsic;
use super::types::IntrinsicType;
use serde::Deserialize;
use std::collections::HashMap;
use std::path::Path;
#[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)]

View file

@ -6,9 +6,9 @@ mod intrinsic;
mod json_parser;
mod types;
use crate::common::cli::ProcessedCli;
use crate::common::SupportedArchitectureTest;
use crate::common::compare::compare_outputs;
use crate::common::supporting_test::SupportedArchitectureTest;
use crate::common::types::ProcessedCli;
use functions::{build_c, build_rust};
use intrinsic::Intrinsic;
use json_parser::get_neon_intrinsics;

View file

@ -1,101 +0,0 @@
use itertools::Itertools;
use std::path::PathBuf;
/// Intrinsic test tool
#[derive(clap::Parser)]
#[command(
name = "Intrinsic test tool",
about = "Generates Rust and C programs for intrinsics and compares the output"
)]
pub struct Cli {
/// The input file containing the intrinsics
pub input: PathBuf,
/// The rust toolchain to use for building the rust code
#[arg(long)]
pub toolchain: Option<String>,
/// The C++ compiler to use for compiling the c++ code
#[arg(long, default_value_t = String::from("clang++"))]
pub cppcompiler: String,
/// Run the C programs under emulation with this command
#[arg(long)]
pub runner: Option<String>,
/// Filename for a list of intrinsics to skip (one per line)
#[arg(long)]
pub skip: Option<PathBuf>,
/// Regenerate test programs, but don't build or run them
#[arg(long)]
pub generate_only: bool,
/// Pass a target the test suite
#[arg(long, default_value_t = String::from("aarch64-unknown-linux-gnu"))]
pub target: String,
/// Set the linker
#[arg(long)]
pub linker: Option<String>,
/// Set the sysroot for the C++ compiler
#[arg(long)]
pub cxx_toolchain_dir: Option<String>,
}
pub struct ProcessedCli {
pub filename: PathBuf,
pub toolchain: Option<String>,
pub cpp_compiler: Option<String>,
pub c_runner: String,
pub target: String,
pub linker: Option<String>,
pub cxx_toolchain_dir: Option<String>,
pub skip: Vec<String>,
}
impl ProcessedCli {
pub fn new(cli_options: Cli) -> Self {
let filename = cli_options.input;
let c_runner = cli_options.runner.unwrap_or_default();
let target = cli_options.target;
let linker = cli_options.linker;
let cxx_toolchain_dir = cli_options.cxx_toolchain_dir;
let skip = if let Some(filename) = cli_options.skip {
let data = std::fs::read_to_string(&filename).expect("Failed to open file");
data.lines()
.map(str::trim)
.filter(|s| !s.contains('#'))
.map(String::from)
.collect_vec()
} else {
Default::default()
};
let (toolchain, cpp_compiler) = if cli_options.generate_only {
(None, None)
} else {
(
Some(
cli_options
.toolchain
.map_or_else(String::new, |t| format!("+{t}")),
),
Some(cli_options.cppcompiler),
)
};
Self {
toolchain: toolchain,
cpp_compiler: cpp_compiler,
c_runner: c_runner,
target: target,
linker: linker,
cxx_toolchain_dir: cxx_toolchain_dir,
skip: skip,
filename: filename,
}
}
}

View file

@ -1,12 +1,7 @@
use super::types::FailureReason;
use rayon::prelude::*;
use std::process::Command;
enum FailureReason {
RunC(String),
RunRust(String),
Difference(String, String, String),
}
pub fn compare_outputs(
intrinsic_name_list: &Vec<String>,
toolchain: &str,
@ -18,11 +13,7 @@ pub fn compare_outputs(
.filter_map(|intrinsic_name| {
let c = Command::new("sh")
.arg("-c")
.arg(format!(
"{runner} ./c_programs/{intrinsic_name}",
runner = runner,
intrinsic_name = intrinsic_name,
))
.arg(format!("{runner} ./c_programs/{intrinsic_name}"))
.output();
let rust = if target != "aarch64_be-unknown-linux-gnu" {
@ -31,9 +22,6 @@ pub fn compare_outputs(
.arg("-c")
.arg(format!(
"cargo {toolchain} run --target {target} --bin {intrinsic_name} --release",
intrinsic_name = intrinsic_name,
toolchain = toolchain,
target = target
))
.env("RUSTFLAGS", "-Cdebuginfo=0")
.output()
@ -42,9 +30,6 @@ pub fn compare_outputs(
.arg("-c")
.arg(format!(
"{runner} ./rust_programs/target/{target}/release/{intrinsic_name}",
runner = runner,
target = target,
intrinsic_name = intrinsic_name,
))
.output()
};
@ -55,14 +40,19 @@ pub fn compare_outputs(
};
if !c.status.success() {
error!("Failed to run C program for intrinsic {}", intrinsic_name);
error!(
"Failed to run C program for intrinsic {intrinsic_name}\nstdout: {stdout}\nstderr: {stderr}",
stdout = std::str::from_utf8(&c.stdout).unwrap_or(""),
stderr = std::str::from_utf8(&c.stderr).unwrap_or(""),
);
return Some(FailureReason::RunC(intrinsic_name.clone()));
}
if !rust.status.success() {
error!(
"Failed to run rust program for intrinsic {}",
intrinsic_name
"Failed to run Rust program for intrinsic {intrinsic_name}\nstdout: {stdout}\nstderr: {stderr}",
stdout = std::str::from_utf8(&rust.stdout).unwrap_or(""),
stderr = std::str::from_utf8(&rust.stderr).unwrap_or(""),
);
return Some(FailureReason::RunRust(intrinsic_name.clone()));
}

View file

@ -83,7 +83,7 @@ pub fn create_c_files(identifiers: &Vec<String>) -> BTreeMap<&String, File> {
identifiers
.par_iter()
.map(|identifier| {
let c_filename = format!(r#"c_programs/{}.cpp"#, identifier);
let c_filename = format!(r#"c_programs/{identifier}.cpp"#);
let file = File::create(&c_filename).unwrap();
(identifier, file)

View file

@ -78,11 +78,7 @@ path = "{binary}/main.rs""#,
/* If there has been a linker explicitly set from the command line then
* we want to set it via setting it in the RUSTFLAGS*/
let cargo_command = format!(
"cargo {toolchain} build --target {target} --release",
toolchain = toolchain,
target = target
);
let cargo_command = format!("cargo {toolchain} build --target {target} --release");
let mut command = Command::new("sh");
command

View file

@ -1,7 +1,16 @@
pub mod cli;
use crate::common::types::ProcessedCli;
pub mod compare;
pub mod gen_c;
pub mod gen_rust;
pub mod supporting_test;
pub mod types;
pub mod values;
/// Architectures must support this trait
/// to be successfully tested.
pub trait SupportedArchitectureTest {
fn create(cli_options: ProcessedCli) -> Self;
fn build_c_file(&self) -> bool;
fn build_rust_file(&self) -> bool;
fn compare_outputs(&self) -> bool;
}

View file

@ -1,10 +0,0 @@
use crate::common::cli::ProcessedCli;
/// Architectures must support this trait
/// to be successfully tested.
pub trait SupportedArchitectureTest {
fn create(cli_options: ProcessedCli) -> Self;
fn build_c_file(&self) -> bool;
fn build_rust_file(&self) -> bool;
fn compare_outputs(&self) -> bool;
}

View file

@ -1,5 +1,113 @@
use itertools::Itertools;
use std::path::PathBuf;
#[derive(Debug, PartialEq)]
pub enum Language {
Rust,
C,
}
pub enum FailureReason {
RunC(String),
RunRust(String),
Difference(String, String, String),
}
/// Intrinsic test tool
#[derive(clap::Parser)]
#[command(
name = "Intrinsic test tool",
about = "Generates Rust and C programs for intrinsics and compares the output"
)]
pub struct Cli {
/// The input file containing the intrinsics
pub input: PathBuf,
/// The rust toolchain to use for building the rust code
#[arg(long)]
pub toolchain: Option<String>,
/// The C++ compiler to use for compiling the c++ code
#[arg(long, default_value_t = String::from("clang++"))]
pub cppcompiler: String,
/// Run the C programs under emulation with this command
#[arg(long)]
pub runner: Option<String>,
/// Filename for a list of intrinsics to skip (one per line)
#[arg(long)]
pub skip: Option<PathBuf>,
/// Regenerate test programs, but don't build or run them
#[arg(long)]
pub generate_only: bool,
/// Pass a target the test suite
#[arg(long, default_value_t = String::from("aarch64-unknown-linux-gnu"))]
pub target: String,
/// Set the linker
#[arg(long)]
pub linker: Option<String>,
/// Set the sysroot for the C++ compiler
#[arg(long)]
pub cxx_toolchain_dir: Option<String>,
}
pub struct ProcessedCli {
pub filename: PathBuf,
pub toolchain: Option<String>,
pub cpp_compiler: Option<String>,
pub c_runner: String,
pub target: String,
pub linker: Option<String>,
pub cxx_toolchain_dir: Option<String>,
pub skip: Vec<String>,
}
impl ProcessedCli {
pub fn new(cli_options: Cli) -> Self {
let filename = cli_options.input;
let c_runner = cli_options.runner.unwrap_or_default();
let target = cli_options.target;
let linker = cli_options.linker;
let cxx_toolchain_dir = cli_options.cxx_toolchain_dir;
let skip = if let Some(filename) = cli_options.skip {
let data = std::fs::read_to_string(&filename).expect("Failed to open file");
data.lines()
.map(str::trim)
.filter(|s| !s.contains('#'))
.map(String::from)
.collect_vec()
} else {
Default::default()
};
let (toolchain, cpp_compiler) = if cli_options.generate_only {
(None, None)
} else {
(
Some(
cli_options
.toolchain
.map_or_else(String::new, |t| format!("+{t}")),
),
Some(cli_options.cppcompiler),
)
};
Self {
toolchain: toolchain,
cpp_compiler: cpp_compiler,
c_runner: c_runner,
target: target,
linker: linker,
cxx_toolchain_dir: cxx_toolchain_dir,
skip: skip,
filename: filename,
}
}
}

View file

@ -6,8 +6,8 @@ mod arm;
mod common;
use arm::ArmTestProcessor;
use common::cli::{Cli, ProcessedCli};
use common::supporting_test::SupportedArchitectureTest;
use common::SupportedArchitectureTest;
use common::types::{Cli, ProcessedCli};
fn main() {
pretty_env_logger::init();