Skip to content

[HLSL] Add MatVec interpretation and bias coverage for LinAlg - #8775

Open
Jack Elliott (JoeCitizen) wants to merge 4 commits into
microsoft:mainfrom
JoeCitizen:linalg-hlk-matvec-interpretation
Open

[HLSL] Add MatVec interpretation and bias coverage for LinAlg#8775
Jack Elliott (JoeCitizen) wants to merge 4 commits into
microsoft:mainfrom
JoeCitizen:linalg-hlk-matvec-interpretation

Conversation

@JoeCitizen

@JoeCitizen Jack Elliott (JoeCitizen) commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Proposal 0035 permits a thread-scope Multiply vector to be native or an InterpretedVector, pairing a packed vector with an interpretation type. The interpreted forms had no coverage.

These six tests cover non-uniform F16 in row-major and column-major layouts, packed SInt8 and UInt8 inputs, unsigned UInt32 output, and MultiplyAdd with the bias in a separate resource. The UInt8 case reuses the SInt8 bytes so high-bit lanes decode differently under the two interpretations. Expected values come from overflow-checked host dot products, and the full output allocation including padding and guard bytes is compared against a poison fill.

Column-major is required rather than gated: a thread-scope load permits row-major, column-major and optimal layouts, and only transposed loads need a driver query. MatVecMulAdd_Thread_4x8_F16_IndependentBias fails on WARP, which advertises the F16 tuple then rejects dx.op.linAlgMatVecMulAdd as an invalid overload, matching two existing failures on the merge base.

Copilot AI balanced review requested due to automatic review settings August 13, 2026 21:03

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.

Pull request overview

Adds thread-scope LinAlg matrix-vector tests for layouts, interpreted inputs, unsigned output, and independent bias.

Changes:

  • Adds six Multiply/MultiplyAdd execution tests.
  • Adds host-side encoding, overflow-checked oracles, capability checks, and guard-byte validation.

💡 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
Copilot AI review requested due to automatic review settings August 13, 2026 21:58
@JoeCitizen
Jack Elliott (JoeCitizen) force-pushed the linalg-hlk-matvec-interpretation branch from baa671f to 2010c0e Compare August 13, 2026 21:58

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@damyanp Damyan Pepper (damyanp) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Some observations, none of these should block the PR after it has been reviewed by someone with more domain knowledge than me.

Comment thread tools/clang/unittests/HLSLExec/LinAlgTests.cpp Outdated
Comment thread tools/clang/unittests/HLSLExec/LinAlgTests.cpp Outdated
Comment thread tools/clang/unittests/HLSLExec/LinAlgTests.cpp Outdated
Copilot AI review requested due to automatic review settings August 14, 2026 20:33

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (2)

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

  • Please use the explicit result type under the repository's almost-never-auto convention. runShaderOp declares this as std::shared_ptr<st::ShaderOpTestResult> in HlslExecTestUtils.h:601.
  auto Result =

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

  • Per the repository's almost-never-auto convention, this straightforward return type should be explicit. createComputeOp is declared as returning std::unique_ptr<st::ShaderOp> in HlslExecTestUtils.h:571.

This issue also appears on line 2287 of the same file.

  auto Op = createComputeOp(Shader, "cs_6_10", RootSignature, Args->c_str());

Copilot AI review requested due to automatic review settings August 14, 2026 22:06

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Jack Elliott and others added 4 commits August 15, 2026 10:34
Exercise non-uniform F16 row-major and column-major layouts, packed SInt8 and
UInt8 interpreted inputs, unsigned UInt32 output, and a separate non-uniform
bias resource. High-bit UInt8 lanes distinguish unsigned from signed decoding
of the same bytes.

Derive every expected result with overflow-checked host dot products plus
optional bias, encode packed lanes least-significant-byte first, and compare
the complete poisoned output including padding and guard bytes. Query the
exact vector, matrix, bias, and result capability tuple, requiring both
mandatory F16 layouts and gating only optional output cases.

Column-major is required rather than capability gated because a thread scope
matrix load permits row-major, column-major and optimal layouts, and only
transposed loads are implementation specific and need a driver query.

Assisted-by: GitHub Copilot

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 83725f5d-8e98-4c1d-91ee-ad47629e007b
LinAlgTests.cpp places helper namespaces before the test classes that use
them: cpu_oracle sits at the top of the file, ahead of the first test class.
matvec_interpretation was appended after the classes instead, which left no
way for a LinAlgCPUOracleTests method to call into it without a forward
declaration.

This is a pure relocation of the namespace block. No line is added, removed
or edited: the file has the same 6060 lines before and after, and the sorted
set of lines is identical. clang-format reports no drift.

Verified with the full HLSLExec LinAlg selection on WARP, compared per test
rather than by totals: 45 total, 39 passed, 5 failed, 1 skipped, with the
non-passing set unchanged from the parent commit.

Assisted-by: GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 83725f5d-8e98-4c1d-91ee-ad47629e007b
Move the checked int64 helpers into cpu_oracle, next to the existing
checkedMultiply and checkedAdd for size_t. That namespace is already the
file's home for arithmetic the oracle relies on, so matvec_interpretation no
longer carries its own copies. The checks stay: encodeComponents accepts
UInt32 values up to 4294967295, so a UInt32 matrix times a UInt32 vector
overflows int64 by construction. An overflow in the oracle yields a wrong
expected value, which can pass a broken implementation rather than fail a
correct one, so this is the direction worth guarding.

Report the rejected value when a component cannot be represented in the
target type. All six rejection sites now name the type and the value instead
of failing with no context, and componentTypeName covers SInt8 and UInt8
rather than returning "Unsupported" for them.

Promote the oracle self-test out of runCase into its own method on
LinAlgCPUOracleTests, so it runs once instead of once per case. That class
already exists for exactly this purpose and deliberately carries no Kits
metadata, so HLK runs never select it. Each assertion gets its own VERIFY,
replacing a single six-term conjunction that could not say which part failed.

Verified with the full HLSLExec LinAlg selection on WARP, compared per test
rather than by totals: 46 total, 40 passed, 5 failed, 1 skipped. The only
difference from the parent commit is the added MatVecHostOracle passing; the
non-passing set is unchanged.

Assisted-by: GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 83725f5d-8e98-4c1d-91ee-ad47629e007b
Follows the same review feedback Damyan and Chris gave on microsoft#8774, applied here
so the two pull requests stay consistent and so neither lands this code.

Every value these helpers guarded is authored by the test: dimensions are
literals of at most M=16 and N=16, and the largest integer literal in the file
is 65504. The widest accumulation the oracle can perform is far below the
int64 range, so the overflow branches were unreachable, and an overflow would
have indicated a bug in the test rather than a driver failing conformance.

checkedAddInt64 and checkedMultiplyInt64 are removed together with the two
self-test assertions that existed only to exercise them. calculateExpected
returns its result directly rather than an optional and reads as ordinary
arithmetic. Its size preconditions are already established by isCaseValid,
which runCase verifies before any of this is reached.

This also removes a collision that neither pull request shows in its own diff.
microsoft#8774 defines the same two helpers in the same cpu_oracle namespace but in a
different region of the file, so git would have merged both without conflict
and left main with a duplicate definition.

Verified with the full HLSLExec LinAlg selection on WARP, compared per test
rather than by totals: 46 total, 40 passed, 5 failed, 1 skipped, identical to
the parent commit.

Assisted-by: GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 83725f5d-8e98-4c1d-91ee-ad47629e007b
Copilot AI review requested due to automatic review settings August 14, 2026 22:47
@JoeCitizen
Jack Elliott (JoeCitizen) force-pushed the linalg-hlk-matvec-interpretation branch from c89b779 to 9b8b5b5 Compare August 14, 2026 22:47

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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (2)

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

  • The host oracle performs the dot product with unchecked signed int64_t multiplication and addition. A valid supported case using large U32 operands can therefore trigger signed-overflow undefined behavior and produce unreliable expected bytes, contrary to the PR description's overflow-checked oracle claim. Please use checked or wider arithmetic and reject results that cannot be represented before encoding them.
      Expected[Row] +=
          Case.MatrixValues[static_cast<size_t>(Row) * Case.N + Column] *
          Case.InterpretedVectorValues[Column];

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

  • This round-trip check can itself invoke undefined behavior: INT64_MAX rounds to 2^63 when converted to float, and converting that out-of-range float back to int64_t is undefined. Check that FloatValue is within the half-open int64_t range before performing the cast, then do the exactness comparison.

This issue also appears on line 1922 of the same file.

      if (static_cast<int64_t>(FloatValue) != Value)
        return reportUnrepresentable(Type, Value);

@damyanp Damyan Pepper (damyanp) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM - my previous comments are all addressed.

@JoeCitizen
Jack Elliott (JoeCitizen) enabled auto-merge (squash) August 15, 2026 00:38
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.

3 participants