I’m using linux pgi workstation 10.3. I have a free library from NVdia named “batched solver”. It’s a accelerated lib for the computation of batched small scale linear equation. However it is writen in CUDA C, while my program is wirten in CUDA fortran. So i wonder if there is some way to call the function which writen in cuda c, or maybe you can help me to get a cuda fortran version.
The source code of batched solver is too long to paste here.
You can check The Official NVIDIA Forums | NVIDIA , or you can provide a E-mail, i will send a email to you.
Thanks!
Hi Siwuxie,
So i wonder if there is some way to call the function which writen in cuda c,
Sure. CUDA C and CUDA Fortran work well together and each can call the other.
To call a CUDA C global routine from CUDA Fortran, you need to write an ISO C Binding interface block for the routine. Once defined, you would then call the routine as any other CUDA routine. Standard Fortran calling C issues still apply. Things like column major versus row major, zero versus 1 based indexing, etc.
I wrote an article Tuning a Monte Carlo Algorithm on GPUs, where I include an example on calling a CUDA C “Mersenne Twister” routine from CUDA Fortran.
Here’s the interface block:
interface
! C function to load the Mersenne Twister input data set
subroutine loadMTGPU(dat_path) bind(c,name='loadMTGPU')
use iso_c_binding
character(len=80) :: dat_path
end subroutine loadMTGPU
! C function to initialize the random seed on the GPU
subroutine seedMTGPU(seed) bind(c,name='seedMTGPU')
use iso_c_binding
integer(c_int), value :: seed ! Pass by value
end subroutine seedMTGPU
! CUDA C Mersenne Twister algorithm to generate an array of random
! numbers in parallel. Note that nvcc has added '__entry' to the
! end of the function name.
subroutine RandomGPU(d_Rand, n_per_rng) bind(c,name='randomgpu__entry')
use iso_c_binding
real(c_float), dimension(:), device :: d_Rand
integer, value :: n_per_rng ! pass by value
end subroutine RandomGPU
end interface
Then call the routines as you normally would:
! initalize and then call the RNG for dX
write(dpath,'(a)') 'mtdata/MersenneTwister.dat'//char(0)
call loadMTGPU(dpath)
call seedmtgpu(777)
call randomgpu<<<32>>>(dX,N_PER_THD)
Hope this helps,
Mat
Hi mat
Thanks for your interface! It really worked well!
siwuxie