fix(avgpool2d): preserve pooling semantics end to end#100
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #100 +/- ##
==========================================
+ Coverage 73.53% 73.77% +0.24%
==========================================
Files 91 91
Lines 20372 20444 +72
==========================================
+ Hits 14980 15083 +103
+ Misses 5392 5361 -31
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 5 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
|
a scan of all 613 ONNX models in HyZor 12 evaluated datasets found zero affected AveragePool nodes, so this PR doesn't changes benchmark result. It's a correctness fix, not a ranking score fix. ACT claims general PyTorch/ONNX support, but before this change, a perfectly legal padded AvgPool would silently yield a self-contradictory constraint. |
A soundness bug.
ACT previously dropped
ceil_mode,count_include_pad, anddivisor_overrideduring PyTorch-to-ACT conversion. For anAvgPool2dlayer using these semantics, ACT could therefore analyze a different linear operator from the source PyTorch/ONNX model. A proof about that different operator is not a sound proof about the original model.There was also an internal inconsistency in the interval transformer: bounds were computed using PyTorch's default
count_include_pad=True, whileW_equivdivided by the number of valid input elements. For example, with a 3x3 input,kernel=2,stride=2,padding=1, and only the top-left input equal to 1:1 / 4 = 0.25W_equivoutput:1 / 1 = 1.0One qualification: the current canonical constraint exporter does not lower the
avgpool2d:equality tag and fails loudly instead. Therefore, we have not observed a false certificate caused specifically by that equality matrix. The confirmed soundness issue is the loss/inconsistent handling of source-model pooling semantics across the supported propagation paths.When is it triggered?
The old implementation is affected by:
padding > 0together withcount_include_padsemantics;ceil_mode=Truewhen it adds a trailing pooling window;Nonedivisor_override;The common configuration
does not expose the bug because every pooling window contains exactly the full kernel area.
Why did the previous CI runs not detect it?
The existing
layer_testing_cnn_poolfixture used only:For that case, the buggy and correct denominator formulas are identical. The code was executed, but the semantic branch that exposes the bug was not exercised.
There were two additional masking factors:
padding=0from the affected padded/ceil/divisor cases.Influence on HyZor forzen results
We also scanned the evaluated models. Among the 475 unique models in the frozen 2213-instance suite, only the cGAN model contains AveragePool, and all ten nodes use
padding=0. A scan of all 661 VNN-COMP 2025 models found no semantically affected AveragePool node. Therefore, there is no evidence that this bug changed the frozen experimental results.Fix in this PR
This PR makes the pooling semantics explicit and consistent end to end:
ceil_mode,count_include_pad, anddivisor_overridethrough PyTorch-to-ACT and ACT-to-PyTorch conversion.W_equiv.ceil_mode=True;