kSpatialDim Class — pytorch Architecture
Architecture documentation for the kSpatialDim class in ConvPrepack.cpp from the pytorch codebase.
Entity Profile
Source Code
aten/src/ATen/native/quantized/cudnn/ConvPrepack.cpp lines 18–105
template <int kSpatialDim>
c10::intrusive_ptr<ConvPackedParamsBase<kSpatialDim>> PackedConvWeightCudnn<
kSpatialDim>::
prepack(
at::Tensor weight,
std::optional<at::Tensor> bias,
torch::List<int64_t> stride,
torch::List<int64_t> padding,
torch::List<int64_t> output_padding,
torch::List<int64_t> dilation,
int64_t groups,
bool transpose) {
// TODO: need to check out to implement groups for conv operator in Conv.cpp
TORCH_CHECK(groups == 1, "Quantized cudnn conv2d is currently limited to groups = 1; received groups =", groups);
TORCH_CHECK(weight.qscheme() == c10::kPerTensorAffine, "Unsupported qscheme: ", toString(weight.qscheme()));
TORCH_CHECK(
kSpatialDim == 2, // 1D is packed as 2d, hence we don't need other checks
"cuDNN packing only supports 2D convolution.");
TORCH_CHECK(
weight.ndimension() == kSpatialDim + 2,
"Weights are expected to have ",
kSpatialDim + 2,
" dimensions");
TORCH_CHECK(
stride.size() == kSpatialDim,
"stride should contain ",
kSpatialDim,
" elements for ",
kSpatialDim,
"D convolution.");
TORCH_CHECK(
padding.size() == kSpatialDim,
"quantized::conv_prepack (cudnn): Specify front/top/left padding only. "
"end/bottom/right padding assumed to be equal to front/top/left");
TORCH_CHECK(
!transpose || output_padding.size() == kSpatialDim,
"quantized::conv_prepack: Specify top/left output padding "
"only. bottom/right padding assumed to be equal to top/left");
TORCH_CHECK(
dilation.size() == kSpatialDim,
"quantized::conv_prepack (cudnn): dilation should contain ",
kSpatialDim,
" elements for ",
kSpatialDim,
"D convolution.");
TORCH_CHECK(!transpose, "cudNN quantized conv prepack expects transpose = false")
const auto num_unpadded_output_channels = weight.size(0);
const auto qtype = weight.qscheme();
if (bias.has_value()) {
TORCH_CHECK(bias.value().dim() == 1, "bias should be a vector (1D Tensor)");
TORCH_CHECK(
bias.value().size(0) == num_unpadded_output_channels,
"bias should have K elements: " + std::to_string(num_unpadded_output_channels));
// TODO: we create a broadcasted_bias tensor later so I think we don't need to make this contiguous here.
// we will revisit this when nvidia adds proper support for broadcasting
// bias_contig = bias->contiguous();
}
// cudnn v8.4.0 expects conv2d's int8 weight tensor's input and output channels to be a multiple of 4. if it is not
// we need to explicitly pad it to a multiple of 4 ourselves as cudnn does not currently support padding.
// TODO: when and if cudnn enables padding in their operators, we can remove padding on our end;
// currently, limit padding support to groups=1 (ungrouped conv)
// TODO: implement this for groups > 1
auto num_input_channels = weight.size(1);
auto num_output_slices2pad = (4 - num_unpadded_output_channels % 4) % 4;
auto num_input_slices2pad = (4 - num_input_channels % 4) % 4;
if (num_output_slices2pad != 0 || num_input_slices2pad != 0) {
// the second argument is an initializer list of padded values. there are 2 values for each dimension.
// refer to https://pytorch.org/docs/stable/generated/torch.nn.functional.pad.html for more details
weight = at::pad(weight, {0, 0, 0, 0, 0, num_input_slices2pad, 0, num_output_slices2pad}, "constant", 0);
if (bias.has_value()) {
bias.value() = at::pad(bias.value(), {0, num_output_slices2pad}, "constant", 0);
}
}
auto ret_ptr = c10::make_intrusive<PackedConvWeightCudnn<kSpatialDim>>(
weight.to(c10::MemoryFormat::ChannelsLast), // TODO: this assumes 2D I think. make it more general?
std::move(bias),
stride,
padding,
output_padding,
dilation,
groups,
transpose,
qtype,
num_unpadded_output_channels);
return ret_ptr;
}
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free