1 //===-- Exhaustive test template for math functions -------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <atomic> 10 #include <fenv.h> 11 #include <functional> 12 #include <iostream> 13 #include <mutex> 14 #include <sstream> 15 #include <thread> 16 #include <vector> 17 18 #include "src/__support/FPUtil/FPBits.h" 19 20 #include "exhaustive_test.h" 21 22 template <typename T, typename FloatType> 23 void LlvmLibcExhaustiveTest<T, FloatType>::test_full_range( 24 T start, T stop, mpfr::RoundingMode rounding) { 25 int n_threads = std::thread::hardware_concurrency(); 26 std::vector<std::thread> thread_list; 27 std::mutex mx_cur_val; 28 int current_percent = -1; 29 T current_value = start; 30 std::atomic<uint64_t> failed(0); 31 for (int i = 0; i < n_threads; ++i) { 32 thread_list.emplace_back([&, this]() { 33 while (true) { 34 T range_begin, range_end; 35 int new_percent = -1; 36 { 37 std::lock_guard<std::mutex> lock(mx_cur_val); 38 if (current_value == stop) 39 return; 40 41 range_begin = current_value; 42 if (stop >= increment && stop - increment >= current_value) { 43 range_end = current_value + increment; 44 } else 45 range_end = stop; 46 current_value = range_end; 47 int pc = 100.0 * double(range_end - start) / double(stop - start); 48 if (current_percent != pc) { 49 new_percent = pc; 50 current_percent = pc; 51 } 52 } 53 if (new_percent >= 0) { 54 std::stringstream msg; 55 msg << new_percent << "% is in process \r"; 56 std::cout << msg.str() << std::flush; 57 ; 58 } 59 60 bool check_passed = check(range_begin, range_end, rounding); 61 if (!check_passed) { 62 std::stringstream msg; 63 msg << "Test failed in range: " << std::dec << range_begin << " to " 64 << range_end << " [0x" << std::hex << range_begin << ", 0x" 65 << range_end << "), [" << std::hexfloat 66 << static_cast<FloatType>(__llvm_libc::fputil::FPBits<FloatType>( 67 static_cast<T>(range_begin))) 68 << ", " 69 << static_cast<FloatType>( 70 __llvm_libc::fputil::FPBits<FloatType>(range_end)) 71 << ") " << std::endl; 72 std::cerr << msg.str() << std::flush; 73 74 failed.fetch_add(1); 75 } 76 } 77 }); 78 } 79 80 for (auto &thread : thread_list) { 81 if (thread.joinable()) { 82 thread.join(); 83 } 84 } 85 std::cout << std::endl; 86 std::cout << "Test " << ((failed > 0) ? "FAILED" : "PASSED") << std::endl; 87 } 88 89 template void 90 LlvmLibcExhaustiveTest<uint32_t>::test_full_range(uint32_t, uint32_t, 91 mpfr::RoundingMode); 92 template void LlvmLibcExhaustiveTest<uint64_t, double>::test_full_range( 93 uint64_t, uint64_t, mpfr::RoundingMode); 94