Skip to content

metal : add CONV_2D_DW (depthwise convolution) support#21565

Merged
ggerganov merged 9 commits into
ggml-org:masterfrom
Sou-ly:metal-conv2d-dw
Jul 9, 2026
Merged

metal : add CONV_2D_DW (depthwise convolution) support#21565
ggerganov merged 9 commits into
ggml-org:masterfrom
Sou-ly:metal-conv2d-dw

Conversation

@Sou-ly

@Sou-ly Sou-ly commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Addresses Feature Request: Implement missing ops from backends #14909
  • Adds Metal GPU acceleration for GGML_OP_CONV_2D_DW (depthwise 2D convolution), used by MobileNet/EfficientNet-style architectures
  • Supports both WHCN (contiguous) and CWHN (channels-first) memory layouts via byte-stride indexing
  • Supports f32 and f16 kernel weights with f32 input/output
  • Adds extra tests for performance benchmarking

Performance (Apple M5)

Shape Layout Kernel Metal M5 CPU M5 Speedup
[19,30,128,1] WHCN [7,7,1,128] 88.01 us 4717.40 us 53.60x
[19,30,128,1] CWHN [7,7,1,128] 48.72 us 3795.78 us 77.91x
[24,1,128,1] WHCN [15,1,1,128] 8.59 us 2825.94 us 329.0x
[24,1,256,1] WHCN [31,1,1,256] 28.32 us 3398.27 us 120.0x
[24,1,256,1] CWHN [31,1,1,256] 15.66 us 2694.99 us 172.1x
[512,512,256,1] WHCN [3,3,1,256] 15265 us 86947 us 5.69x
[512,512,256,1] CWHN [3,3,1,256] 16445 us 41038 us 2.50x
[112,112,32,1] WHCN [3,3,1,32] 95.88 us 4590.27 us 47.88x
[112,112,32,1] CWHN [3,3,1,32] 98.48 us 2775.28 us 28.18x
[56,56,128,1] WHCN [5,5,1,128] 52.20 us 3828.11 us 73.34x
[56,56,128,1] CWHN [5,5,1,128] 42.93 us 4605.90 us 107.3x

Test plan

  • test-backend-ops test -o CONV_2D_DW — 4/4 tests pass on Metal (both WHCN and CWHN layouts)
  • Results verified against CPU reference implementation

AI usage disclosure

Yes: PR description (partial), code cleanup and template implementations for different data formats than FP32. Same as my implementation of ADD1 #21267

@Sou-ly Sou-ly requested a review from a team as a code owner April 7, 2026 14:50
@ggml-gh-bot

ggml-gh-bot Bot commented Apr 7, 2026

Copy link
Copy Markdown

Hi @Sou-ly, thanks for your contribution!

Per our contribution guidelines, the automated PR checker found the following issue(s) that need your attention:

  • AI-generated content: This project does not accept PRs, descriptions or commit messages that are fully or predominantly AI-generated. If you have used AI to assist you in writing code, please make sure to disclose that explicitly.

Please note that maintainers reserve the right to make final decisions on PRs. If you believe there is a mistake, please comment below.

@Sou-ly Sou-ly requested a review from ggerganov as a code owner April 7, 2026 15:15
@github-actions github-actions Bot added testing Everything test related ggml changes relating to the ggml tensor library for machine learning Apple Metal https://en.wikipedia.org/wiki/Metal_(API) labels Apr 7, 2026
@Sou-ly Sou-ly force-pushed the metal-conv2d-dw branch from a8265cb to 2947778 Compare June 1, 2026 04:29
@QuintinShaw

Copy link
Copy Markdown

FWIW, I tested this locally on an Apple M1 iMac at PR head 29477782f8da01a1a77bb032c511c604f6385f84.

The dedicated backend op test looks good here:

./build/bin/test-backend-ops test -o CONV_2D_DW
MTL0: 4/4 tests passed
3/3 backends passed

I also ran the full backend test suite on the PR head, and once more after a clean no-commit merge with current master (039e20a2db9e87b2477c76cc04905f3e1acad77f). Both runs finished with 3/3 backends passed.

For my downstream ASR path, I tried a few local-only depthwise-conv shapes that show up in encoder-style workloads:

Shape Layout Kernel Metal M1 CPU Speedup
[19,30,128,1], kernel [7,7,1,128] WHCN F32 239.49 us 1520.58 us 6.35x
[19,30,128,1], kernel [7,7,1,128] CWHN F32 323.92 us 468.19 us 1.45x
[24,1,128,1], kernel [15,1,1,128] WHCN F32 10.29 us 44.56 us 4.33x
[24,1,256,1], kernel [31,1,1,256] WHCN F32 16.11 us 144.93 us 9.00x
[24,1,256,1], kernel [31,1,1,256] CWHN F32 16.62 us 203.10 us 12.22x

I also did a quick local check of the F16-weight Metal path by comparing Metal F16-kernel output against Metal F32-kernel output, using F16-representable weights. The 13 cases I tried all matched exactly (max_abs=0, NMSE=0). That included the ASR shapes above, dilation, prime channel counts, batch > 1, and a W=1 boundary case.

One caveat: the large synthetic [512,512,256,1] perf case was slower than CPU on this M1, so the win seems pretty shape-dependent. For the smaller ASR-style shapes I care about, though, this path was consistently faster.

@ggerganov ggerganov self-assigned this Jun 27, 2026
@Sou-ly Sou-ly force-pushed the metal-conv2d-dw branch from 2947778 to 8e6cb7b Compare June 28, 2026 15:11
@Sou-ly

Sou-ly commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed testing @QuintinShaw! I reworked the Metal dispatch based on your feedback — 3D grid for the standard path, and a separate channel-tiled kernel for non-contiguous layouts (CWHN). Here are updated numbers on an M5:

Shape Layout Kernel Metal M5 CPU M5 Speedup
[19,30,128,1] WHCN [7,7,1,128] 88.01 us 4717.40 us 53.60x
[19,30,128,1] CWHN [7,7,1,128] 48.72 us 3795.78 us 77.91x
[24,1,128,1] WHCN [15,1,1,128] 8.59 us 2825.94 us 329.0x
[24,1,256,1] WHCN [31,1,1,256] 28.32 us 3398.27 us 120.0x
[24,1,256,1] CWHN [31,1,1,256] 15.66 us 2694.99 us 172.1x
[512,512,256,1] WHCN [3,3,1,256] 15265 us 86947 us 5.69x
[512,512,256,1] CWHN [3,3,1,256] 16445 us 41038 us 2.50x
[112,112,32,1] WHCN [3,3,1,32] 95.88 us 4590.27 us 47.88x
[112,112,32,1] CWHN [3,3,1,32] 98.48 us 2775.28 us 28.18x
[56,56,128,1] WHCN [5,5,1,128] 52.20 us 3828.11 us 73.34x
[56,56,128,1] CWHN [5,5,1,128] 42.93 us 4605.90 us 107.3x

The large [512,512,256,1] case is now faster than CPU for both layouts. Metal wins across the board.

@ggerganov

Copy link
Copy Markdown
Member

I added some F16 tests that are failing.

@Sou-ly Sou-ly force-pushed the metal-conv2d-dw branch from 5c8a3e2 to 365c8c1 Compare July 8, 2026 14:02
@Sou-ly

Sou-ly commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@ggerganov thanks for the F16 tests, the CPU backend was reading F16 kernel weights as float (casting raw bytes), fixed in 365c8c1. Metal side was already handling it via the TK template. All 8 tests pass now.

@Sou-ly Sou-ly force-pushed the metal-conv2d-dw branch from 365c8c1 to c8e6cb6 Compare July 9, 2026 02:42
@ggerganov ggerganov merged commit 92b187c into ggml-org:master Jul 9, 2026
31 of 32 checks passed
@ggerganov

ggerganov commented Jul 9, 2026

Copy link
Copy Markdown
Member

@Sou-ly Could you take a look why these conv_2d_dw tests started failing: https://github.com/ggml-org/ggml/actions/runs/29016861329/job/86113894431?pr=1558#step:5:535

This is the branch: ggml-org/ggml#1558

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

Labels

Apple Metal https://en.wikipedia.org/wiki/Metal_(API) ggml changes relating to the ggml tensor library for machine learning testing Everything test related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants