Могу ли я использовать сокращение OpenMP, когда переменная является элементом массива?

Руководство OpenMP говорит

Имя типа в declare reduction Директива не может быть типом функции, типом массива, ссылочным типом или типом, квалифицированным как const, volatile или же restrict,

Что я могу сделать, чтобы превратить мои результаты в элементы массива? Я начал с:

int main()
{
// create an input array
static const int snum = 5000;
int input[snum];
for(int i=0; i<snum; ++i){
input[i] = i+1;
}

// shared output variables for reduction
int sum[2];
sum[0] = 0;
sum[1] = 0;

#pragma omp parallel for
#pragma omp declare reduction(+:sum[0])
#pragma omp declare reduction(+:sum[1])
for(int i=0; i<snum; ++i) {
int* p = input+i;
if(i%2==0)
sum[0] += *p;
else
sum[1] += *p;
}
}

Это дает ошибку компилятора:

27013152.cpp:16:9: error: ‘#pragma’ is not allowed here
#pragma omp declare reduction(+:sum[0])
^~~
27013152.cpp:17:33: error: ‘sum’ does not name a type
#pragma omp declare reduction(+:sum[1])
^~~
27013152.cpp:17:36: error: expected ‘:’ before ‘[’ token
#pragma omp declare reduction(+:sum[1])
^

-1

Решение

Вы ошибаетесь в ошибке, которую получаете. Это не значит, что вы не можете сделать сокращение на чередующихся элементах. Это означает, что вы не можете сделать редукцию в элемент массива.

То есть вы не можете сделать reduction(+:sum[0]), Но вы можете сделать сокращение в другую скалярную переменную, а затем скопировать в элемент массива:

void sum_int(const int input[], int num, int *sum)
{
int sum_even = 0, sum_odd = 0;

#pragma omp parallel for reduction(+:sum_even) reduction(+:sum_odd)
for (int i = 0; i < num; i++) {
if (i % 2 == 0)
sum_even += input[i];
else
sum_odd += input[i];
}

sum[0] = sum_even;
sum[1] = sum_odd;
}
1

Другие решения

Сокращение массивов в C / C ++ теперь возможно начиная с OpenMP 4.5.
В основном, вы должны указать разделы массива (см. Раздел 2.4, стр. 44 спецификации OpenMP 4.5.).
Ваша спецификация #pragma будет выглядеть так:

#pragma omp parallel reduction(+:sum[:2])

Будьте осторожны с этим, однако, вы должны понимать, что каждый поток будет
выделить собственную версию раздела массива; если вы делаете это в целом
массивы со многими потоками, вы заставите вашу память взорваться.

1

По вопросам рекламы [email protected]