镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

[ET-VK][runtime] Preserve zero padding in unary operators - #24754

Open
SS-JIA wants to merge 2 commits into
gh/SS-JIA/694/basefrom
gh/SS-JIA/694/head
Open

SS-JIA wants to merge 2 commits into
gh/SS-JIA/694/basefrom
gh/SS-JIA/694/head

Conversation

@SS-JIA

@SS-JIA SS-JIA commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Stack from ghstack (oldest at bottom):

Ulterior Motive

Make buffer storage behave more like texture storage, so one shader can service
both storage types and buffer tensors need only a single vectorized shader.
Zero-valued padding lets later vectorized operators consume full vectors
without masking.

Rationale

What: Unary operators keep the padding of their outputs zero, and buffer
and texture tensors share one vectorized unary shader.

Why: Buffer tensors now pad their packed dim to four, like textures. If
every operator leaves that padding zero, consumers can load whole vec4s without
masking. Padding to four also makes buffer vec4 loads always in bounds, so the
per-element buffer shader is no longer needed.

Details

  • Unary shader
    • Before: buffers used a scalar path, one element per thread; textures
      used a vec4 path. Neither kept padding zero.
    • After: one vec4 path for both. Buffers dispatch padded numel / 4
      threads and index the buffer as vec4s. Math runs in texel_type (fp32 for
      half). Ops that map zero to zero skip masking. Others zero padding lanes
      when op(0) != 0 for the given bounds, e.g. clamp(0, 1, 2).
    • Input padding is assumed zero: an op that maps zero to zero keeps output
      padding zero only if its input's padding is zero.
    • unary_op_preserves_zero(op_type) in unary_op.glslh lists the ops that
      map zero to zero. Like apply_unary_op, it takes the op type as an
      argument.
  • Dispatch
    • New default_pick_vec4_gwg in Common: one thread per output vec4.
      Buffers get padded numel / 4 threads; textures keep the texel grid.
    • The output's hashed layout is passed as a spec constant. Input and output
      must match in storage type and dtype. Buffers must also match in hashed
      layout, since the shader reads and writes the same texel index; textures
      need standard axis maps and matching packed dims.
  • Padding helpers in indexing.glslh
    • num_valid_lanes and mask_padding_lanes take a buffer texel index, a
      texture position or a TensorIndex. When the packed dim needs no padding,
      mask_padding_lanes returns after one check that every thread evaluates
      the same way.
  • Generated correctness tests
    • Before: generated tests compared logical outputs only.

    • After: suites can opt into a physical padding check.
      OutputPaddingCheck poisons the output's padding through an aliased padded
      view before execution, then reads it back and checks it is zero, separately
      from the logical comparison. A packed dim beyond the tensor's rank is
      innermost in that view. Benchmark generation does not insert these checks.

      suite.check_zero_padding = True
    • Enabled for the unary suites, the dedicated tan suite and GELU, which
      now run width-, height- and channels-packed.

    • New padding-checked suites: relu, sigmoid, tanh and abs over
      [-2, 2]; clamp and hardtanh with bounds on both sides of zero; clamp
      with None bounds and int32 inputs; bitwise_not and logical_not on
      bool.

Smaller changes:

  • Registering a second suite for an op adds to the first instead of replacing
    it. The dedicated tan suite gets a name suffix.
  • Optional scalar arguments generate add_none() or a scalar value.
  • New test_generator Python unit test target.
  • New dynamic_clamp_zeroes_output_padding test: clamp with SymInt bounds
    must zero output padding that was poisoned before execution.

Review unary.glsl, unary_op.glslh and indexing.glslh first, then
UnaryOp.cpp and Common, then the test generator.

Authored with Codex and Claude Code.

Differential Revision: D130297303

[ghstack-poisoned]
@pytorch-bot

pytorch-bot Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/24754

Note: Links to docs will display an error until the docs builds have been completed.

❌ 2 New Failures, 4 Pending, 2 Unrelated Failures

As of commit 697efce with merge base 9517b6b (image):

NEW FAILURES - The following jobs have failed:

BROKEN TRUNK - The following jobs 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.

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

[ghstack-poisoned]

This branch was previously deployed

1 inactive deployment
cadence — 697efce6 Deployed Nov 7, 2026 by SS-JIA via hifi-op-test / hifi4 #37209
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants