Repository navigation
feat(hipdnn): add GPU batchnorm backward reference #12520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
BalintCsala
merged 10 commits into
ROCm:develop
from
StreamHPC:users/BalintCsala/batchnorm-backward-gpu-ref
Oct 9, 2026
Merged
Changes from 1 commit
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
446477c
feat(hipdnn): add GPU batchnorm backward reference
90cc000
PR responses
2cfcd6b
PR comments
5e22fd5
Remove redundant barrier
f0c156f
Merge branch 'develop' into users/BalintCsala/batchnorm-backward-gpu-ref
BalintCsala a78b447
Fix build issue
d1d7327
More change requests
2ea24fc
Merge branch 'develop' into users/BalintCsala/batchnorm-backward-gpu-ref
BalintCsala b060e07
Merge branch 'develop' into users/BalintCsala/batchnorm-backward-gpu-ref
BalintCsala 0a4d94f
Merge branch 'develop' into users/BalintCsala/batchnorm-backward-gpu-ref
BalintCsala File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
dnn-providers/integration-tests/gpu-ref/kernels/batchnorm/GpuRefBatchnormBwd.cpp
|
BalintCsala marked this conversation as resolved.
Resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| // Copyright © Advanced Micro Devices, Inc., or its affiliates. | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| // GPU reference Batchnorm backward kernel. | ||
| // Compiled via HipRTC with all tensor and compute types supplied as preprocessor defines. | ||
| // Each block handles one channel and reduces over its N*spatial elements. | ||
|
|
||
| #include "GpuRefTypes.h" | ||
|
|
||
| using namespace gpu_ref; | ||
|
|
||
| extern "C" __global__ void BatchnormBwdRef(BatchnormBwdArgs args) | ||
| { | ||
| auto* dy = static_cast<const GRAD_OUTPUT_TYPE*>(args.dy); | ||
| auto* input = static_cast<const INPUT_TYPE*>(args.input); | ||
| auto* scale = static_cast<const SCALE_BIAS_TYPE*>(args.scale); | ||
| auto* dx = static_cast<GRAD_INPUT_TYPE*>(args.dx); | ||
| auto* dscale = static_cast<SCALE_BIAS_TYPE*>(args.dscale); | ||
| auto* dbias = static_cast<SCALE_BIAS_TYPE*>(args.dbias); | ||
| auto* savedMean = static_cast<const MEAN_VAR_TYPE*>(args.mean); | ||
| auto* savedInvVariance = static_cast<const MEAN_VAR_TYPE*>(args.invVariance); | ||
|
|
||
| constexpr long long localSize = static_cast<long long>(LOCAL_SIZE); | ||
| constexpr bool isChannelLastLayout = static_cast<bool>(IS_CHANNEL_LAST_LAYOUT); | ||
| const long long channel = static_cast<long long>(blockIdx.x); | ||
| const long long lid = static_cast<long long>(threadIdx.x); | ||
| const long long nhw = args.n * args.hw; | ||
| const long long chw = args.c * args.hw; | ||
| const COMPUTE_TYPE invNhw = static_cast<COMPUTE_TYPE>(1.0) / static_cast<COMPUTE_TYPE>(nhw); | ||
|
|
||
| __shared__ COMPUTE_TYPE reduceA[localSize]; | ||
| __shared__ COMPUTE_TYPE reduceB[localSize]; | ||
|
|
||
| COMPUTE_TYPE channelMean; | ||
| COMPUTE_TYPE channelInvVariance; | ||
| if(savedMean == nullptr) | ||
|
BalintCsala marked this conversation as resolved.
Resolved
|
||
| { | ||
| COMPUTE_TYPE sum = static_cast<COMPUTE_TYPE>(0); | ||
| COMPUTE_TYPE squareSum = static_cast<COMPUTE_TYPE>(0); | ||
| for(long long i = lid; i < nhw; i += localSize) | ||
| { | ||
| const long long nidx = i / args.hw; | ||
| const long long hwidx = i - nidx * args.hw; | ||
| const long long index = isChannelLastLayout ? nidx * chw + hwidx * args.c + channel | ||
| : nidx * chw + channel * args.hw + hwidx; | ||
| const COMPUTE_TYPE xValue = toAccum(input[index]); | ||
| sum = sum + xValue; | ||
| squareSum = squareSum + xValue * xValue; | ||
| } | ||
|
|
||
| reduceA[lid] = sum; | ||
| reduceB[lid] = squareSum; | ||
| __syncthreads(); | ||
| for(long long offset = localSize >> 1; offset > 0; offset >>= 1) | ||
| { | ||
| if(lid < offset) | ||
| { | ||
| reduceA[lid] = reduceA[lid] + reduceA[lid + offset]; | ||
| reduceB[lid] = reduceB[lid] + reduceB[lid + offset]; | ||
| } | ||
| __syncthreads(); | ||
| } | ||
|
|
||
| channelMean = reduceA[0] * invNhw; | ||
| COMPUTE_TYPE variance = reduceB[0] * invNhw - channelMean * channelMean; | ||
| if(variance < static_cast<COMPUTE_TYPE>(0)) | ||
|
BalintCsala marked this conversation as resolved.
Resolved
|
||
| { | ||
| variance = static_cast<COMPUTE_TYPE>(0); | ||
| } | ||
| channelInvVariance = rsqrt(variance + toAccum(args.epsilon)); | ||
| } | ||
| else | ||
| { | ||
| channelMean = toAccum(savedMean[channel]); | ||
| channelInvVariance = toAccum(savedInvVariance[channel]); | ||
| } | ||
|
|
||
| COMPUTE_TYPE dotProduct = static_cast<COMPUTE_TYPE>(0); | ||
| COMPUTE_TYPE sumDy = static_cast<COMPUTE_TYPE>(0); | ||
| for(long long i = lid; i < nhw; i += localSize) | ||
| { | ||
| const long long nidx = i / args.hw; | ||
| const long long hwidx = i - nidx * args.hw; | ||
| const long long index = isChannelLastLayout ? nidx * chw + hwidx * args.c + channel | ||
| : nidx * chw + channel * args.hw + hwidx; | ||
| const COMPUTE_TYPE xValue = toAccum(input[index]); | ||
| const COMPUTE_TYPE dyValue = toAccum(dy[index]); | ||
| const COMPUTE_TYPE xHat = (xValue - channelMean) * channelInvVariance; | ||
| dotProduct = dotProduct + xHat * dyValue; | ||
| sumDy = sumDy + dyValue; | ||
| } | ||
|
|
||
| reduceA[lid] = dotProduct; | ||
|
BalintCsala marked this conversation as resolved.
Resolved
|
||
| reduceB[lid] = sumDy; | ||
| __syncthreads(); | ||
| for(long long offset = localSize >> 1; offset > 0; offset >>= 1) | ||
| { | ||
| if(lid < offset) | ||
| { | ||
| reduceA[lid] = reduceA[lid] + reduceA[lid + offset]; | ||
| reduceB[lid] = reduceB[lid] + reduceB[lid + offset]; | ||
| } | ||
| __syncthreads(); | ||
| } | ||
|
|
||
| const COMPUTE_TYPE channelScale = toAccum(scale[channel]); | ||
| const COMPUTE_TYPE meanDyXhat = reduceA[0] * invNhw; | ||
| const COMPUTE_TYPE meanDy = reduceB[0] * invNhw; | ||
| const COMPUTE_TYPE scalarCoefficient = channelScale * channelInvVariance; | ||
|
|
||
| if(lid == 0) | ||
| { | ||
| SCALE_BIAS_TYPE* tag = nullptr; | ||
| dscale[channel] = fromAccum(reduceA[0], tag); | ||
| dbias[channel] = fromAccum(reduceB[0], tag); | ||
| } | ||
|
|
||
| GRAD_INPUT_TYPE* tag = nullptr; | ||
| for(long long i = lid; i < nhw; i += localSize) | ||
| { | ||
| const long long nidx = i / args.hw; | ||
| const long long hwidx = i - nidx * args.hw; | ||
| const long long index = isChannelLastLayout ? nidx * chw + hwidx * args.c + channel | ||
| : nidx * chw + channel * args.hw + hwidx; | ||
| const COMPUTE_TYPE xValue = toAccum(input[index]); | ||
| const COMPUTE_TYPE dyValue = toAccum(dy[index]); | ||
| const COMPUTE_TYPE xHat = (xValue - channelMean) * channelInvVariance; | ||
| const COMPUTE_TYPE dxValue = (dyValue - meanDy - xHat * meanDyXhat) * scalarCoefficient; | ||
| dx[index] = fromAccum(dxValue, tag); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.