MCPcopy Create free account
hub / github.com/pytorch/executorch / quantized_conv2d_impl

Function quantized_conv2d_impl

backends/cortex_m/ops/operators.py:752–812  ·  view source on GitHub ↗
(
    input: torch.Tensor,
    weight: torch.Tensor,
    bias: torch.Tensor | None,
    stride: Sequence[int],
    padding: Sequence[int],
    dilation: Sequence[int],
    input_offset: int,
    output_offset: int,
    requantize_multipliers: torch.Tensor,
    requantize_shifts: torch.Tensor,
    activation_min: int,
    activation_max: int,
)

Source from the content-addressed store, hash-verified

750
751@impl(lib, "quantized_conv2d", "CompositeExplicitAutograd") # type: ignore[misc]
752def quantized_conv2d_impl(
753 input: torch.Tensor,
754 weight: torch.Tensor,
755 bias: torch.Tensor | None,
756 stride: Sequence[int],
757 padding: Sequence[int],
758 dilation: Sequence[int],
759 input_offset: int,
760 output_offset: int,
761 requantize_multipliers: torch.Tensor,
762 requantize_shifts: torch.Tensor,
763 activation_min: int,
764 activation_max: int,
765) -> torch.Tensor:
766 if input.dim() != 4 or weight.dim() != 4:
767 raise RuntimeError("quantized_conv2d expects 4D input and weight tensors")
768 # Convert to int32 for accumulation and apply offsets
769 input_int32 = input.to(torch.int32) + int(input_offset)
770 weight_int32 = weight.to(torch.int32)
771
772 if bias is None:
773 bias_int32 = torch.zeros(
774 weight.shape[0], dtype=torch.int32, device=input.device
775 )
776 else:
777 bias_int32 = bias.to(torch.int32)
778
779 input_channels = input.shape[1]
780 kernel_input_channels = weight.shape[3]
781 groups = input_channels // kernel_input_channels
782
783 # Convert weights back to OIHW layout expected by torch.nn.functional.conv2d
784 weight_oi_hw = weight_int32.permute(0, 3, 1, 2).contiguous()
785
786 conv_acc = F.conv2d(
787 input_int32,
788 weight_oi_hw,
789 bias_int32,
790 stride=tuple(stride),
791 padding=tuple(padding),
792 dilation=tuple(dilation),
793 groups=groups,
794 )
795
796 result_channels = []
797 for output_channel_i in range(conv_acc.shape[1]):
798 result_channel = requantize_cmsis(
799 conv_acc[:, output_channel_i, :, :],
800 int(requantize_multipliers[output_channel_i]),
801 int(requantize_shifts[output_channel_i]),
802 )
803 result_channels.append(result_channel)
804
805 result = torch.stack(result_channels, dim=1)
806
807 result += output_offset
808 result = torch.clamp(result, activation_min, activation_max)
809

Callers

nothing calls this directly

Calls 5

requantize_cmsisFunction · 0.90
zerosMethod · 0.80
toMethod · 0.45
permuteMethod · 0.45
appendMethod · 0.45

Tested by

no test coverage detected