Use CheckCtx in more places

Rather than passing names or identifiers, just pass `CheckCtx` in a few
more places.
This commit is contained in:
Trevor Gross 2024-12-26 07:42:13 +00:00
parent 86aeee818b
commit 7082f9baf7
4 changed files with 17 additions and 13 deletions

View file

@ -14,7 +14,7 @@ use std::{env, fs};
use libm_test::domain::HasDomain;
use libm_test::gen::{domain_logspace, edge_cases};
use libm_test::{MathOp, op};
use libm_test::{CheckBasis, CheckCtx, MathOp, op};
const JL_PLOT: &str = "examples/plot_file.jl";
@ -54,30 +54,32 @@ fn plot_one_operator<Op>(out_dir: &Path, config: &mut String)
where
Op: MathOp<FTy = f32> + HasDomain<f32>,
{
let ctx = CheckCtx::new(Op::IDENTIFIER, CheckBasis::Mpfr);
plot_one_generator(
out_dir,
Op::BASE_NAME.as_str(),
&ctx,
"logspace",
config,
domain_logspace::get_test_cases::<Op>(),
domain_logspace::get_test_cases::<Op>(&ctx),
);
plot_one_generator(
out_dir,
Op::BASE_NAME.as_str(),
&ctx,
"edge_cases",
config,
edge_cases::get_test_cases::<Op, _>(),
edge_cases::get_test_cases::<Op, _>(&ctx),
);
}
/// Plot the output of a single generator.
fn plot_one_generator(
out_dir: &Path,
fn_name: &str,
ctx: &CheckCtx,
gen_name: &str,
config: &mut String,
gen: impl Iterator<Item = (f32,)>,
) {
let fn_name = ctx.base_name_str;
let text_file = out_dir.join(format!("input-{fn_name}-{gen_name}.txt"));
let f = fs::File::create(&text_file).unwrap();

View file

@ -4,7 +4,7 @@ use libm::support::{IntTy, MinInt};
use crate::domain::HasDomain;
use crate::op::OpITy;
use crate::{MathOp, logspace};
use crate::{CheckCtx, MathOp, logspace};
/// Number of tests to run.
// FIXME(ntests): replace this with a more logical algorithm
@ -30,7 +30,7 @@ const NTESTS: usize = {
///
/// This allows us to get reasonably thorough coverage without wasting time on values that are
/// NaN or out of range. Random tests will still cover values that are excluded here.
pub fn get_test_cases<Op>() -> impl Iterator<Item = (Op::FTy,)>
pub fn get_test_cases<Op>(_ctx: &CheckCtx) -> impl Iterator<Item = (Op::FTy,)>
where
Op: MathOp + HasDomain<Op::FTy>,
IntTy<Op::FTy>: TryFrom<usize>,

View file

@ -3,7 +3,7 @@
use libm::support::Float;
use crate::domain::HasDomain;
use crate::{FloatExt, MathOp};
use crate::{CheckCtx, FloatExt, MathOp};
/// Number of values near an interesting point to check.
// FIXME(ntests): replace this with a more logical algorithm
@ -14,7 +14,7 @@ const AROUND: usize = 100;
const MAX_CHECK_POINTS: usize = 10;
/// Create a list of values around interesting points (infinities, zeroes, NaNs).
pub fn get_test_cases<Op, F>() -> impl Iterator<Item = (F,)>
pub fn get_test_cases<Op, F>(_ctx: &CheckCtx) -> impl Iterator<Item = (F,)>
where
Op: MathOp<FTy = F> + HasDomain<F>,
F: Float,

View file

@ -83,21 +83,21 @@ macro_rules! mp_domain_tests {
$(#[$meta])*
fn [< mp_edge_case_ $fn_name >]() {
type Op = libm_test::op::$fn_name::Routine;
domain_test_runner::<Op>(edge_cases::get_test_cases::<Op, _>());
domain_test_runner::<Op, _>(edge_cases::get_test_cases::<Op, _>);
}
#[test]
$(#[$meta])*
fn [< mp_logspace_ $fn_name >]() {
type Op = libm_test::op::$fn_name::Routine;
domain_test_runner::<Op>(domain_logspace::get_test_cases::<Op>());
domain_test_runner::<Op, _>(domain_logspace::get_test_cases::<Op>);
}
}
};
}
/// Test a single routine against domaine-aware inputs.
fn domain_test_runner<Op>(cases: impl Iterator<Item = (Op::FTy,)>)
fn domain_test_runner<Op, I>(gen: impl FnOnce(&CheckCtx) -> I)
where
// Complicated generics...
// The operation must take a single float argument (unary only)
@ -108,9 +108,11 @@ where
Op: HasDomain<Op::FTy>,
// The single float argument tuple must be able to call the `RustFn` and return `RustRet`
(OpFTy<Op>,): TupleCall<OpRustFn<Op>, Output = OpRustRet<Op>>,
I: Iterator<Item = (Op::FTy,)>,
{
let mut mp_vals = Op::new_mp();
let ctx = CheckCtx::new(Op::IDENTIFIER, CheckBasis::Mpfr);
let cases = gen(&ctx);
for input in cases {
let mp_res = Op::run(&mut mp_vals, input);