Skip to content

Fix transpose convolution scratch width for asymmetric strides - #243

Merged
AdrianLundell merged 1 commit into
ARM-software:mainfrom
rascani:fix/transpose-conv-scratch-width
Sep 11, 2026
Merged

AdrianLundell merged 1 commit into
ARM-software:mainfrom
rascani:fix/transpose-conv-scratch-width

Conversation

@rascani

@rascani rascani commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

The rolling-buffer width calculation in both transpose-convolution buffer-size functions uses stride.h in MAX(filter_dims->w, ...). The execution kernel, arm_transpose_conv_s8, uses stride.w. This can underallocate scratch when the width stride exceeds both the height stride and filter width, and can overallocate when the height stride is larger.

For input NHWC [2, 1, 9, 4], filter OHWI [4, 1, 1, 4], output NHWC [2, 1, 17, 4], and stride HW [1, 2], the sizing API returns 272 bytes while the kernel initializes and resets 288 bytes. A guarded host execution against the original implementation overwrote 16 bytes beyond the reported allocation. The corrected size leaves the guard intact. This surfaced as output corruption in ExecuTorch when its memory planner placed a live output immediately after the scratch allocation.

Use the width stride in both sizing functions, matching the existing kernel. The execution kernel and reverse-convolution selection are unchanged. Add 15 binding regression cases covering asymmetric strides and a larger-filter control across scalar, DSP, and MVE backends.

Validation: all 23 tests in Tests/Bindings pass on the rebased branch, and the changed C file passes clang-format 18. The asymmetric-stride cases fail against the original sizing implementation. The same fix was also validated against ExecuTorch's previously pinned CMSIS-NN revision with an end-to-end Cortex-M55 reproducer, with and without Hardtanh; the focused ExecuTorch run had 51 passes and 9 existing expected failures.

Authored and validated with Codex assistance.

Use the width stride in both rolling-buffer size calculations, matching arm_transpose_conv_s8. Using the height stride underallocates scratch when the width stride exceeds both the height stride and filter width, and can overallocate when the height stride is larger.

Cover asymmetric strides and a larger-filter control through the scalar, DSP, and MVE sizing bindings.

Authored with Codex.
@AdrianLundell

Copy link
Copy Markdown
Collaborator

LGTM, thanks for the fix!

@AdrianLundell
AdrianLundell merged commit 9e1b476 into ARM-software:main Sep 11, 2026
rascani added a commit to pytorch/executorch that referenced this pull request Sep 11, 2026
### Summary
Reserve the larger of the CMSIS-NN reported size and the rolling-buffer
kernel requirement during export, leaving reverse-convolution
allocations unchanged. Allow the larger allocation in the optional
runtime check while awaiting
ARM-software/CMSIS-NN#243.

### Test plan
Enable runtime checks in the test runner and cover strided pointwise
transpose convolution in explicit layout, with and without Hardtanh. The
focused M55 suite passed with 51 passes and 9 expected failures; 30
separate allocation checks also passed.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants