Home > Net >  std::exclusive_scan with execution policy does not work in-place
std::exclusive_scan with execution policy does not work in-place

Time:12-28

cppreference says this for std::exclusive_scan:

d_first - the beginning of the destination range; may be equal to first

So there should be no problem with using std::exclusive_scan in "in-place" mode overwriting the storage. However, with the libstdc implementation that comes with GCC 12.2.0, it does not work with the overloads that use an execution policy, even if it is std::execution::seq. Consider this example:

#include <algorithm>
#include <numeric>
#include <execution>
#include <vector>
#include <cassert>

int main()
{
    const int size = 10;
    std::vector<int> vec(size);

    // without execution policy
    std::fill(vec.begin(), vec.end(), 1);
    std::exclusive_scan(vec.begin(), vec.end(), vec.begin(), 0);
    assert(vec[0] == 0); // the first element should be 0
    assert(vec[size-1] == size-1); // the last element should be the sum

    // sequential execution policy
    std::fill(vec.begin(), vec.end(), 1);
    std::exclusive_scan(std::execution::seq, vec.begin(), vec.end(), vec.begin(), 0);
    assert(vec[0] == 0); // the first element should be 0
    assert(vec[size-1] == size-1); // the last element should be the sum

    // parallel execution policy
    std::fill(vec.begin(), vec.end(), 1);
    std::exclusive_scan(std::execution::par, vec.begin(), vec.end(), vec.begin(), 0);
    assert(vec[0] == 0); // the first element should be 0
    assert(vec[size-1] == size-1); // the last element should be the sum
}

See on godbolt: https://godbolt.org/z/Yvax1dz7e

Is this a bug in the cppreference documentation or libstdc implementation? It actually is possible to implement a parallel in-place exclusive scan algorithm.

I know there is Calculate prefix product with std::exclusive_scan and execution policy std::execution::par but it does not ask about a bug.

CodePudding user response:

[exclusive.scan#8] of the standard explicitly says:

Remarksresult may be equal to first.

Also, latest MSVC, unlike GCC and Clang, accepts your code in C 17 mode: https://godbolt.org/z/78W9Wfbvh

So, this is a bug in libstdc implementation, while cppreference correctly represents standard's remark.

  • Related