Can I still rely on the order of the output elements when using par_unseq?

Viewed 464

After reading the documentation I'm still confused about the usage of par_unseq. I know I can't tell anything about the order of execution because of threading and vectorization but can I still rely on the order of the outputs?

transform([x0, x1, x2], f) == [f(x0), f(x1), f(x2)]]

In order words, is this test ever going to fail?

std::vector<int> xs = {1, 2, 3, 4};
std::vector<int> ys(xs.size());

std::transform(
    std::execution::par_unseq,
    cbegin(xs), cend(xs),
    begin(ys),
    [](int x) { return x*x; });

std::vector<int> expected = {1, 4, 9, 16};
ASSERT_EQ(expected , ys);
2 Answers

The Standard, [alg.transform], reads:

Effects: Assigns through every iterator i in the range [result,result + (last1 - first1)) a new corresponding value equal to op(*(first1 + (i - result)) or binary_op(*(first1 + (i - result)), *(first2 + (i - result))).

and (thanks, @Caleth), [algorithms.parallel.overloads]:

Unless otherwise specified, the semantics of ExecutionPolicy algorithm overloads are identical to their overloads without.

So, yes, you can rely on the order in the output.

No, your test is never going to fail because even if order of execution changes, ys[0...3] = xs[0...3] * xs[0...3] = {1*1, 2*2, 3*3, 4*4}; won't change.

Related