[ExecuTorch][WebGPU] Add argmax/argmin ops + int64-output path#21209
[ExecuTorch][WebGPU] Add argmax/argmin ops + int64-output path#21209JCNTH wants to merge 1 commit into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21209
Note: Links to docs will display an error until the docs builds have been completed. ❗ 1 Active SEVsThere are 1 currently active SEVs. If your PR is affected, please view them below: ❌ 46 New Failures, 3 Unrelated FailuresAs of commit feb7511 with merge base 266e0dc ( NEW FAILURES - The following jobs have failed:
FLAKY - The following jobs failed but were likely due to flakiness present on trunk:
BROKEN TRUNK - The following job failed but were present on the merge base:👉 Rebase onto the `viable/strict` branch to avoid these failures
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This PR needs a
|
psiddh
left a comment
There was a problem hiding this comment.
Approving full WebGPU stack
Stack from ghstack (oldest at bottom):
Problem: The WebGPU delegate has no
aten.argmax.default/aten.argmin.default, and — more fundamentally — no int64-OUTPUT support: the AOT downcasts the int64 index to an int32 GPU buffer, but the ExecuTorch program output is int64, andcopy_outputsraw-copied the int64 EValue's bytes from the int32 staging buffer (a size mismatch). argmax would be the first int64-output op. argmax unlocks on-GPU decode sampling.Solution: Port
et_vk.argmax/argmin(last-dim arg-reduction -> int64 index) sharing one handler, mirroring VulkanArgReduce.cpp(arg_reduce_impl, last-dim only, theadd_reduce_per_row_nodeaccumulator that tracks{val, idx}). The kernel reuses the landedamaxlast-dim reduction + index-tracking: a strict>(argmax) /<(argmin) scan keeps the FIRST extremum (= torch tie-break), writing the index as int32 (1 u32/row) to the int32 GPU buffer. Add the int32->int64 output-widening path:copy_outputsnow maps each output's LIVE staging size (cur_nbytes) and, when the host EValue is 2x the int staging buffer, sign-extends int32->int64 into the EValue; matched-dtype outputs keep the unchanged raw-copy path.Implementation:
argmax/Reduce.cppregistersaten.argmax.default+aten.argmin.default->arg_reduce_impl(graph, args, is_argmin); args[in, dim, keepdim, out],dimscalar (last-dim guard),out = args.back(), guards fp32 input / int32 output / shape, resize hook.arg_reduce.wgslis one row per thread.WebGPUGraph::copy_outputsmapscur_nbytes+ the guardeddst == 2*map && is_intwiden.WebGPUBackend::executewrapsexecute()+copy_outputs()in try/catch so a defensive throw never crosses the backend boundary.Constraints: last-dim reduction only (mirrors Vulkan
normalized_dim == ndim-1); fp32 input, int32-backed int64 index output. Thecopy_outputschange is byte-identical for every existing fp32/int8 output (cur_nbytes == EValue nbytesfor matched dtypes) — verified by regression (floor_divide fp32, q8ta convs int8 all still pass).Differential Revision: D112257656