Skip to content

Conversation

@f0k
Copy link
Contributor

@f0k f0k commented Nov 27, 2018

As reported in #13386, the pooling operations can return wrong results for large inputs. The root of the problem is that while the output shape is initially being computed with integer operations, it is converted to float32 for division by the stride and applying either a ceil or a floor depending on the ceil_mode. Since even moderately large integers (the smallest being 16,777,217) cannot be expressed exactly in float32, this leads to wrong result shapes.

This PR relies purely on integer operations to perform the shape computation, including the ceil/floor distinction. Since I could not stand all that duplicated code, I pulled it out into a pooling_shape.h header, similar to the existing linear_upsampling.h header. I hope this is acceptable, let me know if you'd like to see it solved differently. I've also added tests to test_nn.py that fail without my changes and pass with my changes. They cover {max,avg}_pool{1,2,3}d() for CPU and GPU.

Fixes #13386.

@f0k f0k force-pushed the fix-large-pooling-size branch from 78109d6 to 72852f6 Compare November 27, 2018 10:12
@f0k f0k force-pushed the fix-large-pooling-size branch from 72852f6 to 81a436e Compare November 27, 2018 13:35
@soumith
Copy link
Contributor

soumith commented Nov 27, 2018

looks pretty good, thanks @f0k !

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@soumith has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

zdevito pushed a commit to zdevito/ATen that referenced this pull request Nov 27, 2018
Summary:
As reported in #13386, the pooling operations can return wrong results for large inputs. The root of the problem is that while the output shape is initially being computed with integer operations, it is converted to float32 for division by the stride and applying either a `ceil` or a `floor` depending on the `ceil_mode`. Since even moderately large integers (the smallest being 16,777,217) cannot be expressed exactly in float32, this leads to wrong result shapes.

This PR relies purely on integer operations to perform the shape computation, including the ceil/floor distinction. Since I could not stand all that duplicated code, I pulled it out into a `pooling_shape.h` header, similar to the existing `linear_upsampling.h` header. I hope this is acceptable, let me know if you'd like to see it solved differently. I've also added tests to `test_nn.py` that fail without my changes and pass with my changes. They cover `{max,avg}_pool{1,2,3}d()` for CPU and GPU.

Fixes #13386.
Pull Request resolved: pytorch/pytorch#14405

Differential Revision: D13215260

Pulled By: soumith

fbshipit-source-id: 802588ce6cba8db6c346448c3b3c0dac14d12b2d
@f0k f0k deleted the fix-large-pooling-size branch June 27, 2019 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect output shape for max-pooling

4 participants