diff --git a/sycl/include/sycl/accessor.hpp b/sycl/include/sycl/accessor.hpp index f621beb6da45..a1a1e80b42a2 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 diff --git a/sycl/include/sycl/ext/oneapi/bfloat16.hpp b/sycl/include/sycl/ext/oneapi/bfloat16.hpp index dd514739596d..9399fadbceb6 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 f210e1681665..18d3a2799cc4 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); } };