lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | README for libm-test math test suite |
| 2 | ==================================== |
| 3 | |
| 4 | The libm-test math test suite tests a number of function points of |
| 5 | math functions in the GNU C library. The following sections contain a |
| 6 | brief overview. Please note that the test drivers and the Perl script |
| 7 | "gen-libm-test.pl" have some options. A full list of options is |
| 8 | available with --help (for the test drivers) and -h for |
| 9 | "gen-libm-test.pl". |
| 10 | |
| 11 | |
| 12 | What is tested? |
| 13 | =============== |
| 14 | The tests just evaluate the functions at specified points and compare |
| 15 | the results with precomputed values and the requirements of the ISO |
| 16 | C99 standard. |
| 17 | |
| 18 | Besides testing the special values mandated by IEEE 754 (infinities, |
| 19 | NaNs and minus zero), some more or less random values are tested. |
| 20 | |
| 21 | Files that are part of libm-test |
| 22 | ================================ |
| 23 | |
| 24 | The main file is "libm-test.inc". It is independent of the target |
| 25 | platform and the specific real floating type and format and contains |
| 26 | placeholder test "templates" for math functions defined in libm. |
| 27 | The file, along with a generated file named "auto-libm-test-out", |
| 28 | is preprocessed by the Perl script "gen-libm-test.pl" to expand |
| 29 | the templates and produce a set of test cases for each math function |
| 30 | that are specific to the target platform but still independent of |
| 31 | the real floating type. The results of the processing are |
| 32 | "libm-test.c" and a file "libm-test-ulps.h" with platform specific |
| 33 | deltas by which the actual math function results may deviate from |
| 34 | the expected results and still be considered correct. |
| 35 | |
| 36 | The test drivers "test-double.c", "test-float.c", and "test-ldouble.c" |
| 37 | test the normal double, float and long double implementation of libm. |
| 38 | The test drivers with an 'i' in their name ("test-idouble.c", |
| 39 | "test-ifloat.c", and "test-ildoubl.c") test the corresponding inline |
| 40 | functions (where available - otherwise they also test the real |
| 41 | functions in libm). Each driver selects the desired real floating |
| 42 | type to exercise the math functions to test with (float, double, or |
| 43 | long double) by defining a small set of macros just before including |
| 44 | the generic "libm-test.c" file. Each driver also either defines or |
| 45 | undefines the __NO_MATH_INLINES macro just before including |
| 46 | "libm-test.c" to select either the real or inline functions, |
| 47 | respectively. Each driver is compiled into a single executable test |
| 48 | program with the corresponding name. |
| 49 | |
| 50 | As mentioned above, the "gen-libm-test.pl" script looks for a file |
| 51 | named "libm-test-ulps" in the platform specific sysdep directory (or |
| 52 | its fpu or nofpu subdirectory) and for each variant (real floating |
| 53 | type and rounding mode) of every tested function reads from it the |
| 54 | maximum difference expressed as Units of Least Precision (ULP) the |
| 55 | actual result of the function may deviate from the expected result |
| 56 | before it's considered incorrect. |
| 57 | |
| 58 | The "auto-libm-test-out" file contains sets of test cases to exercise, |
| 59 | the conditions under which to exercise each, and the expected results. |
| 60 | The file is generated by the "gen-auto-libm-tests" program from the |
| 61 | "auto-libm-test-in" file. See the comments in gen-auto-libm-tests.c |
| 62 | for details about the content and format of the -in and -out files. |
| 63 | |
| 64 | How can I generate "libm-test-ulps"? |
| 65 | ==================================== |
| 66 | |
| 67 | To automatically generate a new "libm-test-ulps" run "make regen-ulps". |
| 68 | This generates the file "math/NewUlps" in the build directory. The file |
| 69 | contains the sorted results of all the tests. You can use the "NewUlps" |
| 70 | file as the machine's updated "libm-test-ulps" file. Copy "NewUlps" to |
| 71 | "libm-test-ulps" in the appropriate machine sysdep directory. Verify |
| 72 | the changes, post your patch, and check it in after review. |
| 73 | |
| 74 | To manually generate a new "libm-test-ulps" file, first remove "ULPs" |
| 75 | file in the current directory, then you can execute for example: |
| 76 | ./testrun.sh math/test-double -u --ignore-max-ulp=yes |
| 77 | This generates a file "ULPs" with all double ULPs in it, ignoring any |
| 78 | previously calculated ULPs, and running with the newly built dynamic |
| 79 | loader and math library (assumes you didn't install your build). Now |
| 80 | generate the ULPs for all other formats, the tests will be appending the |
| 81 | data to the "ULPs" file. As final step run "gen-libm-test.pl" with the |
| 82 | file as input and ask to generate a pretty printed output in the file |
| 83 | "NewUlps": |
| 84 | gen-libm-test.pl -u ULPs -n |
| 85 | Copy "NewUlps" to "libm-test-ulps" in the appropriate machine sysdep |
| 86 | directory. |
| 87 | |
| 88 | Note that the test drivers have an option "-u" to output an unsorted |
| 89 | list of all epsilons that the functions have. The output can be read |
| 90 | in directly but it's better to pretty print it first. |
| 91 | "gen-libm-test.pl" has an option to generate a pretty-printed and |
| 92 | sorted new ULPs file from the output of the test drivers. |
| 93 | |
| 94 | Contents of libm-test-ulps |
| 95 | ========================== |
| 96 | |
| 97 | Since libm-test-ulps can be generated automatically, just a few notes. |
| 98 | The file contains lines for maximal errors of single functions, like: |
| 99 | |
| 100 | Function "yn": |
| 101 | idouble: 6 |
| 102 | |
| 103 | The keywords are float, ifloat, double, idouble, ldouble and ildouble |
| 104 | (the prefix i stands for inline). |
| 105 | |
| 106 | Adding tests to libm-test.inc |
| 107 | ============================= |
| 108 | |
| 109 | The tests are evaluated by a set of special test macros. The macros |
| 110 | start with "TEST_" followed by a specification the input values, an |
| 111 | underscore and a specification of the output values. As an example, |
| 112 | the test macro for a function with input of type FLOAT (FLOAT is |
| 113 | either float, double, long double) and output of type FLOAT is |
| 114 | "TEST_f_f". The macro's parameter are the name of the function, the |
| 115 | input parameter, output parameter and optionally one exception |
| 116 | parameter. |
| 117 | |
| 118 | The accepted parameter types are: |
| 119 | - "f" for FLOAT |
| 120 | - "b" for boolean - just tests if the output parameter evaluates to 0 |
| 121 | or 1 (only for output). |
| 122 | - "c" for complex. This parameter needs two values, first the real, |
| 123 | then the imaginary part. |
| 124 | - "i" for int. |
| 125 | - "l" for long int. |
| 126 | - "L" for long long int. |
| 127 | - "F" for the address of a FLOAT (only as input parameter) |
| 128 | - "I" for the address of an int (only as input parameter) |
| 129 | |
| 130 | How to read the test output |
| 131 | =========================== |
| 132 | |
| 133 | Running each test on its own at the default level of verbosity will |
| 134 | print on stdout a line describing the implementation of math functions |
| 135 | exercised by the test (float, double, or long double), along with |
| 136 | whether the inline set has been selected, regardless of whether or |
| 137 | not any inline functions actually exist. This is then followed by |
| 138 | the details of test failures (if any). The output concludes by |
| 139 | a summary listing the number of test cases exercised and the number |
| 140 | of test failures uncovered. |
| 141 | |
| 142 | For each test failure (and for each test case at higher levels of |
| 143 | verbosity), the output contains the name of the function under test |
| 144 | and its arguments or conditions that triggered the failure. Note |
| 145 | that the name of the function in the output need not correspond |
| 146 | exactly to the name of the math function actually invoked. For example, |
| 147 | the output will refer to the "acos" function even if the actual function |
| 148 | under test is acosf (for the float version) or acosl (for the long |
| 149 | double version). Also note that the function arguments may be shown |
| 150 | in either the decimal or the hexadecimal floating point format which |
| 151 | may or may not correspond to the format used in the auto-libm-test-in |
| 152 | file. Besides the name of the function, for each test failure the |
| 153 | output contains the actual and expected results and the difference |
| 154 | between the two, printed in both the decimal and hexadecimal |
| 155 | floating point format, and the ULP and maximum ULP for the test |
| 156 | case. |