Merge pull request rust-lang/libm#470 from tgross35/f128-fmod
Add `fmodf128`
This commit is contained in:
commit
3524632b0b
12 changed files with 68 additions and 41 deletions
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ libm_macros::for_each_function! {
|
|||
| fmaxf16
|
||||
| fminf128
|
||||
| fminf16
|
||||
| fmodf128
|
||||
| fmodf16
|
||||
| rintf128
|
||||
| rintf16
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ pub use op::{
|
|||
Ty,
|
||||
};
|
||||
pub use precision::{MaybeOverride, SpecialCase, default_ulp};
|
||||
use run_cfg::EXTENSIVE_MAX_ITERATIONS;
|
||||
use run_cfg::extensive_max_iterations;
|
||||
pub use run_cfg::{CheckBasis, CheckCtx, EXTENSIVE_ENV, GeneratorKind, skip_extensive_test};
|
||||
pub use test_traits::{CheckOutput, Hex, TupleCall};
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ pub fn test_log(s: &str) {
|
|||
writeln!(f, "cargo features: {}", env!("CFG_CARGO_FEATURES")).unwrap();
|
||||
writeln!(f, "opt level: {}", env!("CFG_OPT_LEVEL")).unwrap();
|
||||
writeln!(f, "target features: {}", env!("CFG_TARGET_FEATURES")).unwrap();
|
||||
writeln!(f, "extensive iterations {}", *EXTENSIVE_MAX_ITERATIONS).unwrap();
|
||||
writeln!(f, "extensive iterations {}", extensive_max_iterations()).unwrap();
|
||||
|
||||
Some(f)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -13,18 +13,30 @@ pub const EXTENSIVE_ENV: &str = "LIBM_EXTENSIVE_TESTS";
|
|||
/// Specify the number of iterations via this environment variable, rather than using the default.
|
||||
pub const EXTENSIVE_ITER_ENV: &str = "LIBM_EXTENSIVE_ITERATIONS";
|
||||
|
||||
/// The override value, if set by the above environment.
|
||||
static EXTENSIVE_ITER_OVERRIDE: LazyLock<Option<u64>> = LazyLock::new(|| {
|
||||
env::var(EXTENSIVE_ITER_ENV).map(|v| v.parse().expect("failed to parse iteration count")).ok()
|
||||
});
|
||||
|
||||
/// Specific tests that need to have a reduced amount of iterations to complete in a reasonable
|
||||
/// amount of time.
|
||||
///
|
||||
/// Contains the itentifier+generator combo to match on, plus the factor to reduce by.
|
||||
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.
|
||||
///
|
||||
/// The default value of one greater than `u32::MAX` allows testing single-argument `f32` routines
|
||||
/// and single- or double-argument `f16` routines exhaustively. `f64` and `f128` can't feasibly
|
||||
/// be tested exhaustively; however, [`EXTENSIVE_ITER_ENV`] can be set to run tests for multiple
|
||||
/// hours.
|
||||
pub static EXTENSIVE_MAX_ITERATIONS: LazyLock<u64> = LazyLock::new(|| {
|
||||
let default = 1 << 32;
|
||||
env::var(EXTENSIVE_ITER_ENV)
|
||||
.map(|v| v.parse().expect("failed to parse iteration count"))
|
||||
.unwrap_or(default)
|
||||
});
|
||||
pub fn extensive_max_iterations() -> u64 {
|
||||
let default = 1 << 32; // default value
|
||||
EXTENSIVE_ITER_OVERRIDE.unwrap_or(default)
|
||||
}
|
||||
|
||||
/// Context passed to [`CheckOutput`].
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
|
|
@ -206,12 +218,23 @@ pub fn iteration_count(ctx: &CheckCtx, argnum: usize) -> u64 {
|
|||
let mut total_iterations = match ctx.gen_kind {
|
||||
GeneratorKind::QuickSpaced => domain_iter_count,
|
||||
GeneratorKind::Random => random_iter_count,
|
||||
GeneratorKind::Extensive => *EXTENSIVE_MAX_ITERATIONS,
|
||||
GeneratorKind::Extensive => extensive_max_iterations(),
|
||||
GeneratorKind::EdgeCases => {
|
||||
unimplemented!("edge case tests shoudn't need `iteration_count`")
|
||||
}
|
||||
};
|
||||
|
||||
// Some tests are significantly slower than others and need to be further reduced.
|
||||
if let Some((_id, _gen, scale)) = EXTEMELY_SLOW_TESTS
|
||||
.iter()
|
||||
.find(|(id, gen, _scale)| *id == ctx.fn_ident && *gen == ctx.gen_kind)
|
||||
{
|
||||
// However, do not override if the extensive iteration count has been manually set.
|
||||
if !(ctx.gen_kind == GeneratorKind::Extensive && EXTENSIVE_ITER_OVERRIDE.is_some()) {
|
||||
total_iterations /= scale;
|
||||
}
|
||||
}
|
||||
|
||||
// FMA has a huge domain but is reasonably fast to run, so increase iterations.
|
||||
if ctx.base_name == BaseName::Fma {
|
||||
total_iterations *= 4;
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ libm_macros::for_each_function! {
|
|||
fmaxf16,
|
||||
fminf128,
|
||||
fminf16,
|
||||
fmodf128,
|
||||
fmodf16,
|
||||
rintf128,
|
||||
rintf16,
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
|
|||
| fmaxf16
|
||||
| fminf128
|
||||
| fminf16
|
||||
| fmodf128
|
||||
| fmodf16
|
||||
| rintf128
|
||||
| rintf16
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ fminf128
|
|||
fminf16
|
||||
fmod
|
||||
fmodf
|
||||
fmodf128
|
||||
fmodf16
|
||||
frexp
|
||||
frexpf
|
||||
|
|
|
|||
5
library/compiler-builtins/libm/src/math/fmodf128.rs
Normal file
5
library/compiler-builtins/libm/src/math/fmodf128.rs
Normal 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)
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue