Pad 2D conv input channels to reach the specialized Metal kernel#3904
Open
eyupcanakman wants to merge 1 commit into
Open
Pad 2D conv input channels to reach the specialized Metal kernel#3904eyupcanakman wants to merge 1 commit into
eyupcanakman wants to merge 1 commit into
Conversation
Convs whose input channels are not a multiple of 16 fall back to the general implicit gemm kernel. When the output channels are already aligned, the input channels can be padded up to a multiple of 16 and the specialized kernel used instead, writing straight into the output. Timings on the affected shapes are 1.1x to 1.55x, with the output bit-identical to the previous path. Shapes outside the gate are unchanged.
Member
Just to clarify, does that mean performance improvements are only seen when the convolution is run with stride 1 ? |
Contributor
Author
|
I tried stride 2 in an earlier prototype, where 3x3 regressed to about 0.89x while 5x5 and 7x7 improved to 1.06x and 1.17x. I haven't re-benchmarked that on the final input-only design, so this PR keeps the stride-1 gate and leaves a size-aware stride-2 gate as a follow-up. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed changes
A conv whose input channels are not a multiple of 16 misses the specialized implicit gemm kernel and falls to the general one that #2258 added for these shapes. Making that path faster was left open there.
Zero padding the input channels up to a multiple of 16 and running the specialized kernel beats the general kernel on the original shape, even after paying for the padded work.
The gate is narrow. It needs a stride of 1, an output large enough for implicit gemm, a kernel area of at least 9, and output channels that are already aligned.
conv_transpose2dmaps its stride onto an input dilation, so only the stride-1 transpose qualifies.Leaving the output channels alone lets the kernel write straight into
out, so nothing is sliced or copied back and the result stays row contiguous.Weights get the same zero padding, so the added channels contribute nothing to the sum. Output is bit identical to before in
fp32,fp16andbf16.Peak memory during the conv grows by the padded copies of the input and the weights, both released with the command buffer. Over 220 shapes that hit the gate it ran a median of 1.8x and at most 2.4x, worst where the channel count sits just above a multiple of 16 and the kernel is large.
Added two shapes to
test_conv2d_unaligned_channels.Benchmarks
M5 Pro, macOS 27.0, fp32. One shape per process, best of 150 iterations, the two builds measured turn by turn, min of 7 rounds.
(4, 32, 32, 21) x (128, 3, 3, 21)(4, 32, 32, 370) x (128, 7, 7, 370)(16, 56, 56, 40) x (64, 3, 3, 40)(8, 56, 56, 24) x (32, 5, 5, 24)(16, 28, 28, 200) x (256, 3, 3, 200)(16, 224, 224, 40) x (128, 3, 3, 40)(8, 128, 128, 40) x (128, 7, 7, 40)The first two rows are shapes 1 and 4 from
benchmarks/python/conv_unaligned_bench.py, and the last two are larger, where the padded work amortizes and the gain grows. Shapes that miss the gate run the same code as before and measured 0.96x to 1.05x, the noise floor of the measurement.Checklist
Put an
xin the boxes that apply.pre-commit run --all-filesto format my code / installed pre-commit prior to committing changes