Skip to content

Add a generic rempio2 #888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
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
121 changes: 121 additions & 0 deletions etc/generate-constants.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using Printf

function main()
repo_root = dirname(@__DIR__)
out_dir = joinpath(repo_root, "libm/src/math/generic/generated")

mod_contents = "// autogenerated\n\n"

cfg = Config(out_dir)
mod_contents *= update_rem_pio2(cfg)

path = joinpath(cfg.out_dir, "mod.rs")
write(path, mod_contents)
println("wrote $path")
end

struct Config
out_dir::String
end

@enum FloatTy F16 F32 F64 F128

struct TyInfo
bits::UInt32
sig_bits::UInt32
ity::Type
ty_name::String
end

function ty_info(fty::FloatTy)::TyInfo
if fty == F16
bits = 16
sig_bits = 10
ity = UInt16
elseif fty == F32
bits = 32
sig_bits = 23
ity = UInt32
elseif fty == F64
bits = 64
sig_bits = 52
ity = UInt64
elseif fty == F128
bits = 128
sig_bits = 112
ity = UInt128
else
@assert(false)
end

return TyInfo(
bits,
sig_bits,
ity,
lowercase(string(fty)),
)
end

function update_rem_pio2(cfg::Config)::String
prefix= """
use crate::support::HalfRep;
use super::super::rem_pio2::RemPio2Support;
"""
ret = ""

for fty in [F64]
info = ty_info(fty)
ty_name = info.ty_name
halfbits = info.bits / 2

if info.bits == 32 || info.bits == 64
to_bits = "$(ty_name)_to_bits"
prefix *= "use crate::support::$to_bits;\n"
else
to_bits = "$ty_name::to_bits"
end

bigf_hi(x::BigFloat) = @sprintf "(%s(hf%d!(\"%a\")) >> %d) as u%d" to_bits info.bits x halfbits halfbits
bigf_hex(x::BigFloat) = @sprintf "hf%d!(\"%a\")" info.bits x

setprecision(ty_info(fty).sig_bits + 1)

ty_impl = """
impl RemPio2Support for $ty_name {
const TO_INT: Self = 1.5 / $ty_name::EPSILON;
const INV_PIO2: Self = $(bigf_hex(2 / big(pi)));
const PIO2_1: Self = 1.57079632673412561417e+00;
const PIO2_1T: Self = 6.07710050650619224932e-11;
const PIO2_2: Self = 6.07710050630396597660e-11;
const PIO2_2T: Self = 2.02226624879595063154e-21;
const PIO2_3: Self = 2.02226624871116645580e-21;
const PIO2_3T: Self = 8.47842766036889956997e-32;

const FRAC_5PI_4_HI: HalfRep<Self> = $(bigf_hi(5 * big(pi) / 4));
const FRAC_3PI_4_HI: HalfRep<Self> = $(bigf_hi(3 * big(pi) / 4));
const FRAC_9PI_4_HI: HalfRep<Self> = $(bigf_hi(9 * big(pi) / 4));
const FRAC_7PI_4_HI: HalfRep<Self> = $(bigf_hi(7 * big(pi) / 4));
const FRAC_3PI_2_HI: HalfRep<Self> = $(bigf_hi(3 * big(pi) / 2));
const TAU_HI: HalfRep<Self> = $(bigf_hi(2 * big(pi)));
const FRAC_PI_2_HI: HalfRep<Self> = 0x921fb;
const FRAC_2_POW_20_PI_2: HalfRep<Self> = $(bigf_hi((big(2)^20) * pi / 2));

const MAGIC_F: Self = hf$(info.bits)!("0x1p24");

fn large(x: &[Self], y: &mut [Self], e0: i32, prec: usize) -> i32 {
super::super::super::rem_pio2_large(x, y, e0, prec)
}
}
"""
ret *= ty_impl
end

ret = prefix * "\n" * ret
path = joinpath(cfg.out_dir, "rem_pio2.rs")
write(path, ret)
println("wrote $path")

return "mod rem_pio2;"
end

main()
3 changes: 3 additions & 0 deletions libm-test/src/f8_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ impl Float for f8 {
const ZERO: Self = Self(0b0_0000_000);
const NEG_ZERO: Self = Self(0b1_0000_000);
const ONE: Self = Self(0b0_0111_000);
const TWO: Self = Self(0b0_1000_000);
const THREE: Self = Self(0b0_1000_100);
const FOUR: Self = Self(0b0_1001_000);
const NEG_ONE: Self = Self(0b1_0111_000);
const MAX: Self = Self(0b0_1110_111);
const MIN: Self = Self(0b1_1110_111);
Expand Down
64 changes: 63 additions & 1 deletion libm-test/tests/multiprecision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![cfg(feature = "build-mpfr")]

use libm_test::generate::{case_list, edge_cases, random, spaced};
use libm_test::mpfloat::MpOp;
use libm_test::mpfloat::{MpFloat, MpOp};
use libm_test::{CheckBasis, CheckCtx, CheckOutput, GeneratorKind, MathOp, TupleCall};

const BASIS: CheckBasis = CheckBasis::Mpfr;
Expand Down Expand Up @@ -77,3 +77,65 @@ libm_macros::for_each_function! {
nextafterf,
],
}

// fn mp_runner_rem_pio2<F: Float, Args>(ctx: &CheckCtx, cases: impl Iterator<Item = Args>) {
// let x = MpFloat::new(prec)

// // let mut mp_vals = Op::new_mp();
// for input in cases {
// // let mp_res = Op::run(&mut mp_vals, input);
// let crate_res = input.call_intercept_panics(Op::ROUTINE);

// crate_res.validate(mp_res, input, ctx).unwrap();
// }
// }

// macro_rules! mp_tests_rem_pio2 {
// (
// fn_name: $fn_name:ident,
// attrs: [$($attr:meta),*],
// ) => {
// paste::paste! {
// #[test]
// $(#[$attr])*
// fn [< mp_case_list_ $fn_name >]() {
// type Op = libm_test::op::sin::Routine;
// let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GeneratorKind::List);
// let cases = case_list::get_test_cases_basis::<Op>(&ctx).0;
// mp_runner_rem_pio2(&ctx, cases);
// }

// #[test]
// $(#[$attr])*
// fn [< mp_random_ $fn_name >]() {
// type Op = libm_test::op::sin::Routine;
// let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GeneratorKind::Random);
// let cases = random::get_test_cases::<<Op as MathOp>::RustArgs>(&ctx).0;
// mp_runner_rem_pio2(&ctx, cases);
// }

// #[test]
// $(#[$attr])*
// fn [< mp_edge_case_ $fn_name >]() {
// type Op = libm_test::op::sin::Routine;
// let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GeneratorKind::EdgeCases);
// let cases = edge_cases::get_test_cases::<Op>(&ctx).0;
// mp_runner_rem_pio2(&ctx, cases);
// }

// #[test]
// $(#[$attr])*
// fn [< mp_quickspace_ $fn_name >]() {
// type Op = libm_test::op::sin::Routine;
// let ctx = CheckCtx::new(Op::IDENTIFIER, BASIS, GeneratorKind::QuickSpaced);
// let cases = spaced::get_test_cases::<Op>(&ctx).0;
// mp_runner_rem_pio2(&ctx, cases);
// }
// }
// };
// }

// mp_tests_rem_pio2! {
// fn_name: rem_pio2,
// attrs: [],
// }
3 changes: 3 additions & 0 deletions libm/src/math/generic/generated/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// autogenerated

mod rem_pio2;
29 changes: 29 additions & 0 deletions libm/src/math/generic/generated/rem_pio2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use super::super::rem_pio2::RemPio2Support;
use crate::support::{HalfRep, f64_to_bits};

impl RemPio2Support for f64 {
const TO_INT: Self = 1.5 / f64::EPSILON;
const INV_PIO2: Self = hf64!("0xa.2f9836e4e4418p-4");
const PIO2_1: Self = 1.57079632673412561417e+00;
const PIO2_1T: Self = 6.07710050650619224932e-11;
const PIO2_2: Self = 6.07710050630396597660e-11;
const PIO2_2T: Self = 2.02226624879595063154e-21;
const PIO2_3: Self = 2.02226624871116645580e-21;
const PIO2_3T: Self = 8.47842766036889956997e-32;

const FRAC_5PI_4_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x3.ed4f452aa70bcp+0")) >> 32) as u32;
const FRAC_3PI_4_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x2.5b2f8fe6643a4p+0")) >> 32) as u32;
const FRAC_9PI_4_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x7.118eafb32caecp+0")) >> 32) as u32;
const FRAC_7PI_4_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x5.7f6efa6ee9dd4p+0")) >> 32) as u32;
const FRAC_3PI_2_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x4.b65f1fccc8748p+0")) >> 32) as u32;
const TAU_HI: HalfRep<Self> = (f64_to_bits(hf64!("0x6.487ed5110b46p+0")) >> 32) as u32;
const FRAC_PI_2_HI: HalfRep<Self> = 0x921fb;
const FRAC_2_POW_20_PI_2: HalfRep<Self> =
(f64_to_bits(hf64!("0x1.921fb54442d18p+20")) >> 32) as u32;

const MAGIC_F: Self = hf64!("0x1p24");

fn large(x: &[Self], y: &mut [Self], e0: i32, prec: usize) -> i32 {
super::super::super::rem_pio2_large(x, y, e0, prec)
}
}
3 changes: 3 additions & 0 deletions libm/src/math/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ mod fmin;
mod fminimum;
mod fminimum_num;
mod fmod;
mod generated;
mod rem_pio2;
mod rint;
mod round;
mod scalbn;
Expand All @@ -31,6 +33,7 @@ pub use fmin::fmin;
pub use fminimum::fminimum;
pub use fminimum_num::fminimum_num;
pub use fmod::fmod;
pub(crate) use rem_pio2::rem_pio2;
pub use rint::rint_round;
pub use round::round;
pub use scalbn::scalbn;
Expand Down
Loading
Loading