Skip to content

Resize PR 3: Run Resize on the Metal GPU - #2556

Open
czoli1976 wants to merge 1 commit into
sonos:mainfrom
czoli1976:feature/resize-metal-kernel
Open

Resize PR 3: Run Resize on the Metal GPU#2556
czoli1976 wants to merge 1 commit into
sonos:mainfrom
czoli1976:feature/resize-metal-kernel

Conversation

@czoli1976

@czoli1976 czoli1976 commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Resize had no Metal kernel, so in a GPU graph every node round-tripped its tensor through the host. This adds a resample-one-axis kernel that consumes the same per-axis tap/weight plan the CPU op builds, which makes one kernel enough for nearest, linear, cubic and their antialiased variants — they differ only in window size and weights.

Needed the AxisPlan from #2554 and #2555; now that both are merged this is rebased onto main and stands alone as a single commit.

Wiring

The plan depends only on shapes and attributes, so it is baked at translation time; the node then keeps just its data input. That is also why this is wired in translate_node rather than through register_metal_op!: the macro rewires the same inputs, and Resize's scales/sizes constant is a TDim, whose datum type fails the device-dtype gate in try_make_metal_op — the node was rejected before any translator ran. Nodes with a symbolic shape or a non-constant scales input aren't translated and stay on CPU.

Effect

u2netp (rembg, 38 bilinear Resize nodes), 1×3×320×320, --metal -O, min of 3 interleaved rounds:

before after
Resize nodes on GPU 0 / 38 38 / 38
host round-trips (DeviceSync*) 150 74
end-to-end 560.7 ms 460.7 ms (1.22×)

Outputs match the CPU runtime to 6e-7 max abs (f32 accumulation order).

Two caveats I'd rather state than have you find:

  • This does not make Metal beat CPU on this model — 461 ms vs 419 ms on the same machine. The remaining DeviceSyncToHost is 91% of the Metal profile because 33 OptMaxPool nodes still have no Metal kernel and force 40 host round-trips per inference. Resize was necessary but not sufficient; MaxPool is the next one that matters.
  • Per-op Metal timings in dump --profile are encode time, not GPU execution (the sync nodes absorb that), so I'm quoting only the end-to-end figure.

GpuResize is backend-agnostic and CUDA would need only a launch function, but there's no NVIDIA GPU on my machine, so I haven't written code I can't run. Happy for someone with the hardware to take it.

Testing

test-metal 22762 passed / 0 failed (630 of them Resize node tests, which exercise the kernel — I checked the nodes actually land on MetalResize rather than silently falling back). onnx-tests.sh 1_19_1 green. cargo fmt --all --check and cargo clippy clean.

🍍

@czoli1976 czoli1976 changed the title Run Resize on the Metal GPU Resize PR 3: Run Resize on the Metal GPU Aug 2, 2026
@czoli1976
czoli1976 force-pushed the feature/resize-metal-kernel branch from 690e5af to 592639d Compare August 3, 2026 12:28
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

🔴 Bench vs main — 2 speed regression(s) · ⚠️ 11 secondary

Reference: 2026-08-03 morning nightly run (0d old) · full report → run

Speed — evaltime · prefill · decode

Δ metric device main → PR
🔴 +12.9% inceptionv3
evaltime · pass_mt
cortex-a53 1.12 s → 1.26 s
🔴 +5.1% arm_ml_kws_cnn_m
evaltime · pass
cortex-a9 9.28 ms → 9.76 ms

Improvements

Δ metric device main → PR
🟢 -22.0% parakeet_tdt_600m_v3_f32f32_decoder_pass
evaltime · cpu
i9-11900kb_rtx-4060 0.838 ms → 0.653 ms
⚠️ 11 secondary regression(s)
Δ metric device main → PR
⚠️ +22.7% hey_snips_v1
load · 400ms
cortex-a9 75 ms → 92 ms
⚠️ +22.6% arm_ml_kws_cnn_m
load · pass
cortex-a9 84 ms → 103 ms
⚠️ +20.0% hey_snips_v1
load+optimize · 400ms
cortex-a9 145 ms → 174 ms
⚠️ +18.3% arm_ml_kws_cnn_m
load+optimize · pass
cortex-a9 131 ms → 155 ms
⚠️ +14.5% arm_ml_kws_cnn_m
load+optimize · pass
cortex-a7 117 ms → 134 ms
⚠️ +14.1% arm_ml_kws_cnn_m
load · pass
cortex-a7 78 ms → 89 ms
⚠️ +10.4% hey_snips_v1
load · 400ms
cortex-a7 67 ms → 74 ms
⚠️ +9.2% llama_3_2_3B_instruct_q40ef16_541
load+optimize · cuda
jetson-orin-nx 4.14 s → 4.53 s
⚠️ +6.3% qwen3_1_7B_q40ef16_541
load+optimize · cuda
jetson-orin-nx 3.77 s → 4.01 s
⚠️ +5.9% en_tdnn_15M
RSS @ ready · 2600ms
cortex-a55 111 MB → 117 MB
⚠️ +5.4% arm_ml_kws_cnn_m
load+optimize · pass
cortex-a53 74 ms → 78 ms

Resize had no Metal kernel, so every node round-tripped the tensor through the
host in the middle of a GPU graph. A resample-one-axis kernel now consumes the
same per-axis tap-and-weight plan the CPU op builds, which makes it independent
of the interpolator; the plan is baked at translation time, so the node keeps
only its data input and the scales/sizes TDim constant is dropped.
@kali

kali commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

⚠️⚠️⚠️ Just rebased! ⚠️⚠️⚠️

@kali
kali force-pushed the feature/resize-metal-kernel branch from 592639d to d23cd23 Compare August 6, 2026 17:57
@kali kali closed this Aug 6, 2026
@kali kali reopened this Aug 6, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

🔴 Bench vs main — 1 speed regression(s) · ⚠️ 8 secondary

Reference: 2026-08-07 morning nightly run (0d old) · full report → run

Speed — evaltime · prefill · decode

Δ metric device main → PR
🔴 +8.2% arm_ml_kws_cnn_m
evaltime · pass
cortex-a9 9.23 ms → 9.98 ms
⚠️ 8 secondary regression(s)
Δ metric device main → PR
⚠️ +45.2% arm_ml_kws_cnn_m
load · pass
cortex-a9 84 ms → 122 ms
⚠️ +37.7% arm_ml_kws_cnn_m
load+optimize · pass
cortex-a9 130 ms → 179 ms
⚠️ +16.7% arm_ml_kws_cnn_m
load · pass
cortex-a7 78 ms → 91 ms
⚠️ +14.9% hey_snips_v1
load · 400ms
cortex-a7 67 ms → 77 ms
⚠️ +13.4% hey_snips_v1
load+optimize · 400ms
cortex-a7 112 ms → 127 ms
⚠️ +12.7% arm_ml_kws_cnn_m
load+optimize · pass
cortex-a7 118 ms → 133 ms
⚠️ +12.5% arm_ml_kws_cnn_m
load · pass
cortex-a53 48 ms → 54 ms
⚠️ +11.0% arm_ml_kws_cnn_m
load+optimize · pass
cortex-a53 73 ms → 81 ms

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants