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());