Merge pull request rust-lang/libm#359 from tgross35/update-check-ctx

Change the `CheckCtx` constructor to take a `Name` enum
This commit is contained in:
Trevor Gross 2024-11-02 22:54:48 -05:00 committed by GitHub
commit 0f76ef074f
8 changed files with 32 additions and 45 deletions

View file

@ -628,9 +628,9 @@ impl VisitMut for MacroReplace {
}
}
/// Return the unsuffixed name of a function.
/// Return the unsuffixed version of a function name; e.g. `abs` and `absf` both return `abs`,
/// `lgamma_r` and `lgammaf_r` both return `lgamma_r`.
fn base_name(name: &str) -> &str {
// Keep this in sync with `libm_test::base_name`
let known_mappings = &[
("erff", "erf"),
("erf", "erf"),

View file

@ -47,10 +47,10 @@ where
Op: MathOp,
CachedInput: GenerateInput<Op::RustArgs>,
{
let name = Op::NAME_STR;
let name = Op::NAME;
let ulp = libm_test::musl_allowed_ulp(name);
let ctx = CheckCtx::new(ulp, name, CheckBasis::Musl);
let ctx = CheckCtx::new(ulp, Op::IDENTIFIER, CheckBasis::Musl);
let benchvec: Vec<_> =
random::get_test_cases::<Op::RustArgs>(&ctx).take(BENCH_ITER_ITEMS).collect();

View file

@ -6,7 +6,7 @@ mod precision;
mod test_traits;
pub use libm::support::{Float, Int};
pub use op::{BaseName, MathOp, Name};
pub use op::{BaseName, Identifier, MathOp};
pub use precision::{MaybeOverride, SpecialCase, multiprec_allowed_ulp, musl_allowed_ulp};
pub use test_traits::{CheckBasis, CheckCtx, CheckOutput, GenerateInput, Hex, TupleCall};
@ -17,27 +17,6 @@ pub type TestResult<T = (), E = anyhow::Error> = Result<T, E>;
// List of all files present in libm's source
include!(concat!(env!("OUT_DIR"), "/all_files.rs"));
/// Return the unsuffixed version of a function name; e.g. `abs` and `absf` both return `abs`,
/// `lgamma_r` and `lgammaf_r` both return `lgamma_r`.
pub fn base_name(name: &str) -> &str {
let known_mappings = &[
("erff", "erf"),
("erf", "erf"),
("lgammaf_r", "lgamma_r"),
("modff", "modf"),
("modf", "modf"),
];
match known_mappings.iter().find(|known| known.0 == name) {
Some(found) => found.1,
None => name
.strip_suffix("f")
.or_else(|| name.strip_suffix("f16"))
.or_else(|| name.strip_suffix("f128"))
.unwrap_or(name),
}
}
/// True if `EMULATED` is set and nonempty. Used to determine how many iterations to run.
pub const fn emulated() -> bool {
match option_env!("EMULATED") {

View file

@ -15,10 +15,10 @@
use crate::{CheckOutput, Float, TupleCall};
/// An enum representing each possible routine name.
/// An enum representing each possible symbol name (`sin`, `sinf`, `sinl`, etc).
#[libm_macros::function_enum(BaseName)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Name {}
pub enum Identifier {}
/// The name without any type specifier, e.g. `sin` and `sinf` both become `sin`.
#[libm_macros::base_name_enum]
@ -58,13 +58,13 @@ pub trait MathOp {
type RustRet: CheckOutput<Self::RustArgs>;
/// The name of this function, including suffix (e.g. `sin`, `sinf`).
const NAME: Name;
const IDENTIFIER: Identifier;
/// The name as a string.
const NAME_STR: &'static str = Self::NAME.as_str();
const NAME: &'static str = Self::IDENTIFIER.as_str();
/// The name of the function excluding the type suffix, e.g. `sin` and `sinf` are both `sin`.
const BASE_NAME: BaseName = Self::NAME.base_name();
const BASE_NAME: BaseName = Self::IDENTIFIER.base_name();
/// The function in `libm` which can be called.
const ROUTINE: Self::RustFn;
@ -96,7 +96,7 @@ macro_rules! do_thing {
type RustArgs = $RustArgs;
type RustRet = $RustRet;
const NAME: Name = Name::[< $fn_name:camel >];
const IDENTIFIER: Identifier = Identifier::[< $fn_name:camel >];
const ROUTINE: Self::RustFn = libm::$fn_name;
}
}

View file

@ -219,7 +219,7 @@ impl MaybeOverride<(f64,)> for SpecialCase {
/// Check NaN bits if the function requires it
fn maybe_check_nan_bits<F: Float>(actual: F, expected: F, ctx: &CheckCtx) -> Option<TestResult> {
if !(ctx.base_name == "fabs" || ctx.base_name == "copysign") {
if !(ctx.base_name_str == "fabs" || ctx.base_name_str == "copysign") {
return None;
}
@ -277,7 +277,7 @@ fn maybe_skip_binop_nan<F1: Float, F2: Float>(
) -> Option<TestResult> {
match ctx.basis {
CheckBasis::Musl => {
if (ctx.base_name == "fmax" || ctx.base_name == "fmin")
if (ctx.base_name_str == "fmax" || ctx.base_name_str == "fmin")
&& (input.0.is_nan() || input.1.is_nan())
&& expected.is_nan()
{
@ -287,7 +287,7 @@ fn maybe_skip_binop_nan<F1: Float, F2: Float>(
}
}
CheckBasis::Mpfr => {
if ctx.base_name == "copysign" && input.1.is_nan() {
if ctx.base_name_str == "copysign" && input.1.is_nan() {
SKIP
} else {
None
@ -353,7 +353,7 @@ fn bessel_prec_dropoff<F: Float>(
ulp: &mut u32,
ctx: &CheckCtx,
) -> Option<TestResult> {
if ctx.base_name == "jn" {
if ctx.base_name_str == "jn" {
if input.0 > 4000 {
return XFAIL;
} else if input.0 > 2000 {

View file

@ -11,25 +11,33 @@ use std::fmt;
use anyhow::{Context, bail, ensure};
use crate::{Float, Int, MaybeOverride, SpecialCase, TestResult};
use crate::{BaseName, Float, Identifier, Int, MaybeOverride, SpecialCase, TestResult};
/// Context passed to [`CheckOutput`].
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CheckCtx {
/// Allowed ULP deviation
pub ulp: u32,
pub fn_ident: Identifier,
pub base_name: BaseName,
/// Function name.
pub fn_name: &'static str,
/// Return the unsuffixed version of the function name.
pub base_name: &'static str,
pub base_name_str: &'static str,
/// Source of truth for tests.
pub basis: CheckBasis,
}
impl CheckCtx {
pub fn new(ulp: u32, fname: &'static str, basis: CheckBasis) -> Self {
let base_name = crate::base_name(fname);
Self { ulp, fn_name: fname, base_name, basis }
pub fn new(ulp: u32, fn_ident: Identifier, basis: CheckBasis) -> Self {
Self {
ulp,
fn_ident,
fn_name: fn_ident.as_str(),
base_name: fn_ident.base_name(),
base_name_str: fn_ident.base_name().as_str(),
basis,
}
}
}

View file

@ -34,9 +34,9 @@ where
Op: MathOp,
CachedInput: GenerateInput<Op::RustArgs>,
{
let name = Op::NAME_STR;
let name = Op::NAME;
let ulp = musl_allowed_ulp(name);
let ctx = CheckCtx::new(ulp, name, CheckBasis::Musl);
let ctx = CheckCtx::new(ulp, Op::IDENTIFIER, CheckBasis::Musl);
let cases = random::get_test_cases::<Op::RustArgs>(&ctx);
for input in cases {

View file

@ -29,11 +29,11 @@ where
Op: MathOp + MpOp,
CachedInput: GenerateInput<Op::RustArgs>,
{
let name = Op::NAME_STR;
let name = Op::NAME;
let ulp = multiprec_allowed_ulp(name);
let mut mp_vals = Op::new_mp();
let ctx = CheckCtx::new(ulp, name, CheckBasis::Mpfr);
let ctx = CheckCtx::new(ulp, Op::IDENTIFIER, CheckBasis::Mpfr);
let cases = random::get_test_cases::<Op::RustArgs>(&ctx);
for input in cases {