Leandro Lacerda 2abd58cb7e
[Offload] Add framework for math conformance tests (#149242)
This PR introduces the initial version of a C++ framework for the
conformance testing of GPU math library functions, building upon the
skeleton provided in #146391.

The main goal of this framework is to systematically measure the
accuracy of math functions in the GPU libc, verifying correctness or at
least conformance to standards like OpenCL via exhaustive or random
accuracy tests.
2025-07-29 11:08:27 -05:00

87 lines
2.4 KiB
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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains the definition of the TestResult class, which aggregates
/// and stores the results of a math test run.
///
//===----------------------------------------------------------------------===//
#ifndef MATHTEST_TESTRESULT_HPP
#define MATHTEST_TESTRESULT_HPP
#include <cstdint>
#include <optional>
#include <tuple>
#include <utility>
namespace mathtest {
template <typename OutType, typename... InTypes>
class [[nodiscard]] TestResult {
public:
struct [[nodiscard]] TestCase {
std::tuple<InTypes...> Inputs;
OutType Actual;
OutType Expected;
explicit constexpr TestCase(std::tuple<InTypes...> &&Inputs, OutType Actual,
OutType Expected) noexcept
: Inputs(std::move(Inputs)), Actual(std::move(Actual)),
Expected(std::move(Expected)) {}
};
TestResult() = default;
explicit TestResult(uint64_t UlpDistance, bool IsFailure,
TestCase &&Case) noexcept
: MaxUlpDistance(UlpDistance), FailureCount(IsFailure ? 1 : 0),
TestCaseCount(1) {
if (IsFailure)
WorstFailingCase.emplace(std::move(Case));
}
void accumulate(const TestResult &Other) noexcept {
if (Other.MaxUlpDistance > MaxUlpDistance) {
MaxUlpDistance = Other.MaxUlpDistance;
WorstFailingCase = Other.WorstFailingCase;
}
FailureCount += Other.FailureCount;
TestCaseCount += Other.TestCaseCount;
}
[[nodiscard]] bool hasPassed() const noexcept { return FailureCount == 0; }
[[nodiscard]] uint64_t getMaxUlpDistance() const noexcept {
return MaxUlpDistance;
}
[[nodiscard]] uint64_t getFailureCount() const noexcept {
return FailureCount;
}
[[nodiscard]] uint64_t getTestCaseCount() const noexcept {
return TestCaseCount;
}
[[nodiscard]] const std::optional<TestCase> &
getWorstFailingCase() const noexcept {
return WorstFailingCase;
}
private:
uint64_t MaxUlpDistance = 0;
uint64_t FailureCount = 0;
uint64_t TestCaseCount = 0;
std::optional<TestCase> WorstFailingCase;
};
} // namespace mathtest
#endif // MATHTEST_TESTRESULT_HPP