156 lines · plain
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains the definition of various metaprogramming helpers and11/// support utilities for the math test framework.12///13//===----------------------------------------------------------------------===//14 15#ifndef MATHTEST_SUPPORT_HPP16#define MATHTEST_SUPPORT_HPP17 18#include <cstddef>19#include <tuple>20#include <type_traits>21#include <utility>22 23namespace mathtest {24 25//===----------------------------------------------------------------------===//26// Function & Type Traits27//===----------------------------------------------------------------------===//28 29namespace detail {30 31template <typename T> struct FunctionTraitsImpl;32 33template <typename RetType, typename... ArgTypes>34struct FunctionTraitsImpl<RetType(ArgTypes...)> {35 using ReturnType = RetType;36 using ArgTypesTuple = std::tuple<ArgTypes...>;37};38 39template <typename RetType, typename... ArgTypes>40struct FunctionTraitsImpl<RetType(ArgTypes...) noexcept>41 : FunctionTraitsImpl<RetType(ArgTypes...)> {};42 43template <typename FuncType>44struct FunctionTraitsImpl<FuncType *> : FunctionTraitsImpl<FuncType> {};45} // namespace detail46 47template <auto Func>48using FunctionTraits = detail::FunctionTraitsImpl<49 std::remove_pointer_t<std::decay_t<decltype(Func)>>>;50 51template <typename FuncType>52using FunctionTypeTraits = detail::FunctionTraitsImpl<FuncType>;53 54template <typename T> struct TypeIdentityOf {55 using type = T;56};57 58template <typename TupleTypes, template <typename...> class Template>59struct ApplyTupleTypes;60 61template <template <typename...> class Template, typename... Ts>62struct ApplyTupleTypes<std::tuple<Ts...>, Template> {63 using type = Template<Ts...>;64};65 66template <typename TupleTypes, template <typename...> class Template>67using ApplyTupleTypes_t = typename ApplyTupleTypes<TupleTypes, Template>::type;68 69namespace detail {70 71template <typename T> struct KernelSignatureOfImpl;72 73template <typename RetType, typename... ArgTypes>74struct KernelSignatureOfImpl<RetType(ArgTypes...)> {75 using type = void(const std::decay_t<ArgTypes> *..., RetType *, std::size_t);76};77 78template <typename RetType, typename... ArgTypes>79struct KernelSignatureOfImpl<RetType(ArgTypes...) noexcept>80 : KernelSignatureOfImpl<RetType(ArgTypes...)> {};81} // namespace detail82 83template <auto Func>84using KernelSignatureOf = detail::KernelSignatureOfImpl<85 std::remove_pointer_t<std::decay_t<decltype(Func)>>>;86 87template <auto Func>88using KernelSignatureOf_t = typename KernelSignatureOf<Func>::type;89 90//===----------------------------------------------------------------------===//91// Kernel Argument Packing92//===----------------------------------------------------------------------===//93 94template <typename... ArgTypes> struct KernelArgsPack;95 96template <typename ArgType> struct KernelArgsPack<ArgType> {97 std::decay_t<ArgType> Arg;98 99 constexpr KernelArgsPack(ArgType &&Arg) : Arg(std::forward<ArgType>(Arg)) {}100};101 102template <typename ArgType0, typename ArgType1, typename... ArgTypes>103struct KernelArgsPack<ArgType0, ArgType1, ArgTypes...> {104 std::decay_t<ArgType0> Arg0;105 KernelArgsPack<ArgType1, ArgTypes...> Args;106 107 constexpr KernelArgsPack(ArgType0 &&Arg0, ArgType1 &&Arg1, ArgTypes &&...Args)108 : Arg0(std::forward<ArgType0>(Arg0)),109 Args(std::forward<ArgType1>(Arg1), std::forward<ArgTypes>(Args)...) {}110};111 112template <typename... ArgTypes>113KernelArgsPack<ArgTypes...> makeKernelArgsPack(ArgTypes &&...Args) {114 return KernelArgsPack<ArgTypes...>(std::forward<ArgTypes>(Args)...);115}116 117//===----------------------------------------------------------------------===//118// Configuration Helpers119//===----------------------------------------------------------------------===//120 121template <auto Func> struct FunctionConfig;122 123namespace detail {124 125template <typename... BufferTypes>126static constexpr std::size_t getDefaultBufferSize() {127 static_assert(sizeof...(BufferTypes) > 0,128 "At least one buffer type must be provided");129 130 constexpr std::size_t TotalMemoryInBytes = 512ULL << 20; // 512 MiB131 constexpr std::size_t ElementTupleSize = (sizeof(BufferTypes) + ...);132 133 static_assert(ElementTupleSize > 0,134 "Cannot calculate buffer size for empty types");135 136 return TotalMemoryInBytes / ElementTupleSize;137}138} // namespace detail139 140template <typename BufferType, typename BufferTupleTypes>141struct DefaultBufferSizeFor;142 143template <typename BufferType, typename... BufferTypes>144struct DefaultBufferSizeFor<BufferType, std::tuple<BufferTypes...>> {145 static constexpr std::size_t value // NOLINT(readability-identifier-naming)146 = detail::getDefaultBufferSize<BufferType, BufferTypes...>();147};148 149template <typename OutType, typename InTypesTuple>150inline constexpr std::size_t151 DefaultBufferSizeFor_v // NOLINT(readability-identifier-naming)152 = DefaultBufferSizeFor<OutType, InTypesTuple>::value;153} // namespace mathtest154 155#endif // MATHTEST_SUPPORT_HPP156