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.
156 lines
5.1 KiB
C++
156 lines
5.1 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 various metaprogramming helpers and
|
|
/// support utilities for the math test framework.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef MATHTEST_SUPPORT_HPP
|
|
#define MATHTEST_SUPPORT_HPP
|
|
|
|
#include <cstddef>
|
|
#include <tuple>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
namespace mathtest {
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Function & Type Traits
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
namespace detail {
|
|
|
|
template <typename T> struct FunctionTraitsImpl;
|
|
|
|
template <typename RetType, typename... ArgTypes>
|
|
struct FunctionTraitsImpl<RetType(ArgTypes...)> {
|
|
using ReturnType = RetType;
|
|
using ArgTypesTuple = std::tuple<ArgTypes...>;
|
|
};
|
|
|
|
template <typename RetType, typename... ArgTypes>
|
|
struct FunctionTraitsImpl<RetType(ArgTypes...) noexcept>
|
|
: FunctionTraitsImpl<RetType(ArgTypes...)> {};
|
|
|
|
template <typename FuncType>
|
|
struct FunctionTraitsImpl<FuncType *> : FunctionTraitsImpl<FuncType> {};
|
|
} // namespace detail
|
|
|
|
template <auto Func>
|
|
using FunctionTraits = detail::FunctionTraitsImpl<
|
|
std::remove_pointer_t<std::decay_t<decltype(Func)>>>;
|
|
|
|
template <typename FuncType>
|
|
using FunctionTypeTraits = detail::FunctionTraitsImpl<FuncType>;
|
|
|
|
template <typename T> struct TypeIdentityOf {
|
|
using type = T;
|
|
};
|
|
|
|
template <typename TupleTypes, template <typename...> class Template>
|
|
struct ApplyTupleTypes;
|
|
|
|
template <template <typename...> class Template, typename... Ts>
|
|
struct ApplyTupleTypes<std::tuple<Ts...>, Template> {
|
|
using type = Template<Ts...>;
|
|
};
|
|
|
|
template <typename TupleTypes, template <typename...> class Template>
|
|
using ApplyTupleTypes_t = typename ApplyTupleTypes<TupleTypes, Template>::type;
|
|
|
|
namespace detail {
|
|
|
|
template <typename T> struct KernelSignatureOfImpl;
|
|
|
|
template <typename RetType, typename... ArgTypes>
|
|
struct KernelSignatureOfImpl<RetType(ArgTypes...)> {
|
|
using type = void(const std::decay_t<ArgTypes> *..., RetType *, std::size_t);
|
|
};
|
|
|
|
template <typename RetType, typename... ArgTypes>
|
|
struct KernelSignatureOfImpl<RetType(ArgTypes...) noexcept>
|
|
: KernelSignatureOfImpl<RetType(ArgTypes...)> {};
|
|
} // namespace detail
|
|
|
|
template <auto Func>
|
|
using KernelSignatureOf = detail::KernelSignatureOfImpl<
|
|
std::remove_pointer_t<std::decay_t<decltype(Func)>>>;
|
|
|
|
template <auto Func>
|
|
using KernelSignatureOf_t = typename KernelSignatureOf<Func>::type;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Kernel Argument Packing
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
template <typename... ArgTypes> struct KernelArgsPack;
|
|
|
|
template <typename ArgType> struct KernelArgsPack<ArgType> {
|
|
std::decay_t<ArgType> Arg;
|
|
|
|
constexpr KernelArgsPack(ArgType &&Arg) : Arg(std::forward<ArgType>(Arg)) {}
|
|
};
|
|
|
|
template <typename ArgType0, typename ArgType1, typename... ArgTypes>
|
|
struct KernelArgsPack<ArgType0, ArgType1, ArgTypes...> {
|
|
std::decay_t<ArgType0> Arg0;
|
|
KernelArgsPack<ArgType1, ArgTypes...> Args;
|
|
|
|
constexpr KernelArgsPack(ArgType0 &&Arg0, ArgType1 &&Arg1, ArgTypes &&...Args)
|
|
: Arg0(std::forward<ArgType0>(Arg0)),
|
|
Args(std::forward<ArgType1>(Arg1), std::forward<ArgTypes>(Args)...) {}
|
|
};
|
|
|
|
template <typename... ArgTypes>
|
|
KernelArgsPack<ArgTypes...> makeKernelArgsPack(ArgTypes &&...Args) {
|
|
return KernelArgsPack<ArgTypes...>(std::forward<ArgTypes>(Args)...);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Configuration Helpers
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
template <auto Func> struct FunctionConfig;
|
|
|
|
namespace detail {
|
|
|
|
template <typename... BufferTypes>
|
|
static constexpr std::size_t getDefaultBufferSize() {
|
|
static_assert(sizeof...(BufferTypes) > 0,
|
|
"At least one buffer type must be provided");
|
|
|
|
constexpr std::size_t TotalMemoryInBytes = 512ULL << 20; // 512 MiB
|
|
constexpr std::size_t ElementTupleSize = (sizeof(BufferTypes) + ...);
|
|
|
|
static_assert(ElementTupleSize > 0,
|
|
"Cannot calculate buffer size for empty types");
|
|
|
|
return TotalMemoryInBytes / ElementTupleSize;
|
|
}
|
|
} // namespace detail
|
|
|
|
template <typename BufferType, typename BufferTupleTypes>
|
|
struct DefaultBufferSizeFor;
|
|
|
|
template <typename BufferType, typename... BufferTypes>
|
|
struct DefaultBufferSizeFor<BufferType, std::tuple<BufferTypes...>> {
|
|
static constexpr std::size_t value // NOLINT(readability-identifier-naming)
|
|
= detail::getDefaultBufferSize<BufferType, BufferTypes...>();
|
|
};
|
|
|
|
template <typename OutType, typename InTypesTuple>
|
|
inline constexpr std::size_t
|
|
DefaultBufferSizeFor_v // NOLINT(readability-identifier-naming)
|
|
= DefaultBufferSizeFor<OutType, InTypesTuple>::value;
|
|
} // namespace mathtest
|
|
|
|
#endif // MATHTEST_SUPPORT_HPP
|