Это, похоже, ошибка в компиляторе Intel, я могу надежно воспроизвести ее на примере C, не содержащем векторов:
#include <stdio.h>
void my_sum_fun(int* outp, int* inp) {
printf("%d @ %p += %d @ %p\n", *outp, outp, *inp, inp);
*outp = *outp + *inp;
}
int my_init(int* orig) {
printf("orig: %d @ %p\n", *orig, orig);
return *orig;
}
#pragma omp declare reduction(my_sum : int : my_sum_fun(&omp_out, &omp_in) initializer(omp_priv = my_init(&omp_orig))
int main()
{
int s = 0;
#pragma omp parallel for reduction(my_sum : s)
for (int i = 0; i < 2; i++)
s+= 1;
printf("sum: %d\n", s);
}
Выход:
orig: 0 @ 0x7ffee43ccc80
0 @ 0x7ffee43ccc80 += 1 @ 0x7ffee43cc780
orig: 1 @ 0x7ffee43ccc80
1 @ 0x7ffee43ccc80 += 2 @ 0x2b56d095ca80
sum: 3
Применяет операцию сокращения к исходной переменной до инициализации частной копии из исходного значения. Это приводит к неверному результату.
Вы можете вручную добавить барьер в качестве обходного пути:
#pragma omp parallel reduction(vec_double_plus : w)
{
#pragma omp for
for (int i = 0; i < 4; ++i)
for (int j = 0; j < w.size(); ++j)
w[j] += 1;
#pragma omp barrier
}