Recently I try to use Thrust in CUDA Fortran code, and I find a example from the documents of nvidia. The codes are shown as follow (have some minor modifications):
file name: csort.cu
#include <thrust/device_vector.h>
#include <thrust/device_ptr.h>
#include <thrust/sort.h>
extern "C" {
void sort_int_wrapper(int *data, int N)
{
thrust::device_ptr<int> dev_ptr(data);
thrust::sort(dev_ptr, dev_ptr + N);
}
}
file name: thrust_module.f90
module thrust
interface thrustsort
subroutine sort_int(input,N) bind(C,name='sort_int_wrapper')
use iso_c_binding
integer(c_int),device :: input(*)
integer(c_int),value :: N
end subroutine
end interface
end module
file name: test_sort.f90 (main)
program testsort
use thrust
integer, allocatable :: cpuData(:)
integer, allocatable, device :: gpuData(:)
integer :: N = 10
allocate(cpuData(N))
allocate(gpuData(N))
do i = 1, N
cpuData(i) = int(random(i)*10 + random(i)*100)
end do
print*,cpuData
gpuData = cpuData
call thrustsort(gpuData,N)
cpuData = gpuData
print*,cpuData
end program
And finally the makefile:
NVINC = -I/software/nvidia/hpcsdk/2022/Linux_x86_64/22.2/cuda/include
F90FLAGS = -cuda -gpu=cc75 -O3
all: test_sort
test_sort: test_sort.o csort.o thrust_module.o
nvfortran $(F90FLAGS) -o $@ $^
test_sort.o: test_sort.f90 thrust_module.o
nvfortran -c $(F90FLAGS) $< -o $@
csort.o: csort.cu
nvcc -c -arch sm_75 $(NVINC) $^ -o $@
thrust_module.o: thrust_module.f90
nvfortran -c $(F90FLAGS) $^ -o $@
clean:
rm csort.o test_sort.o test_sort
As you can see, I use the NVIDIA HPC SDK v22.2 throught the modulefile (module load nvidia/hpcsdk/22.2). But when I begin to compile these file through makefile, it bumps out massive error hints which are partly shown below:
nvfortran -c -Mcuda -gpu=cc75 -O3 thrust_module.f90 -o thrust_module.o
nvfortran -c -Mcuda -gpu=cc75 -O3 test_sort.f90 -o test_sort.o
nvcc -c -arch sm_75 -I/software/nvidia/hpcsdk/2022/Linux_x86_64/22.2/cuda/include csort.cu -o csort.o
nvfortran -Mcuda -gpu=cc75 -O3 -o test_sort test_sort.o csort.o thrust_module.o
csort.o: In function __static_initialization_and_destruction_0(int, int)': tmpxft_000095cc_00000000-6_csort.cudafe1.cpp:(.text+0x2364): undefined reference to
std::ios_base::Init::Init()’
tmpxft_000095cc_00000000-6_csort.cudafe1.cpp:(.text+0x2379): undefined reference to std::ios_base::Init::~Init()' csort.o: In function
std::exception::exception()‘:
tmpxft_000095cc_00000000-6_csort.cudafe1.cpp:(.text._ZNSt9exceptionC2Ev[_ZNSt9exceptionC5Ev]+0xb): undefined reference to vtable for std::exception' csort.o: In function
std::bad_alloc::bad_alloc()’:
tmpxft_000095cc_00000000-6_csort.cudafe1.cpp:(.text._ZNSt9bad_allocC2Ev[_ZNSt9bad_allocC5Ev]+0x1b): undefined reference to vtable for std::bad_alloc' csort.o: In function
thrust::system::error_category::~error_category()‘:
tmpxft_000095cc_00000000-6_csort.cudafe1.cpp:(.text._ZN6thrust6system14error_categoryD0Ev[_ZN6thrust6system14error_categoryD5Ev]+0x25): undefined reference to operator delete(void*, unsigned long)' csort.o: In function
thrust::system::detail::generic_error_category::messageabi:cxx11 const’:
tmpxft_000095cc_00000000-6_csort.cudafe1.cpp:(.text._ZNK6thrust6system6detail22generic_error_category7messageB5cxx11Ei[_ZNK6thrust6system6detail22generic_error_category7messageB5cxx11Ei]+0x3d): undefined reference to `__cxa_guard_acquire’
tmpxft_000095cc_00000000-6_csort.cudafe1.cpp:
…
(.data.rel.ro._ZTIN6thrust6system14error_categoryE[_ZTIN6thrust6system14error_categoryE]+0x0): undefined reference to vtable for __cxxabiv1::__class_type_info' csort.o:(.data.rel.local.DW.ref.__gxx_personality_v0[DW.ref.__gxx_personality_v0]+0x0): undefined reference to
__gxx_personality_v0’
pgacclnk: child process exit status 1: /usr/bin/ld
makefile:7: recipe for target ‘test_sort’ failed
make: *** [test_sort] Error 2
I’m very confused about these. Is there any other reliance for the compiler when use the CUDA C in the CUDA Fortran? Or the mismatch between the CUDA (Thrust) ver. and GNU?