Skip to content
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

add support for leading_zeros, trailing_zeros and fix count_ones #213

Open
wants to merge 30 commits into
base: main
Choose a base branch
from

Conversation

Firestar99
Copy link
Member

@Firestar99 Firestar99 commented Jan 29, 2025

In main leading_zeros and trailing_zeros require some obscure Intel Extension. This PR changes them to use the GLSL.std.450 functions FindILsb and FindUMsb, which do the exact same thing. Though they slightly mismatch when passing in 0, rust expects the bit count of the type but they return !0/-1. And they require to be used exclusively with 32bit integers, so some careful type and bitcasting is required to emulate it for all other types, like u8, u16 and u64.

Also fixes count_ones and bit_reverse, as VUID-StandaloneSpirv-Base-04781 also requires their args to always be 32bit integers as well but we were ignoring it.

While removing the Intel extension, some code managing enabled extensions was triggering an unused warning, so I removed it in 1fb0301 which we may revert if needed.

Closes #210 #215

@Firestar99

This comment was marked as outdated.

@LegNeato
Copy link
Collaborator

LegNeato commented Jan 29, 2025

Sweet! I actually looked at this too, just didn't put my WIP up. Differences between what I did:

I pushed a branch. I think the code is largely correct, but it is only lightly tested:

https://github.com/LegNeato/rust-gpu/tree/clz

This runs wgsl shaders and rust shaders and compares the output.
If the output differs, the test fails. Differential testing is better
than snapshot testing or golden file testing as there are no reference
files to get outdated.

Note that we are only using wgpu for now, but I want to also vary
the host-side crate / use `ash`. At least we are using `wgpu`'s vulkan
support on linux, so we are not just testing naga's translation.
Without this it waits on the package lock anyway
Looks like this option isn't there anymore?
@Firestar99 Firestar99 force-pushed the leading_trailing_zeros branch from 702cb97 to c53e03c Compare February 10, 2025 10:06
@Firestar99 Firestar99 changed the title add support for leading_zeros and trailing_zeros add support for leading_zeros, trailing_zeros and fix count_ones Feb 10, 2025
@Firestar99
Copy link
Member Author

Firestar99 commented Feb 10, 2025

This is ready for review, but completely untested beyond compile tests. Would love some integration tests or fuzzing right now, as it's quite easy to screw up bitcasts or misread documentation. But I guess some careful reviewing must do.

@Firestar99 Firestar99 marked this pull request as ready for review February 10, 2025 14:25
@Firestar99 Firestar99 requested a review from eddyb as a code owner February 10, 2025 14:25
@LegNeato
Copy link
Collaborator

You could rebase on #216 ?

@Firestar99 Firestar99 force-pushed the leading_trailing_zeros branch from 10f0283 to c0c5879 Compare February 11, 2025 14:12
@Firestar99
Copy link
Member Author

Sure, there you go a rebase, git could just do it automatically. I assume CI will now do run some difftests?

@LegNeato
Copy link
Collaborator

Yep! Now you can add a runtime diff test for this if you want. But I'll also be revamping a bit and squashing that PR, so I don't want to make your git stuff more annoying. Up to you if it is worth it or want to land as-is!

}
.with_type(ty)
}
_ => self.fatal("count_ones on a non-integer type"),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: wrong function name in comment

_ => {
let undef = self.undef(ty).def(self);
self.zombie(undef, &format!(
"counting leading / trailing zeros on unsupported {ty:?} bit integer type"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: wrong function name in comment

let lower = self.emit().s_convert(u32, None, arg).unwrap();
let higher = self
.emit()
.shift_left_logical(ty, None, arg, u32_32)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this should be shift_right_logical ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

u32::leading_zeros intrinic requires weird extension to work
2 participants