1#ifndef CS_CUDA_REDUCE_H
2#define CS_CUDA_REDUCE_H
55#if defined(__CUDACC__)
70template <
size_t blockSize,
size_t str
ide,
typename T>
71__device__
static void __forceinline__
72cs_cuda_reduce_warp_reduce_sum(
volatile T *stmp,
77 if (blockSize >= 64) stmp[tid] += stmp[tid + 32];
78 if (blockSize >= 32) stmp[tid] += stmp[tid + 16];
79 if (blockSize >= 16) stmp[tid] += stmp[tid + 8];
80 if (blockSize >= 8) stmp[tid] += stmp[tid + 4];
81 if (blockSize >= 4) stmp[tid] += stmp[tid + 2];
82 if (blockSize >= 2) stmp[tid] += stmp[tid + 1];
87 if (blockSize >= 64) {
89 for (
size_t i = 0; i < stride; i++)
90 stmp[tid*stride + i] += stmp[(tid + 32)*stride + i];
92 if (blockSize >= 32) {
94 for (
size_t i = 0; i < stride; i++)
95 stmp[tid*stride + i] += stmp[(tid + 16)*stride + i];
97 if (blockSize >= 16) {
99 for (
size_t i = 0; i < stride; i++)
100 stmp[tid*stride + i] += stmp[(tid + 8)*stride + i];
102 if (blockSize >= 8) {
104 for (
size_t i = 0; i < stride; i++)
105 stmp[tid*stride + i] += stmp[(tid + 4)*stride + i];
107 if (blockSize >= 4) {
109 for (
size_t i = 0; i < stride; i++)
110 stmp[tid*stride + i] += stmp[(tid + 2)*stride + i];
112 if (blockSize >= 2) {
114 for (
size_t i = 0; i < stride; i++)
115 stmp[tid*stride + i] += stmp[(tid + 1)*stride + i];
140template <
size_t blockSize,
size_t str
ide,
typename T>
141__device__
static void __forceinline__
142cs_cuda_reduce_block_reduce_sum(T *stmp,
152 if (blockSize >= 1024) {
154 stmp[tid] += stmp[tid + 512];
158 if (blockSize >= 512) {
160 stmp[tid] += stmp[tid + 256];
164 if (blockSize >= 256) {
166 stmp[tid] += stmp[tid + 128];
169 if (blockSize >= 128) {
171 stmp[tid] += stmp[tid + 64];
176 cs_cuda_reduce_warp_reduce_sum<blockSize, stride>(stmp, tid);
181 if (tid == 0) sum_block[blockIdx.x] = stmp[0];
187 if (blockSize >= 1024) {
190 for (
size_t i = 0; i < stride; i++)
191 stmp[tid*stride + i] += stmp[(tid + 512)*stride + i];
195 if (blockSize >= 512) {
198 for (
size_t i = 0; i < stride; i++)
199 stmp[tid*stride + i] += stmp[(tid + 256)*stride + i];
203 if (blockSize >= 256) {
206 for (
size_t i = 0; i < stride; i++)
207 stmp[tid*stride + i] += stmp[(tid + 128)*stride + i];
210 if (blockSize >= 128) {
213 for (
size_t i = 0; i < stride; i++)
214 stmp[tid*stride + i] += stmp[(tid + 64)*stride + i];
219 cs_cuda_reduce_warp_reduce_sum<blockSize, stride>(stmp, tid);
225 for (
size_t i = 0; i < stride; i++)
226 sum_block[(blockIdx.x)*stride + i] = stmp[i];
244template <
size_t blockSize,
size_t str
ide,
typename T>
245__global__
static void
246cs_cuda_reduce_sum_single_block(
size_t n,
250 __shared__ T sdata[blockSize * stride];
252 size_t tid = threadIdx.x;
260 for (
size_t i = threadIdx.x; i < n; i+= blockSize)
261 r_s[0] += g_idata[i];
266 for (
size_t j = blockSize/2; j > CS_CUDA_WARP_SIZE; j /= 2) {
268 sdata[tid] += sdata[tid + j];
273 if (tid < 32) cs_cuda_reduce_warp_reduce_sum<blockSize, stride>(sdata, tid);
274 if (tid == 0) *g_odata = sdata[0];
280 for (
size_t k = 0;
k < stride;
k++) {
282 sdata[tid*stride +
k] = 0.;
285 for (
size_t i = threadIdx.x; i < n; i+= blockSize) {
287 for (
size_t k = 0;
k < stride;
k++) {
288 r_s[
k] += g_idata[i*stride +
k];
293 for (
size_t k = 0;
k < stride;
k++)
294 sdata[tid*stride +
k] = r_s[
k];
297 for (
size_t j = blockSize/2; j > CS_CUDA_WARP_SIZE; j /= 2) {
300 for (
size_t k = 0;
k < stride;
k++)
301 sdata[tid*stride +
k] += sdata[(tid + j)*stride +
k];
306 if (tid < 32) cs_cuda_reduce_warp_reduce_sum<blockSize, stride>(sdata, tid);
309 for (
size_t k = 0;
k < stride;
k++)
310 g_odata[
k] = sdata[
k];
329template <
size_t blockSize,
typename R,
typename T>
330__device__
static void __forceinline__
331cs_cuda_reduce_warp_reduce(
volatile T *stmp,
336 if (blockSize >= 64) reducer.combine(stmp[tid], stmp[tid + 32]);
337 if (blockSize >= 32) reducer.combine(stmp[tid], stmp[tid + 16]);
338 if (blockSize >= 16) reducer.combine(stmp[tid], stmp[tid + 8]);
339 if (blockSize >= 8) reducer.combine(stmp[tid], stmp[tid + 4]);
340 if (blockSize >= 4) reducer.combine(stmp[tid], stmp[tid + 2]);
341 if (blockSize >= 2) reducer.combine(stmp[tid], stmp[tid + 1]);
361template <
size_t blockSize,
typename R,
typename T>
362__device__
static void __forceinline__
363cs_cuda_reduce_block_reduce(T *stmp,
372 if (blockSize >= 1024) {
374 reducer.combine(stmp[tid], stmp[tid + 512]);
378 if (blockSize >= 512) {
380 reducer.combine(stmp[tid], stmp[tid + 256]);
384 if (blockSize >= 256) {
386 reducer.combine(stmp[tid], stmp[tid + 128]);
389 if (blockSize >= 128) {
391 reducer.combine(stmp[tid], stmp[tid + 64]);
396 cs_cuda_reduce_warp_reduce<blockSize, R>(stmp, tid);
401 if (tid == 0) rd_block[blockIdx.x] = stmp[0];
418template <
size_t blockSize,
typename R,
typename T>
419__global__
static void
420cs_cuda_reduce_single_block(
size_t n,
424 extern __shared__
int p_stmp[];
425 T *sdata =
reinterpret_cast<T *
>(p_stmp);
428 size_t tid = threadIdx.x;
431 reducer.identity(r_s[0]);
432 reducer.identity(sdata[tid]);
434 for (
size_t i = threadIdx.x; i < n; i+= blockSize)
435 reducer.combine(r_s[0], g_idata[i]);
440 for (
size_t j = blockSize/2; j > CS_CUDA_WARP_SIZE; j /= 2) {
442 reducer.combine(sdata[tid], sdata[tid + j]);
447 if (tid < 32) cs_cuda_reduce_warp_reduce<blockSize, R>(sdata, tid);
448 if (tid == 0) *g_odata = sdata[0];
@ k
Definition: cs_field_pointer.h:68