24#ifndef GPU_CUDA_RUSUCTION_OPERATORS_HH
25#define GPU_CUDA_RUSUCTION_OPERATORS_HH
29#include <cooperative_groups.h>
30#include <cooperative_groups/reduce.h>
43 __device__
inline operator T*()
45 extern __shared__
int __smem[];
49 __device__
inline operator const T*()
const
51 extern __shared__
int __smem[];
60 __device__
inline operator double*()
62 extern __shared__
double __smem_d[];
63 return (
double*)__smem_d;
66 __device__
inline operator const double*()
const
68 extern __shared__
double __smem_d[];
69 return (
double*)__smem_d;
75template <
typename T,
typename DESCRIPTOR,
typename REDUCTION_OP,
typename CONDITION>
79 namespace cg = cooperative_groups;
82 cg::thread_block cta = cg::this_thread_block();
87 unsigned int tid = threadIdx.x;
88 CellID iCell = blockIdx.x * (blockDim.x * 2) + threadIdx.x;
91 T mySum = (iCell < size) && mask(cell) && (cell.template getField<field::reduction::TAG_CORE>() == (int)1)
96 if (iCell + blockDim.x < size) {
99 if (mask(cell2) && (cell2.template getField<field::reduction::TAG_CORE>() == (
int)1)) {
100 mySum = REDUCTION_OP {}(mySum, thrust::raw_pointer_cast(field)[iCell + blockDim.x]);
107 for (
unsigned int stride = blockDim.x / 2; stride > 0; stride >>= 1) {
109 sdata[tid] = mySum = REDUCTION_OP {}(mySum, sdata[tid + stride]);
117 g_odata[blockIdx.x] = mySum;
121template <
typename T,
typename REDUCTION_OP>
124 namespace cg = cooperative_groups;
125 cg::thread_block cta = cg::this_thread_block();
128 unsigned int tid = threadIdx.x;
129 unsigned int i = threadIdx.x + blockDim.x * blockIdx.x;
133 for (
int idx = i; idx < partialCount; idx += blockDim.x) {
134 mySum = REDUCTION_OP {}(mySum, partialSums[idx]);
139 for (
unsigned int stride = blockDim.x / 2; stride > 0; stride >>= 1) {
141 sdata[tid] = mySum = REDUCTION_OP{}(mySum, sdata[tid + stride]);
147 d_result[0] = sdata[0];
152template <
typename T,
typename DESCRIPTOR,
typename REDUCTION_OP,
typename CONDITION>
159 const auto block_size = 32;
160 const auto block_count = (nCells + (block_size * 2) - 1) / (block_size * 2);
162 thrust::device_vector<T> d_partial(block_count, (T)0.0);
165 devPtr, thrust::raw_pointer_cast(d_partial.data()), lattice, nCells);
169 thrust::raw_pointer_cast(d_partial.data()), block_count, paramInDevice);
175template <
typename FIELD,
typename REDUCTION_OP,
typename CONDITION>
176template <
typename T,
typename DESCRIPTOR>
177void BlockLatticeFieldReductionO<FIELD, REDUCTION_OP, CONDITION>::type<ConcreteBlockLattice<
180 blockLattice.template getData<OperatorParameters<BlockLatticeFieldReductionO>>();
183template <
typename FIELD,
typename REDUCTION_OP,
typename CONDITION>
184template <
typename T,
typename DESCRIPTOR>
188 auto&
parameters = blockLattice.template getData<OperatorParameters<BlockLatticeFieldReductionO>>().
parameters;
189 const auto& blockField = blockLattice.template getField<FIELD>();
192 parameters.template get<fields::array_of<FIELD>>();
203 for (
unsigned iD = 0; iD < blockField.d; iD++) {
204 cudaPointerAttributes attributes;
205 cudaError_t error = cudaPointerGetAttributes(&attributes, elementField[iD]);
206 if (error == cudaSuccess) {
207 if (attributes.devicePointer !=
nullptr) {
209 else if (attributes.hostPointer !=
nullptr) {
210 std::cout <<
"elementField is on the host" << std::endl;
214 std::cerr <<
"Error in cudaPointerGetAttributes: " << cudaGetErrorString(error) << std::endl;
216 auto devPtr = thrust::device_pointer_cast(
217 blockField[iD].deviceData());
218 if (devPtr ==
nullptr) {
219 std::cerr <<
"Invalid device pointer at index " << iD << std::endl;
Implementation of BlockLattice on a concrete PLATFORM.
Device-side implementation of the Cell concept for post processors.
Device-side view of a block lattice.
std::size_t getNcells() const any_platform
void check()
Check errors.
Top level namespace for all of OpenLB.
void reduceKernelInBlock(thrust::device_ptr< const T > field, T *g_odata, gpu::cuda::DeviceBlockLattice< T, DESCRIPTOR > lattice, CellID size) __global__
ref: https://github.com/NVIDIA/cuda-samples/blob/master/Samples/2_Concepts_and_Techniques/reduction/r...
std::uint32_t CellID
Type for sequential block-local cell indices.
void reductionFunctionDevice(thrust::device_ptr< const T > devPtr, ConcreteBlockLattice< T, DESCRIPTOR, Platform::GPU_CUDA > &blockLattice, T *paramInDevice)
void reduceKernelInGrid(const T *partialSums, int partialCount, T *d_result) __global__
@ GPU_CUDA
Vector CPU (AVX2 / AVX-512 collision)