Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 25 additions & 23 deletions tmva/sofie/inc/TMVA/ROperator_Conv.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -137,28 +137,37 @@ public:
k2 + (fAttrDilations[1] - 1) * (k2 - 1),
k3 + (fAttrDilations[2] - 1) * (k3 - 1)};

if (fAttrStrides.empty()) {
fAttrStrides = {1, 1, 1};
}
if (fDim < 3)
fAttrStrides.resize(3, 1);

if (fAttrAutopad == "NOTSET") {
if (fAttrPads.empty()) {
fAttrPads = {1, 1, 1, 1, 1, 1};
}
} else if (fAttrAutopad == "SAME_UPPER" || fAttrAutopad == "SAME_LOWER") {
if (fDim == 1)
fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[0] / 2};
else if (fDim == 2)
fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2};
else if (fDim == 3)
fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[2] / 2,
fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[2] / 2};
// add extra padding at beginning or end (depending if SAME_UPPER or SAME_LOWER)
// need to check this!
if (fAttrKernelShape[0] % 2 == 1) {
(fAttrAutopad == "SAME_UPPER") ? fAttrPads[0]++ : fAttrPads[i1]++;
for (size_t d = 0; d < fDim; ++d) {
if (input[d + 2].isParam)
throw std::runtime_error(
"TMVA SOFIE Conv Op: SAME padding with parametric input shape is not supported");
}
if (fDim > 1 && fAttrKernelShape[1] % 2 == 1) {
(fAttrAutopad == "SAME_UPPER") ? fAttrPads[1]++ : fAttrPads[i2]++;
}
if (fDim > 2 && fAttrKernelShape[2] % 2 == 1) {
(fAttrAutopad == "SAME_UPPER") ? fAttrPads[2]++ : fAttrPads[i3]++;
// ONNX SAME padding: total_pad = max(0, (ceil(in/stride)-1)*stride + kernel - in)
// SAME_UPPER places extra padding at end, SAME_LOWER at beginning
fAttrPads.assign(6, 0);
for (size_t d = 0; d < fDim; ++d) {
size_t inSize = input[d + 2].dim;
size_t stride_d = fAttrStrides[d];
size_t outSize = (inSize + stride_d - 1) / stride_d;
int totalPad = std::max(0, (int)((outSize - 1) * stride_d + fAttrKernelShape[d]) - (int)inSize);
if (fAttrAutopad == "SAME_UPPER") {
fAttrPads[d] = (size_t)(totalPad / 2);
fAttrPads[d + fDim] = (size_t)(totalPad - totalPad / 2);
} else {
fAttrPads[d] = (size_t)(totalPad - totalPad / 2);
fAttrPads[d + fDim] = (size_t)(totalPad / 2);
}
}
} else if (fAttrAutopad != "VALID") {
throw
Expand All @@ -167,13 +176,6 @@ public:
// to be sure pad is vector of size 6
if (fDim < 3) fAttrPads.resize(6, 0);

if (fAttrStrides.empty()) {
fAttrStrides = {1, 1, 1};
}
if (fDim < 3)
fAttrStrides.resize(3, 1);


Dim input1 = input[2];
Dim input2 = (fDim > 1) ? input[3] : Dim{1};
Dim input3 = (fDim > 2) ? input[4] : Dim{1};
Expand Down
45 changes: 21 additions & 24 deletions tmva/sofie/inc/TMVA/ROperator_Pool.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -132,29 +132,33 @@ public:
k2 + (fAttrDilations[1] - 1) * (k2 - 1),
k3 + (fAttrDilations[2] - 1) * (k3 - 1)};

if (fAttrStrides.empty()) {
fAttrStrides = {1, 1, 1};
}
if (fDim < 3)
fAttrStrides.resize(3, 1);

if (fAttrAutopad == "NOTSET") {
// in auto_pad is NOTSET then fAttrPads should have been set or default zero is used
if (fAttrPads.empty()) {
fAttrPads = {0, 0, 0, 0, 0, 0};
}
} else if (fAttrAutopad == "SAME_UPPER" || fAttrAutopad == "SAME_LOWER") {
if (fDim == 1)
fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[0] / 2};
else if (fDim == 2)
fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2};
else if (fDim == 3)
fAttrPads = {fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[2] / 2,
fAttrKernelShape[0] / 2, fAttrKernelShape[1] / 2, fAttrKernelShape[2] / 2};
// add extra padding at beginning or end (depending if SAME_UPPER or SAME_LOWER)
// need to check this!
if (fAttrKernelShape[0] % 2 == 1) {
(fAttrAutopad == "SAME_UPPER") ? fAttrPads[0]++ : fAttrPads[i1]++;
}
if (fDim > 1 && fAttrKernelShape[1] % 2 == 1) {
(fAttrAutopad == "SAME_UPPER") ? fAttrPads[1]++ : fAttrPads[i2]++;
}
if (fDim > 2 && fAttrKernelShape[2] % 2 == 1) {
(fAttrAutopad == "SAME_UPPER") ? fAttrPads[2]++ : fAttrPads[i3]++;
// ONNX SAME padding: total_pad = max(0, (ceil(in/stride)-1)*stride + kernel - in)
// SAME_UPPER places extra padding at end, SAME_LOWER at beginning
fAttrPads.assign(6, 0);
for (size_t d = 0; d < fDim; ++d) {
size_t inSize = input[0][d + 2];
size_t stride_d = fAttrStrides[d];
size_t outSize = (inSize + stride_d - 1) / stride_d;
int totalPad = std::max(0, (int)((outSize - 1) * stride_d + fAttrKernelShape[d]) - (int)inSize);
if (fAttrAutopad == "SAME_UPPER") {
fAttrPads[d] = (size_t)(totalPad / 2);
fAttrPads[d + fDim] = (size_t)(totalPad - totalPad / 2);
} else {
fAttrPads[d] = (size_t)(totalPad - totalPad / 2);
fAttrPads[d + fDim] = (size_t)(totalPad / 2);
}
}
} else if (fAttrAutopad != "VALID") {
throw
Expand All @@ -163,13 +167,6 @@ public:
// to be sure pad is vector of size 6
if (fDim < 3) fAttrPads.resize(6, 0);

if (fAttrStrides.empty()) {
fAttrStrides = {1, 1, 1};
}

if (fDim < 3)
fAttrStrides.resize(3, 1);

size_t input1 = input[0][2];
size_t input2 = (fDim > 1) ? input[0][3] : 1;
size_t input3 = (fDim > 2) ? input[0][4] : 1;
Expand Down
21 changes: 21 additions & 0 deletions tmva/sofie/test/TestCustomModelsFromONNX.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ constexpr auto modelDataSuffix = "_FromONNX.dat";
#include "input_models/references/ConvWithPadding.ref.hxx"
#include "input_models/references/ConvWithoutPadding.ref.hxx"
#include "input_models/references/ConvWithAutopadSameLower.ref.hxx"
#include "input_models/references/ConvWithAutopadSameUpper.ref.hxx"
#include "input_models/references/ConvWithStridesPadding.ref.hxx"
#include "input_models/references/ConvWithStridesNoPadding.ref.hxx"
#include "input_models/references/ConvWithAsymmetricPadding.ref.hxx"
Expand Down Expand Up @@ -663,6 +664,26 @@ TEST(ONNX, ConvWithAutopadSameLower)
}
}

TEST(ONNX, ConvWithAutopadSameUpper)
{
constexpr float TOLERANCE = DEFAULT_TOLERANCE;

// Input (1,1,5,5) with values 0..24; kernel (1,1,3,3) all-ones, auto_pad=SAME_UPPER, stride=1
// Odd kernel: total_pad=2 per dim, begin=1 end=1 (symmetric); output shape (1,1,5,5)
std::vector<float> input(25);
std::iota(input.begin(), input.end(), 0.0f);
ASSERT_INCLUDE_AND_RUN(std::vector<float>, "ConvWithAutopadSameUpper", input);

// Checking output size
EXPECT_EQ(output.size(), sizeof(ConvWithAutopadSameUpper_ExpectedOutput::output) / sizeof(float));

float *correct = ConvWithAutopadSameUpper_ExpectedOutput::output;

// Checking every output value, one by one
for (size_t i = 0; i < output.size(); ++i) {
EXPECT_LE(std::abs(output[i] - correct[i]), TOLERANCE);
}
}

TEST(ONNX, ConvWithStridesPadding)
{
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace ConvWithAutopadSameUpper_ExpectedOutput {
float output[] = {12., 21., 27., 33., 24., 33., 54., 63., 72., 51., 63., 99., 108.,
117., 81., 93., 144., 153., 162., 111., 72., 111., 117., 123., 84.};
} // namespace ConvWithAutopadSameUpper_ExpectedOutput