diff --git a/libc/docs/index.rst b/libc/docs/index.rst --- a/libc/docs/index.rst +++ b/libc/docs/index.rst @@ -66,3 +66,4 @@ strings runtimes_build stdio + math diff --git a/libc/docs/math.rst b/libc/docs/math.rst new file mode 100644 --- /dev/null +++ b/libc/docs/math.rst @@ -0,0 +1,230 @@ +=========================== +Math Functions in LLVM-libc +=========================== + +.. role:: raw-html(raw) + :format: html + +.. |check| replace:: :raw-html:`✅` + +.. contents:: Table of Contents + :depth: 4 + :local: + +Summary +======= + +* This document tracks the status of the implementation of math functions in + LLVM libc. + +Implementation Requirements / Goals +=================================== + +* The highest priority is to be as accurate as possible, according to the C and + IEEE 754 standards. By default, we will aim to be correctly rounded for all + rounding modes, based on the floating point environment: + + - *FE_TONEAREST* : round-to-the-nearest, tie-to-even. + - *FE_UPWARD* : round up (toward :math:`+\infty`). + - *FE_DOWNWARD* : round down (toward :math:`-\infty`). + - *FE_TOWARDZERO* : round toward zero. + +* Our next requirement is that the outputs are consistent across all platforms. + Notice that the consistency requirement will be satisfied automatically if the + implementation is correctly rounded. + +* Our last requirement for the implementations is to have good and predicable + performance: + + - The average performance should be comparable to other ``libc`` + implementations. + - The worst case performance should be within 10X-20X of the average. + - Platform-specific implementations or instructions could be added whenever it + makes sense and provides significant performance boost. + +* For other use cases that have strict requirements on the code size, memory + footprint, or latency, such as embedded systems, we will aim to be as accurate + as possible within the memory or latency budgets, and consistent across all + platforms. + + +Source Locations +================ + +- The main source is located at: `libc/src/math `_. +- The tests are located at: `libc/test/src/math `_. +- The floating point utilities are located at: `libc/src/__support/FPUtil `_. + +Add a new math function to LLVM libc +==================================== + +* To add a new math function, follow the steps at: `libc/src/math/docs/add_math_function.md `_. + +Implementation Status +===================== + +Basic Operations +---------------- + +============== ================ =============== ====================== + (float) (double) (long double) +============== ================ =============== ====================== +ceil |check| |check| |check| +copysign |check| |check| |check| +fabs |check| |check| |check| +fdim |check| |check| |check| +floor |check| |check| |check| +fmax |check| |check| |check| +fmin |check| |check| |check| +fmod +fpclassify +frexp |check| |check| |check| +ilogb |check| |check| |check| +isfinite +isgreater +isgreaterequal +isinf +isless +islessequal +islessgreater +isnan +isnormal +isubordered +ldexp |check| |check| |check| +llrint |check| |check| |check| +llround |check| |check| |check| +logb |check| |check| |check| +lrint |check| |check| |check| +lround |check| |check| |check| +modf |check| |check| |check| +nan +nearbyint |check| |check| |check| +nextafter |check| |check| |check| +nexttoward +remainder |check| |check| |check| +remquo |check| |check| |check| +rint |check| |check| |check| +round |check| |check| |check| +scalbn +signbit +trunc |check| |check| |check| +============== ================ =============== ====================== + +Higher Math Functions +--------------------- + +============== ================ =============== ====================== + (float) (double) (long double) +============== ================ =============== ====================== +acos +acosh +asin +asinh +atan +atan2 +atanh +cbrt +cos |check| |check| +cosh +erf +erfc +exp |check| +exp2 |check| +expm1 |check| +fma |check| |check| +hypot |check| |check| +lgamma +log |check| +log10 |check| +log1p |check| +log2 |check| +pow +sin |check| |check| +sincos |check| |check| +sinh +sqrt |check| |check| |check| +tan +tanh +tgamma +============== ================ =============== ====================== + +Accuracy of Higher Math Functions +================================= + +============== ================ =============== ====================== + (float) (double) (long double) +============== ================ =============== ====================== +cos 0.776 ULPs large +exp |check| +exp2 |check| +expm1 |check| +fma |check| |check| +hypot |check| |check| +log |check| +log10 |check| +log1p |check| +log2 |check| +sin 0.561 ULPs large +sincos 0.776 ULPs large +sqrt |check| |check| |check| +============== ================ =============== ====================== + +Legends: + +* |check|: correctly rounded for all 4 rounding modes. +* CR: correctly rounded for the default rounding mode (round-to-the-nearest, + tie-to-even). +* x ULPs: largest errors recorded. + +.. + TODO(lntue): Add a new page to discuss about the algorithms used in the + implementations and include the link here. + + +Performance +=========== + +* Simple performance testings are located at: `libc/test/src/math/differential_testing `_. + +* We also use the *perf* tool from the `CORE-MATH `_ + project: `link `_. + The performance results from the CORE-MATH's perf tool is reported in the + table below. + ++--------------+-------------------------------+-------------------------------+-------------------------------------+---------------------------------------------------------------------+ +| | Reciprocal throughput (ns) | Latency (ns) | Testing ranges | Testing configuration | +| +-----------+-------------------+-----------+-------------------+ +------------+-------------------------+--------------+---------------+ +| | LLVM libc | Reference (glibc) | LLVM libc | Reference (glibc) | | CPU | OS | Compiler | Special flags | ++==============+===========+===================+===========+===================+=====================================+============+=========================+==============+===============+ +| cosf | 37 | 32 | 73 | 72 | :math:`[0, 2\pi]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| expf | 14 | 9 | 58 | 42 | :math:`[-10, 10]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| exp2f | 25 | 8 | 81 | 37 | :math:`[-10, 10]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| exp2f | 25 | 8 | 81 | 37 | :math:`[-10, 10]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| expm1f | 14 | 53 | 59 | 146 | :math:`[-10, 10]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| hypotf | 25 | 15 | 64 | 49 | :math:`[-10, 10] \times [-10, 10]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| logf | 12 | 10 | 56 | 46 | :math:`[e^{-1}, e]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| log10f | 13 | 25 | 57 | 72 | :math:`[e^{-1}, e]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| log1pf | 16 | 33 | 61 | 97 | :math:`[e^{-0.5} - 1, e^{0.5} - 1]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| log2f | 13 | 10 | 57 | 46 | :math:`[e^{-1}, e]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | FMA | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ +| sinf | 38 | 32 | 73 | 72 | :math:`[-\pi, \pi]` | Ryzen 1700 | Ubuntu 20.04 LTS x86_64 | Clang 12.0.0 | | ++--------------+-----------+-------------------+-----------+-------------------+-------------------------------------+------------+-------------------------+--------------+---------------+ + +References +========== + +* `CRLIBM `_. +* `RLIBM `_. +* `Sollya `_. +* `The CORE-MATH Project `_. +* `The GNU C Library (glibc) `_. +* `The GNU MPFR Library `_.