From b788a3fbf8b82dd9c7df66838bdc30420ef2b6ec Mon Sep 17 00:00:00 2001 From: Julian Oppermann Date: Fri, 12 Jan 2024 08:17:53 -1000 Subject: [PATCH] [SYCL][Fusion][NoSTL] Reimplement `Indices` class without `std::array` (#12340) The `jit_compiler::NDRange` class stores global/local sizes and an offset as instances of `jit_compiler::Indices`, which previously was just an alias to `std::array`. To elide this use of the STL class, I implemented a drop-in replacement which is backed by a C array and provides a minimal set of accessors and operators. *This PR is part of a series of changes to remove uses of STL classes in the kernel fusion interface to prevent ABI issues in the future.* --------- Signed-off-by: Julian Oppermann --- sycl-fusion/common/include/Kernel.h | 40 ++++++++++++++++++- .../jit-compiler/lib/fusion/FusionHelper.cpp | 2 +- sycl-fusion/jit-compiler/lib/fusion/Hashing.h | 4 ++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/sycl-fusion/common/include/Kernel.h b/sycl-fusion/common/include/Kernel.h index bff7644826b41..f88463b5a3138 100644 --- a/sycl-fusion/common/include/Kernel.h +++ b/sycl-fusion/common/include/Kernel.h @@ -147,7 +147,45 @@ struct SYCLArgumentDescriptor { /// List of SYCL/OpenCL kernel attributes. using AttributeList = std::vector; -using Indices = std::array; +/// +/// Class to model a three-dimensional index. +class Indices { +public: + static constexpr size_t size() { return Size; } + + constexpr Indices() : Values{0, 0, 0} {} + constexpr Indices(size_t V1, size_t V2, size_t V3) : Values{V1, V2, V3} {} + + constexpr const size_t *begin() const { return Values; } + constexpr const size_t *end() const { return Values + Size; } + constexpr size_t *begin() { return Values; } + constexpr size_t *end() { return Values + Size; } + + constexpr const size_t &operator[](int Idx) const { return Values[Idx]; } + constexpr size_t &operator[](int Idx) { return Values[Idx]; } + + friend bool operator==(const Indices &A, const Indices &B) { + return std::equal(A.begin(), A.end(), B.begin()); + } + + friend bool operator!=(const Indices &A, const Indices &B) { + return !(A == B); + } + + friend bool operator<(const Indices &A, const Indices &B) { + return std::lexicographical_compare(A.begin(), A.end(), B.begin(), B.end(), + std::less{}); + } + + friend bool operator>(const Indices &A, const Indices &B) { + return std::lexicographical_compare(A.begin(), A.end(), B.begin(), B.end(), + std::greater{}); + } + +private: + static constexpr size_t Size = 3; + size_t Values[Size]; +}; /// /// Class to model SYCL nd_range diff --git a/sycl-fusion/jit-compiler/lib/fusion/FusionHelper.cpp b/sycl-fusion/jit-compiler/lib/fusion/FusionHelper.cpp index 9a58ad59746a3..853377f513781 100644 --- a/sycl-fusion/jit-compiler/lib/fusion/FusionHelper.cpp +++ b/sycl-fusion/jit-compiler/lib/fusion/FusionHelper.cpp @@ -92,7 +92,7 @@ Expected> helper::FusionHelper::addFusedKernel( { const auto MDFromND = [&LLVMCtx](const auto &ND) { auto MDFromIndices = [&LLVMCtx](const auto &Ind) -> Metadata * { - std::array MD{nullptr}; + std::array MD{nullptr}; std::transform( Ind.begin(), Ind.end(), MD.begin(), [&LLVMCtx](auto I) { return getConstantIntMD(LLVMCtx, I); }); diff --git a/sycl-fusion/jit-compiler/lib/fusion/Hashing.h b/sycl-fusion/jit-compiler/lib/fusion/Hashing.h index 4234f33c1abd5..55cb51284ff52 100644 --- a/sycl-fusion/jit-compiler/lib/fusion/Hashing.h +++ b/sycl-fusion/jit-compiler/lib/fusion/Hashing.h @@ -34,6 +34,10 @@ inline llvm::hash_code hash_value(const ParameterIdentity &IP) { return llvm::hash_combine(IP.LHS, IP.RHS); } +inline llvm::hash_code hash_value(const Indices &I) { + return llvm::hash_combine_range(I.begin(), I.end()); +} + inline llvm::hash_code hash_value(const NDRange &ND) { return llvm::hash_combine(ND.getDimensions(), ND.getGlobalSize(), ND.getLocalSize(), ND.getOffset());