Skip to content

Fix quantized Conv1d same padding with even kernels in XNNPACK#20734

Open
SakshamKapoor2911 wants to merge 5 commits into
pytorch:mainfrom
SakshamKapoor2911:sk/fix-xnnpack-conv1d-same-padding
Open

Fix quantized Conv1d same padding with even kernels in XNNPACK#20734
SakshamKapoor2911 wants to merge 5 commits into
pytorch:mainfrom
SakshamKapoor2911:sk/fix-xnnpack-conv1d-same-padding

Conversation

@SakshamKapoor2911

@SakshamKapoor2911 SakshamKapoor2911 commented Jul 5, 2026

Copy link
Copy Markdown

Fixes #20558.
Related to #20553.

Summary

Quantized nn.Conv1d(..., padding="same") with an even kernel exports with
asymmetric padding (unequal left/right amounts), which cannot be folded into
the convolution's symmetric padding field. The original pad-folding approach
in this PR was replaced with the explicit-PAD approach from #20553:

  • InsertPadQDQPass — inserts implicit quantize/dequantize pairs after
    constant_pad_nd nodes in quantized contexts so they serialize as quantized
    static pads. Refactored with additional guard checks (pad_value, pad_amounts,
    negative amounts) and correct idempotency.
  • ConvolutionConfig._get_act_deps — pulls zero-valued constant_pad_nd nodes
    (and their QDQ chain if InsertPadQDQPass already ran) into the convolution's
    partition for both 1D and 2D convs. The merged method replaces separate 1D
    and 2D implementations that existed on this branch.
  • Regression test — quantized Conv1d even-kernel same-padding covering both
    symmetric and asymmetric pad cases, validated by numerical comparison.
  • Removed unrelated init.py re-ordering and no-op conv1d_unsqueeze_pass
    changes.

With these changes, an even-kernel padding="same" conv1d graph:

dequant -> constant_pad_nd -> convolution

becomes (after XNNPACK preprocessing and partitioning):

[dequant -> pad -> q -> dq -> conv]  (single XNNPACK delegate)

Test plan

python -m pytest backends/xnnpack/test/ops/test_conv1d.py -q
# 7 passed (1 new regression test with 4 subTests)

python -m pytest backends/xnnpack/test/ops/test_conv2d.py -q
# 32 passed

python -m pytest backends/xnnpack/test/passes/test_insert_pad_qdq.py -q
# 3 passed

python -m pytest backends/xnnpack/test/ops/test_static_constant_pad.py -q
# 8 passed

lintrunner -a
# No lint issues

cc @GregoryComer @digantdesai @cbilgin @JakeStevens @freddan80 @per @zingo @oscarandersson8218 @mansnils @Sebastian-Larsson @robell @rascani

Copilot AI review requested due to automatic review settings July 5, 2026 12:35
@pytorch-bot

pytorch-bot Bot commented Jul 5, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/20734

Note: Links to docs will display an error until the docs builds have been completed.

⚠️ 12 Awaiting Approval

As of commit 4c18238 with merge base a6d812a (image):

AWAITING APPROVAL - The following workflows need approval before CI can run:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 5, 2026
@linux-foundation-easycla

linux-foundation-easycla Bot commented Jul 5, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: SakshamKapoor2911 / name: SakshamKapoor2911 (e7636f5)

Copilot AI 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.

Pull request overview

This PR fixes an XNNPACK delegation/runtime correctness issue for statically-quantized nn.Conv1d(padding="same") with even kernel sizes by folding the explicit temporal constant_pad_nd into asymmetric Conv2d padding during Conv1d→Conv2d lowering, and ensuring the serialized graph’s metadata matches the folded asymmetric padding.

Changes:

  • Extend XNNPACK partitioning and Conv1d unsqueeze lowering to absorb temporal-only zero constant_pad_nd into the quantized Conv1d partition and fold it into asymmetric xnnpack_input_padding.
  • Teach Conv2d serialization to use folded asymmetric padding metadata when present, and add a late pass to repair Conv1d folded-pad tensor metadata after retracing passes.
  • Add a regression test covering quantized Conv1d even-kernel padding="same".

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
backends/xnnpack/test/ops/test_conv1d.py Adds a regression test for quantized Conv1d even-kernel padding="same" and factors out calibration sample generation.
backends/xnnpack/partition/config/gemm_configs.py Extends convolution activation-dependency discovery to include temporal-only zero constant_pad_nd for quantized Conv1d so it can be partitioned/delegated.
backends/xnnpack/operators/op_conv2d.py Uses folded asymmetric xnnpack_input_padding metadata (top/right/bottom/left) when present instead of symmetric ATen padding args.
backends/xnnpack/_passes/conv1d_unsqueeze_pass.py Folds eligible temporal-only constant_pad_nd into asymmetric input padding during Conv1d→Conv2d lowering and adds a pass to restore correct tensor metadata for folded-pad Conv1d.
backends/xnnpack/_passes/init.py Registers the new folded-pad metadata repair pass in the default XNNPACK pass pipeline.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread backends/xnnpack/_passes/conv1d_unsqueeze_pass.py Outdated
@pytorch-bot

pytorch-bot Bot commented Jul 5, 2026

Copy link
Copy Markdown

❌ 🤖 pytorchbot command failed:

Got EOF while in a quoted string```
Try `@pytorchbot --help` for more info.

@SakshamKapoor2911

Copy link
Copy Markdown
Author

@pytorchbot label "release notes: xnnpack"

@pytorch-bot pytorch-bot Bot added the release notes: xnnpack Changes to the XNNPack backend delegate label Jul 5, 2026
@digantdesai digantdesai requested a review from JakeStevens July 7, 2026 16:19
@nil-is-all nil-is-all added the module: xnnpack Issues related to xnnpack delegation and the code under backends/xnnpack/ label Jul 8, 2026
Copilot AI review requested due to automatic review settings July 8, 2026 17:58

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added ciflow/trunk module: arm Issues related to arm backend labels Jul 8, 2026
@pytorch-bot

pytorch-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

The following ciflow label(s) have been added but CI has not been triggered yet because the workflows are awaiting approval:

  • ciflow/trunk

Once a maintainer approves the workflows (scroll to the bottom of the PR page), the corresponding CI jobs will be triggered automatically. Please ping one of the reviewers if you do not have access to approve and run workflows.

Comment thread backends/arm/_passes/arm_pass_utils.py Outdated
Comment thread backends/cortex_m/quantizer/pattern_matcher.py Outdated
Copilot AI review requested due to automatic review settings July 8, 2026 19:50
@SakshamKapoor2911 SakshamKapoor2911 force-pushed the sk/fix-xnnpack-conv1d-same-padding branch from 43c6c72 to 529a792 Compare July 8, 2026 19:50

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SakshamKapoor2911 SakshamKapoor2911 force-pushed the sk/fix-xnnpack-conv1d-same-padding branch from 529a792 to 619ae4c Compare July 8, 2026 20:00
Copilot AI review requested due to automatic review settings July 8, 2026 20:00

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@JakeStevens

JakeStevens commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

The PR for 2D has landed:

#20553

You can take the same approach here; have an explicit PAD op, which gets executed in XNNPACK. We can then later fold that XNNPACK pad in the delegated graph, this is a follow up to both of these PRs.

As is, this code will also fail on:

class M(torch.nn.Module):
    def __init__(self):
          super().__init__()
          self.conv = torch.nn.Conv1d(1, 8, kernel_size=4, padding="same")
      def forward(self, x):
          out = torch.reshape(x, (1, 1, 256))
          out = self.conv(out)
          return torch.flatten(out, 1)   # even kernel + this line => crash

Copilot AI review requested due to automatic review settings July 9, 2026 16:00
@SakshamKapoor2911

Copy link
Copy Markdown
Author

Addressed review feedback: adopted the same approach as #20553 — keep the constant_pad_nd as an explicit PAD op executed in XNNPACK instead of folding it into asymmetric Conv2d padding.

Changes:

  1. Removed pad-folding from Conv1dUnsqueezePass — the pad is no longer absorbed into asymmetric conv padding
  2. Removed Conv1dFoldedPadMetaPass — no longer needed since tensor metadata propagates correctly with the standalone pad
  3. Reverted xnnpack_input_padding handling in op_conv2d.py — symmetric padding from ATen args is used again
  4. Added InsertPadQDQPass — inserts implicit QDQ after quantized-context pads so they serialize as quantized static pads (same mechanism as Delegate even-kernel 'same'-padding convs via a quantized static pad (#20553) #20553)
  5. The crash case with conv1d(padding='same', even kernel) → flatten is fixed because the pad is now a standalone op with correct shape propagation

The pad can be folded in the delegated graph later as a follow-up optimization (per the review suggestion).

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@JakeStevens

Copy link
Copy Markdown
Contributor

I believe you need to rebase and make sure the commit I shared is landed in your branch, there are merge conflicts from duplicated code

 approach)

Instead of folding constant_pad_nd into asymmetric Conv2d padding,
keep it as an explicit XNNPACK pad op:

- Remove pad-folding logic from Conv1dUnsqueezePass
- Remove Conv1dFoldedPadMetaPass (no longer needed)
- Revert xnnpack_input_padding handling in op_conv2d.py
- Add InsertPadQDQPass: inserts QDQ after pad in quantized contexts
  so it serializes as a quantized static pad

This matches the approach from pytorch#20553 and fixes the crash with
conv1d -> flatten (even kernel + same padding).
@SakshamKapoor2911 SakshamKapoor2911 force-pushed the sk/fix-xnnpack-conv1d-same-padding branch from 3b7443f to bf3644f Compare July 11, 2026 07:35
Copilot AI review requested due to automatic review settings July 11, 2026 07:35
@SakshamKapoor2911

Copy link
Copy Markdown
Author

Rebased onto current main and resolved the duplicated-code conflict. The conflict was an add/add in insert_pad_qdq.py#20553 and this PR each introduced an InsertPadQDQPass. Kept #20553's canonical version (already landed on main) and dropped the duplicate import from __init__.py. No other files conflicted. PR is ready for another look.

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@JakeStevens

Copy link
Copy Markdown
Contributor

Please setup and run lintrunner to resolve the failures. See

https://github.com/pytorch/executorch/blob/main/CONTRIBUTING.md#lintrunner

Also it seems like you've duplicated the get act dep in Gemm config instead of only updating as necessary.

I have not fully reviewed but I did notice that your comment said it kept the existing pad pass but the commit has substantial changes to it.

Refactor InsertPadQDQPass with guard checks (pad_value, pad_amounts,
negative amounts) and correct idempotency (re-add is_quant check).
Use is_dequant instead of matching specific dequant target. Add
super().call() retrace to update graph_module metadata.

Merge duplicated _get_act_deps in ConvolutionConfig — handle both 1D
and 2D convs with their respective pad constraints. Also follow QDQ
chain (dequant -> pad -> q -> dq -> conv) when InsertPadQDQPass has
already inserted a quantize/dequantize pair after the pad.

Restore XNNPACK pass ordering in __init__.py and Conv1dUnsqueezePass
variable scoping to match origin/main (no functional change).

Add regression test for quantized Conv1d even-kernel same-padding
covering both symmetric and asymmetric pad cases.

Co-authored-by: Claude
Copilot AI review requested due to automatic review settings July 12, 2026 17:32

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

Labels

ciflow/trunk CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: arm Issues related to arm backend module: xnnpack Issues related to xnnpack delegation and the code under backends/xnnpack/ release notes: xnnpack Changes to the XNNPack backend delegate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Quantized Conv1d with even kernel + padding="same" produces incorrect XNNPACK output

4 participants