From 48b7415793a181a68d10570cc6a4d0e10a0979fc Mon Sep 17 00:00:00 2001 From: y Date: Fri, 15 May 2026 13:44:28 -0700 Subject: [PATCH 1/2] [SYCL][NFC] Drop from half_type.hpp / bfloat16.hpp half_type.hpp included only to make std::hash's primary template visible for the std::hash specialization. Replace with a forward declaration (`namespace std { template struct hash; }`) and inline the hash body so it no longer calls std::hash{}, which requires the primary definition. Same treatment in bfloat16.hpp (already had sycl::bit_cast in scope). Saves the transitive chain (~30 ms parse + 60+ headers) on every TU that pulls sycl::half. --- sycl/include/sycl/ext/oneapi/bfloat16.hpp | 5 +++-- sycl/include/sycl/half_type.hpp | 16 +++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/bfloat16.hpp b/sycl/include/sycl/ext/oneapi/bfloat16.hpp index dd514739596d3..9399fadbceb6f 100644 --- a/sycl/include/sycl/ext/oneapi/bfloat16.hpp +++ b/sycl/include/sycl/ext/oneapi/bfloat16.hpp @@ -636,10 +636,11 @@ inline bfloat16 getBfloat16WithRoundingMode(const Ty &a) { // Specialization of some functions in namespace `std`. namespace std { -// Specialization of `std::hash`. +// Specialization of `std::hash`. See +// half_type.hpp for the rationale on avoiding `std::hash`. template <> struct hash { size_t operator()(sycl::ext::oneapi::bfloat16 const &Key) const noexcept { - return hash{}(sycl::bit_cast(Key)); + return static_cast(sycl::bit_cast(Key)); } }; diff --git a/sycl/include/sycl/half_type.hpp b/sycl/include/sycl/half_type.hpp index f210e16816659..18d3a2799cc49 100644 --- a/sycl/include/sycl/half_type.hpp +++ b/sycl/include/sycl/half_type.hpp @@ -10,9 +10,9 @@ #include -// For std::hash, seems to be the most lightweight header provide it under -// C++17: -#include +namespace std { +template struct hash; +} #ifdef __SYCL_DEVICE_ONLY__ #include @@ -50,10 +50,16 @@ inline std::istream &operator>>(std::istream &I, sycl::half &rhs) { // Partial specialization of some functions in namespace `std` namespace std { -// Partial specialization of `std::hash` +// Partial specialization of `std::hash`. Avoid calling +// `std::hash` so we don't need / for the +// primary template definition; the bit pattern of a 16-bit half hashes +// to itself zero-extended into a size_t (identity on the underlying +// integer is what libstdc++/libc++ do for std::hash too). template <> struct hash { size_t operator()(sycl::half const &Key) const noexcept { - return hash{}(reinterpret_cast(Key)); + uint16_t Bits = 0; + __builtin_memcpy(&Bits, &Key, sizeof(Bits)); + return static_cast(Bits); } }; From c5cfb0137eca1b21c7c27122e02d30687bde3560 Mon Sep 17 00:00:00 2001 From: y Date: Fri, 15 May 2026 13:56:43 -0700 Subject: [PATCH 2/2] Hash is provided by memory, fix comment --- sycl/include/sycl/accessor.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sycl/include/sycl/accessor.hpp b/sycl/include/sycl/accessor.hpp index f621beb6da455..a1a1e80b42a2c 100644 --- a/sycl/include/sycl/accessor.hpp +++ b/sycl/include/sycl/accessor.hpp @@ -34,10 +34,9 @@ #include // for range #include // for size_t -#include // for hash #include // for reverse_iterator #include // for numeric_limits -#include // for shared_ptr +#include // for shared_ptr, hash #include // for enable_if_t /// \file accessor.hpp