Skip to content

Vulkan: hoist the pointwise conv spatial divides out of the K loop - #22780

Open
msluszniak wants to merge 1 commit into
pytorch:mainfrom
msluszniak:ms/vulkan-pw-hoist-spatial-coords
Open

Vulkan: hoist the pointwise conv spatial divides out of the K loop#22780
msluszniak wants to merge 1 commit into
pytorch:mainfrom
msluszniak:ms/vulkan-pw-hoist-spatial-coords

Conversation

@msluszniak

@msluszniak msluszniak commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Summary

conv2d_pw_tiled recovers the (x, y) texel coordinate from the flattened spatial index with a divide and a modulo by W_out. W_out is a runtime uniform, so neither strength reduces to a shift, and both sat inside the loop over K: once per (m, k4) on the input loads, and again per output texel on the store. The coordinates depend only on m, so a conv with K4 = 4 issued four times as many integer divides as the arithmetic they fed.

This computes them once per invocation and passes them down. No change to the tiling, the dispatch, or the math.

Measurements

Three models, both GPU vendors. Arms interleaved within one session, per-dispatch GPU timestamps from the query pool, median of 3 rounds. Mali-G76 is a Galaxy S10+, Adreno 840 a Galaxy S26 Ultra.

model device conv2d_pw share conv2d_pw whole graph GPU
lraspp-mobilenet-v3-large fp16 @520 Mali-G76 71% 256.3 -> 72.0 ms (3.56x) 284.1 -> 100.2 ms (2.83x)
selfie-segmentation fp16 @256 Mali-G76 66% 8.02 -> 4.18 ms (1.92x) 12.2 -> 8.3 ms (1.47x)
selfie-segmentation fp16 @256 Adreno 840 66% 0.657 -> 0.519 ms (1.27x) 1.179 -> 1.041 ms (1.13x)
PP-OCRv6 fp16 Adreno 840 41% 32.08 -> 23.64 ms (1.36x) 65.76 -> 57.34 ms (1.15x)

The gain tracks how much of the graph is pointwise convolution and how deep the K loop is, which is why lraspp gains most: more channels means more K iterations, so more redundant divides per invocation. A transformer with no pointwise convs (CLIP ViT-B/32 vision, 0 such dispatches) is unaffected at 1.000x, as expected.

End to end on lraspp this is 310.3 -> 114.1 ms on Mali. For reference the XNNPACK int8 build of the same model, which is what that backend ships as its Android default, measures 93.0 ms there.

Interleaving matters on the Mali part: the same binary reads 25.2 ms hot and 8.0 ms settled, so arms measured in separate sessions are not comparable. Within a session, round to round spread is under 1%.

Correctness

Output is bit identical before and after on every model measured, max |diff| = 0.0, including on inputs chosen to produce non-degenerate outputs.

conv2d_pw_tiled recovers the (x, y) texel coordinate from the flattened
spatial index with a divide and a modulo by W_out. W_out is a runtime
uniform, so neither strength reduces to a shift, and both sat inside the
loop over K: once per (m, k4) on the input loads, and again per output
texel on the store. The coordinates depend only on m, so a conv with
K4 = 4 issued four times as many integer divides as the arithmetic they
fed.

Compute them once per invocation and pass them down. On a Mali-G76,
selfie segmentation fp16 at 256x256 spends 66% of its GPU time in this
shader, and that drops from 8.02 ms to 4.18 ms (1.92x); whole-graph GPU
time goes 12.2 ms to 8.3 ms and end-to-end inference 14.6 ms to 10.7 ms.
Output is bit identical before and after.
@msluszniak
msluszniak requested a review from SS-JIA as a code owner September 13, 2026 10:10
@pytorch-bot pytorch-bot Bot added the module: vulkan Issues related to the Vulkan delegate and code under backends/vulkan/ label Sep 13, 2026
@pytorch-bot

pytorch-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown

🔗 Helpful Links

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

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

⚠️ 15 Awaiting Approval

As of commit 2e6e14e with merge base 14dab10 (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 Sep 13, 2026
@github-actions

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

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: vulkan Issues related to the Vulkan delegate and code under backends/vulkan/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants