| 172 | // Reduces each block by key |
| 173 | template<typename Ti, typename Tk, typename To, af_op_t op, uint DIMX> |
| 174 | __global__ static void reduce_blocks_by_key(int *reduced_block_sizes, |
| 175 | Param<Tk> reduced_keys, |
| 176 | Param<To> reduced_vals, |
| 177 | CParam<Tk> keys, CParam<Ti> vals, |
| 178 | int n, bool change_nan, To nanval, |
| 179 | const int nBlocksZ) { |
| 180 | const int tidx = blockIdx.x * blockDim.x + threadIdx.x; |
| 181 | const int bidy = blockIdx.y; |
| 182 | const int bidz = blockIdx.z % nBlocksZ; |
| 183 | const int bidw = blockIdx.z / nBlocksZ; |
| 184 | |
| 185 | const int laneid = tidx % 32; |
| 186 | |
| 187 | const int nWarps = DIMX / 32; |
| 188 | |
| 189 | // |
| 190 | // Allocate and initialize shared memory |
| 191 | |
| 192 | __shared__ int |
| 193 | warpReduceSizes[nWarps]; // number of reduced elements in each warp |
| 194 | |
| 195 | __shared__ compute_t<Tk> warpReduceKeys[nWarps] |
| 196 | [maxResPerWarp]; // reduced key |
| 197 | // segments for |
| 198 | // each warp |
| 199 | __shared__ compute_t<To> warpReduceVals[nWarps] |
| 200 | [maxResPerWarp]; // reduced values |
| 201 | // for each warp |
| 202 | // corresponding to |
| 203 | // each key segment |
| 204 | |
| 205 | // space to hold left/right-most keys of each reduced warp to check if |
| 206 | // reduction should happen across boundaries |
| 207 | __shared__ compute_t<Tk> warpReduceLeftBoundaryKeys[nWarps]; |
| 208 | __shared__ compute_t<Tk> warpReduceRightBoundaryKeys[nWarps]; |
| 209 | |
| 210 | // space to hold right-most values of each reduced warp to check if |
| 211 | // reduction should happen across boundaries |
| 212 | __shared__ compute_t<To> warpReduceRightBoundaryVals[nWarps]; |
| 213 | |
| 214 | // space to compact and finalize all reductions within block |
| 215 | __shared__ compute_t<Tk> warpReduceKeysSmemFinal[nWarps * maxResPerWarp]; |
| 216 | __shared__ compute_t<To> warpReduceValsSmemFinal[nWarps * maxResPerWarp]; |
| 217 | |
| 218 | // |
| 219 | // will hold final number of reduced elements in block |
| 220 | __shared__ int reducedBlockSize; |
| 221 | |
| 222 | if (threadIdx.x == 0) { reducedBlockSize = 0; } |
| 223 | if (threadIdx.x < nWarps * maxResPerWarp) |
| 224 | warpReduceValsSmemFinal[threadIdx.x] = scalar<compute_t<To>>(0); |
| 225 | __syncthreads(); |
| 226 | |
| 227 | common::Binary<compute_t<To>, op> reduce; |
| 228 | common::Transform<compute_t<Ti>, compute_t<To>, op> transform; |
| 229 | |
| 230 | // load keys and values to threads |
| 231 | compute_t<Tk> k; |
nothing calls this directly
no test coverage detected