MCPcopy Create free account
hub / github.com/NVIDIA/TensorRT / parallelSums_8x4

Function parallelSums_8x4

plugin/instanceNormalizationPlugin/instanceNormCommon.h:550–611  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

548
549template <int32_t THREADS_PER_CTA>
550static inline __device__ void parallelSums_8x4(float* smem, float (&x)[4], int32_t nhw)
551{
552 // The size of a warp.
553 int32_t const THREADS_PER_WARP = 32;
554 // The number of warps in a CTA.
555 int32_t const WARPS_PER_CTA = THREADS_PER_CTA / THREADS_PER_WARP;
556 // The number of threads per pixel.
557 int32_t const THREADS_PER_PIXEL = 8;
558 // The number of elements per ldg.
559 int32_t const ELEMENTS_PER_LDG = 4;
560 // The warp decomposition.
561 int32_t const warp_id = threadIdx.x / THREADS_PER_WARP;
562 int32_t const lane_id = threadIdx.x % THREADS_PER_WARP;
563
564#pragma unroll
565 for (int32_t i = 0; i < ELEMENTS_PER_LDG; ++i)
566 {
567 x[i] += __shfl_sync(0xffffffffU, x[i], THREADS_PER_PIXEL + lane_id);
568 x[i] += __shfl_sync(0xffffffffU, x[i], THREADS_PER_PIXEL * 2 + lane_id);
569 }
570
571 // The warp leaders, write to SMEM.
572 if (lane_id < THREADS_PER_PIXEL)
573 {
574 writeToSmem(smem, warp_id * THREADS_PER_PIXEL + lane_id, x);
575 }
576
577 // The data is in SMEM. Do the final reduction.
578 __syncthreads();
579
580 // The 1st warp does all the work.
581 // We do the final reduction each half-warp sequentially reduces the final values.
582 if (warp_id == 0)
583 {
584 readFromSmem(x, smem, threadIdx.x);
585
586#pragma unroll
587 for (int32_t offset = 1; offset < WARPS_PER_CTA / (THREADS_PER_WARP / THREADS_PER_PIXEL); ++offset)
588 {
589 float y[ELEMENTS_PER_LDG];
590 // Read the mean and variance from the other pixel.
591 readFromSmem(y, smem, threadIdx.x + offset * THREADS_PER_WARP);
592 // Compute the updated sum.
593 add(x, y);
594 }
595
596 for (int32_t i = 0; i < ELEMENTS_PER_LDG; ++i)
597 {
598 x[i] += __shfl_sync(0xffffffffU, x[i], THREADS_PER_PIXEL + lane_id);
599 x[i] += __shfl_sync(0xffffffffU, x[i], THREADS_PER_PIXEL * 2 + lane_id);
600 }
601
602 // Make sure the data was read from SMEM.
603 __syncwarp();
604
605 // Store the final values.
606 if (threadIdx.x < THREADS_PER_PIXEL)
607 {

Callers

nothing calls this directly

Calls 3

writeToSmemFunction · 0.85
readFromSmemFunction · 0.85
addFunction · 0.70

Tested by

no test coverage detected