This is the mail archive of the
mailing list for the glibc project.
Re: [RFC] How to add vector math functions to Glibc
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: Andrew Senkevich <andrew dot n dot senkevich at gmail dot com>
- Cc: libc-alpha <libc-alpha at sourceware dot org>
- Date: Thu, 18 Sep 2014 17:04:55 +0000
- Subject: Re: [RFC] How to add vector math functions to Glibc
- Authentication-results: sourceware.org; auth=none
- References: <CAMXFM3tjquzniXP1weqxSVFJyhXqsf2PHuyrrrmqp7K0ZzORqA at mail dot gmail dot com> <CAMXFM3sGMNX1DEPAMt7qUR4UREF_xUAQjCG1OjBiZH2aoOFiPA at mail dot gmail dot com>
On Thu, 18 Sep 2014, Andrew Senkevich wrote:
> > 1. Should functions go in libm or a separate libmvec library?
> If integrate new functions with libm it will be easier for developers
> to employ vectorization and should improve acceptance.
> Libmvec case affects compiler options and it seems new header need to
> be included instead of math.h, or is it OK include it in math.h?
> But libmvec could be better from the side of optional build (mentioned
> later in 2.) in case of addition most modern implementations.
There is also the option of installing libm.so as a linker script that
refers to libmvec inside AS_NEEDED - libc.so is already a linker script
after all. That way, libmvec would automatically be linked into programs
that need it (preserving compatibility with the POSIX rules about what
library names need specifying to get what functions), without restricting
the tools that can build glibc if vector extensions are added for which
tool support is recent, but building libmvec is optional.
> > 2. What requirements on the compiler / assembler versions used are imposed
> > by the requirement that the ABI provided by glibc's shared libraries must
> > not depend on the tools used to build glibc, and what such requirements is
> > it OK to impose (it may be OK to move to GCC 4.6 as minimum compiler at
> > present, but requiring a more recent version would be a problem; we'd need
> > to consider what binutils version we can require)? If a separate libmvec
> > is used, is it OK simply not to build it if those requirements aren't met?
> > (It's definitely not OK for the ABI of a library to vary incompatibly, but
> > it might be OK for the presence of a library to be conditional.)
> Addition of vectorized versions in currently existing in Glibc ISAs
> may not affect build (f.e. SSE4, AVX, AVX2 in x86_64 case).
> Most modern implementation imply necessary checks in configure and
> hiding under according macros, another words it can have optional
It looks like AVX2 support was new in binutils 2.22. Currently the
minimum is 2.20. Do we think it's OK to move the minimum to 2.22 (or
later), or do we need to make libmvec optional on x86_64?
> > 3. Should it be declared that these vectorized functions do not set errno?
> > (If so, then any header code that enables them to be used must of course
> > avoid enabling them in the default -fmath-errno case.) Similarly, do they
> > follow the other goals documented in the glibc manual for accuracy of
> > results and exceptions (for all input values, including e.g. range
> > reduction)? If not, further conditionals such as -ffast-math may be
> > needed.
> For x86_64 these functions doesn't set errno and have less accuracy so we
> need to require to set -fast-math (which sets -fno-math-errno) to use
> them (or may be set -ffast-math under -fopenmp for x86_64).
We should understand the specific properties of the functions to know what
the relevant conditions are under which they can be used. (Those
conditions should then map to preprocessor conditions in the bits/ header
that is how glibc tells the compiler about availability of the functions.)
According to the description at <https://sourceware.org/glibc/wiki/libm>,
the functions may have inaccurate exceptions (-fno-trapping-math needed),
not set errno (-fno-math-errno needed), may not work properly outside
round-to-nearest mode (-fno-rounding-math needed - which is the default).
A 4-ulp maximum error is also stated (which is within the accuracy goals
expected by the testsuite for most functions, though some users may want
more accurate functions). They are stated to work for special cases, so
no need for -ffinite-math-only.
Right now, there are no preprocessor macros for -fno-trapping-math,
-fno-math-errno or -fno-rounding-math. So I think you're constrained to
using these functions only if __FAST_MATH__ is predefined. However, it
would be a good idea to add GCC predefines for each of those three
options. Then these functions could be used if (defined
__NO_TRAPPING_MATH__ && defined __NO_MATH_ERRNO__ && defined
__NO_ROUNDING_MATH__) || defined __FAST_MATH__. (People using older
compilers could choose to define those macros themselves if they want the
functions without using -ffast-math. There could also be a glibc-defined
macro for users to define - just like __USE_STRING_INLINES, you could have
__USE_MATH_VECTOR_FUNCTIONS that users can use to enable these functions
even if their compiler options would not otherwise cause them to be used.)
__NO_MATH_ERRNO__ would be otherwise useful for replacing _LIB_VERSION /
libieee with a better way of selecting no-errno versions of functions.
Given these properties of the functions, we can then appropriately
condition which tests from libm-test.inc are run for them.
> > 4. We need to handle different architectures having different sets of
> > functions vectorized.
> We need to have some way for #pragma simd declare to be architecture dependent.
> It gives possibility to have different sets of vectorized functions
> for different architectures.
I think having a long series of macros such as __DECL_SIMD_COS_DOUBLE as I
suggested in <https://sourceware.org/ml/libc-alpha/2014-09/msg00182.html>,
that the architecture-specific <bits/math-vector.h> header may or may not
define, would work for this.
The default bits/math-vector.h, for architectures without such functions,
should be minimal (that is, it should not be necessary to define long
series of macros for functions you don't have versions of on your
architecture, so that adding vectorized versions of a new function for one
architecture doesn't require you to update the files for lots of other
architectures to say they don't have vectorized versions of that function;
architecture-independent files should handle the macros possibly not being
> > 6. How do we handle different glibc versions having vectorized functions
> > for different vector ISA extensions?
> It seems it is became problem only if someone has old installed Glibc
> version and binary with symbol from new Glibc version?
No, this is the point about the pragma used being required to have
GCC-version-independent semantics about what vector ISAs the function is
available for, so that old glibc and headers work when used with newer
compilers that know about newer vector ISAs - hence the need for some
OpenMP extension for that purpose.
Joseph S. Myers