//
//===----------------------------------------------------------------------===//
+#include <atomic>
#include <fenv.h>
#include <functional>
#include <iostream>
+#include <mutex>
#include <sstream>
-#include <string>
#include <thread>
#include <vector>
-#include "exhaustive_test.h"
#include "src/__support/FPUtil/FPBits.h"
-#include "utils/UnitTest/Test.h"
-template <typename T>
-void LlvmLibcExhaustiveTest<T>::test_full_range(T start, T stop, int nthreads,
- mpfr::RoundingMode rounding) {
- std::vector<std::thread> thread_list(nthreads);
- T increment = (stop - start - 1) / nthreads + 1;
- T begin = start;
- T end = start + increment - 1;
- for (int i = 0; i < nthreads; ++i) {
- thread_list.emplace_back([this, begin, end, rounding]() {
- std::stringstream msg;
- msg << "-- Testing from " << begin << " to " << end << " [0x" << std::hex
- << begin << ", 0x" << end << "), [" << std::hexfloat
- << float(__llvm_libc::fputil::FPBits<float>(
- static_cast<uint32_t>(begin)))
- << ", "
- << float(
- __llvm_libc::fputil::FPBits<float>(static_cast<uint32_t>(end)))
- << ") ..." << std::endl;
- std::cout << msg.str();
- msg.str("");
+#include "exhaustive_test.h"
+
+template <typename T, typename FloatType>
+void LlvmLibcExhaustiveTest<T, FloatType>::test_full_range(
+ T start, T stop, mpfr::RoundingMode rounding) {
+ int n_threads = std::thread::hardware_concurrency();
+ std::vector<std::thread> thread_list;
+ std::mutex mx_cur_val;
+ int current_percent = -1;
+ T current_value = start;
+ std::atomic<uint64_t> failed(0);
+ for (int i = 0; i < n_threads; ++i) {
+ thread_list.emplace_back([&, this]() {
+ while (true) {
+ T range_begin, range_end;
+ int new_percent = -1;
+ {
+ std::lock_guard<std::mutex> lock(mx_cur_val);
+ if (current_value == stop)
+ return;
- bool result = check(begin, end, rounding);
+ range_begin = current_value;
+ if (stop >= increment && stop - increment >= current_value) {
+ range_end = current_value + increment;
+ } else
+ range_end = stop;
+ current_value = range_end;
+ int pc = 100.0 * double(range_end - start) / double(stop - start);
+ if (current_percent != pc) {
+ new_percent = pc;
+ current_percent = pc;
+ }
+ }
+ if (new_percent >= 0) {
+ std::stringstream msg;
+ msg << new_percent << "% is in process \r";
+ std::cout << msg.str() << std::flush;
+ ;
+ }
- msg << "** Finished testing from " << std::dec << begin << " to " << end
- << " [0x" << std::hex << begin << ", 0x" << end << "), ["
- << std::hexfloat
- << float(__llvm_libc::fputil::FPBits<float>(
- static_cast<uint32_t>(begin)))
- << ", "
- << float(
- __llvm_libc::fputil::FPBits<float>(static_cast<uint32_t>(end)))
- << ") : " << (result ? "PASSED" : "FAILED") << std::endl;
- std::cout << msg.str();
+ bool check_passed = check(range_begin, range_end, rounding);
+ if (!check_passed) {
+ std::stringstream msg;
+ msg << "Test failed in range: " << std::dec << range_begin << " to "
+ << range_end << " [0x" << std::hex << range_begin << ", 0x"
+ << range_end << "), [" << std::hexfloat
+ << static_cast<FloatType>(__llvm_libc::fputil::FPBits<FloatType>(
+ static_cast<T>(range_begin)))
+ << ", "
+ << static_cast<FloatType>(
+ __llvm_libc::fputil::FPBits<FloatType>(range_end))
+ << ") " << std::endl;
+ std::cerr << msg.str() << std::flush;
+
+ failed.fetch_add(1);
+ }
+ }
});
- begin += increment;
- end += increment;
- if (end > stop)
- end = stop;
}
+
for (auto &thread : thread_list) {
if (thread.joinable()) {
thread.join();
}
}
+ std::cout << std::endl;
+ std::cout << "Test " << ((failed > 0) ? "FAILED" : "PASSED") << std::endl;
}
template void
-LlvmLibcExhaustiveTest<uint32_t>::test_full_range(uint32_t, uint32_t, int,
- mpfr::RoundingMode);
-template void
-LlvmLibcExhaustiveTest<uint64_t>::test_full_range(uint64_t, uint64_t, int,
- mpfr::RoundingMode);
+ LlvmLibcExhaustiveTest<uint32_t>::test_full_range(uint32_t, uint32_t,
+ mpfr::RoundingMode);
+template void LlvmLibcExhaustiveTest<uint64_t, double>::test_full_range(
+ uint64_t, uint64_t, mpfr::RoundingMode);
//
//===----------------------------------------------------------------------===//
+#include "src/__support/CPP/TypeTraits.h"
+#include "src/__support/FPUtil/FPBits.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
#include "utils/UnitTest/Test.h"
// 4. Call: test_full_range(start, stop, nthreads, rounding)
namespace mpfr = __llvm_libc::testing::mpfr;
-template <typename T>
+template <typename T, typename FloatType = float>
struct LlvmLibcExhaustiveTest : public __llvm_libc::testing::Test {
+ static constexpr T increment = (1 << 20);
+ static_assert(
+ __llvm_libc::cpp::IsSameV<
+ T, typename __llvm_libc::fputil::FPBits<FloatType>::UIntType>,
+ "Types are not consistent");
// Break [start, stop) into `nthreads` subintervals and apply *check to each
// subinterval in parallel.
- void test_full_range(T start, T stop, int nthreads,
- mpfr::RoundingMode rounding);
+ void test_full_range(T start, T stop, mpfr::RoundingMode rounding);
virtual bool check(T start, T stop, mpfr::RoundingMode rounding) = 0;
};
}
};
-static constexpr int NUM_THREADS = 16;
-
// Range: [0, 128];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x4300'0000U;
TEST_F(LlvmLibcExp2fExhaustiveTest, PostiveRangeRoundNearestTieToEven) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS,
- mpfr::RoundingMode::Nearest);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcExp2fExhaustiveTest, PostiveRangeRoundUp) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS, mpfr::RoundingMode::Upward);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcExp2fExhaustiveTest, PostiveRangeRoundDown) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS,
- mpfr::RoundingMode::Downward);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcExp2fExhaustiveTest, PostiveRangeRoundTowardZero) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS,
- mpfr::RoundingMode::TowardZero);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::TowardZero);
}
// Range: [-150, 0];
static constexpr uint32_t NEG_STOP = 0xc316'0000U;
TEST_F(LlvmLibcExp2fExhaustiveTest, NegativeRangeRoundNearestTieToEven) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS,
- mpfr::RoundingMode::Nearest);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcExp2fExhaustiveTest, NegativeRangeRoundUp) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS, mpfr::RoundingMode::Upward);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcExp2fExhaustiveTest, NegativeRangeRoundDown) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS,
- mpfr::RoundingMode::Downward);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcExp2fExhaustiveTest, NegativeRangeRoundTowardZero) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS,
- mpfr::RoundingMode::TowardZero);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
}
}
};
-static const int NUM_THREADS = std::thread::hardware_concurrency();
-
// Range: [0, 89];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x42b2'0000U;
TEST_F(LlvmLibcExpfExhaustiveTest, PostiveRangeRoundNearestTieToEven) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS,
- mpfr::RoundingMode::Nearest);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcExpfExhaustiveTest, PostiveRangeRoundUp) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS, mpfr::RoundingMode::Upward);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcExpfExhaustiveTest, PostiveRangeRoundDown) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS,
- mpfr::RoundingMode::Downward);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcExpfExhaustiveTest, PostiveRangeRoundTowardZero) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS,
- mpfr::RoundingMode::TowardZero);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::TowardZero);
}
// Range: [-104, 0];
static constexpr uint32_t NEG_STOP = 0xc2d0'0000U;
TEST_F(LlvmLibcExpfExhaustiveTest, NegativeRangeRoundNearestTieToEven) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS,
- mpfr::RoundingMode::Nearest);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcExpfExhaustiveTest, NegativeRangeRoundUp) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS, mpfr::RoundingMode::Upward);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcExpfExhaustiveTest, NegativeRangeRoundDown) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS,
- mpfr::RoundingMode::Downward);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcExpfExhaustiveTest, NegativeRangeRoundTowardZero) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS,
- mpfr::RoundingMode::TowardZero);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
}
}
};
-static const int NUM_THREADS = std::thread::hardware_concurrency();
-
// Range: [0, 89];
static constexpr uint32_t POS_START = 0x0000'0000U;
static constexpr uint32_t POS_STOP = 0x42b2'0000U;
TEST_F(LlvmLibcExpm1fExhaustiveTest, PostiveRangeRoundNearestTieToEven) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS,
- mpfr::RoundingMode::Nearest);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcExpm1fExhaustiveTest, PostiveRangeRoundUp) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS, mpfr::RoundingMode::Upward);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcExpm1fExhaustiveTest, PostiveRangeRoundDown) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS,
- mpfr::RoundingMode::Downward);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcExpm1fExhaustiveTest, PostiveRangeRoundTowardZero) {
- test_full_range(POS_START, POS_STOP, NUM_THREADS,
- mpfr::RoundingMode::TowardZero);
+ test_full_range(POS_START, POS_STOP, mpfr::RoundingMode::TowardZero);
}
// Range: [-104, 0];
static constexpr uint32_t NEG_STOP = 0xc2d0'0000U;
TEST_F(LlvmLibcExpm1fExhaustiveTest, NegativeRangeRoundNearestTieToEven) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS,
- mpfr::RoundingMode::Nearest);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcExpm1fExhaustiveTest, NegativeRangeRoundUp) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS, mpfr::RoundingMode::Upward);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcExpm1fExhaustiveTest, NegativeRangeRoundDown) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS,
- mpfr::RoundingMode::Downward);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcExpm1fExhaustiveTest, NegativeRangeRoundTowardZero) {
- test_full_range(NEG_START, NEG_STOP, NUM_THREADS,
- mpfr::RoundingMode::TowardZero);
+ test_full_range(NEG_START, NEG_STOP, mpfr::RoundingMode::TowardZero);
}
// Range of the first input: [2^23, 2^24);
static constexpr uint32_t START = (23U + 127U) << 23;
static constexpr uint32_t STOP = ((23U + 127U) << 23) + 1;
-static constexpr int NUM_THREADS = 1;
TEST_F(LlvmLibcHypotfExhaustiveTest, RoundNearestTieToEven) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::Nearest);
+ test_full_range(START, STOP, mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcHypotfExhaustiveTest, RoundUp) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::Upward);
+ test_full_range(START, STOP, mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcHypotfExhaustiveTest, RoundDown) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::Downward);
+ test_full_range(START, STOP, mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcHypotfExhaustiveTest, RoundTowardZero) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::TowardZero);
+ test_full_range(START, STOP, mpfr::RoundingMode::TowardZero);
}
// Range: [1, 10];
// static constexpr uint32_t START = 0x3f80'0000U;
// static constexpr uint32_t STOP = 0x41c0'0000U;
-static constexpr int NUM_THREADS = 16;
-
TEST_F(LlvmLibcLog10fExhaustiveTest, RoundNearestTieToEven) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::Nearest);
+ test_full_range(START, STOP, mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcLog10fExhaustiveTest, RoundUp) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::Upward);
+ test_full_range(START, STOP, mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcLog10fExhaustiveTest, RoundDown) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::Downward);
+ test_full_range(START, STOP, mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcLog10fExhaustiveTest, RoundTowardZero) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::TowardZero);
+ test_full_range(START, STOP, mpfr::RoundingMode::TowardZero);
}
// Range: [-1, 0];
// static constexpr uint32_t START = 0x8000'0000U;
// static constexpr uint32_t STOP = 0xbf80'0000U;
-static constexpr int NUM_THREADS = 16;
TEST_F(LlvmLibclog1pfExhaustiveTest, RoundNearestTieToEven) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::Nearest);
+ test_full_range(START, STOP, mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibclog1pfExhaustiveTest, RoundUp) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::Upward);
+ test_full_range(START, STOP, mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibclog1pfExhaustiveTest, RoundDown) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::Downward);
+ test_full_range(START, STOP, mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibclog1pfExhaustiveTest, RoundTowardZero) {
- test_full_range(START, STOP, NUM_THREADS, mpfr::RoundingMode::TowardZero);
+ test_full_range(START, STOP, mpfr::RoundingMode::TowardZero);
}
};
TEST_F(LlvmLibcLog2fExhaustiveTest, RoundNearestTieToEven) {
- test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+ test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcLog2fExhaustiveTest, RoundUp) {
- test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+ test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcLog2fExhaustiveTest, RoundDown) {
- test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+ test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcLog2fExhaustiveTest, RoundTowardZero) {
- test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+ test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::TowardZero);
}
};
TEST_F(LlvmLibcLogfExhaustiveTest, RoundNearestTieToEven) {
- test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+ test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Nearest);
}
TEST_F(LlvmLibcLogfExhaustiveTest, RoundUp) {
- test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+ test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Upward);
}
TEST_F(LlvmLibcLogfExhaustiveTest, RoundDown) {
- test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+ test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::Downward);
}
TEST_F(LlvmLibcLogfExhaustiveTest, RoundTowardZero) {
- test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U, /*nthreads=*/16,
+ test_full_range(/*start=*/0U, /*stop=*/0x7f80'0000U,
mpfr::RoundingMode::TowardZero);
}