! ! Copyright (C) 2001-2012 Quantum ESPRESSO group ! This file is distributed under the terms of the ! GNU General Public License. See the file `License' ! in the root directory of the present distribution, ! or http://www.gnu.org/copyleft/gpl.txt . ! !---------------------------------------------------------------------------- MODULE random_numbers_gpum !---------------------------------------------------------------------------- !! Module for random numbers generation - GPU double. ! USE kinds, ONLY : DP #if defined(__CUDA) USE cudafor #endif ! IMPLICIT NONE ! CONTAINS ! !------------------------------------------------------------------------ FUNCTION randy_gpu ( irand ) !------------------------------------------------------------------------ REAL(DP) :: randy_gpu INTEGER, optional :: irand #if defined(__CUDA) attributes(DEVICE) :: randy_gpu #endif call errore('randy','use randy_vect_gpu on GPUs',1) END FUNCTION randy_gpu !------------------------------------------------------------------------ SUBROUTINE randy_vect_gpu ( r_d, n, irand ) !------------------------------------------------------------------------ ! ! randy_vect_gpu(r, n, irand): reseed with initial seed idum=irand ( 0 <= irand <= ic, see below) ! if randyv is not explicitly initialized, it will be ! initialized with seed idum=0 the first time it is called ! randy_vect_gpu(r, n) : generate uniform real(DP) numbers x in [0,1] ! USE random_numbers, ONLY : randy #if defined(__CUDA) USE curand #endif REAL(DP) :: r_d(n) #if defined(__CUDA) attributes(DEVICE) :: r_d #endif INTEGER :: i, n INTEGER, optional :: irand ! INTEGER :: ist INTEGER, SAVE :: idum=0 #if defined(__CUDA) type(curandGenerator), SAVE :: gen LOGICAL, SAVE :: first=.true. ! IF ( present(irand) ) THEN idum = MIN( ABS(irand), idum) first=.true. END IF ! IF ( first ) THEN ! first = .false. ist=curandDestroyGenerator(gen) ist=curandCreateGenerator(gen, CURAND_RNG_PSEUDO_XORWOW) ! or CURAND_RNG_PSEUDO_MRG32k3a ist=curandSetPseudoRandomGeneratorSeed(gen, idum) ! END IF ! ist=curandGenerateUniformDouble(gen,r_d,n) ! #else ! randy_vect_gpu is not a GPU array in this case ! ! ist means starting index here ist = 1 IF ( present(irand) ) THEN r_d(1) = randy(irand) ist = 2 END IF DO i = ist, n r_d(i) = randy() END DO #endif RETURN ! END SUBROUTINE randy_vect_gpu ! !------------------------------------------------------------------------ SUBROUTINE randy_vect_debug_gpu (r_d, n, irand ) !------------------------------------------------------------------------ ! ! randy_vect_debug_gpu(r, n, irand): reseed with initial seed idum=irand ( 0 <= irand <= ic, see below) ! if randyv is not explicitly initialized, it will be ! initialized with seed idum=0 the first time it is called ! randy_vect_debug_gpu(r, n) : generate uniform real(DP) numbers x in [0,1] ! USE random_numbers, ONLY : randy ! REAL(DP) :: r_d(n) INTEGER, optional :: irand #if defined(__CUDA) attributes(DEVICE) :: r_d #endif INTEGER :: n, i, ist REAL(DP), ALLOCATABLE :: aux_v(:) ! ALLOCATE(aux_v(n)) ! ist = 1 IF ( present(irand) ) THEN aux_v(1) = randy(irand) ist = 2 END IF ! DO i = ist, n aux_v(i) = randy() END DO ! r_d(1:n) = aux_v(1:n) ! DEALLOCATE(aux_v) END SUBROUTINE randy_vect_debug_gpu ! !------------------------------------------------------------------------ SUBROUTINE set_random_seed ( ) !------------------------------------------------------------------------ ! ! poor-man random seed for randy ! INTEGER, DIMENSION (8) :: itime INTEGER :: iseed REAL(DP) :: drand(1) #if defined(__CUDA) attributes(DEVICE) :: drand #endif ! CALL date_and_time ( values = itime ) ! itime contains: year, month, day, time difference in minutes, hours, ! minutes, seconds and milliseconds. iseed = ( itime(8) + itime(6) ) * ( itime(7) + itime(4) ) CALL randy_vect_gpu ( drand, 1, iseed ) CALL randy_vect_debug_gpu (drand, 1, iseed ) ! END SUBROUTINE set_random_seed ! END MODULE random_numbers_gpum