-
Notifications
You must be signed in to change notification settings - Fork 60
Remove unsafe from unconditionally safe subgroup ops #306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…ible, but not undefined behavior
…sible, but not undefined behavior
…t possible, but not undefined behavior
… not undefined behavior
Since I copied over the spirv spec for each function, it's actually surprisingly simple to just Ctrl+F for I do agree that undefined result should be considered safe. I'd love to see a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cleaned up the docs a bit and added a safety section everywhere except cluster ops. I want to try to make them safe in a followup PR with some const assertions. Added it here anyway
Also discovered that subgroup_quad_broadcast
is also safe, just the result may be undefined.
Ready to merge from my side
05a15a2
to
1590c70
Compare
I decided to add the custer ops safety into this PR. It needs to remain unsafe due to one precondition that we cannot statically verify, as group size is defined by the device: const {
assert!(CLUSTER_SIZE >= 1, "`ClusterSize` must be at least 1");
assert!(
CLUSTER_SIZE.is_power_of_two(),
"`ClusterSize` must be a power of 2"
);
// Cannot be verified with static assertions:
// `ClusterSize` must not be greater than the size of the group
} |
I'd love if someone else from the team has a quick read over this one. @LegNeato ? |
@Firestar99 it should be pretty simple to generate safe wrappers from the same macro if you think it's worth including. ( E: Scratch the idea for safe wrappers. This can definitely be enforced in a way that makes it unconditionally safe because any cluster size used by the spv module has to be known at compile time (it's a const generic) alongside the enabling capabilities (GroupNonUniform*). The module can't be loaded if the enabling capabilities aren't supported by the target device. This could be extended to subgroup size constraints too. But I don't know if the infrastructure is there for that. |
First, I'd merge this as is and move any further enhancements to a new PR.
I'm reading "size of the group" to be equivalent to the subgroupSize property of the device, which is device dependent obviously. So there's no way you can check this at compile time. (There's devices with varying subgroup size, so Vulkan 1.3 has min and max)
I don't know if you'd want to have a fix subgroup size defined in the shader. That said, I'm not experienced with how people use clustered ops, I haven't found a good use-case for them yet. |
Agreed
It's not that it'd be constant, it'd be "module requires subgroupSize >= X" |
https://registry.khronos.org/vulkan/specs/latest/man/html/SubgroupSize.html The SubgroupSize builtin is required to match the subgroupSize property (on the host), until 1.6 or with additional extensions / options. Intel and Apple can use smaller subgroups than reported (both in the shader and on the host). Intel supports subgroup_size_control, so it can be set to a known value. The number of active threads within a subgroup can be queried by a subgroup add op. While sound, this isn't zero cost. I would probably leave clustered ops as unsafe unless there's motivation. It is difficult to use subgroup ops without a known size (constant or spec constant), just like many algorithms may require a specific workgroup size. |
Fixes #305. Here is what I decided to allow, and the justification for each.