[ExecuTorch][WebGPU] slice_copy Double-arg scalar handling + view_copy/alias glue#20865
[ExecuTorch][WebGPU] slice_copy Double-arg scalar handling + view_copy/alias glue#20865JCNTH wants to merge 1 commit into
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/20865
Note: Links to docs will display an error until the docs builds have been completed. ✅ You can merge normally! (1 Unrelated Failure)As of commit f35d269 with merge base aceeb40 ( 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
|
Stack from ghstack (oldest at bottom):
Hardens
slice_copyscalar-arg decoding against edge-dialectDouble-serialized indices and adds theview_copy/alias/clonereshape pass-throughs needed for graph glue.Problem — two graph-glue gaps: (1) the edge dialect sometimes serializes an integer
sliceindex (dim/start/end/step) as a floating-pointDouble(e.g. a0start), which theslicehandler rejected as unsupported; (2) contiguous reshape / aliasing ops (view_copy,alias_copy,clone,_clone_dim_order) had no handler, breaking otherwise-delegatable subgraphs.Solution — Before — a
Double-typed slice index threw, and reshape/alias ops had no handler. After —slice_copyscalar reads accept an integralDouble(truncating to the int index) and reject only a genuinely fractional one, whileSymInt(dynamic start/end) andNull(default) still resolve as before; andview_copy/alias_copy/clone/_clone_dim_orderall lower to a single contiguous flat copy (or an in-place no-op when input and output alias the same buffer).Implementation:
read_scalar(dim/step) andread_index(start/end) switch on the value type:Int(INT64_MAX-> default),Double-> truncated int iff it round-trips (static_cast<int64_t>(d)back tod) else throw"non-integral ..."(NaN and out-of-int64-range doubles are rejected before the cast, since casting them is UB),Null-> default;read_indexadditionally resolves aSymIntviaread_symint.out_bufi -> in_bufiby walking per-dim strides, with the sliced dim's input coord= start + coord*step; dynamicstart/end/SymIntare handled by a resize hook that recomputes the liveout[dim]length (ceiling division) and rewrites the meta/params uniforms plus the dispatch count (mirrors Vulkanresize_slice_copy_node).add_flat_copy(shared by all the reshape/alias ops) type-checks both args are tensors, guards 4-byte alignment and equalnbytes(a view preservesnumel, so this also prevents an OOB copy), then either skips the copy whenin.buffer == out.buffer(aliased, already in place;CopyBufferToBufferrejectssrc == dst) or emits a buffer-to-buffer copy; a resize hook keeps the live output shape and copy byte-count in sync under dynamic shapes._clone_dim_orderignores itsdim_orderarg (the AOT pass elides it via shape and dtype).backends/vulkan/runtime/graph/ops/impl/Slice.cpp(normalize_idx/INT64_MAXdefault and the ceiling-division length) andbackends/vulkan/runtime/graph/ops/impl/View.cpp(theview_bufferno-remap contiguous reshape).Constraints — fp32 (4-byte-aligned) operands;
slicerequiresstep >= 1and an in-rangedim; a fractionalDoubleindex is a hard error, not truncated;view/alias/clonerequire equal input/outputnumel(contiguous reshape only, no layout remap).Co-authored-with: Claude Code.
Differential Revision: D110836670