87 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 RangeBasedGenerator class, a base11/// class for input generators that operate on a sequence of ranges.12///13//===----------------------------------------------------------------------===//14 15#ifndef MATHTEST_RANGEBASEDGENERATOR_HPP16#define MATHTEST_RANGEBASEDGENERATOR_HPP17 18#include "mathtest/IndexedRange.hpp"19#include "mathtest/InputGenerator.hpp"20 21#include "llvm/ADT/ArrayRef.h"22#include "llvm/Support/Parallel.h"23 24#include <algorithm>25#include <array>26#include <cassert>27#include <cstddef>28#include <cstdint>29#include <tuple>30 31namespace mathtest {32 33template <typename Derived, typename... InTypes>34class [[nodiscard]] RangeBasedGenerator : public InputGenerator<InTypes...> {35public:36 void reset() noexcept override { NextFlatIndex = 0; }37 38 [[nodiscard]] std::size_t39 fill(llvm::MutableArrayRef<InTypes>... Buffers) noexcept override {40 const std::array<std::size_t, NumInputs> BufferSizes = {Buffers.size()...};41 const std::size_t BufferSize = BufferSizes[0];42 assert((BufferSize != 0) && "Buffer size cannot be zero");43 assert(std::all_of(BufferSizes.begin(), BufferSizes.end(),44 [&](std::size_t Size) { return Size == BufferSize; }) &&45 "All input buffers must have the same size");46 47 if (NextFlatIndex >= Size)48 return 0;49 50 const auto BatchSize = std::min<uint64_t>(BufferSize, Size - NextFlatIndex);51 const auto CurrentFlatIndex = NextFlatIndex;52 NextFlatIndex += BatchSize;53 54 auto BufferPtrsTuple = std::make_tuple(Buffers.data()...);55 56 llvm::parallelFor(0, BatchSize, [&](std::size_t Offset) {57 static_cast<Derived *>(this)->writeInputs(CurrentFlatIndex, Offset,58 BufferPtrsTuple);59 });60 61 return static_cast<std::size_t>(BatchSize);62 }63 64protected:65 using RangesTupleType = std::tuple<IndexedRange<InTypes>...>;66 67 static constexpr std::size_t NumInputs = sizeof...(InTypes);68 static_assert(NumInputs > 0, "The number of inputs must be at least 1");69 70 explicit constexpr RangeBasedGenerator(71 const IndexedRange<InTypes> &...Ranges) noexcept72 : RangesTuple(Ranges...) {}73 74 explicit constexpr RangeBasedGenerator(75 uint64_t Size, const IndexedRange<InTypes> &...Ranges) noexcept76 : RangesTuple(Ranges...), Size(Size) {}77 78 RangesTupleType RangesTuple;79 uint64_t Size = 0;80 81private:82 uint64_t NextFlatIndex = 0;83};84} // namespace mathtest85 86#endif // MATHTEST_RANGEBASEDGENERATOR_HPP87