function [dZ, dOffset, dScale] = internal_groupnormBackward(dZ, X, scale, numGroups, epsilon, channelDim)
% This function is undocumented and will change in a future release.

%   [dX, dOffset, dScale] = internal_groupnormBackward(dZ, X, scale, numGroups, epsilon, channelDim)
%   Compute adjoints for group normalization.
%
%   Inputs:
%     dZ              Adjoint of forward result. Shape is only non-trivial in channel dimension.
%                     numeric array
%     X               Batch data.
%                     numeric array
%     scale           Scale. Also called gamma. Shape is only non-trivial in channel dimension.
%                     numeric array
%     numGroups       Number of groups.
%                     double
%     epsilon         Constant to avoid division by zero.
%                     numeric scalar
%     channelDim      Channel dimension.
%                     double
%
%   Outputs:
%     dX              Adjoint of X. Shape is same as X.
%                     numeric array
%     dOffset         Adjoint of offset. Shape is same as offset.
%                     numeric array
%     dScale          Adjoint of scale. Shape is same as scale.
%                     numeric array

%   Copyright 2020-2021 The MathWorks, Inc.

if ~isreal(dZ)
    error(message('deep:dlarray:ComplexGradientOutput', 'groupnorm'));
end

[dZ, dOffset, dScale] = nnet.internal.cnnhost.groupNormalizationBackward(...
    dZ, X, scale, epsilon, channelDim, numGroups);

end
