我正在尝试在C中的孤立例程中包含归约变量。我意识到我需要通过指针将变量传递给例程,以确保将其视为共享(在封闭的并行区域中共享) 。但是,当我尝试编译时,编译器不喜欢该变量是指针(我认为)这一事实,并且抱怨它没有指针的归约类型,即使用cray编译器时,我得到以下错误:
CC-1642 craycc: ERROR File = main.c, Line = 33
The OpenMP reduction clause does not accept pointer or reference types.
#pragma omp for reduction(+:sum)
使用此示例代码时:
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
int myroutine(double *, double *, int);
int main(void){
double a[100];
double sum;
int i;
int n = 100;
for(i=0;i<n;i++){
a[i]=3.2;
}
#pragma omp parallel shared(a,n,sum)
{
myroutine(a, &sum, n);
}
printf("sum = %lf\n",sum);
return 0;
}
int myroutine(double *a, double *sum, int n){
int i;
#pragma omp for reduction(+:sum)
for(i=0;i<n;i++){
*sum += a[i];
}
return 0;
}
我需要做一些从传递的指针变量到本地变量的复制吗?还是有其他方法可以实现这一目标?
答案 0 :(得分:0)
int myroutine(double *a, double *sum, int n)
{
int i;
static double localSum = *sum;
#pragma omp for reduction(+:localSum)
for(i=0;i<n;i++){
localSum += a[i];
}
*sum = localSum;
return 0;
}
可以工作,但是很糟糕,因为如果您在嵌套的并行区域中的不同团队中尝试使用它,则会损坏。 (虽然如果您不使用嵌套并行性,并且不从独立的pthreads启动OpenMP,这是安全的,但几乎是同一回事!)
我希望像
#pragma omp for reduction(+:sum[0])
在OpenMP 5.0中可以工作,其中减少了对数组节的支持,但是不幸的是编译器可能还不存在(可以理解,因为规范尚未定稿!)
答案 1 :(得分:-1)
在这种情况下,裸露的指针是不明确的-编译器无法知道它是单个值,也可能是多个。但是,您可以使用带有一个元素的简单 array部分来帮助编译器:
#pragma omp for reduction(+:sum[:1])
自OpenMP 4.5开始有效-幸运的是,Cray编译器支持该功能。我在GCC 8.2.0上进行了测试
P.S。 Jim的建议sum[0]
似乎也可以与GCC一起使用,但是我不确定该怎么做。我在简化文档中找不到对数组元素(或根据OpenMP词汇表包括数组元素的数组项)的任何显式引用。