how to generate Poisson-distributed random number using curand?

Hello,

I am using CUDA Fortran and want to generate a Poisson-distributed random “integer” number using curand.
But the variable type for output values in curandGeneratePoisson function is defined as “real”.

 integer(4) function curandGeneratePoisson(generator, array, num, lambda )
   type(curandGenerator) :: generator
   real(8), device :: array(*) ! Host or device depending on the generator
   integer(kind=c_intptr_t) :: num
   real(8) :: lambda

I do not understand why the output values are not “integer” type.
When I input an integer type variable for “array”, I received type mismatch error.
On the other hand, when I input a real type variable for “array”, all the results are 0.

Does anyone know how to generate a Poisson-distributed random “integer” number using curand?

Thanks,

Hi hinokky,

I think we have the interface wrong so added a problem report (TPR #27940) and sent in engineering for correction.

In the meantime, you’ll need to write your own interface. Something like:

program testcurand1
call foo1(100)
end
!
subroutine foo1(n)
use cudafor
use curand
integer, managed :: a(n)
type(curandGenerator) :: g
real(8) :: lambda

interface
integer function curandGeneratePoisson2(generator, array, num, lambda ) &
                            bind(C, name='curandGeneratePoisson')
  import curandGenerator
!DIR$ IGNORE_TKR (K) num, (D) array
  type(curandGenerator), value :: generator
  integer, device :: array(*)
  integer(kind=int_ptr_kind()), value :: num
  real(8), value :: lambda
end function
end interface

a = 0
lambda= 4.0
passing = .true.
istat = curandCreateGenerator(g,CURAND_RNG_PSEUDO_DEFAULT)
istat = curandSetPseudoRandomGeneratorSeed(g, 1234)
istat = curandGeneratePoisson2(g, a, n, lambda)
istat = cudaDeviceSynchronize()
istat = curandDestroyGenerator(g)
print *, a

end

Thanks for the report,
Mat

Hi Mat,

Thank you for the suggestion and for sending the problem report.
Now I can generate Poisson-distributed random numbers, thanks!

hinokky

Hi Mat!

Looking at your code in this channel, I wrote the following one to generate double precision random number with normal distribution. However, its outputs are zero only. Could you help me in this regard. Here is the modified code:
!----------------------------------------------------------------------------------------------------------------
program testcurand1
call foo1(100)
end
!
subroutine foo1(n)
use cudafor
use curand
real*8, managed :: a(n)
type(curandGenerator) :: g
real(8) :: mean, stddev

interface
real8 function curandGenerateNormalDouble2(gen, array, num, mean, stddev) &
bind(C, name=‘curandGenerateNormalDouble’)
import curandGenerator
!DIR$ IGNORE_TKR (K) num, (D) array
type(curandGenerator), value :: gen
real
8, device :: array(*)
integer(kind=int_ptr_kind()), value :: num
real(8), value :: mean, stddev
end function
end interface

a = 0
mean = 0.d0
stddev = 0.d0
passing = .true.
istat = curandCreateGenerator(g,CURAND_RNG_PSEUDO_DEFAULT)
istat = curandSetPseudoRandomGeneratorSeed(g, 1234)
istat = curandGenerateNormalDouble2(g, a, n, mean, stddev)
istat = cudaDeviceSynchronize()
istat = curandDestroyGenerator(g)
print *, a

end
!----------------------------------------------------------------------------------------------------------------

With thanks,
Rakesh

Hi Mat!

The code posted above has one mistake that I have set stddev=0. That is why its output was all zero. Setting any desired stddev, it will work accordingly.

Thanks,
Rakesh

The original issue, TPR #27940, is fixed in all NVIDIA HPC SDK compiler releases.

  • Brent