Skip to content

[tmva][sofie] Implement padding generation for ConvTranspose with explicitly set output_shape - #23088

Open
Sainava wants to merge 1 commit into
root-project:masterfrom
Sainava:fix/sofie-convtranspose-output-shape
Open

[tmva][sofie] Implement padding generation for ConvTranspose with explicitly set output_shape#23088
Sainava wants to merge 1 commit into
root-project:masterfrom
Sainava:fix/sofie-convtranspose-output-shape

Conversation

@Sainava

@Sainava Sainava commented Aug 17, 2026

Copy link
Copy Markdown

This Pull request:

Changes or fixes:

  • Resolves a TODO in ROperator_ConvTranspose.hxx by dynamically calculating head and tail padding based on the ONNX specification when output_shape is explicitly provided.
  • Removes the previous early runtime_error exception and cleans up legacy commented-out padding attempts to streamline the control flow.
  • Accurately calculates the effective kernel shape (accounting for dilations) to ensure padding generation remains mathematically correct when dilations > 1.
  • Includes a safety check to prevent unsigned integer underflow (size_t) if an invalid or mathematically impossible output_shape is passed to the engine.

Checklist:

  • tested changes locally (compiled TMVA locally to verify C++ shape inference logic and syntax)
  • updated the docs (if necessary)

@Sainava
Sainava requested a review from lmoneta as a code owner August 17, 2026 19:19
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

Test Results

    23 files      23 suites   3d 17h 35m 26s ⏱️
 3 859 tests  3 858 ✅ 0 💤 1 ❌
78 618 runs  78 617 ✅ 0 💤 1 ❌

For more details on these failures, see this check.

Results for commit 391dd8a.

♻️ This comment has been updated with latest results.

@Sainava
Sainava force-pushed the fix/sofie-convtranspose-output-shape branch from 97adbb9 to 391dd8a Compare August 18, 2026 07:21
@guitargeek guitargeek changed the title [TMVA SOFIE] Implement padding generation for ConvTranspose with explicitly set output_shape [tmva][sofie] Implement padding generation for ConvTranspose with explicitly set output_shape Aug 18, 2026
@guitargeek guitargeek self-assigned this Aug 18, 2026

@guitargeek guitargeek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for tackling this! The total-padding formula itself is right and matches the ONNX spec, including the output_padding term and the dilated kernel. But there are two correctness issues that need fixing before this can go in, plus a missing test.

1. The padding split is backwards. The spec says:

If (auto_pads == SAME_UPPER): pads[start_i] = total/2;         pads[end_i] = total - total/2
Else:                         pads[start_i] = total - total/2; pads[end_i] = total/2

The reachable path here is always auto_pad == NOTSET (the block above throws for SAME_*), i.e. the Else case — so the larger half belongs at the start, not the end. The commented-out legacy code you removed actually had this part right. (The SAME_UPPER variant is what the PR currently implements unconditionally.)

2. Asymmetric pads are silently discarded downstream, so the result is wrong.

Generate() can't express asymmetric padding: col2im takes a single pad_h/pad_w, so when pads[begin] != pads[end] it prints to std::cout and averages them. The averaged padding no longer matches the fShapeY that ShapeInference() derived, and col2im then walks data_col with the wrong column count, which garbles the whole output rather than just shifting it.

Concretely, for the classic 2× upsample (kernel 3, stride 2, dilation 1, output_shape = 2 * input): total_padding == 1 → pads (0, 1) -> averaged to 0 -> col2im consumes 3 of the 4 input columns. So the feature is correct when total_padding is even and silently wrong when it's odd, and odd is exactly the most common real-world ConvTranspose block. The only signal to the user is a std::cout line at code-generation time.

Either fix is fine by me:

  • Minimal: fix the split per the spec, then throw when fAttrPads[i] != fAttrPads[i + fDim] with a message saying asymmetric padding isn't supported yet. Still strictly better than today's blanket throw.
  • Proper, and not much more work: generalise col2im in tmva/sofie/src/SOFIE_common_helpers.cxx to take pad_begin/pad_end per axis. Its structure makes this easy — output_h becomes (height + pad_h_begin + pad_h_end - eff_kernel) / stride + 1 and input_row starts at -pad_h_begin; nothing else changes. That would also let the averaging hack in Generate() be deleted.

3. Please add a test.

tmva/sofie/test/generate_input_models.py computes expected outputs with onnx's ReferenceEvaluator, so a make_ConvTranspose2dOutputShape() model (kernel 3, stride 2, output_shape = [2h, 2w]) plus a TEST_INPUTS entry and a TEST(ONNX, ...) in0 TestCustomModelsFromONNX.cxx gets you spec conformance checked automatically, and would have caught both issues above. Since the whole point of the PR is spec conformance, I'd like to see this before merging.

Unrelated: the one red CI check (test-stressgraphics-chrome on fedora44) is a known graphics flake, nothing to do with your change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants