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

How to cast simd_mask of type T to another type? #41

Closed
torshepherd opened this issue Aug 28, 2023 · 3 comments
Closed

How to cast simd_mask of type T to another type? #41

torshepherd opened this issue Aug 28, 2023 · 3 comments
Assignees
Labels
documentation The documentation (cppreference) needs to be improved

Comments

@torshepherd
Copy link

version / revision Operating System Compiler & Version Compiler Flags CPU
  GCC (trunk/all)          |      x86-64      |    GCC (trunk/all)        |  -mavx2      |

Testcase

using doublev = std::experimental::native_simd<double>;
using size_tv = std::experimental::rebind_simd_t<std::size_t, doublev>;

struct Bound
{
    std::vector<doublev> vals;
    std::vector<size_tv> idxs;
};

void min(Bound& a, const Bound& b) {
    for (std::size_t i = 0; i < a.vals.size(); ++i)
    {
        const auto otherIsLess = b.vals[i] < a.vals[i];
        std::experimental::where(otherIsLess, a.vals[i]) = b.vals[i];
        std::experimental::where(otherIsLess, a.idxs[i]) = b.idxs[i];
    }
}

Actual Results

This code doesn't compile (https://godbolt.org/z/666G5YTqK)

Expected Results

I couldn't find anywhere on cppreference indicating the correct pattern for this use case - how can I apply a mask to different SIMD types of different element_type's?

@mattkretz
Copy link
Member

Well, it's an embarrassing omission in the Parallelism TS 2. The libstdc++ implementation provides two ways out:

where(otherIsLess.__cvt(), a.idxs[i]) = b.idxs[i];

or, the verbose variant (which, except for the __proposed namespace, the C++ committee would have okayed for the TS):

where(std::experimental::__proposed::static_simd_cast<typename size_tv::mask_type>(otherIsLess), a.idxs[i]) = b.idxs[i];

I recommend:

namespace stdx
{
  using namespace std::experimental;
  using namespace std::experimental::__proposed;
}

or simply use https://github.com/mattkretz/vir-simd.

I guess cppreference should discuss this issue in some form...

@mattkretz mattkretz added the documentation The documentation (cppreference) needs to be improved label Aug 28, 2023
@mattkretz mattkretz self-assigned this Aug 28, 2023
@mattkretz
Copy link
Member

Added a Notes section to https://en.cppreference.com/w/cpp/experimental/simd/simd_cast.

@torshepherd
Copy link
Author

Thank you for the response! By the way, this library is amazing. Thank you for your hard work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation The documentation (cppreference) needs to be improved
Projects
None yet
Development

No branches or pull requests

2 participants