From 2c362eda93ddec98a7ef93709c2568b3abd032c6 Mon Sep 17 00:00:00 2001 From: Harsh Chauhan Date: Sun, 31 May 2026 15:34:14 +0530 Subject: [PATCH] fix maxpool/avgpool reading wrong pad indices for asym padding --- tmva/sofie/inc/TMVA/ROperator_Pool.hxx | 10 ++++----- tmva/sofie/test/TestCustomModelsFromONNX.cxx | 20 ++++++++++++++++++ .../test/input_models/MaxPool2d_AsymPad.onnx | Bin 0 -> 165 bytes .../references/MaxPool2d_AsymPad.ref.hxx | 3 +++ 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 tmva/sofie/test/input_models/MaxPool2d_AsymPad.onnx create mode 100644 tmva/sofie/test/input_models/references/MaxPool2d_AsymPad.ref.hxx diff --git a/tmva/sofie/inc/TMVA/ROperator_Pool.hxx b/tmva/sofie/inc/TMVA/ROperator_Pool.hxx index f07dc3ab31d85..6f142808d8e3d 100644 --- a/tmva/sofie/inc/TMVA/ROperator_Pool.hxx +++ b/tmva/sofie/inc/TMVA/ROperator_Pool.hxx @@ -287,20 +287,20 @@ public: // find lower bounds of filtered area int hmin = - fAttrPads[0]; // minimum lower bound value of filter area // use stride instead of 1 when ceil_mode=1, so the loop covers the extra partial window - int hmax = fShapeX[2] + fAttrPads[1] - fAttrKernelShape[0] + (fAttrCeilMode ? (int)fAttrStrides[0] : 1); + int hmax = fShapeX[2] + fAttrPads[fDim] - fAttrKernelShape[0] + (fAttrCeilMode ? (int)fAttrStrides[0] : 1); int wmin,wmax,dmin,dmax; if(fDim >= 2){ - wmin = - fAttrPads[2]; // minimum lower bound value of filter area - wmax = fShapeX[3] + fAttrPads[3] - fAttrKernelShape[1] + (fAttrCeilMode ? (int)fAttrStrides[1] : 1); + wmin = -fAttrPads[1]; // minimum lower bound value of filter area + wmax = fShapeX[3] + fAttrPads[fDim + 1] - fAttrKernelShape[1] + (fAttrCeilMode ? (int)fAttrStrides[1] : 1); } else{ wmin=1; wmax=1; } if(fDim == 3){ - dmin = - fAttrPads[4]; // minimum lower bound value of filter area - dmax = fShapeX[4] + fAttrPads[5] - fAttrKernelShape[2] + (fAttrCeilMode ? (int)fAttrStrides[2] : 1); + dmin = -fAttrPads[2]; // minimum lower bound value of filter area + dmax = fShapeX[4] + fAttrPads[fDim + 2] - fAttrKernelShape[2] + (fAttrCeilMode ? (int)fAttrStrides[2] : 1); } else{ dmin=1; diff --git a/tmva/sofie/test/TestCustomModelsFromONNX.cxx b/tmva/sofie/test/TestCustomModelsFromONNX.cxx index 79c0ab20f5efe..b9857830820ac 100644 --- a/tmva/sofie/test/TestCustomModelsFromONNX.cxx +++ b/tmva/sofie/test/TestCustomModelsFromONNX.cxx @@ -32,6 +32,7 @@ constexpr auto modelDataSuffix = "_FromONNX.dat"; #include "input_models/references/MaxPool2d.ref.hxx" #include "input_models/references/MaxPool2d_CeilMode.ref.hxx" #include "input_models/references/MaxPool3d.ref.hxx" +#include "input_models/references/MaxPool2d_AsymPad.ref.hxx" #include "input_models/references/Max.ref.hxx" #include "input_models/references/MaxMultidirectionalBroadcast.ref.hxx" #include "input_models/references/MinMultidirectionalBroadcast.ref.hxx" @@ -848,6 +849,25 @@ TEST(ONNX, MaxPool2d){ } +TEST(ONNX, MaxPool2d_AsymPad) +{ + constexpr float TOLERANCE = DEFAULT_TOLERANCE; + + // 1x1x4x4 input with values 0..15 + std::vector input({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}); + + ASSERT_INCLUDE_AND_RUN(std::vector, "MaxPool2d_AsymPad", input); + + // pads=[0,1,0,1] (width padded, height not) gives a 1x1x3x5 output; + // the pre-fix code mis-read the pads and produced a 4x4 grid instead + EXPECT_EQ(output.size(), std::size(MaxPool2d_AsymPad_ExpectedOutput::output)); + + float *correct = MaxPool2d_AsymPad_ExpectedOutput::output; + for (size_t i = 0; i < output.size(); ++i) { + EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE); + } +} + TEST(ONNX, MaxPool2d_CeilMode) { constexpr float TOLERANCE = DEFAULT_TOLERANCE; diff --git a/tmva/sofie/test/input_models/MaxPool2d_AsymPad.onnx b/tmva/sofie/test/input_models/MaxPool2d_AsymPad.onnx new file mode 100644 index 0000000000000000000000000000000000000000..bacb19d2886a18ae643bca33d97a94f74d37e168 GIT binary patch literal 165 zcmdcHf{w1AOaOOT7D zATg!bfx&?hgh4_AT#%E5TlfM$KuM|fW(w2X^{D1Tp}EdLIPY& b9E?!R0;E}zfRd3|B$