Skip to content

XNNPack: Extend to_copy support when skip_dim_order=True - #22075

Open
Erik-Lundell wants to merge 2 commits into
pytorch:mainfrom
Erik-Lundell:xnnpack-to-copy
Open

XNNPack: Extend to_copy support when skip_dim_order=True#22075
Erik-Lundell wants to merge 2 commits into
pytorch:mainfrom
Erik-Lundell:xnnpack-to-copy

Conversation

@Erik-Lundell

@Erik-Lundell Erik-Lundell commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

With the default XNNPACK test config, skip_dim_order=False rewrites aten._to_copy.default to dim_order_ops._to_dim_order_copy.default path is already supported through CloneDimOrderConfig.

Add a ToCopy partitioner config to partition the operator. _to_copy already had a node_visitor due to DimOrderOpsRevertPass creating _to_copy nodes for permutation. Expand this to also support dtype conversion using to_copy.

Extend RemoveRedundantCopy pass to handle to_copy
nodes with redundant dtypes.

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

With the default XNNPACK test config, skip_dim_order=False rewrites
aten._to_copy.default to dim_order_ops._to_dim_order_copy.default
path is already supported through CloneDimOrderConfig.

Add a ToCopy partitioner config to partition the operator.
_to_copy already had a node_visitor due to DimOrderOpsRevertPass
creating _to_copy nodes for permutation. Expand this to
also support dtype conversion using to_copy.

Extend RemoveRedundantCopy pass to handle to_copy
nodes with redundant dtypes.

Signed-off-by: Erik Lundell <erik.lundell@arm.com>
Change-Id: I22a06ba2079aeb4bbd6bb53b1086a4b857b7bf76
@Erik-Lundell Erik-Lundell added module: xnnpack Issues related to xnnpack delegation and the code under backends/xnnpack/ partner: arm For backend delegation, kernels, demo, etc. from the 3rd-party partner, Arm labels Aug 24, 2026
@pytorch-bot

pytorch-bot Bot commented Aug 24, 2026

Copy link
Copy Markdown

🔗 Helpful Links

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

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

✅ No Failures

As of commit 8f684de with merge base d7c5dd4 (image):
💚 Looks good so far! There are no failures yet. 💚

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 Aug 24, 2026
@Erik-Lundell Erik-Lundell added the release notes: none Do not include this in the release notes label Aug 24, 2026
@Erik-Lundell Erik-Lundell changed the title XNNPack: Extend to_copy support wheh skip_dim_order=True XNNPack: Extend to_copy support when skip_dim_order=True Aug 24, 2026
@Erik-Lundell
Erik-Lundell force-pushed the xnnpack-to-copy branch 2 times, most recently from a6cd216 to 8f684de Compare August 24, 2026 14:33
- Rely on meta from ChannelsLastTaggedReshapePass
for data layout.
- Fix test for sort_decomposed_operations.

Signed-off-by: Erik Lundell <erik.lundell@arm.com>
Change-Id: I47b26202a6b24aa08e6b699522887e52438ef580
@JakeStevens

Copy link
Copy Markdown
Contributor

@claude please review

@claude

claude Bot commented Aug 24, 2026

Copy link
Copy Markdown

Claude finished @JakeStevens's task in 7m 42s —— View job


Code Review

  • Read changed files
  • Analyze correctness & design
  • Post review feedback

Nice work — the decomposition into TRANSPOSE/CAST/COPY is clean, the "make the source of truth the reshape pass, fall back to memory_format only when untagged" split is well reasoned, and the tests cover the new paths well. A few points below, ordered by importance.


1. ToCopyConfig permits dtype conversions the visitor can't faithfully serialize

ToCopyConfig.check_constraints (generic_node_configs.py:539) only validates the dim-order side. Any dtype pair is accepted and routed to the CASTXNNConvert path. But NodeVisitor.get_serialized_dtype (node_visitor.py:266-278) only recognizes fp32/fp16/bf16 (plus quant types) — every other dtype silently falls back to xnn_datatype_fp32.

So an integer→float _to_copy (e.g. int32 → float32) would declare the input tensor as fp32 while its data is int32, and emit an fp32 → fp32 convert. For a constant this may be masked by buffer folding, but for a runtime integer activation this is a correctness bug.

Contrast with ToDimOrderCopyConfig (:507), which explicitly gates the dtype dimension. I'd recommend ToCopyConfig mirror that: reject changes_dtype conversions whose source/target aren't in the XNNPACK-supported float set (fp32/fp16/bf16), with a why(...) reason. Otherwise please confirm how integer sources are handled. Fix this →

2. Quantized redundant-copy path was not given the same dtype/shape guard

The new _same_tensor_type_and_shape / _preserves_tensor_type_and_shape guards were added to _try_remove_regular_redundant_to_copy (remove_redundant_copy_pass.py:49 and :71), which is correct. But _try_remove_quantized_redundant_to_copy (:83) still removes copies based purely on memory-format tags, with no dtype/shape check. If a dtype-changing _to_copy ever appears inside a dq → to_copy → q chain, it would be incorrectly elided. Probably out of scope for this PR, but worth either guarding for symmetry or adding a short comment noting the quantized path assumes dtype-preserving copies.

3. _append_output_tensor — redundant parameter

At the call site (op_to_copy.py:295-298), output_is_channels_last is passed both as the output_is_channels_last arg and again as convert_to_nhwc. They're always identical, so convert_to_nhwc is dead surface area on an already 12-parameter helper. Dropping it and using output_is_channels_last internally would simplify the signature. Minor, per the repo's "choose simpler, more concise" guidance.


Things I checked that look correct

  • No circular import from the new top-level ChannelsLastTaggedReshapePass import in op_to_copy.pynode_visitor.py already imports it the same way.
  • Intermediate-tensor dtype threading in the decomposition loop is consistent for both TRANSPOSE→CAST and CAST→TRANSPOSE orderings, and sort_decomposed_operations correctly runs the transpose on the smaller dtype.
  • tag_node handling of None/preserve_format (inheriting the input's NCHW/NHWC tag) is sound, and the match / X | None / tuple[...] syntax is fine given requires-python >=3.10.
  • Transpose num_dims is read back from the serialized tensor, so it stays consistent with define_tensor's NHWC permutation.
    · branch xnnpack-to-copy

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

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: xnnpack Issues related to xnnpack delegation and the code under backends/xnnpack/ partner: arm For backend delegation, kernels, demo, etc. from the 3rd-party partner, Arm release notes: none Do not include this in the release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants