From a99abc6e930e44b57ea5e201dbaa2db6bdef8657 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Wed, 15 Dec 2021 22:22:33 +0100 Subject: [PATCH 1/3] Vector component const conversion operators should return references This is necessary for consistency between the representation of vector types between host and device, as well as for consistency with the way vector types behave when defined as structures (as is the case for code ported from CUDA). Without this patch, this simple test case: ```` const float& pick(float4 const& v) { return v.x; } const volatile float& pick(float4 const volatile& v) { return v.x; } int main() { const float4 c = make_float4(0, 1, 2, 3); volatile float4 v = make_float4(1, 2, 3, 0); std::cout << pick(c) << std::endl; std::cout << pick(v) << std::endl; } ```` will fail to compile when built with the host compiler. Closes hipamd issue #3 --- include/hip/amd_detail/amd_hip_vector_types.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/hip/amd_detail/amd_hip_vector_types.h b/include/hip/amd_detail/amd_hip_vector_types.h index c183a734..623d968f 100644 --- a/include/hip/amd_detail/amd_hip_vector_types.h +++ b/include/hip/amd_detail/amd_hip_vector_types.h @@ -209,9 +209,15 @@ template struct is_scalar : public integral_constant(data)[idx]; + } __HOST_DEVICE__ - operator T() const volatile noexcept { return data[idx]; } + constexpr operator const volatile T&() const volatile noexcept { + return reinterpret_cast< + const volatile T (&)[sizeof(Vector) / sizeof(T)]>(data)[idx]; + } #ifdef __HIP_ENABLE_VECTOR_SCALAR_ACCESSORY_ENUM_CONVERSION__ // The conversions to enum are fairly ghastly, but unfortunately used in From cc81f2c7b8cd0c9cb4ba4ca912d1585b213c405b Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Thu, 16 Dec 2021 09:05:52 +0100 Subject: [PATCH 2/3] Only overload vector operators for convertible types This is necessary to avoid errors about ambiguous overloads in code such as ```` struct Point { float4 pos; float mass; }; template Point operator+(Point const& p, T const& v) { return Point{p.pos + v, p.mass}; } int main() { float4 v = make_float4(0, 1, 2, 3); Point p{make_float4(3, 2, 1, 0), 1.0f}; Point q = p + v; } ```` when building with the host compiler. Closes hipamd issue #4 --- include/hip/amd_detail/amd_hip_vector_types.h | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/include/hip/amd_detail/amd_hip_vector_types.h b/include/hip/amd_detail/amd_hip_vector_types.h index 623d968f..a9f36a38 100644 --- a/include/hip/amd_detail/amd_hip_vector_types.h +++ b/include/hip/amd_detail/amd_hip_vector_types.h @@ -955,6 +955,13 @@ template struct is_scalar : public integral_constant + template /* operator return value */> + using enable_if_convertible = typename + std::enable_if>::value, R>::type; + template __HOST_DEVICE__ inline @@ -968,7 +975,7 @@ template struct is_scalar : public integral_constant operator+( + enable_if_convertible operator+( const HIP_vector_type& x, U y) noexcept { return HIP_vector_type{x} += HIP_vector_type{y}; @@ -977,7 +984,7 @@ template struct is_scalar : public integral_constant operator+( + enable_if_convertible operator+( U x, const HIP_vector_type& y) noexcept { return HIP_vector_type{x} += y; @@ -996,7 +1003,7 @@ template struct is_scalar : public integral_constant operator-( + enable_if_convertible operator-( const HIP_vector_type& x, U y) noexcept { return HIP_vector_type{x} -= HIP_vector_type{y}; @@ -1005,7 +1012,7 @@ template struct is_scalar : public integral_constant operator-( + enable_if_convertible operator-( U x, const HIP_vector_type& y) noexcept { return HIP_vector_type{x} -= y; @@ -1024,7 +1031,7 @@ template struct is_scalar : public integral_constant operator*( + enable_if_convertible operator*( const HIP_vector_type& x, U y) noexcept { return HIP_vector_type{x} *= HIP_vector_type{y}; @@ -1033,7 +1040,7 @@ template struct is_scalar : public integral_constant operator*( + enable_if_convertible operator*( U x, const HIP_vector_type& y) noexcept { return HIP_vector_type{x} *= y; @@ -1052,7 +1059,7 @@ template struct is_scalar : public integral_constant operator/( + enable_if_convertible operator/( const HIP_vector_type& x, U y) noexcept { return HIP_vector_type{x} /= HIP_vector_type{y}; @@ -1061,7 +1068,7 @@ template struct is_scalar : public integral_constant operator/( + enable_if_convertible operator/( U x, const HIP_vector_type& y) noexcept { return HIP_vector_type{x} /= y; @@ -1090,7 +1097,7 @@ template struct is_scalar : public integral_constant& x, U y) noexcept + enable_if_convertible operator==(const HIP_vector_type& x, U y) noexcept { return x == HIP_vector_type{y}; } @@ -1098,7 +1105,7 @@ template struct is_scalar : public integral_constant& y) noexcept + enable_if_convertible operator==(U x, const HIP_vector_type& y) noexcept { return HIP_vector_type{x} == y; } @@ -1116,7 +1123,7 @@ template struct is_scalar : public integral_constant& x, U y) noexcept + enable_if_convertible operator!=(const HIP_vector_type& x, U y) noexcept { return !(x == y); } @@ -1124,7 +1131,7 @@ template struct is_scalar : public integral_constant& y) noexcept + enable_if_convertible operator!=(U x, const HIP_vector_type& y) noexcept { return !(x == y); } From 223d35d8aca296c0810f9d7e39a71f31e86c06ae Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Thu, 16 Dec 2021 09:47:58 +0100 Subject: [PATCH 3/3] Vector ops: support compilers without ext_vector_type This allows compilation of code such as ```` int main() { float4 v1, v2, v3; v3 = v1 + v2; v3 = v1 - v2; v3 = v1 * v2; v3 = v1 / v2; int4 i1, i2, i3; i3 = -i1; i3 = ~i2; i3 = i1 % i2; i3 = i1 ^ i2; i3 = i1 >> i2; i3 = i1 << i2; } ```` with a host compiler that supports __has_attribute, but does not support the ext_vector_type attribute (e.g. g++). --- include/hip/amd_detail/amd_hip_vector_types.h | 84 ++++++++++++++++--- 1 file changed, 72 insertions(+), 12 deletions(-) diff --git a/include/hip/amd_detail/amd_hip_vector_types.h b/include/hip/amd_detail/amd_hip_vector_types.h index a9f36a38..5c7d4e4c 100644 --- a/include/hip/amd_detail/amd_hip_vector_types.h +++ b/include/hip/amd_detail/amd_hip_vector_types.h @@ -811,7 +811,12 @@ template struct is_scalar : public integral_constant struct is_scalar : public integral_constant struct is_scalar : public integral_constant struct is_scalar : public integral_constant struct is_scalar : public integral_constant struct is_scalar : public integral_constant struct is_scalar : public integral_constant struct is_scalar : public integral_constant struct is_scalar : public integral_constant struct is_scalar : public integral_constant struct is_scalar : public integral_constant>=(const HIP_vector_type& x) noexcept { - data >>= x.data; + #if __has_attribute(ext_vector_type) + data >>= x.data; + #else + for (auto i = 0u; i < rank; ++i) + data[i] >>= x.data[i]; + #endif return *this; } @@ -950,7 +1005,12 @@ template struct is_scalar : public integral_constant