Repository navigation
Releases: anun333/crmvec
Release list
crmvec 0.12.2: bfloat16 under GCC 13 on AArch64, and CORE-MATH ea7a421
Built by GCC 13 on AArch64 with the fp16 extension, crmvec's bfloat16
functions were wrong: f16check found 125,576 wrong results of 54,132,736.
GCC 13 loads a __bf16 constant with the FMOV instruction's half-precision
immediate, which encodes binary16, so 1.0 arrives as 0.0078125 (GCC bug
111867, fixed in GCC 14 and not backported). -march=native turns the fp16
extension on for most current Arm cores, and GCC 13 is Ubuntu 24.04's
default compiler. The bfloat16 files are now compiled with fp16 off under
GCC before 14, and the same build then matches MPFR on every input.
Packages built for the baseline architecture (armv8-a), as distributions
build them, were not affected.
On AArch64, make check now checks every half-precision and bfloat16 input
(f16check, against MPFR 4.2 or against the hash of outputs that matched
MPFR); until now only x86-64 ran it. The arm64 CI job also builds it with
the fp16 extension.
The CORE-MATH files are now those of its master branch at ea7a421 (they
were e78b460's): sin, exp, log, cbrtf16 and acos_bf16 changed upstream,
then cosh, cospi, exp, exp10, exp2, log10, log2, sinh, sinpi and tanpi.
Old against new, in all four rounding modes, the numeric results and
exception flags are the same on every input tried: 805,831,028 and
686,469,600 calls on x86-64 and aarch64, with every worst case CORE-MATH
lists for the updated binary64 functions.
sin of +inf, -inf and a NaN now returns +NaN, where 0.12.1 returned -NaN,
in both libraries and the libm preload, because CORE-MATH's sin does so
since its commit 040ee48. That changes three of the fast mode's results, so
its kernel version is now 2 (fast/bits-v2.txt; only sin differs from
version 1, and crmvec-run --fast --stamp records the version).
Otherwise the libraries give the same results as 0.12.1's.
crmvec 0.12.1: packages for older distribution releases
crmvec's packages now build on the distribution releases still in long-term
use. The RPM spec builds with gcc-toolset-14 on RHEL 8 and 9 and with gcc13 on
openSUSE Leap 15, whose own compilers are too old. The packages build, pass
make check, install and run on AlmaLinux 8, 9 and 10, openSUSE Leap 15.6 and
16.0, Debian 13, Fedora 44 and Ubuntu 24.04.
Building now needs gcc 13 or newer on x86-64 (__bf16, for the bfloat16
functions; _Float16 needs 12). make checks this before compiling anything and
names the compiler to use on each older release. Debian 12 and Ubuntu 22.04
have no gcc 13 in their archives; conda-forge's crmvec runs there.
Fixed in the checks: on openSUSE, whose gcc builds non-PIE executables,
mpfrcheck stopped as VOID, because its guard took a library function's
address to find which libmvec.so.1 it had loaded; it now asks the dynamic
loader. With MPFR older than 4.2 (RHEL 8 and 9, Ubuntu 22.04, Leap 15)
f16check could not be built; it now builds without MPFR and compares a hash
of all its outputs with f16check-hash.txt, recorded from builds whose every
output matched MPFR. mpfrcheck and f16check link -ldl, for glibc before 2.34.
Unchanged: the libraries. libmvec.so.1, the fast mode's library and
libcrpreload.so built from 0.12.1 are byte-identical to 0.12.0's built
with the same compiler.
Checked before the tag: CI on x86-64 and arm64; the packages of AlmaLinux 8,
9 and 10, openSUSE Leap 15.6 and 16.0, Debian 13, Fedora 44 and Ubuntu
24.04, each built with make check, installed and run; Nix; the conda package
as conda-forge builds it; and make check and the preload's check (620,756,992
calls) natively on a Neoverse N1.
crmvec 0.12.0: a faster fast mode, with versioned results
The fast mode (crmvec-run --fast; x86-64 with AVX2 and FMA) now binds each AVX2
entry point at load time straight to its kernel, which holds the rounding-mode
test, instead of testing the CPU and the rounding mode and then calling it. On
an AMD EPYC 7773X it takes a median 1.02 times glibc 2.41's libmvec time (from
1.09), floats 1.00 (from 1.17), and is at or under glibc on 23 of the 52
functions (from 16). Its results are unchanged.
The fast mode's results are now versioned. Unlike the correctly rounded mode's,
they are defined by its kernels, not by mathematics, so a change to a kernel
would change them. fast/bits-v1.txt records kernel version 1: the fast
libraries of 0.10.0, 0.11.1 and 0.12.0 give the same results, and make
check-fast fails on any library that doesn't. A release that changes a result
will bump the version and say so (docs/fast-mode.md, "Versions").
Fixed: crmvec-stamp recorded a crmvec-run --fast run as correctly rounded. It
now records the fast mode, not correctly rounded, with its kernel version
(FastKernelVersion in crmvec-libm.json). A fast-mode run stamped with 0.11.0
or 0.11.1 says "correctly rounded" where it should say fast mode.
New: docs/distros.md, what crmvec changes on 14 LTS distributions (glibc 2.17
to 2.43): which functions are not correctly rounded there, which depend on the
CPU, and each image's glibc package, with the raw output and the probes to
rerun it (make craccuracy craccuracy-zsign cpupath).
Unchanged: the correctly rounded library, libcrpreload.so, and the 165
CORE-MATH files (as of e78b460).
Checked before the tag: CI on x86-64 and arm64; the Fedora 44, Nix and
Ubuntu 24.04 packages, each running make check; the conda package as
conda-forge builds it (gcc 15, glibc 2.17), whose fast library gives kernel
version 1's results on every float input; make check-fast in full on an AMD
EPYC 7773X; and make check and the preload's check (620,756,992 calls, every
rounding mode, with and without FZ) natively on a Neoverse N1.
crmvec 0.11.1: CORE-MATH's stand-alone cbrtf16
CORE-MATH's f16/cbrtf16.c no longer calls the C library's cbrtf (CORE-MATH 398b235 and
e78b460), so crmvec's workaround for it, crmvec-cbrtf16.h, is gone. The results are the
same: every half and bfloat16 input of every function, in four rounding modes, checked
against MPFR before and after (54,132,736 results). All 165 CORE-MATH files crmvec
carries are byte-identical to CORE-MATH's master at e78b460.
crmvec 0.11.0: the correctly rounded libm on aarch64 too, and ways to turn it on without changing the operating system.
libcrpreload.so on aarch64. CORE-MATH's 76 correctly rounded functions under
the C library's names, now on aarch64 Linux as on x86-64:
crmvec-run --libm ./program
Checked against CORE-MATH on a Neoverse N1: every input of the 33 one-argument
float functions in the four rounding modes and under flush-to-zero, and 2^20
inputs of every function in each mode with and without it. A median of 1.36
times glibc's time per call there.
A cheaper underflow. An underflowing exp, exp2, exp10, erfc or tgamma now
sets errno without testing the exception flag: 19 ns a call, from about 230.
Over a whole FreeSurfer recon-all, the preload costs 13% more than glibc, from
27%, with the same outputs.
Without changing the operating system (docs/lab.md):
- conda install crmvec-libm turns the correctly rounded math on for every
program run from that conda environment, and conda remove turns it off
(once the package is on conda-forge); - contrib/modules/ has Lmod and Tcl module files for clusters;
- crmvec-stamp OUTPUT_DIR, or crmvec-run --stamp, records in a run's outputs
which math it used.
docs/evidence.md has the cases we measured where the math library changed a
program's results.
CORE-MATH updated to e072473: sin.c now builds where a 128-bit integer to
double conversion is missing, and pow.c no longer raises a spurious underflow
flag in directed rounding. The results are the same on 2^24 inputs in each
rounding mode.
crmvec 0.10.0
crmvec 0.10.0: a fast mode, for when the same answer everywhere is enough.
Correct rounding costs about three to four times glibc's time on x86-64. Many
programs need their results to be the same on every machine, not correctly
rounded. For them, crmvec now also installs fast/libmvec.so.1:
crmvec-run --fast ./program
Its 52 functions are not correctly rounded. Each one is a fixed sequence of
IEEE operations within OpenCL's accuracy bound for that function (measured as
the OpenCL CTS measures it: the floats on every input), at a median of 1.09
times glibc's time on a Zen 3 core. Every entry point runs the same kernel and
none uses an instruction whose bits vary between processors, so a program gets
the same bits on every x86-64 CPU with AVX2 and FMA, whichever vector width it
was built for. On older CPUs, and outside round-to-nearest, it returns the
correctly rounded results instead. Through PoCL, the OpenCL conformance
tests' math checks pass with it for the six functions PoCL's vectorizer sends
to libmvec (with glibc's libmvec, exp and log fail).
What it gives up is agreement with other libraries: a correctly rounded result
is the one every correct implementation gives, and the fast mode's results
agree only with themselves. The default library, correctly rounded, is
unchanged.
crmvec 0.9.0
crmvec 0.9.0: correctly rounded scalar math too.
On x86-64, crmvec now also installs libcrpreload.so: CORE-MATH's correctly
rounded elementary functions under the C library's names (exp, log, sin,
pow, atan2, erfc, tgamma, the float forms, C23's sinpi family; 76 in all).
crmvec-run --libm ./program runs a program with it, so its ordinary libm
calls return the same bits on every CPU and every glibc version, not only
its vectorized loops. It holds an FMA build and a plain x86-64 build and
picks one per CPU at load, with the same results; it sets errno and the
exception flags as glibc does. Where it was tried, it made FSL FLIRT,
MCFLIRT and ANTs registrations that depended on the CPU (AVX2) and on the
glibc version byte-identical across both.
Checked: every function against CORE-MATH on 2^22 inputs, in four rounding
modes by four flush-to-zero settings, results and flags, for all three
builds; make check runs the same at 2^16. The vector library is unchanged
from 0.8.0.
Packaging: the Debian package's make check passes again; since 0.6.0 it had
read a nested make's "Leaving directory" line as a verdict and failed. The
Debian, Fedora, Nix and conda packages were each built and checked for this
release.
crmvec is on conda-forge since this week (0.7.2 first; the feedstock will
follow this release).
crmvec 0.8.0
crmvec 0.8.0: the same correctly rounded results, faster.
Eighteen float functions (logf, log2f, log10f, log1pf, expm1f, tanhf,
atanf, asinf, acosf, atanhf, asinhf, acoshf, cbrtf, erff, erfcf, asinpif,
acospif, atanpif) get new AVX2 vector paths. They compute just enough
precision to decide the rounding of nearly every input, and leave the
rest to CORE-MATH. Results are bit-for-bit what 0.7.2 gave, which is
CORE-MATH's correctly rounded result, on all 2^32 inputs of each
function, and under flush-to-zero too. Time per element on an AMD EPYC
7773X, through the AVX2 entry points:
logf 2.49 -> 1.77 ns log2f 2.54 -> 1.93 log10f 2.60 -> 2.04
log1pf 3.61 -> 2.37 expm1f 3.07 -> 1.99 tanhf 3.62 -> 3.25
atanf 3.29 -> 1.96 asinf 4.13 -> 2.00 acosf 5.10 -> 2.06
atanhf 4.58 -> 2.67 asinhf 4.96 -> 4.13 acoshf 4.90 -> 3.81
cbrtf 4.20 -> 2.14 erff 3.79 -> 2.97 erfcf 5.63 -> 3.92
asinpif 10.44 -> 2.32 acospif 10.49 -> 2.45 atanpif 10.16 -> 2.71
Also: crtest verify under flush-to-zero (CRTEST_FTZ=1); the pi functions
in crtest's every-input check; -Werror=undef for crmvec.c; check-pocl.py
exits 2 when it cannot give a verdict; CORE-MATH 284b3b0's sinpi.c.
Nix users: from 0.6.0 to 0.7.2 the Nix recipe skipped make check without
saying so. It runs it again from 0.8.0 (every verdict passes with current
nixpkgs).
crmvec 0.7.2
- x86: a vector path for double
rsqrt(AVX2 and FMA; the SSE2 entry point goes through it), CORE-MATH's fast path transcribed; lanes it cannot decide go tocr_rsqrt. 2.6 times faster than CORE-MATH's scalarrsqrton a Zen 3. Checked byrsqrt-vcheck, inmake check, on CORE-MATH's hard cases at every scale, with a control that must fail. - CORE-MATH:
powf.candsin.cfrom masterfe94e92, so all 165 of CORE-MATH's files are byte-identical to its master again. No changed result was found (sin: 2^26 large arguments and 1,975,928 hard cases;powf: 2.7 billion pairs; four rounding modes). - Build:
mpfrcheckandpownf-searchneed MPFR 4.2; with an older MPFR they are left out instead of stopping the build. crtest:CRTEST_LOG2Nsets the random sample size ofverify64(andverify64e).crmvec-run:--helpand--version(asked for by conda-forge's review, as a test of the installed package); with no arguments it prints the usage and exits 2.
crmvec 0.7.1
- CORE-MATH:
powf.cfrom mastere3f1fcc, so all 165 of CORE-MATH's files are byte-identical to its master again. It removes an undefined shift (reported 2026-09-27) thatcr_powf(0x1.ffff36p-1f, 0x1.03ac88p+24f)reaches in 0.7.0. No changed result was found: 0 differences from 0.7.0'spowfon 2.7 billion pairs in the four rounding modes, and none among 40.7 million exact results in round-upward. - Nothing else changes.