MCPcopy Create free account
hub / github.com/PaddlePaddle/Paddle / FullReductionKernel

Function FullReductionKernel

patches/eigen/TensorReductionGpu.h:134–210  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

132template <int BlockSize, int NumPerThread, typename Self,
133 typename Reducer, typename Index>
134__global__ void FullReductionKernel(Reducer reducer, const Self input, Index num_coeffs,
135 typename Self::CoeffReturnType* output, unsigned int* semaphore) {
136#if (defined(EIGEN_HIP_DEVICE_COMPILE) && defined(__HIP_ARCH_HAS_WARP_SHUFFLE__)) || (EIGEN_CUDA_ARCH >= 300)
137 // Initialize the output value
138 const Index first_index = blockIdx.x * BlockSize * NumPerThread + threadIdx.x;
139 if (gridDim.x == 1) {
140 if (first_index == 0) {
141 *output = reducer.initialize();
142 }
143 }
144 else {
145 if (threadIdx.x == 0) {
146 unsigned int block = atomicCAS(semaphore, 0u, 1u);
147 if (block == 0) {
148 // We're the first block to run, initialize the output value
149 atomicExchCustom(output, reducer.initialize());
150 __threadfence();
151 atomicExch(semaphore, 2u);
152 }
153 else {
154 // Wait for the first block to initialize the output value.
155 // Use atomicCAS here to ensure that the reads aren't cached
156 unsigned int val;
157 do {
158 val = atomicCAS(semaphore, 2u, 2u);
159 }
160 while (val < 2u);
161 }
162 }
163 }
164
165 __syncthreads();
166
167 eigen_assert(gridDim.x == 1 || *semaphore >= 2u);
168
169 typename Self::CoeffReturnType accum = reducer.initialize();
170 Index max_iter = numext::mini<Index>(num_coeffs - first_index, NumPerThread*BlockSize);
171 for (Index i = 0; i < max_iter; i+=BlockSize) {
172 const Index index = first_index + i;
173 eigen_assert(index < num_coeffs);
174 typename Self::CoeffReturnType val = input.m_impl.coeff(index);
175 reducer.reduce(val, &accum);
176 }
177
178#pragma unroll
179 for (int offset = warpSize/2; offset > 0; offset /= 2) {
180 #if defined(EIGEN_HIPCC)
181 // use std::is_floating_point to determine the type of reduced_val
182 // This is needed because when Type == double, hipcc will give a "call to __shfl_down is ambguous" error
183 // and list the float and int versions of __shfl_down as the candidate functions.
184 if (std::is_floating_point<typename Self::CoeffReturnType>::value) {
185 reducer.reduce(__shfl_down(static_cast<float>(accum), offset, warpSize), &accum);
186 } else {
187 reducer.reduce(__shfl_down(static_cast<int>(accum), offset, warpSize), &accum);
188 }
189 #elif defined(EIGEN_CUDA_SDK_VER) && EIGEN_CUDA_SDK_VER < 90000
190 reducer.reduce(__shfl_down(accum, offset, warpSize), &accum);
191 #else

Callers

nothing calls this directly

Calls 4

atomicExchCustomFunction · 0.85
atomicReduceFunction · 0.85
initializeMethod · 0.45
reduceMethod · 0.45

Tested by

no test coverage detected