17#include "../global/global.h"
18#include "../global/global_cuda.h"
19#include "../utils/gpu.hpp"
21namespace reduction_utilities::backport
31template <
class To,
class From>
32__device__
constexpr To
bit_cast(
const From& from)
noexcept
36 static_assert(
sizeof(To) ==
sizeof(From));
37 memcpy(&to, &from,
sizeof(To));
48inline long long __device__
atomicMin(
long long* address,
long long val)
51 unsigned long long* address_as_ull = (
unsigned long long*)address;
52 unsigned long long old = *address_as_ull;
53 unsigned long long assumed;
57 long long assumed_LL = bit_cast<long long>(assumed);
58 long long newval_LL = (assumed_LL < val) ? assumed_LL : val;
59 old = atomicCAS(address_as_ull, assumed, bit_cast<long long>(newval_LL));
61 }
while (assumed != old);
63 return bit_cast<long long>(old);
68#if defined(O_HIP) && (HIP_VERSION < 50700000)
73using ::reduction_utilities::backport::atomicMin;
96 for (
int offset = warpSize / 2; offset > 0; offset /= 2) {
97 val = max(val, __shfl_down(val, offset));
116 __shared__ Real shared[::maxWarpsPerBlock];
118 int lane = threadIdx.x % warpSize;
119 int warpId = threadIdx.x / warpSize;
124 shared[warpId] = val;
130 val = (threadIdx.x < blockDim.x / warpSize) ? shared[lane] : 0;
157 int i = backport::bit_cast<int>(val);
158 return i >= 0 ? i : (1 << 31) | ~i;
167inline __device__
long long encode(
double val)
169 auto i = backport::bit_cast<std::int64_t>(val);
170 return i >= 0 ? i : (1ULL << 63) | ~i;
182 val = (1 << 31) | ~val;
184 return backport::bit_cast<float>(val);
193inline __device__
double decode(
long long val)
196 val = (1ULL << 63) | ~val;
198 return backport::bit_cast<double>(val);
210inline __device__ float atomicMaxBits(float* address, float val)
213 return atomicMax(address, val);
215 int old = atomicMax((
int*)address,
encode(val));
232 return atomicMax(address, val);
234 long long old = atomicMax((
long long*)address,
encode(val));
251 return atomicMin(address, val);
253 int old = atomicMin((
int*)address,
encode(val));
270 return atomicMin(address, val);
272 long long old = atomicMin((
long long*)address,
encode(val));
320 if (threadIdx.x == 0) {
363template <std::
size_t N, std::
size_t Blocksize>
364__device__
void blockAccumulateIntoNReals(Real* __restrict__ dest, Real* __restrict__ src_shared)
368 for (
unsigned int s = blockDim.x / 2; s > 0; s >>= 1) {
369 if (threadIdx.x < s) {
370 for (
unsigned int cur_ind = 0; cur_ind < N; cur_ind++) {
371 src_shared[N * threadIdx.x + cur_ind] += src_shared[N * (threadIdx.x + s) + cur_ind];
378 if (threadIdx.x == 0) {
379 for (
unsigned int cur_ind = 0; cur_ind < N; cur_ind++) {
380 atomicAdd(dest + cur_ind,
381 src_shared[cur_ind]);
Namespace to contain device resident reduction functions. Includes functions and kernels for array re...
Definition reduction_utilities.cu:17
__device__ float atomicMinBits(float *address, float val)
Perform an atomic reduction to find the minimum value of val
Definition reduction_utilities.h:248
__device__ float decode(int val)
Decodes an int as a float.
Definition reduction_utilities.h:179
__device__ void gridReduceMax(Real val, Real *out)
Perform a reduction within the grid to find the maximum value of val. Note that the value of out shou...
Definition reduction_utilities.h:314
__device__ Real warpReduceMax(Real val)
Perform a reduction within the warp/wavefront to find the maximum value of val
Definition reduction_utilities.h:94
__device__ float atomicMaxBits(float *address, float val)
Perform an atomic reduction to find the maximum value of val
Definition reduction_utilities.h:210
__device__ int encode(float val)
Encode a float as an int.
Definition reduction_utilities.h:155
__global__ void kernelReduceMax(Real *in, Real *out, size_t N)
Find the maximum value in the array. Make sure to initialize out correctly before using this kernel; ...
Definition reduction_utilities.cu:19
__device__ Real blockReduceMax(Real val)
Perform a reduction within the block to find the maximum value of val
Definition reduction_utilities.h:112
long long __device__ atomicMin(long long *address, long long val)
Perform an atomic reduction to find the minimum value of val
Definition reduction_utilities.h:48
__device__ constexpr To bit_cast(const From &from) noexcept
Do a device side bit cast.
Definition reduction_utilities.h:32