Add fmodf128

This function is significantly slower than all others so includes an
override in `EXTREMELY_SLOW_TESTS`. Without it, PR CI takes ~1hour and
the extensive tests in CI take ~1day.
This commit is contained in:
Trevor Gross 2025-01-24 05:58:08 +00:00
parent b863308979
commit 71200bc3ce
11 changed files with 40 additions and 33 deletions

View file

@ -90,7 +90,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
FloatTy::F128,
Signature { args: &[Ty::F128, Ty::F128], returns: &[Ty::F128] },
None,
&["copysignf128", "fdimf128", "fmaxf128", "fminf128"],
&["copysignf128", "fdimf128", "fmaxf128", "fminf128", "fmodf128"],
),
(
// `(f32, f32, f32) -> f32`

View file

@ -111,6 +111,7 @@ main!(
icount_bench_fmin_group,
icount_bench_fminf_group,
icount_bench_fmod_group,
icount_bench_fmodf128_group,
icount_bench_fmodf16_group,
icount_bench_fmodf_group,
icount_bench_frexp_group,

View file

@ -131,6 +131,7 @@ libm_macros::for_each_function! {
| fmaxf16
| fminf128
| fminf16
| fmodf128
| fmodf16
| rintf128
| rintf16

View file

@ -152,6 +152,7 @@ libm_macros::for_each_function! {
floorf16,
fmod,
fmodf,
fmodf128,
fmodf16,
frexp,
frexpf,
@ -301,21 +302,6 @@ macro_rules! impl_op_for_ty {
}
}
impl MpOp for crate::op::[<fmod $suffix>]::Routine {
type MpTy = (MpFloat, MpFloat);
fn new_mp() -> Self::MpTy {
(new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
}
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
this.0.assign(input.0);
this.1.assign(input.1);
let ord = this.0.rem_assign_round(&this.1, Nearest);
prep_retval::<Self::RustRet>(&mut this.0, ord)
}
}
impl MpOp for crate::op::[<frexp $suffix>]::Routine {
type MpTy = MpFloat;
@ -481,6 +467,21 @@ macro_rules! impl_op_for_ty_all {
prep_retval::<Self::RustRet>(&mut this.0, Ordering::Equal)
}
}
impl MpOp for crate::op::[<fmod $suffix>]::Routine {
type MpTy = (MpFloat, MpFloat);
fn new_mp() -> Self::MpTy {
(new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
}
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
this.0.assign(input.0);
this.1.assign(input.1);
let ord = this.0.rem_assign_round(&this.1, Nearest);
prep_retval::<Self::RustRet>(&mut this.0, ord)
}
}
}
};
}
@ -526,22 +527,6 @@ impl MpOp for crate::op::lgammaf_r::Routine {
}
}
// No fmodf128 yet
impl MpOp for crate::op::fmodf16::Routine {
type MpTy = (MpFloat, MpFloat);
fn new_mp() -> Self::MpTy {
(new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
}
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
this.0.assign(input.0);
this.1.assign(input.1);
let ord = this.0.rem_assign_round(&this.1, Nearest);
prep_retval::<Self::RustRet>(&mut this.0, ord)
}
}
/* stub implementations so we don't need to special case them */
impl MpOp for crate::op::nextafter::Routine {

View file

@ -22,7 +22,10 @@ static EXTENSIVE_ITER_OVERRIDE: LazyLock<Option<u64>> = LazyLock::new(|| {
/// amount of time.
///
/// Contains the itentifier+generator combo to match on, plus the factor to reduce by.
const EXTEMELY_SLOW_TESTS: &[(Identifier, GeneratorKind, u64)] = &[];
const EXTEMELY_SLOW_TESTS: &[(Identifier, GeneratorKind, u64)] = &[
(Identifier::Fmodf128, GeneratorKind::QuickSpaced, 40),
(Identifier::Fmodf128, GeneratorKind::Extensive, 40),
];
/// Maximum number of iterations to run for a single routine.
///

View file

@ -93,6 +93,7 @@ libm_macros::for_each_function! {
fmaxf16,
fminf128,
fminf16,
fmodf128,
fmodf16,
rintf128,
rintf16,

View file

@ -100,6 +100,7 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
| fmaxf16
| fminf128
| fminf16
| fmodf128
| fmodf16
| rintf128
| rintf16

View file

@ -449,6 +449,13 @@
],
"type": "f32"
},
"fmodf128": {
"sources": [
"src/math/fmodf128.rs",
"src/math/generic/fmod.rs"
],
"type": "f128"
},
"fmodf16": {
"sources": [
"src/math/fmodf16.rs",

View file

@ -63,6 +63,7 @@ fminf128
fminf16
fmod
fmodf
fmodf128
fmodf16
frexp
frexpf

View file

@ -0,0 +1,5 @@
/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn fmodf128(x: f128, y: f128) -> f128 {
super::generic::fmod(x, y)
}

View file

@ -378,6 +378,7 @@ cfg_if! {
mod floorf128;
mod fmaxf128;
mod fminf128;
mod fmodf128;
mod rintf128;
mod roundf128;
mod sqrtf128;
@ -390,6 +391,7 @@ cfg_if! {
pub use self::floorf128::floorf128;
pub use self::fmaxf128::fmaxf128;
pub use self::fminf128::fminf128;
pub use self::fmodf128::fmodf128;
pub use self::rintf128::rintf128;
pub use self::roundf128::roundf128;
pub use self::sqrtf128::sqrtf128;