Skip to content

[HLSL] Add LinAlg descriptor bounds coverage for matrix accumulation - #8881

Open
Jack Elliott (JoeCitizen) wants to merge 2 commits into
microsoft:mainfrom
JoeCitizen:linalg-hlk-accumulate-bounds
Open

[HLSL] Add LinAlg descriptor bounds coverage for matrix accumulation#8881
Jack Elliott (JoeCitizen) wants to merge 2 commits into
microsoft:mainfrom
JoeCitizen:linalg-hlk-accumulate-bounds

Conversation

@JoeCitizen

@JoeCitizen Jack Elliott (JoeCitizen) commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Proposal 0035 lets an implementation resolve an out-of-bounds descriptor access either by dropping the whole operation or by dropping only the elements the view does not admit whole. Add some OOB tests specifically for accumulation.

Assisted-by: GitHub Copilot

Proposal 0035 permits an implementation to resolve an out-of-bounds
descriptor access either by dropping the whole operation or by dropping
only the elements the view does not admit whole, and it states that
bounds checking is not required for root descriptors. The existing
accumulate coverage binds through addRootView, so it cannot reach either
rule; only the store and load paths had bounded-view cases.

These two cases bind MatrixAccumulateToDescriptor through a bounded
descriptor table and accept exactly the two permitted outcomes, mirroring
the shapes already used for MatrixStoreToDescriptor: a packed 16x16 F16
matrix behind a 260 byte view, which cuts two elements into row 8, and an
offset 4x8 F16 matrix with a padded 32 byte stride behind a 172 byte view,
which cuts within row 1 rather than on the padding. Both boundaries fall
mid-row so a row-granular bounds check cannot pass, and both are carried
over from the store cases so the two opcodes are compared on identical
geometry.

Accumulation needs a destination seed that a store cannot reproduce,
otherwise accumulating onto the seed and storing the addend give the same
buffer and the case cannot tell MatrixAccumulateToDescriptor from
MatrixStoreToDescriptor. The addend and the seed are therefore distinct
arithmetic sequences, starting at 1 and 1000, and the expected sums are
generated from their own closed form with a step of two rather than by
replaying the addition the GPU performs. Every value stays below 2048, so
all of them, and all of the seeds, are exact in F16 and the comparison can
be for equality.

makeSequentialMatrix gains an optional step so the expected image comes
from the same range-guarded helper as the other two rather than from a
hand-rolled loop; it defaults to one, so existing callers are unaffected.
accumulateBufferBoundedByView is the accumulate-side counterpart to
storeBufferBoundedByView: an accumulation the bounds check rejects never
touches memory, so the elements the view does not admit whole keep the
value the destination was seeded with rather than the poison the store
version restores.

Both non-vacuity guards are carried across from the store runner. They are
what stop a view that admits everything, or nothing, from making the case
pass without discriminating: the two candidates must differ from each
other and from the unbounded image. The source is deliberately viewed in
full so an observed result cannot be attributed to a bounds check on the
load instead of the accumulation.

Validated on WARP against a matched runtime. The full LinAlg class goes
from 87 tests, 74 passed, 8 failed, 5 skipped to 89 tests, 76 passed, 8
failed, 5 skipped, and a per-test comparison shows the only two
differences are the cases added here; no existing test changes bucket. The
eight failures are pre-existing and unrelated, covering group-shared
memory skew and the three known WARP Convert defects.

Assisted-by: GitHub Copilot
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 83725f5d-8e98-4c1d-91ee-ad47629e007b

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The test logic correctly distinguishes the permitted outcomes; only a non-blocking explicit-type style issue remains.

Pull request overview

Adds matrix-accumulation coverage for permitted out-of-bounds descriptor behavior.

Changes:

  • Adds stepped sequential matrices and accumulation-boundary oracle logic.
  • Adds packed and offset/padded descriptor-table tests.
File summaries
File Description
tools/clang/unittests/HLSLExec/LinAlgTests.cpp Adds bounded-view accumulation tests and supporting oracle utilities.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tools/clang/unittests/HLSLExec/LinAlgTests.cpp Outdated
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Copilot AI review requested due to automatic review settings September 4, 2026 00:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The tests correctly cover both permitted bounds behaviors; only a minor explicit-type style issue remains.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

tools/clang/unittests/HLSLExec/LinAlgTests.cpp:4172

  • Use the explicit return type here. runShaderOp returns a straightforward std::shared_ptr<st::ShaderOpTestResult> (HlslExecTestUtils.cpp:1609), so auto does not meet this repository's explicit-type style.
  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

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

Labels

None yet

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

2 participants