(Naga) Cooperative Matrix Support - #8251
Conversation
881da16 to
430d104
Compare
|
Haven't actually looked in the PR yet, but you should take a look at the presentation about cooperative matrices from the F2F: https://docs.google.com/presentation/d/1wiy3-ar58ah1W9Qc5trd0gG7fwCo93IJ9YCtQoR6W6c/edit?slide=id.g30fc39156ff_0_0#slide=id.g30fc39156ff_0_0 and the dawn design doc https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/subgroup_matrix.md just to make sure things are synced up with upstream. |
|
@cwfitzgerald this is very useful, thanks for linking! Funny to see the timing of that presentation roughly matching when I started working on it, independently. I looked at the slides as well as the design doc, and here is my first feedback. Apologies if it's not thought through enough!
There are very similar types - textures and sampler - which also are very abstract from the shader writer point of view. Was it considered to just use the "Handle" storage class?
There is a choice for each of them: scope, role (left/right/acc), type, etc, to be either a generic argument or a part of the name. In this PR, for example, the role is encoded as a generic A/B/C. I think that makes sense because it allows to express operations like matrix store cleanly as generic instead of overloaded for all kinds of the matrix. Similarly, the "subgroup" part. If we had it as a generic scope, it could also use it in other parts of the language/API (e.g. barriers).
A boolean argument is generally a bad API pattern, since the call site has no clue about what it means from just looking at the invocation. Since this is supposed to be a constant anyway, maybe this is a good application for including this into the function name itself? This PR is currently exposing it as Overall, looks reasonable. Curious if Apple had concerns about some parts as well. |
|
@cwfitzgerald @jimblandy do you have a strong preference on how to proceed with the changes? I'm at the point where things basically work, and the test is validating correctly. We could:
I'm fine either way. I just want to use this for a project and will be on a branch if I'm not able to merge. My preference would be (1). |
7da965e to
07be9e9
Compare
|
Ok, I've got |
|
I think it's our standard practice to land experimental things, so I think it's okay for us to review and land this as-is. However, the WebGPU committee will almost certainly approve some version of Alan's proposal, eventually, so if we put something different in wgpu, it will just need to be changed. So, I'd like to really encourage you to adapt what you've got to Alan's proposal as much as feasible, but we shouldn't block merging on 100% compliance. |
|
Yeah landing this as is is fine. Once the proposal lands against WebGPU @kvark could you raise concerns against the gpuweb repo, we're not really involved in the proposal here. |
cwfitzgerald
left a comment
There was a problem hiding this comment.
Generally looks good! I have some concerns, mainly around testing.
- Wiring this up with wgpu shouldn't be too difficult as it's a pure shader-side change and wiring that up would let us write a few runtime tests, which would go a long way to make me feel confident that this feature is actually working (and ensures it stays working).
- Some testing of error handling in the wgsl frontend would be great, particularly in the
wgsl_errors.rstest file. There's some interesting new surface to test here, so getting some coverage there would be great. - Finally, this is strictly non-blocking but would be great, if you can, wiring up spirv-in would be nice as it would give access to this feature to people not using wgsl. From what I can see of the spirv backend it shouldn't be too difficult, though that's a guess.
|
@jimblandy I'm happy to update it once WebGPU is settled, but I don't want to do so pre-emptively. I made sure the API is really similar, so updating in this direction will be straightforward. |
|
Sounds good! Re-request my review when this is ready for another look (and CI is clean) |
5c136fd to
39296a8
Compare
|
Rebased again. The failures appear to be unrelated to the PR (but related to the recent landing of mesh shaders). |
|
My guess is the updated rspirv caused it to start emitting EXT identifiers instead of NV identifiers. The snapshots should be regenerated. |
|
it looks like wgpu now requires Rust newer than 1.91.1, which is very inconvenient for me to run since the last NixOs packaged rust is 1.91.1 |
|
All rebased, test outputs updated, and the code improved to run the example on both Vulkan and Metal. |
cwfitzgerald
left a comment
There was a problem hiding this comment.
Issues with notes are non-blocking, so lets merge this and we an iterate later. Nice!
|
|
||
| Example usage: | ||
|
|
||
| ```/dev/null/cooperative-matrix-host.rs#L1-40 |
There was a problem hiding this comment.
yikes, some trashy leftover
There was a problem hiding this comment.
This doc is broadly good, but honestly is a bit large and impenetrable. I think it should be trimmed down a bit, but we don't need to block this PR on it, the important information is there which is the important part.
| }); | ||
| } | ||
|
|
||
| log::info!( |
There was a problem hiding this comment.
Please downgrade this to debug message. It is annoying for libraries to print info messages, especially in codebases that have nothing to do with cooperative matrices at all.
This was the result of discussion in #3206.
There was a problem hiding this comment.
Would you be able to make a PR?
The cooperative matrix support (gfx-rs#8251) started declaring the Vulkan memory model, but the rest of the generated code kept GLSL450-model assumptions, leaving storage and workgroup accesses private and barriers without availability/visibility operations (gfx-rs#8805). The writer now decides the memory model up front - when a module uses cooperative matrices, or when the new `spv::Options::use_vulkan_memory_model` requests it (gfx-rs#1545) - and under the model: - storage and workgroup loads/stores (including cooperative matrix loads/stores and the workgroup zero-init polyfill) carry `NonPrivatePointer` with a `MakePointerVisible`/`MakePointerAvailable` scope: QueueFamily for `@coherent` globals, Workgroup otherwise; - control and memory barriers add `MakeAvailable | MakeVisible` semantics; - atomics and storage barriers use QueueFamily scope instead of Device, which would require the `vulkanMemoryModelDeviceScope` feature; - the `Coherent` and `Volatile` decorations, forbidden by the model, are replaced by per-access memory operands, with volatile atomics using the `Volatile` memory semantics bit. The new wgsl-vulkan-memory-model test exercises the opt-in path with coherent, volatile, and plain storage buffers, workgroup memory, atomics, and both barriers; the output and the regenerated cooperative matrix snapshots pass spirv-val under Vulkan 1.1 rules. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WRD8L4KyVGxJfKTqkX3gmh
Connections
Blocked by gfx-rs/rspirv#265
Since rspirv fails validation of the product, even though it's correct.
Description
Adding shader support for KHR_cooperative_matrix. Considering a rather simple scope that is portable between Vulkan and Metal.
Testing
Adds tests.
Squash or Rebase?
Rebase.
Checklist
cargo fmt.taplo format.cargo clippy --tests. If applicable, add:--target wasm32-unknown-unknowncargo xtask testto run tests.CHANGELOG.mdentry.API choices
SPIRV and Metal have a fine intersection of the cooperative matrix functionality, with some caveats:
coop_mat.OpCooperativeMatrixLoadKHRandOpCooperativeMatrixMulAddKHRas expressions andOpCooperativeMatrixStoreKHRas a statement. Metal has all of them 3 as statements. I followed SPIR-V notion here, as does Google's proposal.Things left for follow-up: