[libc-commits] [libc] [libc] Initial support for exhaustive math tests on the GPU (PR #73720)

Joseph Huber via libc-commits libc-commits at lists.llvm.org
Tue Feb 6 05:30:39 PST 2024


================
@@ -0,0 +1,137 @@
+//===-- Exhaustive test template for math functions -------------*- C++ -*-===//
+//
+// 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 "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+
+#include <atomic>
+#include <functional>
+#include <iostream>
+#include <mutex>
+#include <sstream>
+#include <thread>
+#include <vector>
+
+// To test exhaustively for inputs in the range [start, stop) in parallel:
+// 1. Define a Checker class with:
+//    - FloatType: define floating point type to be used.
+//    - FPBits: fputil::FPBits<FloatType>.
+//    - UIntType: define bit type for the corresponding floating point type.
+//    - uint64_t check(start, stop, rounding_mode): a method to test in given
+//          range for a given rounding mode, which returns the number of
+//          failures.
+// 2. Use LlvmLibcExhaustiveMathTest<Checker> class
+// 3. Call: test_full_range(start, stop, nthreads, rounding)
+//       or test_full_range_all_roundings(start, stop).
+// * For single input single output math function, use the convenient template:
+//   LlvmLibcUnaryOpExhaustiveMathTest<FloatType, Op, Func>.
+namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
+
+template <typename T> using UnaryOp = T(T);
+
+template <typename T, mpfr::Operation Op, UnaryOp<T> Func>
+struct UnaryOpChecker : public virtual LIBC_NAMESPACE::testing::Test {
+  using FloatType = T;
+  using FPBits = LIBC_NAMESPACE::fputil::FPBits<FloatType>;
+  using UIntType = typename FPBits::UIntType;
+
+  static constexpr UnaryOp<FloatType> *FUNC = Func;
+  static constexpr mpfr::Operation OP = Op;
+
+  // Check in a range, return the number of failures.
+  bool check(FloatType in, FloatType out, mpfr::RoundingMode rounding) {
+    mpfr::ForceRoundingMode r(rounding);
+    if (!r.success)
+      return true;
+
+    bool correct = TEST_MPFR_MATCH_ROUNDING(Op, in, out, 0.5, rounding);
+    return !correct;
+  }
+};
+
+// Checker class needs inherit from LIBC_NAMESPACE::testing::Test and provide
+// UIntType and check method.
+template <typename Checker>
+struct LlvmLibcExhaustiveMathTest
+    : public virtual LIBC_NAMESPACE::testing::Test,
+      public Checker {
+  using FloatType = typename Checker::FloatType;
+  using FPBits = typename Checker::FPBits;
+  using UIntType = typename Checker::UIntType;
+
+  static constexpr UIntType BLOCK_SIZE = (1 << 25);
+
+  // Break [start, stop) into chunks and compare results on the GPU vs the CPU.
+  void test_full_range(UIntType start, UIntType stop,
+                       mpfr::RoundingMode rounding) {
+
+    // TODO: We can run the GPU asynchronously to compute the next block.
+    // However, the main bottleneck is MPFR on the CPU.
+    uint64_t failed = 0;
+    for (UIntType chunk = start; chunk <= stop; chunk += BLOCK_SIZE) {
+      uint64_t percent = (static_cast<double>(chunk - start) /
+                          static_cast<double>(stop - start)) *
+                         100.0;
+      std::cout << percent << "% is in process     \r" << std::flush;
+      UIntType end = std::min(stop, chunk + BLOCK_SIZE);
+
+      std::vector<FloatType> data(BLOCK_SIZE, FloatType(0));
+
+      FloatType *ptr = data.data();
+      // Fill the buffer with the computed results from the GPU.
+#pragma omp target teams distribute parallel for map(from : ptr[0 : BLOCK_SIZE])
----------------
jhuber6 wrote:

I think that's just how `clang-format` treats pragmas.

https://github.com/llvm/llvm-project/pull/73720


More information about the libc-commits mailing list