Now I’m working with a scientific project in which we use fortran-cuda from PGI. We have found that PGI’s omp support is so poor that we can not have paralleled omp task in some situation by pgfortran. So we decided to pull out something out and make it C++ and compile it with g++.
The other reason why we want to mix PGI’s pgfortran compiler with GNU’s g++ is that we need to use the pgfortran to compile the cuda-fortran part of our code and we also need to use NVCC from Nvidia( which use g++ to compile the host code) to compile that OMP segments which have CUDA in them and which can not be compiled correctly by pgfortran.
So here is the Fortran code:
program taskf
use omp_lib
!use iso_c_binding
integer :: a
external task
!a=10
!$OMP parallel num_threads(10)
print*, 'There are ',omp_get_num_threads(),'threads in fortran',' and this is thread', omp_get_thread_num()
!$OMP single
print *, 'Wining thread is' ,omp_get_thread_num()
call task(a)
!$OMP end single
!$OMP end parallel
end program taskf
And here is the C++ code
#include <stdio.h>
#include<stdlib.h>
#include<omp.h>
external "C" void task_(int *a){
for(int i=0;i<10;++i)
{
#pragma omp task
{
printf("from thread %d, num of%d \n",omp_get_thread_num(),omp_get_num_threads());
}
}
}
And here is my Makefile:
task: taskc.o taskf.o
gfortran taskf.o taskc.o -o myTask -lstdc++ -fopenmp
taskf.o: taskf.f90
gfortran -c taskf.f90 -fopenmp
taskc.o: taskc.cpp
g++ -c taskc.cpp -fopenmp
clean: taskf.o taskc.o
rm taskf.o taskc.o
At last when I link the C++ object files compiled by g++ and the Fortran object files compiled by pgfortran together, if I don’t put a -lgomp option there, there will be link errors. But if I put it there, the behavior of OMP threads is weird. The Fortran can only recognize 1 threads while the C++ can recognize the total 10 threads.
I think the problem is that the two different compiler use different OMP library and gomp is GNU’s library. So anyone knows how to link them correctly? Or can someone tell me how to link the PGI’s OMP library?