Change default ULP to use enum matching

Migrate from string to enum matching and tie this to `CheckCtx::new`, so
no tests need to explicitly set ULP.
This commit is contained in:
Trevor Gross
2024-11-02 23:03:41 -05:00
committed by Trevor Gross
parent 0f76ef074f
commit 5032fcf139
6 changed files with 47 additions and 59 deletions

View File

@@ -7,7 +7,7 @@ mod test_traits;
pub use libm::support::{Float, Int};
pub use op::{BaseName, Identifier, MathOp};
pub use precision::{MaybeOverride, SpecialCase, multiprec_allowed_ulp, musl_allowed_ulp};
pub use precision::{MaybeOverride, SpecialCase, default_ulp};
pub use test_traits::{CheckBasis, CheckCtx, CheckOutput, GenerateInput, Hex, TupleCall};
/// Result type for tests is usually from `anyhow`. Most times there is no success value to

View File

@@ -3,7 +3,10 @@
use core::f32;
use crate::{CheckBasis, CheckCtx, Float, Int, TestResult};
use CheckBasis::{Mpfr, Musl};
use Identifier as Id;
use crate::{CheckBasis, CheckCtx, Float, Identifier, Int, TestResult};
/// Type implementing [`IgnoreCase`].
pub struct SpecialCase;
@@ -14,50 +17,42 @@ const MUSL_DEFAULT_ULP: u32 = 2;
/// Default ULP allowed to differ from multiprecision (i.e. infinite) results.
const MULTIPREC_DEFAULT_ULP: u32 = 1;
/// ULP allowed to differ from muls results.
/// ULP allowed to differ from the results returned by a test basis.
///
/// Note that these results were obtained using 400,000,000 rounds of random inputs, which
/// Note that these results were obtained using 400M rounds of random inputs, which
/// is not a value used by default.
pub fn musl_allowed_ulp(name: &str) -> u32 {
// Consider overrides xfail
match name {
#[cfg(x86_no_sse)]
"asinh" | "asinhf" => 6,
"lgamma" | "lgamma_r" | "lgammaf" | "lgammaf_r" => 400,
"tanh" | "tanhf" => 4,
"tgamma" => 20,
"j0" | "j0f" | "j1" | "j1f" => {
pub fn default_ulp(ctx: &CheckCtx) -> u32 {
match (&ctx.basis, ctx.fn_ident) {
// Overrides that apply to either basis
(_, Id::J0 | Id::J0f | Id::J1 | Id::J1f) => {
// Results seem very target-dependent
if cfg!(target_arch = "x86_64") { 4000 } else { 800_000 }
}
"jn" | "jnf" => 1000,
"sincosf" => 500,
#[cfg(not(target_pointer_width = "64"))]
"exp10" => 4,
#[cfg(not(target_pointer_width = "64"))]
"exp10f" => 4,
_ => MUSL_DEFAULT_ULP,
}
}
(_, Id::Jn | Id::Jnf) => 1000,
/// ULP allowed to differ from multiprecision results.
pub fn multiprec_allowed_ulp(name: &str) -> u32 {
// Consider overrides xfail
match name {
"asinh" | "asinhf" => 2,
"acoshf" => 4,
"atanh" | "atanhf" => 2,
"exp10" | "exp10f" => 3,
"j0" | "j0f" | "j1" | "j1f" => {
// Results seem very target-dependent
if cfg!(target_arch = "x86_64") { 4000 } else { 800_000 }
}
"jn" | "jnf" => 1000,
"lgamma" | "lgammaf" | "lgamma_r" | "lgammaf_r" => 16,
"sinh" | "sinhf" => 2,
"tanh" | "tanhf" => 2,
"tgamma" => 20,
_ => MULTIPREC_DEFAULT_ULP,
// Overrides for musl
#[cfg(x86_no_sse)]
(Musl, Id::Asinh | Id::Asinhf) => 6,
#[cfg(not(target_pointer_width = "64"))]
(Musl, Id::Exp10 | Id::Exp10f) => 4,
(Musl, Id::Lgamma | Id::LgammaR | Id::Lgammaf | Id::LgammafR) => 400,
(Musl, Id::Sincosf) => 500,
(Musl, Id::Tanh | Id::Tanhf) => 4,
(Musl, Id::Tgamma) => 20,
// Overrides for MPFR
(Mpfr, Id::Acoshf) => 4,
(Mpfr, Id::Asinh | Id::Asinhf) => 2,
(Mpfr, Id::Atanh | Id::Atanhf) => 2,
(Mpfr, Id::Exp10 | Id::Exp10f) => 3,
(Mpfr, Id::Lgamma | Id::LgammaR | Id::Lgammaf | Id::LgammafR) => 16,
(Mpfr, Id::Sinh | Id::Sinhf) => 2,
(Mpfr, Id::Tanh | Id::Tanhf) => 2,
(Mpfr, Id::Tgamma) => 20,
// Defaults
(Musl, _) => MUSL_DEFAULT_ULP,
(Mpfr, _) => MULTIPREC_DEFAULT_ULP,
}
}

View File

@@ -29,15 +29,18 @@ pub struct CheckCtx {
}
impl CheckCtx {
pub fn new(ulp: u32, fn_ident: Identifier, basis: CheckBasis) -> Self {
Self {
ulp,
/// Create a new check context, using the default ULP for the function.
pub fn new(fn_ident: Identifier, basis: CheckBasis) -> Self {
let mut ret = Self {
ulp: 0,
fn_ident,
fn_name: fn_ident.as_str(),
base_name: fn_ident.base_name(),
base_name_str: fn_ident.base_name().as_str(),
basis,
}
};
ret.ulp = crate::default_ulp(&ret);
ret
}
}