blob: 9e0cbe8cd6abe282d0a036d01fc2aecf0808b187 [file] [log] [blame]
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()
}