Skip to content

Vulkan: halve the pointwise conv spatial tile - #22781

Open
msluszniak wants to merge 1 commit into
pytorch:mainfrom
msluszniak:ms/vulkan-pw-tile-m2
Open

Vulkan: halve the pointwise conv spatial tile#22781
msluszniak wants to merge 1 commit into
pytorch:mainfrom
msluszniak:ms/vulkan-pw-tile-m2

Conversation

@msluszniak

@msluszniak msluszniak commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Summary

conv2d_pw_tiled is generated only at TILE_M=4. TILE_M=2 is faster on every model and both GPU vendors I measured, so this changes the generated variant and the matching global workgroup size. Nothing else about the shader, the tiling logic or the math changes.

Measurements

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

model device conv2d_pw whole graph GPU
lraspp-mobilenet-v3-large fp16 @520 Mali-G76 71.5 -> 43.8 ms (1.63x) 99.3 -> 71.7 ms (1.38x)
selfie-segmentation fp16 @256 Mali-G76 4.21 -> 2.32 ms (1.82x) 8.46 -> 6.54 ms (1.29x)
lraspp-mobilenet-v3-large fp16 @520 Adreno 840 5.35 -> 5.00 ms (1.07x) 10.95 -> 10.59 ms (1.03x)
selfie-segmentation fp16 @256 Adreno 840 0.530 -> 0.435 ms (1.22x) 1.050 -> 0.956 ms (1.10x)
PP-OCRv6 fp16 Adreno 840 23.66 -> 23.72 ms (1.00x) 57.5 -> 58.2 ms (0.99x)

No regression anywhere; the Mali gain is the large one.

Why 2 and not something else

The tile size was swept, not guessed. On Mali-G76 with lraspp, relative to the current TILE_M=4:

variant conv2d_pw vs current
TILE_M=2 43.8 ms 1.63x
TILE_M=1 73.7 ms 0.97x
TILE_M=8 287.6 ms 0.24x
TILE_N4=2 436.1 ms 0.16x
TILE_N4=4 1136.8 ms 0.06x

2 is a genuine optimum: 1 gives each invocation too little work, and anything wider falls off a cliff. The magnitude of the wide variants (4x to 16x, not tens of percent) points at register spilling rather than occupancy, and it reproduces in both dispatch shapes I have - selfie is small-N4/large-M, lraspp is large-N4/small-M.

Note TILE_M4 is left at 1. It is declared in this shader's parameter list but none of the includes conv2d_pw_tiled.glsl actually pulls in reference it, so it has no effect here.

Correctness

Output is bit identical to the current shader at every tile size tested, on both devices, max |diff| = 0.0.

cc @SS-JIA @manuelcandales @digantdesai @cbilgin

@msluszniak
msluszniak requested a review from SS-JIA as a code owner September 13, 2026 11:17
@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/22781

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

⚠️ 16 Awaiting Approval

As of commit bf7ef40 with merge base 903696a (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.

@msluszniak
msluszniak force-pushed the ms/vulkan-pw-tile-m2 branch 2 times, most recently from 22f9761 to 41e4a5a Compare September 13, 2026 11:27
conv2d_pw_tiled is generated only at TILE_M=4. TILE_M=2 is faster on every
model and both GPU vendors measured, and the tile size is otherwise
unchanged, so this just moves the generated variant.

Mali-G76 (Galaxy S10+), conv2d_pw / whole-graph GPU, median of interleaved
rounds: lraspp-mobilenet-v3-large fp16 @520 71.5 -> 43.8 ms (1.63x) and
99.3 -> 71.7 ms (1.38x); selfie-segmentation fp16 @256 4.21 -> 2.32 ms
(1.82x) and 8.46 -> 6.54 ms (1.29x).

Adreno 840 (Galaxy S26 Ultra): lraspp 5.35 -> 5.00 ms (1.07x) and
10.95 -> 10.59 ms (1.03x); selfie 0.530 -> 0.435 ms (1.22x) and
1.050 -> 0.956 ms (1.10x); PP-OCRv6 fp16 neutral at 1.00x / 0.99x.

Going the other way is much worse, which is what makes 2 the optimum
rather than a local accident: TILE_M=1 is 0.97x, TILE_M=8 0.24x,
TILE_N4=2 0.16x and TILE_N4=4 0.06x on Mali.

Output is bit identical at every tile size tested.
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