Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel for loop with std::for_each and std::views::iota

I want to set up an easy workaround for parallelized index-based for-loops using std::views.

For running in sequence the code looks like this:

int main() {

    //pseudo-random numbers

    random_device rd;
    default_random_engine eng(rd());
    uniform_int_distribution<int> distr(0, 100);

    auto r = ranges::views::iota(0, 10);
    vector<double> v(10, 1);
    for_each(r.begin(), r.end(), [&](int i) {v[i] = distr(eng); });
    for (auto&& i : v) cout << i << " "; cout << endl;
}

This works fine. I am using the standard version of std::for_each(), not the one in the ranges namespace, because those don't have the execution policies. Now the parallel version. Only difference:

for_each(execution::par, r.begin(), r.end(), [&](int i) {v[i] = distr(eng); });

MSVC gives an error:

error C2338: Parallel algorithms require forward iterators or stronger

I found a similar issue here: Using ranges::view::iota in parallel algorithms and I implemented the solution offered there:

    auto r = views::iota(0) | views::take(10);
    vector<double> v(10, 1);
    auto input_range = ranges::common_view(r);

    for_each(execution::par, ranges::begin(input_range), ranges::end(input_range), [&](int i) {v[i] = distr(eng); });
    for (auto&& i : v) cout << i << " "; cout << endl;

However, I am still facing the error

error C2338: Parallel algorithms require forward iterators or stronger.

Does someone know whether there is a solution to this issue?

like image 321
Urwald Avatar asked Jul 23 '26 00:07

Urwald


2 Answers

The return type of operator*() of views::iota's iterator is not a reference type but a value type, which makes it not a forward iterator but an input iterator in C++17. Since the C++17 parallel algorithm requires forward iterators, you cannot apply it to views::iota.

Does someone know whether there is a solution to this issue?

There is already a paper p2408r4 addressing this issue, so there is no simple solution in the standard until it is adopted.

like image 163
康桓瑋 Avatar answered Jul 24 '26 16:07

康桓瑋


p2408 is adopted in C++23 now. In MSVC 19.34 (VS 17.4) or later, the code will compile if you turn on /std:c++latest (/std:c++20 will also work). EXAMPLE

like image 24
fir las Avatar answered Jul 24 '26 16:07

fir las



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!