Skip to content

Commit 665516d

Browse files
[NFC][SYCL] Add sycl::detail::sycl_obj_hash helper (#19812)
Unfortunately, can't simplify further in C++17. In C++20 that could be changed to ``` template <class T> requires(is_sycl_common_reference_semantics_class_v<T>) struct std::hash<T> { // sycl_obj_hash impl inlined here. }; ``` But even in C++17 this PR removes copy-paste and places the implementation in a single place.
1 parent beb11ba commit 665516d

File tree

16 files changed

+105
-245
lines changed

16 files changed

+105
-245
lines changed

sycl/include/sycl/accessor.hpp

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2937,61 +2937,24 @@ host_accessor(buffer<DataT, Dimensions, AllocatorT>, Type1, Type2, Type3, Type4,
29372937
} // namespace _V1
29382938
} // namespace sycl
29392939

2940-
namespace std {
29412940
template <typename DataT, int Dimensions, sycl::access::mode AccessMode,
29422941
sycl::access::target AccessTarget,
29432942
sycl::access::placeholder IsPlaceholder>
2944-
struct hash<sycl::accessor<DataT, Dimensions, AccessMode, AccessTarget,
2945-
IsPlaceholder>> {
2946-
using AccType = sycl::accessor<DataT, Dimensions, AccessMode, AccessTarget,
2947-
IsPlaceholder>;
2948-
2949-
size_t operator()(const AccType &A) const {
2950-
#ifdef __SYCL_DEVICE_ONLY__
2951-
// Hash is not supported on DEVICE. Just return 0 here.
2952-
(void)A;
2953-
return 0;
2954-
#else
2955-
// getSyclObjImpl() here returns a pointer to either AccessorImplHost
2956-
// or LocalAccessorImplHost depending on the AccessTarget.
2957-
auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
2958-
return hash<decltype(AccImplPtr)>()(AccImplPtr);
2959-
#endif
2960-
}
2961-
};
2943+
struct std::hash<
2944+
sycl::accessor<DataT, Dimensions, AccessMode, AccessTarget, IsPlaceholder>>
2945+
: public sycl::detail::sycl_obj_hash<
2946+
sycl::accessor<DataT, Dimensions, AccessMode, AccessTarget,
2947+
IsPlaceholder>,
2948+
false /*SupportedOnDevice*/> {};
29622949

29632950
template <typename DataT, int Dimensions, sycl::access_mode AccessMode>
2964-
struct hash<sycl::host_accessor<DataT, Dimensions, AccessMode>> {
2965-
using AccType = sycl::host_accessor<DataT, Dimensions, AccessMode>;
2966-
2967-
size_t operator()(const AccType &A) const {
2968-
#ifdef __SYCL_DEVICE_ONLY__
2969-
// Hash is not supported on DEVICE. Just return 0 here.
2970-
(void)A;
2971-
return 0;
2972-
#else
2973-
// getSyclObjImpl() here returns a pointer to AccessorImplHost.
2974-
auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
2975-
return hash<decltype(AccImplPtr)>()(AccImplPtr);
2976-
#endif
2977-
}
2978-
};
2951+
struct std::hash<sycl::host_accessor<DataT, Dimensions, AccessMode>>
2952+
: public sycl::detail::sycl_obj_hash<
2953+
sycl::host_accessor<DataT, Dimensions, AccessMode>,
2954+
false /*SupportedOnDevice*/> {};
29792955

29802956
template <typename DataT, int Dimensions>
2981-
struct hash<sycl::local_accessor<DataT, Dimensions>> {
2982-
using AccType = sycl::local_accessor<DataT, Dimensions>;
2983-
2984-
size_t operator()(const AccType &A) const {
2985-
#ifdef __SYCL_DEVICE_ONLY__
2986-
// Hash is not supported on DEVICE. Just return 0 here.
2987-
(void)A;
2988-
return 0;
2989-
#else
2990-
// getSyclObjImpl() here returns a pointer to LocalAccessorImplHost.
2991-
auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
2992-
return hash<decltype(AccImplPtr)>()(AccImplPtr);
2993-
#endif
2994-
}
2995-
};
2996-
2997-
} // namespace std
2957+
struct std::hash<sycl::local_accessor<DataT, Dimensions>>
2958+
: public sycl::detail::sycl_obj_hash<
2959+
sycl::local_accessor<DataT, Dimensions>,
2960+
false /*SupportedOnDevice*/> {};

sycl/include/sycl/accessor_image.hpp

Lines changed: 17 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,62 +1357,29 @@ class __SYCL_EBO host_sampled_image_accessor
13571357
} // namespace _V1
13581358
} // namespace sycl
13591359

1360-
namespace std {
13611360
template <typename DataT, int Dimensions, sycl::access_mode AccessMode,
13621361
sycl::image_target AccessTarget>
1363-
struct hash<sycl::unsampled_image_accessor<DataT, Dimensions, AccessMode,
1364-
AccessTarget>> {
1365-
using AccType = sycl::unsampled_image_accessor<DataT, Dimensions, AccessMode,
1366-
AccessTarget>;
1367-
1368-
size_t operator()(const AccType &A) const {
1369-
#ifdef __SYCL_DEVICE_ONLY__
1370-
// Hash is not supported on DEVICE. Just return 0 here.
1371-
(void)A;
1372-
return 0;
1373-
#else
1374-
auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
1375-
return hash<decltype(AccImplPtr)>()(AccImplPtr);
1376-
#endif
1377-
}
1378-
};
1362+
struct std::hash<
1363+
sycl::unsampled_image_accessor<DataT, Dimensions, AccessMode, AccessTarget>>
1364+
: public sycl::detail::sycl_obj_hash<
1365+
sycl::unsampled_image_accessor<DataT, Dimensions, AccessMode,
1366+
AccessTarget>,
1367+
false /*SupportedOnDevice*/> {};
13791368

13801369
template <typename DataT, int Dimensions, sycl::access_mode AccessMode>
1381-
struct hash<
1382-
sycl::host_unsampled_image_accessor<DataT, Dimensions, AccessMode>> {
1383-
using AccType =
1384-
sycl::host_unsampled_image_accessor<DataT, Dimensions, AccessMode>;
1385-
1386-
size_t operator()(const AccType &A) const {
1387-
auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
1388-
return hash<decltype(AccImplPtr)>()(AccImplPtr);
1389-
}
1370+
struct std::hash<
1371+
sycl::host_unsampled_image_accessor<DataT, Dimensions, AccessMode>>
1372+
: public sycl::detail::sycl_obj_hash<
1373+
sycl::host_unsampled_image_accessor<DataT, Dimensions, AccessMode>> {
13901374
};
13911375

13921376
template <typename DataT, int Dimensions, sycl::image_target AccessTarget>
1393-
struct hash<sycl::sampled_image_accessor<DataT, Dimensions, AccessTarget>> {
1394-
using AccType = sycl::sampled_image_accessor<DataT, Dimensions, AccessTarget>;
1395-
1396-
size_t operator()(const AccType &A) const {
1397-
#ifdef __SYCL_DEVICE_ONLY__
1398-
// Hash is not supported on DEVICE. Just return 0 here.
1399-
(void)A;
1400-
return 0;
1401-
#else
1402-
auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
1403-
return hash<decltype(AccImplPtr)>()(AccImplPtr);
1404-
#endif
1405-
}
1406-
};
1377+
struct std::hash<sycl::sampled_image_accessor<DataT, Dimensions, AccessTarget>>
1378+
: public sycl::detail::sycl_obj_hash<
1379+
sycl::sampled_image_accessor<DataT, Dimensions, AccessTarget>,
1380+
false /*SupportedOnDevice*/> {};
14071381

14081382
template <typename DataT, int Dimensions>
1409-
struct hash<sycl::host_sampled_image_accessor<DataT, Dimensions>> {
1410-
using AccType = sycl::host_sampled_image_accessor<DataT, Dimensions>;
1411-
1412-
size_t operator()(const AccType &A) const {
1413-
auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
1414-
return hash<decltype(AccImplPtr)>()(AccImplPtr);
1415-
}
1416-
};
1417-
1418-
} // namespace std
1383+
struct std::hash<sycl::host_sampled_image_accessor<DataT, Dimensions>>
1384+
: public sycl::detail::sycl_obj_hash<
1385+
sycl::host_sampled_image_accessor<DataT, Dimensions>> {};

sycl/include/sycl/buffer.hpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -863,12 +863,7 @@ buffer(const T *, const range<dimensions> &,
863863
} // namespace _V1
864864
} // namespace sycl
865865

866-
namespace std {
867866
template <typename T, int dimensions, typename AllocatorT>
868-
struct hash<sycl::buffer<T, dimensions, AllocatorT>> {
869-
size_t operator()(const sycl::buffer<T, dimensions, AllocatorT> &b) const {
870-
return hash<std::shared_ptr<sycl::detail::buffer_impl>>()(
871-
sycl::detail::getSyclObjImpl(b));
872-
}
873-
};
874-
} // namespace std
867+
struct std::hash<sycl::buffer<T, dimensions, AllocatorT>>
868+
: public sycl::detail::sycl_obj_hash<
869+
sycl::buffer<T, dimensions, AllocatorT>> {};

sycl/include/sycl/context.hpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -311,11 +311,6 @@ inline exception::exception(context Ctx, int EV,
311311
} // namespace _V1
312312
} // namespace sycl
313313

314-
namespace std {
315-
template <> struct hash<sycl::context> {
316-
size_t operator()(const sycl::context &Context) const {
317-
return hash<std::shared_ptr<sycl::detail::context_impl>>()(
318-
sycl::detail::getSyclObjImpl(Context));
319-
}
320-
};
321-
} // namespace std
314+
template <>
315+
struct std::hash<sycl::context>
316+
: public sycl::detail::sycl_obj_hash<sycl::context> {};

sycl/include/sycl/detail/impl_utils.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#pragma once
1010

1111
#include <cassert> // for assert
12+
#include <functional> // for hash
1213
#include <type_traits> // for add_pointer_t
1314
#include <utility> // for forward
1415

@@ -58,6 +59,23 @@ T createSyclObjFromImpl(
5859
return createSyclObjFromImpl<T>(ImplRef.shared_from_this());
5960
}
6061

62+
template <typename T, bool SupportedOnDevice = true> struct sycl_obj_hash {
63+
size_t operator()(const T &Obj) const {
64+
if constexpr (SupportedOnDevice) {
65+
auto &Impl = sycl::detail::getSyclObjImpl(Obj);
66+
return std::hash<std::decay_t<decltype(Impl)>>{}(Impl);
67+
} else {
68+
#ifdef __SYCL_DEVICE_ONLY__
69+
(void)Obj;
70+
return 0;
71+
#else
72+
auto &Impl = sycl::detail::getSyclObjImpl(Obj);
73+
return std::hash<std::decay_t<decltype(Impl)>>{}(Impl);
74+
#endif
75+
}
76+
}
77+
};
78+
6179
} // namespace detail
6280
} // namespace _V1
6381
} // namespace sycl

sycl/include/sycl/device.hpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,6 @@ class __SYCL_STANDALONE_DEBUG __SYCL_EXPORT device
407407
} // namespace _V1
408408
} // namespace sycl
409409

410-
namespace std {
411-
template <> struct hash<sycl::device> {
412-
size_t operator()(const sycl::device &Device) const {
413-
return hash<std::shared_ptr<sycl::detail::device_impl>>()(
414-
sycl::detail::getSyclObjImpl(Device));
415-
}
416-
};
417-
} // namespace std
410+
template <>
411+
struct std::hash<sycl::device>
412+
: public sycl::detail::sycl_obj_hash<sycl::device> {};

sycl/include/sycl/event.hpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,6 @@ class __SYCL_EXPORT event : public detail::OwnerLessBase<event> {
175175
} // namespace _V1
176176
} // namespace sycl
177177

178-
namespace std {
179-
template <> struct hash<sycl::event> {
180-
size_t operator()(const sycl::event &e) const {
181-
return hash<std::shared_ptr<sycl::detail::event_impl>>()(
182-
sycl::detail::getSyclObjImpl(e));
183-
}
184-
};
185-
} // namespace std
178+
template <>
179+
struct std::hash<sycl::event>
180+
: public sycl::detail::sycl_obj_hash<sycl::event> {};

sycl/include/sycl/ext/oneapi/bindless_images_memory.hpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,7 @@ enum class image_memory_handle_type : unsigned int {
117117
} // namespace _V1
118118
} // namespace sycl
119119

120-
namespace std {
121-
template <> struct hash<sycl::ext::oneapi::experimental::image_mem> {
122-
size_t operator()(
123-
const sycl::ext::oneapi::experimental::image_mem &image_mem) const {
124-
return hash<std::shared_ptr<
125-
sycl::ext::oneapi::experimental::detail::image_mem_impl>>()(
126-
sycl::detail::getSyclObjImpl(image_mem));
127-
}
128-
};
129-
} // namespace std
120+
template <>
121+
struct std::hash<sycl::ext::oneapi::experimental::image_mem>
122+
: public sycl::detail::sycl_obj_hash<
123+
sycl::ext::oneapi::experimental::image_mem> {};

sycl/include/sycl/ext/oneapi/experimental/async_alloc/memory_pool.hpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,7 @@ class __SYCL_EXPORT memory_pool {
110110
} // namespace _V1
111111
} // namespace sycl
112112

113-
namespace std {
114-
template <> struct hash<sycl::ext::oneapi::experimental::memory_pool> {
115-
size_t operator()(
116-
const sycl::ext::oneapi::experimental::memory_pool &mem_pool) const {
117-
return hash<std::shared_ptr<
118-
sycl::ext::oneapi::experimental::detail::memory_pool_impl>>()(
119-
sycl::detail::getSyclObjImpl(mem_pool));
120-
}
121-
};
122-
} // namespace std
113+
template <>
114+
struct std::hash<sycl::ext::oneapi::experimental::memory_pool>
115+
: public sycl::detail::sycl_obj_hash<
116+
sycl::ext::oneapi::experimental::memory_pool> {};

sycl/include/sycl/ext/oneapi/virtual_mem/physical_mem.hpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,7 @@ class __SYCL_EXPORT physical_mem
7171
} // namespace _V1
7272
} // namespace sycl
7373

74-
namespace std {
75-
template <> struct hash<sycl::ext::oneapi::experimental::physical_mem> {
76-
size_t operator()(
77-
const sycl::ext::oneapi::experimental::physical_mem &PhysicalMem) const {
78-
return hash<std::shared_ptr<sycl::detail::physical_mem_impl>>()(
79-
sycl::detail::getSyclObjImpl(PhysicalMem));
80-
}
81-
};
82-
} // namespace std
74+
template <>
75+
struct std::hash<sycl::ext::oneapi::experimental::physical_mem>
76+
: public sycl::detail::sycl_obj_hash<
77+
sycl::ext::oneapi::experimental::physical_mem> {};

0 commit comments

Comments
 (0)