Calling a cuda C device subroutine.

Hello,

I read in the user guide:

“A subroutine or function with the device attribute must appear within a Fortran module, and may only be called from device subprograms in the same module.”

Now, have been using this tutorial http://www.pgroup.com/lit/articles/insider/v2n1a4.htm, to call the Mersenne Twister in the CUDA C examples from the cuda fortran code. But now I need to modify it so that the RandomGPU C global subroutine becomes a device subroutine. Il have included an INTERFACE in the fortran module were I want to call it from but I get the following error message:

PGF90-S-0155-Illegal call from device code to randomgpu_dev (test_my_twist.cuf: 17)

Is it possible at all to call a C device subroutine from the CUDA fortran code? Or am I doing something wrong?

Here is a relevant part of the code:

MODULE WHATEVER
USE CUDAFOR

INTERFACE
subroutine RandomGPU_dev(d_Rand, n_per_rng) bind(c,name='randomgpu_dev__entry')
        use iso_c_binding
        real(c_float), dimension(:) :: d_Rand
        integer, value :: n_per_rng  ! pass by value
end subroutine RandomGPU_dev
END INTERFACE

CONTAINS

ATTRIBUTES(GLOBAL) SUBROUTINE RNG_TEST()
real, dimension(10) :: Y

call randomgpu_dev(Y,5)

END SUBROUTINE RNG_TEST

END MODULE WHATEVER

Hi Benoit,

A subroutine or function with the device attribute must appear within a Fortran module, and may only be called from device subprograms in the same module.

This restriction is due to the lack of a linker for the GPU. Hence, there is no way to associate device symbols from different objects. Secondly, the NVIDIA GPU’s don’t currently support calling so all device routines need to be inlined by the compiler. Hence, all device routines must be within the same file.

Your two options are to use the method I used in the tutorial or translate the Mersenne Twister algorithm to CUDA Fortran and add it to your module.

  • Mat

Ok, thank you.

Since I am trying to port a large radiative transfer monte carlo code to GPU, I really need to have the RNG as a device subroutine and not store the random numbers in
large arrays…I guess, I will have to translate the mersenne twister into fortran. That’s
what I started to do initialy, but I realized that the C code is using unsigned integers which do not exist in fortran (I think). So I cannot do this blindly using integer*4, or I may destroy the statistical properties of the RNG. I guees I’ll have to go to the original paper…

Benoit.