是否可以在孤立的C例程中使用通过指针传递参数的归约变量?

时间:2018-09-14 14:18:40

标签: c parallel-processing openmp

我正在尝试在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;

}

我需要做一些从传递的指针变量到本地变量的复制吗?还是有其他方法可以实现这一目标?

2 个答案:

答案 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词汇表包括数组元素的数组项)的任何显式引用。