1

我现在正在开发一个用 CUDA-Fortran 编码的项目。唯一可以编译 CUDA-Fortran 的编译器是 Portland group 的 pgfortran 编译器。但是我们发现了一个错误,即 pgfortran 编译器总是序列化 OMP 任务指令。简而言之:当使用 PGI 的编译器编译时,OMP TASK 不是并行的,而在使用 GNU 的编译器编译时是并行的。我们已将此情况报告给 PGI,但我们不确定修复该错误需要多长时间。所以现在我试图从 Fortran 程序(在 testF.cuf 中)调用一个 C 函数(更具体地说是一个 CUDA 函数)并将 OMP 任务指令放入 C 函数(在 cuda.cu 中),因为我们知道 gcc 的 omp任务工作正常。

testF.cuf:

external cfunction
...    
cfunction( foo )

cuda.cu

extern "C" function_(Foo * foo){

#pragma omp parallel
{
  ...
#pragma omp single
  {
     ...
#pragma omp task 
    {
      ...
    }
  }
 }
}

结果是没有任何 OMP 指令的 Fortran 程序可以调用 C 函数并且 OMP 任务是并行的。但是一旦我们在 Fortran 代码中加入了任何 OMP 内容,或者在编译 Fortran 代码时只放置了一个 -mp 标志。C 文件中的 OMP 任务会以 PGI 的方式运行:序列化。如果我将 OMP 任务更改为 OMP 并行,结果将再次正确。这表明 pgfortran 会将 C 代码中的 OMP 链接到 pgfortran 的错误方式中。

这是我的Makefile:

myFtoCU: cuda.o testF.o
   pgfortran cuda.o testF.o -o myFtoCU  -Mcuda=5.0  -lstdc++ -lgomp 
cuda.o: cuda.cu
   nvcc   -c cuda.cu -o cuda.o  -Xcompiler -fopenmp  -lgomp
testF.o: testF.cuf
   pgfortran -c testF.cuf -Mcuda=5.0 -lstdc++ -lgomp -mp
clean:  cuda.o testF.o myFtoCU
   rm cuda.o testF.o ./myFtoCU

我想问题是当我将 cuda.o 和 testF.o 链接在一起时,链接器强制 cuda.o 中的 OMP 充当 pgfortran 的 OMP 任务,这是错误的。

那么有没有人知道如何正确链接这两个对象,同时保持 C( CUDA ) 函数更独立?

4

0 回答 0