Skip to content
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

Fix max_pool2d with ceil_mode bug #46558

Closed
5 changes: 3 additions & 2 deletions aten/src/ATen/native/Pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ static inline T pooling_output_shape_pad_lr(
T outputSize = div_rtn<T>(
inputSize + pad_l + pad_r - dilation * (kernelSize - 1) - 1 +
(ceil_mode ? stride - 1 : 0), stride) + 1;
if (pad_l) {
if (ceil_mode) {
// ensure that the last pooling starts inside the image
// needed to avoid problems in ceil mode
if ((outputSize - 1) * stride >= inputSize + pad_l)
if ((outputSize - 1) * stride >= inputSize + pad_l + pad_r) {
--outputSize;
}
}
return outputSize;
}
Expand Down
11 changes: 11 additions & 0 deletions aten/src/ATen/native/quantized/cpu/kernels/QuantizedOpKernels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,17 @@ void _qavg_pool_nhwc_kernel(
float multiplier = input_scale / output_scale / divide_factor;
int input_zero_point_m_size = -input_zero_point * size;

if (size == 0) {
heitorschueroff marked this conversation as resolved.
Show resolved Hide resolved
for (int c = 0; c < nInputPlane; ++c) {
o_p[c] = at::native::quantize_val<scalar_t>(
1.0f / multiplier,
output_zero_point,
input_zero_point_m_size)
.val_;
}
continue;
}

int c_start = 0;

// For int8 quantization, we implicitly use int32 as accumulation
Expand Down
6 changes: 3 additions & 3 deletions test/quantization/test_quantized_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ def pool_output_shape(input_size, kernel_size, padding, stride,
output_size = (
(input_size + 2 * padding - dilation * (kernel_size - 1) - 1
+ (stride - 1 if ceiling_mode else 0)) // stride + 1)
if (padding > 0 and
((output_size - 1) * stride >= input_size + padding)):
output_size += 1
if (ceiling_mode and
((output_size - 1) * stride >= input_size + 2 * padding)):
output_size -= 1
return output_size

"""
Expand Down
9 changes: 9 additions & 0 deletions test/test_nn.py
Original file line number Diff line number Diff line change
Expand Up @@ -10511,6 +10511,15 @@ def test(nonlinearity, *args, **kwargs):
test('threshold', 3, 2)
test('threshold', 3, 2, inplace=True)

def test_pooling_shape(self, device):
heitorschueroff marked this conversation as resolved.
Show resolved Hide resolved
def check(expected_out_shape, sizes, *args, **kwargs):
t = torch.randn(sizes, device=device)
self.assertEqual(torch.nn.functional.max_pool3d(t, *args, **kwargs).shape, expected_out_shape)
heitorschueroff marked this conversation as resolved.
Show resolved Hide resolved

check((1, 1, 3, 4), (1, 1, 6, 7), kernel_size=1, stride=2, padding=0, ceil_mode=True)
heitorschueroff marked this conversation as resolved.
Show resolved Hide resolved
check((1, 2, 3, 3), (1, 3, 4, 5), kernel_size=2, stride=2, padding=1, ceil_mode=False)
check((1, 3, 3, 4), (1, 3, 4, 5), kernel_size=2, stride=2, padding=1, ceil_mode=True)

@onlyOnCPUAndCUDA # TODO: fix on XLA
def test_adaptive_avg_pool2d_output_size_one(self, device):
def helper(size, memory_format):
Expand Down