我正在开发一个现在用CUDA-Fortran编码的项目。唯一可以编译CUDA-Fortran的编译器是Portland组的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)功能更独立的同时正确链接这两个对象?