Skip to content

Commit 614c00d

Browse files
authored
Merge pull request rust-lang#470 from tgross35/f128-fmod
Add `fmodf128`
2 parents bae270f + 68b9036 commit 614c00d

File tree

12 files changed

+68
-41
lines changed

12 files changed

+68
-41
lines changed

crates/libm-macros/src/shared.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option<Signature>, &[&str])]
9090
FloatTy::F128,
9191
Signature { args: &[Ty::F128, Ty::F128], returns: &[Ty::F128] },
9292
None,
93-
&["copysignf128", "fdimf128", "fmaxf128", "fminf128"],
93+
&["copysignf128", "fdimf128", "fmaxf128", "fminf128", "fmodf128"],
9494
),
9595
(
9696
// `(f32, f32, f32) -> f32`

crates/libm-test/benches/icount.rs

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ main!(
111111
icount_bench_fmin_group,
112112
icount_bench_fminf_group,
113113
icount_bench_fmod_group,
114+
icount_bench_fmodf128_group,
114115
icount_bench_fmodf16_group,
115116
icount_bench_fmodf_group,
116117
icount_bench_frexp_group,

crates/libm-test/benches/random.rs

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ libm_macros::for_each_function! {
131131
| fmaxf16
132132
| fminf128
133133
| fminf16
134+
| fmodf128
134135
| fmodf16
135136
| rintf128
136137
| rintf16

crates/libm-test/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub use op::{
2828
Ty,
2929
};
3030
pub use precision::{MaybeOverride, SpecialCase, default_ulp};
31-
use run_cfg::EXTENSIVE_MAX_ITERATIONS;
31+
use run_cfg::extensive_max_iterations;
3232
pub use run_cfg::{CheckBasis, CheckCtx, EXTENSIVE_ENV, GeneratorKind, skip_extensive_test};
3333
pub use test_traits::{CheckOutput, Hex, TupleCall};
3434

@@ -89,7 +89,7 @@ pub fn test_log(s: &str) {
8989
writeln!(f, "cargo features: {}", env!("CFG_CARGO_FEATURES")).unwrap();
9090
writeln!(f, "opt level: {}", env!("CFG_OPT_LEVEL")).unwrap();
9191
writeln!(f, "target features: {}", env!("CFG_TARGET_FEATURES")).unwrap();
92-
writeln!(f, "extensive iterations {}", *EXTENSIVE_MAX_ITERATIONS).unwrap();
92+
writeln!(f, "extensive iterations {}", extensive_max_iterations()).unwrap();
9393

9494
Some(f)
9595
});

crates/libm-test/src/mpfloat.rs

+16-31
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ libm_macros::for_each_function! {
152152
floorf16,
153153
fmod,
154154
fmodf,
155+
fmodf128,
155156
fmodf16,
156157
frexp,
157158
frexpf,
@@ -301,21 +302,6 @@ macro_rules! impl_op_for_ty {
301302
}
302303
}
303304

304-
impl MpOp for crate::op::[<fmod $suffix>]::Routine {
305-
type MpTy = (MpFloat, MpFloat);
306-
307-
fn new_mp() -> Self::MpTy {
308-
(new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
309-
}
310-
311-
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
312-
this.0.assign(input.0);
313-
this.1.assign(input.1);
314-
let ord = this.0.rem_assign_round(&this.1, Nearest);
315-
prep_retval::<Self::RustRet>(&mut this.0, ord)
316-
}
317-
}
318-
319305
impl MpOp for crate::op::[<frexp $suffix>]::Routine {
320306
type MpTy = MpFloat;
321307

@@ -481,6 +467,21 @@ macro_rules! impl_op_for_ty_all {
481467
prep_retval::<Self::RustRet>(&mut this.0, Ordering::Equal)
482468
}
483469
}
470+
471+
impl MpOp for crate::op::[<fmod $suffix>]::Routine {
472+
type MpTy = (MpFloat, MpFloat);
473+
474+
fn new_mp() -> Self::MpTy {
475+
(new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
476+
}
477+
478+
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
479+
this.0.assign(input.0);
480+
this.1.assign(input.1);
481+
let ord = this.0.rem_assign_round(&this.1, Nearest);
482+
prep_retval::<Self::RustRet>(&mut this.0, ord)
483+
}
484+
}
484485
}
485486
};
486487
}
@@ -526,22 +527,6 @@ impl MpOp for crate::op::lgammaf_r::Routine {
526527
}
527528
}
528529

529-
// No fmodf128 yet
530-
impl MpOp for crate::op::fmodf16::Routine {
531-
type MpTy = (MpFloat, MpFloat);
532-
533-
fn new_mp() -> Self::MpTy {
534-
(new_mpfloat::<Self::FTy>(), new_mpfloat::<Self::FTy>())
535-
}
536-
537-
fn run(this: &mut Self::MpTy, input: Self::RustArgs) -> Self::RustRet {
538-
this.0.assign(input.0);
539-
this.1.assign(input.1);
540-
let ord = this.0.rem_assign_round(&this.1, Nearest);
541-
prep_retval::<Self::RustRet>(&mut this.0, ord)
542-
}
543-
}
544-
545530
/* stub implementations so we don't need to special case them */
546531

547532
impl MpOp for crate::op::nextafter::Routine {

crates/libm-test/src/run_cfg.rs

+30-7
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,30 @@ pub const EXTENSIVE_ENV: &str = "LIBM_EXTENSIVE_TESTS";
1313
/// Specify the number of iterations via this environment variable, rather than using the default.
1414
pub const EXTENSIVE_ITER_ENV: &str = "LIBM_EXTENSIVE_ITERATIONS";
1515

16+
/// The override value, if set by the above environment.
17+
static EXTENSIVE_ITER_OVERRIDE: LazyLock<Option<u64>> = LazyLock::new(|| {
18+
env::var(EXTENSIVE_ITER_ENV).map(|v| v.parse().expect("failed to parse iteration count")).ok()
19+
});
20+
21+
/// Specific tests that need to have a reduced amount of iterations to complete in a reasonable
22+
/// amount of time.
23+
///
24+
/// Contains the itentifier+generator combo to match on, plus the factor to reduce by.
25+
const EXTEMELY_SLOW_TESTS: &[(Identifier, GeneratorKind, u64)] = &[
26+
(Identifier::Fmodf128, GeneratorKind::QuickSpaced, 40),
27+
(Identifier::Fmodf128, GeneratorKind::Extensive, 40),
28+
];
29+
1630
/// Maximum number of iterations to run for a single routine.
1731
///
1832
/// The default value of one greater than `u32::MAX` allows testing single-argument `f32` routines
1933
/// and single- or double-argument `f16` routines exhaustively. `f64` and `f128` can't feasibly
2034
/// be tested exhaustively; however, [`EXTENSIVE_ITER_ENV`] can be set to run tests for multiple
2135
/// hours.
22-
pub static EXTENSIVE_MAX_ITERATIONS: LazyLock<u64> = LazyLock::new(|| {
23-
let default = 1 << 32;
24-
env::var(EXTENSIVE_ITER_ENV)
25-
.map(|v| v.parse().expect("failed to parse iteration count"))
26-
.unwrap_or(default)
27-
});
36+
pub fn extensive_max_iterations() -> u64 {
37+
let default = 1 << 32; // default value
38+
EXTENSIVE_ITER_OVERRIDE.unwrap_or(default)
39+
}
2840

2941
/// Context passed to [`CheckOutput`].
3042
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -206,12 +218,23 @@ pub fn iteration_count(ctx: &CheckCtx, argnum: usize) -> u64 {
206218
let mut total_iterations = match ctx.gen_kind {
207219
GeneratorKind::QuickSpaced => domain_iter_count,
208220
GeneratorKind::Random => random_iter_count,
209-
GeneratorKind::Extensive => *EXTENSIVE_MAX_ITERATIONS,
221+
GeneratorKind::Extensive => extensive_max_iterations(),
210222
GeneratorKind::EdgeCases => {
211223
unimplemented!("edge case tests shoudn't need `iteration_count`")
212224
}
213225
};
214226

227+
// Some tests are significantly slower than others and need to be further reduced.
228+
if let Some((_id, _gen, scale)) = EXTEMELY_SLOW_TESTS
229+
.iter()
230+
.find(|(id, gen, _scale)| *id == ctx.fn_ident && *gen == ctx.gen_kind)
231+
{
232+
// However, do not override if the extensive iteration count has been manually set.
233+
if !(ctx.gen_kind == GeneratorKind::Extensive && EXTENSIVE_ITER_OVERRIDE.is_some()) {
234+
total_iterations /= scale;
235+
}
236+
}
237+
215238
// FMA has a huge domain but is reasonably fast to run, so increase iterations.
216239
if ctx.base_name == BaseName::Fma {
217240
total_iterations *= 4;

crates/libm-test/tests/compare_built_musl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ libm_macros::for_each_function! {
9393
fmaxf16,
9494
fminf128,
9595
fminf16,
96+
fmodf128,
9697
fmodf16,
9798
rintf128,
9899
rintf16,

crates/util/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ fn do_eval(basis: &str, op: &str, inputs: &[&str]) {
100100
| fmaxf16
101101
| fminf128
102102
| fminf16
103+
| fmodf128
103104
| fmodf16
104105
| rintf128
105106
| rintf16

etc/function-definitions.json

+7
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,13 @@
449449
],
450450
"type": "f32"
451451
},
452+
"fmodf128": {
453+
"sources": [
454+
"src/math/fmodf128.rs",
455+
"src/math/generic/fmod.rs"
456+
],
457+
"type": "f128"
458+
},
452459
"fmodf16": {
453460
"sources": [
454461
"src/math/fmodf16.rs",

etc/function-list.txt

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ fminf128
6363
fminf16
6464
fmod
6565
fmodf
66+
fmodf128
6667
fmodf16
6768
frexp
6869
frexpf

src/math/fmodf128.rs

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

src/math/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ cfg_if! {
378378
mod floorf128;
379379
mod fmaxf128;
380380
mod fminf128;
381+
mod fmodf128;
381382
mod rintf128;
382383
mod roundf128;
383384
mod sqrtf128;
@@ -390,6 +391,7 @@ cfg_if! {
390391
pub use self::floorf128::floorf128;
391392
pub use self::fmaxf128::fmaxf128;
392393
pub use self::fminf128::fminf128;
394+
pub use self::fmodf128::fmodf128;
393395
pub use self::rintf128::rintf128;
394396
pub use self::roundf128::roundf128;
395397
pub use self::sqrtf128::sqrtf128;

0 commit comments

Comments
 (0)