36#include "hip/hip_runtime.h"
37#include <hip/hip_runtime_api.h>
66__device__ cs_hip_mask_t
73#if (HIP_VERSION >= 60200000 && defined(HIP_ENABLE_WARP_SYNC_BUILTINS)) \
74 || (HIP_VERSION >= 70000000 && !defined(HIP_DISABLE_WARP_SYNC_BUILTINS))
75 return __match_any_sync(mask, v);
77 cs_hip_mask_t lanemask_eq = 1u << (threadIdx.x % CS_HIP_WARP_SIZE);
79 if (!(mask & lanemask_eq))
82 cs_hip_mask_t ref, ballot;
92#if CS_HIP_WARP_SIZE == 64
96 leader = ( mask == 0 ? -1 : __builtin_ctzll(mask) );
98 leader = __ffs(mask) - 1;
101 ref = __shfl(v, leader);
102 ballot = __ballot(v == ref);
104 if (!(ballot & lanemask_eq))
128 int laneid = __lane_id();
129 cs_hip_mask_t lanemask_lt = (1u << laneid) - 1;
130 cs_hip_mask_t lanemask_gt = -2u << laneid;
132#if CS_HIP_WARP_SIZE == 64
133 int rank = __popcll(peers & lanemask_lt);
135 int rank = __popc(peers & lanemask_lt);
138 bool is_leader = (rank == 0);
140 peers &= lanemask_gt;
142 while (__ballot(peers != 0)) {
143#if CS_HIP_WARP_SIZE == 64
144 int next = ( peers == 0 ? -1 : __builtin_ctzll(peers) ) + 1;
149 int next = __ffs(peers);
152 auto tmp = v.shuffle(mask, next - 1);
157 peers &= __ballot(!(rank & 1));
171template <
class T,
size_t...>
193 value += other.value;
199 atomicAdd(&value, other.value);
217 shuffle(cs_hip_mask_t mask,
unsigned laneid)
const noexcept
219#if HIP_VERSION >= 60200000 && defined(HIP_ENABLE_WARP_SYNC_BUILTINS)
227 __device__ cs_hip_mask_t
242 cs_hip_mask_t peers = conflict_mask(mask);
243 if (other.reduce_add(mask, peers)) {
248 __device__ inner_type &
254 __device__ inner_type
const &
260 __device__ inner_type *
266 __device__ inner_type
const *
272 __device__ inner_type &
278 __device__ inner_type
const &
297template <
class T,
size_t Head,
size_t... Tail>
312 for (
size_t i = 0; i < Head; ++i) {
313 data[i].add(other.data[i]);
320 for (
size_t i = 0; i < Head; ++i) {
321 data[i].atomic_add(other.data[i]);
329 for (
size_t i = 0; i < Head; ++i) {
330 previous.data[i] = data[i].
exchange(other.data[i]);
339 for (
size_t i = 0; i < Head; ++i) {
346 shuffle(cs_hip_mask_t mask,
unsigned laneid)
const noexcept
349 for (
size_t i = 0; i < Head; ++i) {
350 shuffled.data[i] = data[i].
shuffle(mask, laneid);
355 __device__ cs_hip_mask_t
371 if (other.reduce_add(mask, peers)) {
397 return reinterpret_cast<inner_type const &
>(*this);
429__device__
static void
433 T norm = sqrt( in[0]*in[0]
437 T inverse_norm = 1. / norm;
439 out[0] = inverse_norm * in[0];
440 out[1] = inverse_norm * in[1];
441 out[2] = inverse_norm * in[2];
458 T norm = in[0]*in[0] + in[1]*in[1] + in[2]*in[2];
__device__ cs_hip_mask_t conflict_mask(cs_hip_mask_t mask) const noexcept
Definition: cs_math_hip.h:356
__device__ bool reduce_add(cs_hip_mask_t mask, cs_hip_mask_t peers) noexcept
Definition: cs_math_hip.h:362
static __device__ assembled_value & ref(inner_type &r) noexcept
Definition: cs_math_hip.h:401
__device__ assembled_value exchange(const assembled_value &restrict other) restrict noexcept
Definition: cs_math_hip.h:326
__device__ assembled_value< T, Tail... > & operator[](size_t i) noexcept
Definition: cs_math_hip.h:377
__device__ void conflict_free_add(cs_hip_mask_t mask, assembled_value other) noexcept
Definition: cs_math_hip.h:368
static __device__ assembled_value const & ref(inner_type const &r) noexcept
Definition: cs_math_hip.h:407
__device__ void atomic_add(const assembled_value &restrict other) restrict noexcept
Definition: cs_math_hip.h:318
typename assembled_value< T, Tail... >::inner_type[Head] inner_type
Definition: cs_math_hip.h:304
__device__ inner_type const & get() const noexcept
Definition: cs_math_hip.h:395
__device__ assembled_value atomic_exchange(const assembled_value &restrict other) restrict noexcept
Definition: cs_math_hip.h:336
__device__ assembled_value< T, Tail... > const & operator[](size_t i) const noexcept
Definition: cs_math_hip.h:383
__device__ inner_type & get() noexcept
Definition: cs_math_hip.h:389
__device__ assembled_value shuffle(cs_hip_mask_t mask, unsigned laneid) const noexcept
Definition: cs_math_hip.h:346
__device__ void add(const assembled_value &restrict other) restrict noexcept
Definition: cs_math_hip.h:310
Class for value assembly using warp-based partial summation to reduce conflict occurences in downstre...
Definition: cs_math_hip.h:172
__device__ cs_hip_mask_t conflict_mask(cs_hip_mask_t mask) const noexcept
Definition: cs_math_hip.h:228
__device__ bool reduce_add(cs_hip_mask_t mask, cs_hip_mask_t peers) noexcept
Definition: cs_math_hip.h:234
static __device__ assembled_value & ref(inner_type &r) noexcept
Definition: cs_math_hip.h:285
__device__ assembled_value exchange(const assembled_value &restrict other) restrict noexcept
Definition: cs_math_hip.h:203
__device__ inner_type * operator->() noexcept
Definition: cs_math_hip.h:261
T inner_type
Definition: cs_math_hip.h:178
assembled_value() noexcept=default
__device__ void conflict_free_add(cs_hip_mask_t mask, assembled_value other) noexcept
Definition: cs_math_hip.h:240
__device__ inner_type const & operator*() const noexcept
Definition: cs_math_hip.h:255
__device__ inner_type const * operator->() const noexcept
Definition: cs_math_hip.h:267
static __device__ assembled_value const & ref(inner_type const &r) noexcept
Definition: cs_math_hip.h:291
__device__ void atomic_add(const assembled_value &restrict other) restrict noexcept
Definition: cs_math_hip.h:197
__device__ inner_type const & get() const noexcept
Definition: cs_math_hip.h:279
__device__ assembled_value atomic_exchange(const assembled_value &restrict other) restrict noexcept
Definition: cs_math_hip.h:211
__device__ inner_type & operator*() noexcept
Definition: cs_math_hip.h:249
__device__ inner_type & get() noexcept
Definition: cs_math_hip.h:273
__device__ assembled_value shuffle(cs_hip_mask_t mask, unsigned laneid) const noexcept
Definition: cs_math_hip.h:217
__device__ void add(const assembled_value &restrict other) restrict noexcept
Definition: cs_math_hip.h:191
#define restrict
Definition: cs_defs.h:148
#define CS_UNUSED(x)
Definition: cs_defs.h:518
static __device__ T cs_math_3_square_norm_hip(const T in[3])
Compute the square norm of a vector of 3 real values.
Definition: cs_math_hip.h:456
__device__ cs_hip_mask_t _conflict_mask(cs_hip_mask_t mask, V v) noexcept
Return the bit mask of the threads that have the same value v.
Definition: cs_math_hip.h:67
__device__ bool _reduce_add(cs_hip_mask_t mask, cs_hip_mask_t peers, T &v) noexcept
Reduction step for conflict-free addition.
Definition: cs_math_hip.h:124
static __device__ void cs_math_3_normalize_hip(const T in[3], T out[3])
Normalise a vector of 3 real values.
Definition: cs_math_hip.h:430