1999-10-26 04:18:27 +08:00
|
|
|
README for libm-test math test suite
|
|
|
|
====================================
|
|
|
|
|
|
|
|
The libm-test math test suite tests a number of function points of
|
|
|
|
math functions in the GNU C library. The following sections contain a
|
|
|
|
brief overview. Please note that the test drivers and the Perl script
|
|
|
|
"gen-libm-test.pl" have some options. A full list of options is
|
|
|
|
available with --help (for the test drivers) and -h for
|
|
|
|
"gen-libm-test.pl".
|
|
|
|
|
|
|
|
|
|
|
|
What is tested?
|
|
|
|
===============
|
|
|
|
The tests just evaluate the functions at specified points and compare
|
|
|
|
the results with precomputed values and the requirements of the ISO
|
|
|
|
C99 standard.
|
|
|
|
|
|
|
|
Besides testing the special values mandated by IEEE 754 (infinities,
|
|
|
|
NaNs and minus zero), some more or less random values are tested.
|
|
|
|
|
|
|
|
Files that are part of libm-test
|
|
|
|
================================
|
|
|
|
|
2015-01-29 12:07:01 +08:00
|
|
|
The main file is "libm-test.inc". It is independent of the target
|
|
|
|
platform and the specific real floating type and format and contains
|
|
|
|
placeholder test "templates" for math functions defined in libm.
|
|
|
|
The file, along with a generated file named "auto-libm-test-out",
|
|
|
|
is preprocessed by the Perl script "gen-libm-test.pl" to expand
|
|
|
|
the templates and produce a set of test cases for each math function
|
|
|
|
that are specific to the target platform but still independent of
|
|
|
|
the real floating type. The results of the processing are
|
|
|
|
"libm-test.c" and a file "libm-test-ulps.h" with platform specific
|
|
|
|
deltas by which the actual math function results may deviate from
|
|
|
|
the expected results and still be considered correct.
|
|
|
|
|
|
|
|
The test drivers "test-double.c", "test-float.c", and "test-ldouble.c"
|
|
|
|
test the normal double, float and long double implementation of libm.
|
|
|
|
The test drivers with an 'i' in their name ("test-idouble.c",
|
|
|
|
"test-ifloat.c", and "test-ildoubl.c") test the corresponding inline
|
|
|
|
functions (where available - otherwise they also test the real
|
|
|
|
functions in libm). Each driver selects the desired real floating
|
|
|
|
type to exercise the math functions to test with (float, double, or
|
|
|
|
long double) by defining a small set of macros just before including
|
|
|
|
the generic "libm-test.c" file. Each driver also either defines or
|
|
|
|
undefines the __NO_MATH_INLINES macro just before including
|
|
|
|
"libm-test.c" to select either the real or inline functions,
|
|
|
|
respectively. Each driver is compiled into a single executable test
|
|
|
|
program with the corresponding name.
|
|
|
|
|
|
|
|
As mentioned above, the "gen-libm-test.pl" script looks for a file
|
|
|
|
named "libm-test-ulps" in the platform specific sysdep directory (or
|
|
|
|
its fpu or nofpu subdirectory) and for each variant (real floating
|
|
|
|
type and rounding mode) of every tested function reads from it the
|
|
|
|
maximum difference expressed as Units of Least Precision (ULP) the
|
|
|
|
actual result of the function may deviate from the expected result
|
|
|
|
before it's considered incorrect.
|
|
|
|
|
|
|
|
The "auto-libm-test-out" file contains sets of test cases to exercise,
|
|
|
|
the conditions under which to exercise each, and the expected results.
|
|
|
|
The file is generated by the "gen-auto-libm-tests" program from the
|
|
|
|
"auto-libm-test-in" file. See the comments in gen-auto-libm-tests.c
|
|
|
|
for details about the content and format of the -in and -out files.
|
1999-10-26 04:18:27 +08:00
|
|
|
|
|
|
|
How can I generate "libm-test-ulps"?
|
|
|
|
====================================
|
|
|
|
|
New Makefile target `regen-ulps'.
The wiki "Regeneration" page has this to say about update ULPs.
"The libm-test-ulps files are semiautomatically updated. To
update an ulps baseline, run each of the failing tests (test-float,
test-double, etc.) with -u; this will generate a file called ULPs;
concatenate each of those files with the existing libm-test-ulps
file, after removing any entries for particularly huge numbers of
ulps that you do not want to mark as expected. Then run
gen-libm-test.pl -n -u FILE where FILE is the concatenated file
produced in the previous step. This generates a file called
NewUlps which is the new sorted version of libm-test-ulps."
The same information is listed in math/README.libm-test, and is a
lot of manual work that you often want to run over-and-over again
while working on a particular test.
The `regen-ulps' convenience target does this automatically for
developers.
We strictly assume the source tree is readonly and add a
new --output-dir option to libm-test.inc to allow for writing
out ULPs to $(objpfx).
When run the new target does the following:
* Starts with the baseline ULPs file.
* Runs each of the libm math tests with -u.
* Adds new changes seen with -u to the baseline.
* Sorts and prepares the test output with gen-libm-test.pl.
* Leaves math/NewUlps in your build tree to copy to your source
tree, cleanup, and checkin.
The math test documentation in math/README.libm-test is updated
document the new Makefile target.
---
2013-04-06 Carlos O'Donell <carlos@redhat.com>
* Makefile.in (regen-ulps): New target.
* math/Makefile [ifneq (no,$(PERL)]: Declare regen-ulps with .PHONY.
[ifneq (no,$(PERL)] (run-regen-ulps): New variable.
[ifneq (no,$(PERL)] (regen-ulps): New target.
[ifeq (no,$(PERL)] (regen-ulps): New target.
* math/libm-test.inc (ulps_file_name): Define.
(output_dir): New variable.
(options): Add "output-dir" option.
(parse_opt): Handle 'o' case.
(main): If output_dir is non-NULL use it as a prefix
otherwise use "".
* math/README.libm-test: Update `How can I generate "libm-test-ulps"?'
2013-04-07 04:22:47 +08:00
|
|
|
To automatically generate a new "libm-test-ulps" run "make regen-ulps".
|
|
|
|
This generates the file "math/NewUlps" in the build directory. The file
|
|
|
|
contains the sorted results of all the tests. You can use the "NewUlps"
|
|
|
|
file as the machine's updated "libm-test-ulps" file. Copy "NewUlps" to
|
|
|
|
"libm-test-ulps" in the appropriate machine sysdep directory. Verify
|
|
|
|
the changes, post your patch, and check it in after review.
|
|
|
|
|
|
|
|
To manually generate a new "libm-test-ulps" file, first remove "ULPs"
|
|
|
|
file in the current directory, then you can execute for example:
|
2013-04-07 05:13:19 +08:00
|
|
|
./testrun.sh math/test-double -u --ignore-max-ulp=yes
|
1999-10-26 04:18:27 +08:00
|
|
|
This generates a file "ULPs" with all double ULPs in it, ignoring any
|
New Makefile target `regen-ulps'.
The wiki "Regeneration" page has this to say about update ULPs.
"The libm-test-ulps files are semiautomatically updated. To
update an ulps baseline, run each of the failing tests (test-float,
test-double, etc.) with -u; this will generate a file called ULPs;
concatenate each of those files with the existing libm-test-ulps
file, after removing any entries for particularly huge numbers of
ulps that you do not want to mark as expected. Then run
gen-libm-test.pl -n -u FILE where FILE is the concatenated file
produced in the previous step. This generates a file called
NewUlps which is the new sorted version of libm-test-ulps."
The same information is listed in math/README.libm-test, and is a
lot of manual work that you often want to run over-and-over again
while working on a particular test.
The `regen-ulps' convenience target does this automatically for
developers.
We strictly assume the source tree is readonly and add a
new --output-dir option to libm-test.inc to allow for writing
out ULPs to $(objpfx).
When run the new target does the following:
* Starts with the baseline ULPs file.
* Runs each of the libm math tests with -u.
* Adds new changes seen with -u to the baseline.
* Sorts and prepares the test output with gen-libm-test.pl.
* Leaves math/NewUlps in your build tree to copy to your source
tree, cleanup, and checkin.
The math test documentation in math/README.libm-test is updated
document the new Makefile target.
---
2013-04-06 Carlos O'Donell <carlos@redhat.com>
* Makefile.in (regen-ulps): New target.
* math/Makefile [ifneq (no,$(PERL)]: Declare regen-ulps with .PHONY.
[ifneq (no,$(PERL)] (run-regen-ulps): New variable.
[ifneq (no,$(PERL)] (regen-ulps): New target.
[ifeq (no,$(PERL)] (regen-ulps): New target.
* math/libm-test.inc (ulps_file_name): Define.
(output_dir): New variable.
(options): Add "output-dir" option.
(parse_opt): Handle 'o' case.
(main): If output_dir is non-NULL use it as a prefix
otherwise use "".
* math/README.libm-test: Update `How can I generate "libm-test-ulps"?'
2013-04-07 04:22:47 +08:00
|
|
|
previously calculated ULPs, and running with the newly built dynamic
|
|
|
|
loader and math library (assumes you didn't install your build). Now
|
|
|
|
generate the ULPs for all other formats, the tests will be appending the
|
|
|
|
data to the "ULPs" file. As final step run "gen-libm-test.pl" with the
|
|
|
|
file as input and ask to generate a pretty printed output in the file
|
|
|
|
"NewUlps":
|
2004-03-25 06:05:34 +08:00
|
|
|
gen-libm-test.pl -u ULPs -n
|
New Makefile target `regen-ulps'.
The wiki "Regeneration" page has this to say about update ULPs.
"The libm-test-ulps files are semiautomatically updated. To
update an ulps baseline, run each of the failing tests (test-float,
test-double, etc.) with -u; this will generate a file called ULPs;
concatenate each of those files with the existing libm-test-ulps
file, after removing any entries for particularly huge numbers of
ulps that you do not want to mark as expected. Then run
gen-libm-test.pl -n -u FILE where FILE is the concatenated file
produced in the previous step. This generates a file called
NewUlps which is the new sorted version of libm-test-ulps."
The same information is listed in math/README.libm-test, and is a
lot of manual work that you often want to run over-and-over again
while working on a particular test.
The `regen-ulps' convenience target does this automatically for
developers.
We strictly assume the source tree is readonly and add a
new --output-dir option to libm-test.inc to allow for writing
out ULPs to $(objpfx).
When run the new target does the following:
* Starts with the baseline ULPs file.
* Runs each of the libm math tests with -u.
* Adds new changes seen with -u to the baseline.
* Sorts and prepares the test output with gen-libm-test.pl.
* Leaves math/NewUlps in your build tree to copy to your source
tree, cleanup, and checkin.
The math test documentation in math/README.libm-test is updated
document the new Makefile target.
---
2013-04-06 Carlos O'Donell <carlos@redhat.com>
* Makefile.in (regen-ulps): New target.
* math/Makefile [ifneq (no,$(PERL)]: Declare regen-ulps with .PHONY.
[ifneq (no,$(PERL)] (run-regen-ulps): New variable.
[ifneq (no,$(PERL)] (regen-ulps): New target.
[ifeq (no,$(PERL)] (regen-ulps): New target.
* math/libm-test.inc (ulps_file_name): Define.
(output_dir): New variable.
(options): Add "output-dir" option.
(parse_opt): Handle 'o' case.
(main): If output_dir is non-NULL use it as a prefix
otherwise use "".
* math/README.libm-test: Update `How can I generate "libm-test-ulps"?'
2013-04-07 04:22:47 +08:00
|
|
|
Copy "NewUlps" to "libm-test-ulps" in the appropriate machine sysdep
|
|
|
|
directory.
|
|
|
|
|
|
|
|
Note that the test drivers have an option "-u" to output an unsorted
|
|
|
|
list of all epsilons that the functions have. The output can be read
|
|
|
|
in directly but it's better to pretty print it first.
|
|
|
|
"gen-libm-test.pl" has an option to generate a pretty-printed and
|
|
|
|
sorted new ULPs file from the output of the test drivers.
|
1999-10-26 04:18:27 +08:00
|
|
|
|
|
|
|
Contents of libm-test-ulps
|
|
|
|
==========================
|
|
|
|
|
2014-03-05 23:02:38 +08:00
|
|
|
Since libm-test-ulps can be generated automatically, just a few notes.
|
|
|
|
The file contains lines for maximal errors of single functions, like:
|
|
|
|
|
1999-10-26 04:18:27 +08:00
|
|
|
Function "yn":
|
2014-03-05 23:02:38 +08:00
|
|
|
idouble: 6
|
1999-10-26 04:18:27 +08:00
|
|
|
|
|
|
|
The keywords are float, ifloat, double, idouble, ldouble and ildouble
|
2013-05-05 00:45:15 +08:00
|
|
|
(the prefix i stands for inline).
|
1999-10-26 04:18:27 +08:00
|
|
|
|
|
|
|
Adding tests to libm-test.inc
|
|
|
|
=============================
|
|
|
|
|
|
|
|
The tests are evaluated by a set of special test macros. The macros
|
|
|
|
start with "TEST_" followed by a specification the input values, an
|
|
|
|
underscore and a specification of the output values. As an example,
|
|
|
|
the test macro for a function with input of type FLOAT (FLOAT is
|
|
|
|
either float, double, long double) and output of type FLOAT is
|
|
|
|
"TEST_f_f". The macro's parameter are the name of the function, the
|
|
|
|
input parameter, output parameter and optionally one exception
|
|
|
|
parameter.
|
|
|
|
|
|
|
|
The accepted parameter types are:
|
|
|
|
- "f" for FLOAT
|
2017-01-21 07:25:13 +08:00
|
|
|
- "j" for long double.
|
1999-10-26 04:18:27 +08:00
|
|
|
- "b" for boolean - just tests if the output parameter evaluates to 0
|
|
|
|
or 1 (only for output).
|
|
|
|
- "c" for complex. This parameter needs two values, first the real,
|
|
|
|
then the imaginary part.
|
|
|
|
- "i" for int.
|
|
|
|
- "l" for long int.
|
|
|
|
- "L" for long long int.
|
2017-01-21 07:25:13 +08:00
|
|
|
- "u" for unsigned int.
|
|
|
|
- "M" for intmax_t.
|
|
|
|
- "U" for uintmax_t.
|
|
|
|
- "p" for an argument (described in the previous character) passed
|
|
|
|
through a pointer rather than directly.
|
1999-10-26 04:18:27 +08:00
|
|
|
- "F" for the address of a FLOAT (only as input parameter)
|
|
|
|
- "I" for the address of an int (only as input parameter)
|
2017-01-21 07:25:13 +08:00
|
|
|
- "1" for an additional output (either output through a pointer passed
|
|
|
|
as an argument, or to a global variable such as signgam).
|
2015-01-29 12:07:01 +08:00
|
|
|
|
|
|
|
How to read the test output
|
|
|
|
===========================
|
|
|
|
|
|
|
|
Running each test on its own at the default level of verbosity will
|
|
|
|
print on stdout a line describing the implementation of math functions
|
|
|
|
exercised by the test (float, double, or long double), along with
|
|
|
|
whether the inline set has been selected, regardless of whether or
|
|
|
|
not any inline functions actually exist. This is then followed by
|
|
|
|
the details of test failures (if any). The output concludes by
|
|
|
|
a summary listing the number of test cases exercised and the number
|
|
|
|
of test failures uncovered.
|
|
|
|
|
|
|
|
For each test failure (and for each test case at higher levels of
|
|
|
|
verbosity), the output contains the name of the function under test
|
|
|
|
and its arguments or conditions that triggered the failure. Note
|
|
|
|
that the name of the function in the output need not correspond
|
|
|
|
exactly to the name of the math function actually invoked. For example,
|
|
|
|
the output will refer to the "acos" function even if the actual function
|
|
|
|
under test is acosf (for the float version) or acosl (for the long
|
|
|
|
double version). Also note that the function arguments may be shown
|
|
|
|
in either the decimal or the hexadecimal floating point format which
|
|
|
|
may or may not correspond to the format used in the auto-libm-test-in
|
|
|
|
file. Besides the name of the function, for each test failure the
|
|
|
|
output contains the actual and expected results and the difference
|
|
|
|
between the two, printed in both the decimal and hexadecimal
|
|
|
|
floating point format, and the ULP and maximum ULP for the test
|
|
|
|
case.
|