From 420474338a6b87b8d55cf2b8fc965874b74752ef Mon Sep 17 00:00:00 2001 From: Wayne Franz Date: Tue, 3 Jun 2025 15:59:36 -0400 Subject: [PATCH] Avoid creating void reference type in device batch memcpy In the batch_memcpy_impl struct, we define two types based on the value of the InputBufferItType template argument. 1. input_type, set to the InputBufferItType's underlying value_type's value_type. 2. Alias, a type that's set using a std::conditional statement that examines the IsMemCpy boolean template arg, and may be set to either unsigned char or the type from (1). Later code creates a reference to (1). This causes problems when (1) is void. This change removes the definition of (1), since it does not appear to be used anywhere else in our repos (it's part of the detail namespace, so it's not public). However, this is not enough to fix the problem, since the compiler evaluates both sides of the std::conditional we use to define (2). To work around this, this change also adds a helper struct type, (AliasType) that uses template specialization on the IsMemCpy boolean to define the type that Alias will be assigned. This allows us to remove the std::conditional statement. --- .../device/detail/device_batch_memcpy.hpp | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/projects/rocprim/rocprim/include/rocprim/device/detail/device_batch_memcpy.hpp b/projects/rocprim/rocprim/include/rocprim/device/detail/device_batch_memcpy.hpp index 84198f6cbc8..569a4383900 100644 --- a/projects/rocprim/rocprim/include/rocprim/device/detail/device_batch_memcpy.hpp +++ b/projects/rocprim/rocprim/include/rocprim/device/detail/device_batch_memcpy.hpp @@ -326,6 +326,25 @@ ROCPRIM_DEVICE ROCPRIM_FORCE_INLINE static void } // namespace batch_memcpy +// This is a helper struct that defines the type used for the batch memcpy operation. +// Use template specialization on IsMemCpy is done in order to avoid using std::conditional. +// Using std::conditional can result in build errors because the compiler evaluates both sides +// of the conditional. +template +struct AliasType { }; + +template +struct AliasType +{ + using type = typename std::iterator_traits::value_type>::value_type; +}; + +template +struct AliasType +{ + using type = unsigned char; +}; + template struct batch_memcpy_impl { @@ -333,13 +352,8 @@ struct batch_memcpy_impl using output_buffer_type = typename std::iterator_traits::value_type; using buffer_size_type = typename std::iterator_traits::value_type; - using input_type = typename std::iterator_traits::value_type; - - using Alias = - typename std::conditional::value_type>::value_type>::type; + // This type is either unsigned char (if IsMemCpy is true) or the InputBufferItType's value type. + using Alias = typename AliasType::type; // Offset over buffers. using buffer_offset_type = uint32_t;