diff options
author | OverMighty <its.overmighty@gmail.com> | 2024-06-08 00:26:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-07 18:26:58 -0400 |
commit | 0cdb0b7473595c3b0ac8840f9089d742dc206725 (patch) | |
tree | f19c313777c8c7d4c1ffe9ed0d3e6cb76d6447db /libc/test | |
parent | 06e12b44cd0fb89058f8b5365184a2f5bbba498d (diff) | |
download | llvm-0cdb0b7473595c3b0ac8840f9089d742dc206725.zip llvm-0cdb0b7473595c3b0ac8840f9089d742dc206725.tar.gz llvm-0cdb0b7473595c3b0ac8840f9089d742dc206725.tar.bz2 |
[libc][math][c23] Add fmodf16 C23 math function (#94629)
Part of #93566.
Diffstat (limited to 'libc/test')
-rw-r--r-- | libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h | 52 | ||||
-rw-r--r-- | libc/test/src/math/performance_testing/CMakeLists.txt | 13 | ||||
-rw-r--r-- | libc/test/src/math/performance_testing/fmodf16_perf.cpp | 27 | ||||
-rw-r--r-- | libc/test/src/math/smoke/CMakeLists.txt | 33 | ||||
-rw-r--r-- | libc/test/src/math/smoke/FModTest.h | 37 | ||||
-rw-r--r-- | libc/test/src/math/smoke/fmodf16_test.cpp | 13 |
6 files changed, 132 insertions, 43 deletions
diff --git a/libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h b/libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h index 504d1be..3027932 100644 --- a/libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h +++ b/libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h @@ -9,6 +9,7 @@ #include "src/__support/FPUtil/FPBits.h" #include "test/src/math/performance_testing/Timer.h" +#include <cstddef> #include <fstream> namespace LIBC_NAMESPACE { @@ -25,7 +26,10 @@ public: static void run_perf_in_range(Func myFunc, Func otherFunc, StorageType startingBit, StorageType endingBit, - StorageType N, std::ofstream &log) { + size_t N, size_t rounds, std::ofstream &log) { + if (endingBit - startingBit < N) + N = endingBit - startingBit; + auto runner = [=](Func func) { volatile T result; if (endingBit < startingBit) { @@ -33,13 +37,15 @@ public: } StorageType step = (endingBit - startingBit) / N; - for (StorageType bitsX = startingBit, bitsY = endingBit;; - bitsX += step, bitsY -= step) { - T x = FPBits(bitsX).get_val(); - T y = FPBits(bitsY).get_val(); - result = func(x, y); - if (endingBit - bitsX < step) { - break; + for (size_t i = 0; i < rounds; i++) { + for (StorageType bitsX = startingBit, bitsY = endingBit;; + bitsX += step, bitsY -= step) { + T x = FPBits(bitsX).get_val(); + T y = FPBits(bitsY).get_val(); + result = func(x, y); + if (endingBit - bitsX < step) { + break; + } } } }; @@ -49,7 +55,7 @@ public: runner(myFunc); timer.stop(); - double my_average = static_cast<double>(timer.nanoseconds()) / N; + double my_average = static_cast<double>(timer.nanoseconds()) / N / rounds; log << "-- My function --\n"; log << " Total time : " << timer.nanoseconds() << " ns \n"; log << " Average runtime : " << my_average << " ns/op \n"; @@ -60,7 +66,8 @@ public: runner(otherFunc); timer.stop(); - double other_average = static_cast<double>(timer.nanoseconds()) / N; + double other_average = + static_cast<double>(timer.nanoseconds()) / N / rounds; log << "-- Other function --\n"; log << " Total time : " << timer.nanoseconds() << " ns \n"; log << " Average runtime : " << other_average << " ns/op \n"; @@ -71,22 +78,24 @@ public: log << " Mine / Other's : " << my_average / other_average << " \n"; } - static void run_perf(Func myFunc, Func otherFunc, const char *logFile) { + static void run_perf(Func myFunc, Func otherFunc, int rounds, + const char *logFile) { std::ofstream log(logFile); log << " Performance tests with inputs in denormal range:\n"; run_perf_in_range(myFunc, otherFunc, /* startingBit= */ StorageType(0), /* endingBit= */ FPBits::max_subnormal().uintval(), - 10'000'001, log); + 1'000'001, rounds, log); log << "\n Performance tests with inputs in normal range:\n"; run_perf_in_range(myFunc, otherFunc, /* startingBit= */ FPBits::min_normal().uintval(), /* endingBit= */ FPBits::max_normal().uintval(), - 10'000'001, log); + 1'000'001, rounds, log); log << "\n Performance tests with inputs in normal range with exponents " "close to each other:\n"; - run_perf_in_range( - myFunc, otherFunc, /* startingBit= */ FPBits(T(0x1.0p-10)).uintval(), - /* endingBit= */ FPBits(T(0x1.0p+10)).uintval(), 1'001'001, log); + run_perf_in_range(myFunc, otherFunc, + /* startingBit= */ FPBits(T(0x1.0p-10)).uintval(), + /* endingBit= */ FPBits(T(0x1.0p+10)).uintval(), + 1'000'001, rounds, log); } static void run_diff(Func myFunc, Func otherFunc, const char *logFile) { @@ -117,6 +126,15 @@ public: #define BINARY_OP_SINGLE_OUTPUT_PERF(T, myFunc, otherFunc, filename) \ int main() { \ LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<T>::run_perf( \ - &myFunc, &otherFunc, filename); \ + &myFunc, &otherFunc, 1, filename); \ return 0; \ } + +#define BINARY_OP_SINGLE_OUTPUT_PERF_EX(T, myFunc, otherFunc, rounds, \ + filename) \ + { \ + LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<T>::run_perf( \ + &myFunc, &otherFunc, rounds, filename); \ + LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<T>::run_perf( \ + &myFunc, &otherFunc, rounds, filename); \ + } diff --git a/libc/test/src/math/performance_testing/CMakeLists.txt b/libc/test/src/math/performance_testing/CMakeLists.txt index d1fb24e..4ea78f9 100644 --- a/libc/test/src/math/performance_testing/CMakeLists.txt +++ b/libc/test/src/math/performance_testing/CMakeLists.txt @@ -88,6 +88,8 @@ add_header_library( binary_op_single_output_diff HDRS BinaryOpSingleOutputPerf.h + DEPENDS + libc.src.__support.FPUtil.fp_bits ) add_perf_binary( @@ -344,6 +346,17 @@ add_perf_binary( ) add_perf_binary( + fmodf16_perf + SRCS + fmodf16_perf.cpp + DEPENDS + .binary_op_single_output_diff + libc.src.math.fmodf16 + libc.src.__support.FPUtil.generic.fmod + libc.src.__support.macros.properties.types +) + +add_perf_binary( fmodf128_perf SRCS fmodf128_perf.cpp diff --git a/libc/test/src/math/performance_testing/fmodf16_perf.cpp b/libc/test/src/math/performance_testing/fmodf16_perf.cpp new file mode 100644 index 0000000..ff01fa6 --- /dev/null +++ b/libc/test/src/math/performance_testing/fmodf16_perf.cpp @@ -0,0 +1,27 @@ +//===-- Performance test for fmodf16 --------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "BinaryOpSingleOutputPerf.h" + +#include "src/__support/FPUtil/generic/FMod.h" +#include "src/__support/macros/properties/types.h" + +#include <stdint.h> + +#define FMOD_FUNC(U) (LIBC_NAMESPACE::fputil::generic::FMod<float16, U>::eval) + +int main() { + BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, FMOD_FUNC(uint16_t), + FMOD_FUNC(uint32_t), 5000, + "fmodf16_u16_vs_u32_perf.log") + + BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, FMOD_FUNC(uint16_t), + FMOD_FUNC(uint64_t), 5000, + "fmodf16_u16_vs_u64_perf.log") + return 0; +} diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 110fa1d..07e8b5d 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -3111,10 +3111,10 @@ add_fp_unittest( HDRS FModTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno libc.src.math.fmodf - libc.src.__support.FPUtil.basic_operations - libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.FPUtil.fenv_impl # FIXME: Currently fails on the GPU build. UNIT_TEST_ONLY ) @@ -3128,10 +3128,10 @@ add_fp_unittest( HDRS FModTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno libc.src.math.fmod - libc.src.__support.FPUtil.basic_operations - libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.FPUtil.fenv_impl # FIXME: Currently fails on the GPU build. UNIT_TEST_ONLY ) @@ -3145,10 +3145,27 @@ add_fp_unittest( HDRS FModTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno libc.src.math.fmodl - libc.src.__support.FPUtil.basic_operations - libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.FPUtil.fenv_impl + # FIXME: Currently fails on the GPU build. + UNIT_TEST_ONLY +) + +add_fp_unittest( + fmodf16_test + SUITE + libc-math-smoke-tests + SRCS + fmodf16_test.cpp + HDRS + FModTest.h + DEPENDS + libc.hdr.fenv_macros + libc.src.errno.errno + libc.src.math.fmodf16 + libc.src.__support.FPUtil.fenv_impl # FIXME: Currently fails on the GPU build. UNIT_TEST_ONLY ) @@ -3162,10 +3179,10 @@ add_fp_unittest( HDRS FModTest.h DEPENDS + libc.hdr.fenv_macros libc.src.errno.errno libc.src.math.fmodf128 - libc.src.__support.FPUtil.basic_operations - libc.src.__support.FPUtil.nearest_integer_operations + libc.src.__support.FPUtil.fenv_impl # FIXME: Currently fails on the GPU build. UNIT_TEST_ONLY ) diff --git a/libc/test/src/math/smoke/FModTest.h b/libc/test/src/math/smoke/FModTest.h index f1015d6..405e310 100644 --- a/libc/test/src/math/smoke/FModTest.h +++ b/libc/test/src/math/smoke/FModTest.h @@ -9,13 +9,13 @@ #ifndef LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H #define LLVM_LIBC_TEST_SRC_MATH_FMODTEST_H -#include "src/__support/FPUtil/BasicOperations.h" -#include "src/__support/FPUtil/NearestIntegerOperations.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/errno/libc_errno.h" #include "test/UnitTest/FEnvSafeTest.h" #include "test/UnitTest/FPMatcher.h" #include "test/UnitTest/Test.h" -#include "hdr/math_macros.h" +#include "hdr/fenv_macros.h" #define TEST_SPECIAL(x, y, expected, dom_err, expected_exception) \ EXPECT_FP_EQ(expected, f(x, y)); \ @@ -210,7 +210,8 @@ public: } void testRegularExtreme(FModFunc f) { - + if constexpr (sizeof(T) < sizeof(float)) + return; TEST_REGULAR(0x1p127L, 0x3p-149L, 0x1p-149L); TEST_REGULAR(0x1p127L, -0x3p-149L, 0x1p-149L); TEST_REGULAR(0x1p127L, 0x3p-148L, 0x1p-147L); @@ -224,20 +225,20 @@ public: TEST_REGULAR(-0x1p127L, 0x3p-126L, -0x1p-125L); TEST_REGULAR(-0x1p127L, -0x3p-126L, -0x1p-125L); - if constexpr (sizeof(T) >= sizeof(double)) { - TEST_REGULAR(0x1p1023L, 0x3p-1074L, 0x1p-1073L); - TEST_REGULAR(0x1p1023L, -0x3p-1074L, 0x1p-1073L); - TEST_REGULAR(0x1p1023L, 0x3p-1073L, 0x1p-1073L); - TEST_REGULAR(0x1p1023L, -0x3p-1073L, 0x1p-1073L); - TEST_REGULAR(0x1p1023L, 0x3p-1022L, 0x1p-1021L); - TEST_REGULAR(0x1p1023L, -0x3p-1022L, 0x1p-1021L); - TEST_REGULAR(-0x1p1023L, 0x3p-1074L, -0x1p-1073L); - TEST_REGULAR(-0x1p1023L, -0x3p-1074L, -0x1p-1073L); - TEST_REGULAR(-0x1p1023L, 0x3p-1073L, -0x1p-1073L); - TEST_REGULAR(-0x1p1023L, -0x3p-1073L, -0x1p-1073L); - TEST_REGULAR(-0x1p1023L, 0x3p-1022L, -0x1p-1021L); - TEST_REGULAR(-0x1p1023L, -0x3p-1022L, -0x1p-1021L); - } + if constexpr (sizeof(T) < sizeof(double)) + return; + TEST_REGULAR(0x1p1023L, 0x3p-1074L, 0x1p-1073L); + TEST_REGULAR(0x1p1023L, -0x3p-1074L, 0x1p-1073L); + TEST_REGULAR(0x1p1023L, 0x3p-1073L, 0x1p-1073L); + TEST_REGULAR(0x1p1023L, -0x3p-1073L, 0x1p-1073L); + TEST_REGULAR(0x1p1023L, 0x3p-1022L, 0x1p-1021L); + TEST_REGULAR(0x1p1023L, -0x3p-1022L, 0x1p-1021L); + TEST_REGULAR(-0x1p1023L, 0x3p-1074L, -0x1p-1073L); + TEST_REGULAR(-0x1p1023L, -0x3p-1074L, -0x1p-1073L); + TEST_REGULAR(-0x1p1023L, 0x3p-1073L, -0x1p-1073L); + TEST_REGULAR(-0x1p1023L, -0x3p-1073L, -0x1p-1073L); + TEST_REGULAR(-0x1p1023L, 0x3p-1022L, -0x1p-1021L); + TEST_REGULAR(-0x1p1023L, -0x3p-1022L, -0x1p-1021L); } }; diff --git a/libc/test/src/math/smoke/fmodf16_test.cpp b/libc/test/src/math/smoke/fmodf16_test.cpp new file mode 100644 index 0000000..9a48c5a --- /dev/null +++ b/libc/test/src/math/smoke/fmodf16_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for fmodf16 ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "FModTest.h" + +#include "src/math/fmodf16.h" + +LIST_FMOD_TESTS(float16, LIBC_NAMESPACE::fmodf16) |