brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 488aefd Raw
101 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 the HostRefChecker class, which11/// verifies the results of a device computation against a reference12/// implementation on the host.13///14//===----------------------------------------------------------------------===//15 16#ifndef MATHTEST_HOSTREFCHECKER_HPP17#define MATHTEST_HOSTREFCHECKER_HPP18 19#include "mathtest/Numerics.hpp"20#include "mathtest/Support.hpp"21#include "mathtest/TestResult.hpp"22 23#include "llvm/ADT/ArrayRef.h"24#include "llvm/ADT/Sequence.h"25#include "llvm/Support/Parallel.h"26 27#include <cstddef>28#include <tuple>29#include <utility>30 31namespace mathtest {32 33template <auto Func> class HostRefChecker {34  using FunctionTraits = FunctionTraits<Func>;35  using InTypesTuple = typename FunctionTraits::ArgTypesTuple;36 37  using FunctionConfig = FunctionConfig<Func>;38 39  template <typename... Ts>40  using BuffersTupleType = std::tuple<llvm::ArrayRef<Ts>...>;41 42public:43  using OutType = typename FunctionTraits::ReturnType;44 45private:46  template <typename... Ts>47  using PartialResultType = TestResult<OutType, Ts...>;48 49public:50  using ResultType = ApplyTupleTypes_t<InTypesTuple, PartialResultType>;51  using InBuffersTupleType = ApplyTupleTypes_t<InTypesTuple, BuffersTupleType>;52 53  HostRefChecker() = delete;54 55  static ResultType check(InBuffersTupleType InBuffersTuple,56                          llvm::ArrayRef<OutType> OutBuffer) noexcept {57    const std::size_t BufferSize = OutBuffer.size();58    std::apply(59        [&](const auto &...InBuffers) {60          assert(61              ((InBuffers.size() == BufferSize) && ...) &&62              "All input buffers must have the same size as the output buffer");63        },64        InBuffersTuple);65 66    assert((BufferSize != 0) && "Buffer size cannot be zero");67 68    ResultType Init;69 70    auto Transform = [&](std::size_t Index) {71      auto CurrentInputsTuple = std::apply(72          [&](const auto &...InBuffers) {73            return std::make_tuple(InBuffers[Index]...);74          },75          InBuffersTuple);76 77      const OutType Actual = OutBuffer[Index];78      const OutType Expected = std::apply(Func, CurrentInputsTuple);79 80      const auto UlpDistance = computeUlpDistance(Actual, Expected);81      const bool IsFailure = UlpDistance > FunctionConfig::UlpTolerance;82 83      return ResultType(UlpDistance, IsFailure,84                        typename ResultType::TestCase(85                            std::move(CurrentInputsTuple), Actual, Expected));86    };87 88    auto Reduce = [](ResultType A, const ResultType &B) {89      A.accumulate(B);90      return A;91    };92 93    const auto Indexes = llvm::seq(BufferSize);94    return llvm::parallelTransformReduce(Indexes.begin(), Indexes.end(), Init,95                                         Reduce, Transform);96  }97};98} // namespace mathtest99 100#endif // MATHTEST_HOSTREFCHECKER_HPP101