Руководство 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]) ^
Вы ошибаетесь в ошибке, которую получаете. Это не значит, что вы не можете сделать сокращение на чередующихся элементах. Это означает, что вы не можете сделать редукцию в элемент массива.
То есть вы не можете сделать 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;
}
Сокращение массивов в C / C ++ теперь возможно начиная с OpenMP 4.5.
В основном, вы должны указать разделы массива (см. Раздел 2.4, стр. 44 спецификации OpenMP 4.5.).
Ваша спецификация #pragma будет выглядеть так:
#pragma omp parallel reduction(+:sum[:2])
Будьте осторожны с этим, однако, вы должны понимать, что каждый поток будет
выделить собственную версию раздела массива; если вы делаете это в целом
массивы со многими потоками, вы заставите вашу память взорваться.