91 lines
3.3 KiB
Rust
91 lines
3.3 KiB
Rust
use super::cli::FailureReason;
|
|
use rayon::prelude::*;
|
|
use std::process::Command;
|
|
|
|
pub fn compare_outputs(
|
|
intrinsic_name_list: &Vec<String>,
|
|
toolchain: &str,
|
|
runner: &str,
|
|
target: &str,
|
|
) -> bool {
|
|
let intrinsics = intrinsic_name_list
|
|
.par_iter()
|
|
.filter_map(|intrinsic_name| {
|
|
let c = Command::new("sh")
|
|
.arg("-c")
|
|
.arg(format!("{runner} ./c_programs/{intrinsic_name}"))
|
|
.output();
|
|
|
|
let rust = Command::new("sh")
|
|
.current_dir("rust_programs")
|
|
.arg("-c")
|
|
.arg(format!(
|
|
"cargo {toolchain} run --target {target} --bin {intrinsic_name} --release",
|
|
))
|
|
.env("RUSTFLAGS", "-Cdebuginfo=0")
|
|
.output();
|
|
|
|
let (c, rust) = match (c, rust) {
|
|
(Ok(c), Ok(rust)) => (c, rust),
|
|
a => panic!("{a:#?}"),
|
|
};
|
|
|
|
if !c.status.success() {
|
|
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}\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()));
|
|
}
|
|
|
|
info!("Comparing intrinsic: {intrinsic_name}");
|
|
|
|
let c = std::str::from_utf8(&c.stdout)
|
|
.unwrap()
|
|
.to_lowercase()
|
|
.replace("-nan", "nan");
|
|
let rust = std::str::from_utf8(&rust.stdout)
|
|
.unwrap()
|
|
.to_lowercase()
|
|
.replace("-nan", "nan");
|
|
|
|
if c == rust {
|
|
None
|
|
} else {
|
|
Some(FailureReason::Difference(intrinsic_name.clone(), c, rust))
|
|
}
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
intrinsics.iter().for_each(|reason| match reason {
|
|
FailureReason::Difference(intrinsic, c, rust) => {
|
|
println!("Difference for intrinsic: {intrinsic}");
|
|
let diff = diff::lines(c, rust);
|
|
diff.iter().for_each(|diff| match diff {
|
|
diff::Result::Left(c) => println!("C: {c}"),
|
|
diff::Result::Right(rust) => println!("Rust: {rust}"),
|
|
diff::Result::Both(_, _) => (),
|
|
});
|
|
println!("****************************************************************");
|
|
}
|
|
FailureReason::RunC(intrinsic) => {
|
|
println!("Failed to run C program for intrinsic {intrinsic}")
|
|
}
|
|
FailureReason::RunRust(intrinsic) => {
|
|
println!("Failed to run rust program for intrinsic {intrinsic}")
|
|
}
|
|
});
|
|
println!("{} differences found", intrinsics.len());
|
|
intrinsics.is_empty()
|
|
}
|