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

Should simd_mask support shift operators #78

Open
danieltowner opened this issue Jun 6, 2023 · 9 comments
Open

Should simd_mask support shift operators #78

danieltowner opened this issue Jun 6, 2023 · 9 comments

Comments

@danieltowner
Copy link
Collaborator

A customer has requested that simd_mask should be shiftable, both in binary and compound assignment forms. Any objection to adding those?

@DenisYaroshevskiy
Copy link

I'm not 100% what that means.

There are a by lane operations and there is what we call slide_left, slide_right - which is a swizzle (thnk bslli)

Which one is it?

@mattkretz
Copy link
Owner

There's a clear answer:

T x;
auto y = (x == 0) << 1;

The type of y determines the behavior of simd. y is going to be an int, because bool promotes to int before the shift operator is called.
So

friend constexpr simd_type
operator<<(simd_mask, int);

This is also consistent with the other operator overloads in simd_mask.

No objection from my side. I'd be interested in seeing a use case, though. :-)

@DenisYaroshevskiy
Copy link

The only reason it works for bool is because of an implicit conversion. I think that in general implicit conversions for simd is an awful idea.

But here - is there a mask implicit conversion to int?

@mattkretz
Copy link
Owner

See Section 4.8 of P1928R3. This was subsequently implemented in P1928R4.

@DenisYaroshevskiy
Copy link

template <class U, class A>
constexpr explicit(sizeof(U) != sizeof(T)) operator simd<U, A>() const noexcept;

?
I don't understand this one.

If implicit conversions from bool to int are to stay, I don't mind this. I didn't know about bool shift.

@danieltowner
Copy link
Collaborator Author

I'm not 100% what that means.

There are a by lane operations and there is what we call slide_left, slide_right - which is a swizzle (thnk bslli)

Which one is it?

Sorry, that was bad of me. I mean the second. What you call slide_left, or like https://en.cppreference.com/w/cpp/algorithm/shift.

std::bitset has these as well (https://en.cppreference.com/w/cpp/utility/bitset/operator_ltltgtgt) and I think in many user's minds (mine included) simd_mask and std::bitset are very comparable, so if you can shift bitsets, then you should be able to similarly shift a simd_mask. This is probably compounded by AVX-512 programmers who also know that predicate masks on that target can be shifted too (e.g., _kshiftri_mask16).

@DenisYaroshevskiy
Copy link

O_o. That is a very useful operation but honestly I'd expect it to be called the same way as it would for simd.

  • Shift like tjis would break operators work by lane

Also - compile time shift only I'd say, otherwise even on avx2 this sucks.

@mattkretz
Copy link
Owner

@danieltowner Why isn't permute(k, shift_by<2>) acceptable here?

@danieltowner
Copy link
Collaborator Author

It probably could be acceptable, it's just not as obvious perhaps, especially for someone coming from a target with bit masks. At the moment the code generated doesn't do very well either, but I guess the compiler could be taught to do better. The best code is generated by

The best code is generated by assuming that https://isocpp.org/files/papers/P2876R0.html#compact_ctor is available (simd_mask(original.to_bitint() << 5). Then it maps to a real shift of the bitmask value itself on targets that support it.

If we had named functions, then shift_left and shift_right could be used to do the operation on a mask too.

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

No branches or pull requests

3 participants