Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Change the CheckCtx constructor to take a Name enum #359

Merged
merged 2 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/libm-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
4 changes: 2 additions & 2 deletions crates/libm-test/benches/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
23 changes: 1 addition & 22 deletions crates/libm-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand All @@ -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") {
Expand Down
12 changes: 6 additions & 6 deletions crates/libm-test/src/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/libm-test/src/precision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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()
{
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
18 changes: 13 additions & 5 deletions crates/libm-test/src/test_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/libm-test/tests/compare_built_musl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions crates/libm-test/tests/multiprecision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down