MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / BiasGradNCHW_SharedAtomics

Function BiasGradNCHW_SharedAtomics

tensorflow/core/kernels/bias_op_gpu.cu.cc:146–205  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

144
145template <typename T>
146__global__ void BiasGradNCHW_SharedAtomics(const T* output_backprop,
147 T* bias_backprop, int32 batch,
148 int32 bias_size, int32 image_size,
149 int group_size) {
150 // Initialize the shared memory.
151 typedef typename AccumulatorType<T>::type AccT;
152 const int32 kSDataSize = 32;
153 __shared__ AccT s_data[kSDataSize];
154 for (int32 index = threadIdx.x; index < kSDataSize; index += blockDim.x) {
155 s_data[index] = AccT(0);
156 }
157 __syncthreads();
158
159 // Accumulate all the values within this thread. They all have the same bias
160 // index.
161 int32 bias_index = blockIdx.x % bias_size;
162 int32 group_index = blockIdx.x / bias_size;
163 int32 total_count = batch * image_size;
164 AccT sum(0);
165 for (int32 index = group_index * blockDim.x + threadIdx.x;
166 index < total_count; index += blockDim.x * group_size) {
167 int32 image_offset = index % image_size;
168 int32 batch = index / image_size;
169 T val = ldg(output_backprop +
170 (batch * bias_size + bias_index) * image_size + image_offset);
171 sum += AccT(val);
172 }
173
174 // Write the accumulated sum in this thread to the shared memory. Each thread
175 // shifts their write location to avoid bank conflict.
176 int bias_offset = threadIdx.x % 32;
177 GpuAtomicAdd(s_data + bias_offset, sum);
178 __syncthreads();
179
180 // Accumulate the results in the shared memory into the first element.
181 // No syncthreads is needed since this is only in the same warp.
182 int32 thread_index = threadIdx.x;
183#if GOOGLE_CUDA
184 if (thread_index < 32) {
185 AccT data = s_data[thread_index];
186 for (int32 delta = warpSize / 2; delta > 0; delta /= 2) {
187 data += GpuShuffleXorSync(kCudaWarpAll, data, delta);
188 }
189 if (thread_index == 0) {
190 GpuAtomicAdd(bias_backprop + bias_index, T(data));
191 }
192 }
193#elif TENSORFLOW_USE_ROCM
194 if (thread_index < 16) s_data[thread_index] += s_data[thread_index + 16];
195 if (thread_index < 8) s_data[thread_index] += s_data[thread_index + 8];
196 if (thread_index < 4) s_data[thread_index] += s_data[thread_index + 4];
197 if (thread_index < 2) s_data[thread_index] += s_data[thread_index + 2];
198 if (thread_index < 1) s_data[thread_index] += s_data[thread_index + 1];
199
200 // The first thread writes out the accumulated result to the global location.
201 if (thread_index == 0) {
202 GpuAtomicAdd(bias_backprop + bias_index, T(s_data[0]));
203 }

Callers

nothing calls this directly

Calls 3

ldgFunction · 0.85
GpuAtomicAddFunction · 0.85
GpuShuffleXorSyncFunction · 0.85

Tested by

no test coverage detected