rocRAND examples#
rocRAND generates
pseudo-random and quasi-random numbers directly into device memory on AMD
GPUs. hipFORT exposes it through the hipfort_rocrand module, together with
hipfort_rocrand_enums for the generator enumerations
(ROCRAND_RNG_PSEUDO_PHILOX4_32_10 and so on). The programs below import
both explicitly.
Every program on this page is a complete, self-contained example that is built
and run as part of the hipFORT test suite. The Fortran 2008 sources live in
test/f2008/rocrand and the equivalent Fortran 2003 sources, which use
type(c_ptr) device pointers and explicit byte counts instead of Fortran
array pointers, live in test/f2003/rocrand.
hipRAND offers the same functionality through an API that follows cuRAND; see the hipRAND examples.
The page is organised by generator, because that is the one choice a program makes up front. Each section shows one worked example and names the sibling programs that pair the same generator with the other distributions.
rocRAND call pattern#
A rocRAND program always follows the same sequence:
Create a generator with
rocrand_create_generator, passing the enumerator that selects the algorithm.Configure it: pseudo-random generators take a seed via
rocrand_set_seed, while quasi-random generators take a dimension count viarocrand_set_quasi_random_generator_dimensions.Allocate a device buffer to receive the numbers.
Call the
rocrand_generate_*routine for the distribution you want.Call
hipDeviceSynchronizebefore reading the results.Copy the buffer back to the host.
Free the device memory and release the generator with
rocrand_destroy_generator.
Keep the following conventions in mind:
rocRAND writes directly into device memory; there is no host-side generation path. The output buffer argument is typed
type(c_ptr)in the binding, so the Fortran 2008 programs passc_loc(dx(1))rather than the array pointer itself.The count argument is the number of elements, typed
integer(c_size_t), not a byte count.A fixed seed makes a pseudo-random sequence reproducible, which is what lets these programs assert on sample statistics.
Every rocRAND call returns a status code. The examples wrap them in
rocrandCheckfrom thehipfort_checkmodule, which aborts on failure.
Building an example#
The examples only need the rocrand and hip hipFORT components:
find_package(hipfort REQUIRED COMPONENTS hip rocrand)
add_executable(my_rand philox_uniform.f08)
target_link_libraries(my_rand PRIVATE hipfort::rocrand hipfort::hip)
See Using hipFORT in your application for the full set of build options.
Output distributions#
Every generator on this page supports the same four combinations, which differ only in the routine called and the type of the output buffer:
rocrand_generate_uniformfills the buffer withreal(c_float)values distributed uniformly over(0, 1], so a correct sample has a mean near 0.5.rocrand_generate_uniform_doubleis thereal(c_double)form.rocrand_generate_normaltakes a mean and a standard deviation in addition to the buffer and count, androcrand_generate_normal_doubleis its double-precision form.
Two further distributions, Poisson and log-normal, are exercised only with the Philox generator and are covered in their own section at the end of the page.
Pseudo-random generators#
The four pseudo-random generators are interchangeable in these programs: each
is created with its own enumerator, seeded with rocrand_set_seed, and then
used identically.
XORWOW#
ROCRAND_RNG_PSEUDO_XORWOW selects the xorshift-based XORWOW generator.
This example generates uniform single-precision values and checks the sample
mean.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Copyright (c) 2020-2026 Advanced Micro Devices, Inc.
!
! Permission is hereby granted, free of charge, to any person obtaining a copy
! of this software and associated documentation files (the "Software"), to deal
! in the Software without restriction, including without limitation the rights
! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! copies of the Software, and to permit persons to whom the Software is
! furnished to do so, subject to the following conditions:
!
! The above copyright notice and this permission notice shall be included in
! all copies or substantial portions of the Software.
!
! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! THE SOFTWARE.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program rocrand_xorwow_uniform_test
use iso_c_binding
use hipfort
use hipfort_check
use hipfort_rocrand
use hipfort_rocrand_enums
implicit none
integer(c_size_t), parameter :: N = 65536
integer(c_int64_t), parameter :: seed = 12345_c_int64_t
real(c_float), parameter :: expected_mean = 0.5, delta = 0.1
type(c_ptr) :: gen = c_null_ptr
real(c_float), allocatable, target, dimension(:) :: hx
real(c_float), pointer, dimension(:) :: dx
real(c_float) :: sample_mean
write(*,"(a)",advance="no") "-- Running test 'XORWOW_UNIFORM' (Fortran 2008 interfaces) - "
! Create generator and set a fixed seed for reproducibility
call rocrandCheck(rocrand_create_generator(gen, ROCRAND_RNG_PSEUDO_XORWOW))
call rocrandCheck(rocrand_set_seed(gen, seed))
! Allocate host- and device-side memory
allocate(hx(N))
call hipCheck(hipMalloc(dx, source=hx))
! Generate uniformly distributed floats on the device.
! output_data is type(c_ptr); take the address of the device pointer target.
call rocrandCheck(rocrand_generate_uniform(gen, c_loc(dx(1)), N))
call hipCheck(hipDeviceSynchronize())
! Transfer data back to host memory
call hipCheck(hipMemcpy(hx, dx, hipMemcpyDeviceToHost))
! Verification: sample mean of (0,1] output should be near 0.5
sample_mean = sum(hx) / real(N)
if (abs(sample_mean - expected_mean) > delta) then
write(*,*) "FAILED! mean out of tolerance: ", sample_mean
call exit(1)
end if
! Cleanup
call hipCheck(hipFree(dx))
deallocate(hx)
call rocrandCheck(rocrand_destroy_generator(gen))
write(*,*) "PASSED!"
end program rocrand_xorwow_uniform_test
test/f2008/rocrand/xorwow_uniform_double.f08, xorwow_normal.f08 and
xorwow_normal_double.f08 cover the remaining distributions.
Philox#
ROCRAND_RNG_PSEUDO_PHILOX4_32_10 selects the counter-based Philox
generator. This example uses the normal distribution, so it also shows the
extra mean and stddev arguments; it checks both the sample mean and
the sample standard deviation, since a generator producing the right mean with
the wrong spread would otherwise pass.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Copyright (c) 2020-2026 Advanced Micro Devices, Inc.
!
! Permission is hereby granted, free of charge, to any person obtaining a copy
! of this software and associated documentation files (the "Software"), to deal
! in the Software without restriction, including without limitation the rights
! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! copies of the Software, and to permit persons to whom the Software is
! furnished to do so, subject to the following conditions:
!
! The above copyright notice and this permission notice shall be included in
! all copies or substantial portions of the Software.
!
! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! THE SOFTWARE.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program rocrand_philox_normal_test
use iso_c_binding
use hipfort
use hipfort_check
use hipfort_rocrand
use hipfort_rocrand_enums
implicit none
integer(c_size_t), parameter :: N = 65536
integer(c_int64_t), parameter :: seed = 12345_c_int64_t
real(c_float), parameter :: mean = 0.0, stddev = 1.0, delta = 0.2
type(c_ptr) :: gen = c_null_ptr
real(c_float), allocatable, target, dimension(:) :: hx
real(c_float), pointer, dimension(:) :: dx
real(c_float) :: sample_mean, sample_std
write(*,"(a)",advance="no") "-- Running test 'PHILOX_NORMAL' (Fortran 2008 interfaces) - "
! Create generator and set a fixed seed for reproducibility
call rocrandCheck(rocrand_create_generator(gen, ROCRAND_RNG_PSEUDO_PHILOX4_32_10))
call rocrandCheck(rocrand_set_seed(gen, seed))
! Allocate host- and device-side memory
allocate(hx(N))
call hipCheck(hipMalloc(dx, source=hx))
! Generate normally distributed floats on the device.
! output_data is type(c_ptr); take the address of the device pointer target.
call rocrandCheck(rocrand_generate_normal(gen, c_loc(dx(1)), N, mean, stddev))
call hipCheck(hipDeviceSynchronize())
! Transfer data back to host memory
call hipCheck(hipMemcpy(hx, dx, hipMemcpyDeviceToHost))
! Verification: sample mean and stddev should match requested parameters
sample_mean = sum(hx) / real(N)
sample_std = sqrt(sum((hx - mean)**2) / real(N))
if (abs(sample_mean - mean) > delta) then
write(*,*) "FAILED! mean out of tolerance: ", sample_mean
call exit(1)
end if
if (abs(sample_std - stddev) > delta) then
write(*,*) "FAILED! stddev out of tolerance: ", sample_std
call exit(1)
end if
! Cleanup
call hipCheck(hipFree(dx))
deallocate(hx)
call rocrandCheck(rocrand_destroy_generator(gen))
write(*,*) "PASSED!"
end program rocrand_philox_normal_test
test/f2008/rocrand/philox_uniform.f08,
philox_uniform_double.f08 and philox_normal_double.f08 cover the
remaining distributions. Philox is also the generator used for the Poisson and
log-normal programs below.
MRG32K3A#
ROCRAND_RNG_PSEUDO_MRG32K3A selects the combined multiple-recursive
generator.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Copyright (c) 2020-2026 Advanced Micro Devices, Inc.
!
! Permission is hereby granted, free of charge, to any person obtaining a copy
! of this software and associated documentation files (the "Software"), to deal
! in the Software without restriction, including without limitation the rights
! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! copies of the Software, and to permit persons to whom the Software is
! furnished to do so, subject to the following conditions:
!
! The above copyright notice and this permission notice shall be included in
! all copies or substantial portions of the Software.
!
! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! THE SOFTWARE.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program rocrand_mrg32k3a_uniform_test
use iso_c_binding
use hipfort
use hipfort_check
use hipfort_rocrand
use hipfort_rocrand_enums
implicit none
integer(c_size_t), parameter :: N = 65536
integer(c_int64_t), parameter :: seed = 12345_c_int64_t
real(c_float), parameter :: expected_mean = 0.5, delta = 0.1
type(c_ptr) :: gen = c_null_ptr
real(c_float), allocatable, target, dimension(:) :: hx
real(c_float), pointer, dimension(:) :: dx
real(c_float) :: sample_mean
write(*,"(a)",advance="no") "-- Running test 'MRG32K3A_UNIFORM' (Fortran 2008 interfaces) - "
call rocrandCheck(rocrand_create_generator(gen, ROCRAND_RNG_PSEUDO_MRG32K3A))
call rocrandCheck(rocrand_set_seed(gen, seed))
allocate(hx(N))
call hipCheck(hipMalloc(dx, source=hx))
! Uniform (0,1] samples have mean 1/2.
call rocrandCheck(rocrand_generate_uniform(gen, c_loc(dx(1)), N))
call hipCheck(hipDeviceSynchronize())
call hipCheck(hipMemcpy(hx, dx, hipMemcpyDeviceToHost))
sample_mean = sum(hx) / real(N, kind(sample_mean))
if (abs(sample_mean - expected_mean) > delta) then
write(*,*) "FAILED! mean out of tolerance: ", sample_mean
call exit(1)
end if
call hipCheck(hipFree(dx))
deallocate(hx)
call rocrandCheck(rocrand_destroy_generator(gen))
write(*,*) "PASSED!"
end program rocrand_mrg32k3a_uniform_test
test/f2008/rocrand/mrg32k3a_uniform_double.f08, mrg32k3a_normal.f08
and mrg32k3a_normal_double.f08 cover the remaining distributions.
MTGP32#
ROCRAND_RNG_PSEUDO_MTGP32 selects the Mersenne Twister for graphics
processors. This example uses the double-precision normal distribution.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Copyright (c) 2020-2026 Advanced Micro Devices, Inc.
!
! Permission is hereby granted, free of charge, to any person obtaining a copy
! of this software and associated documentation files (the "Software"), to deal
! in the Software without restriction, including without limitation the rights
! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! copies of the Software, and to permit persons to whom the Software is
! furnished to do so, subject to the following conditions:
!
! The above copyright notice and this permission notice shall be included in
! all copies or substantial portions of the Software.
!
! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! THE SOFTWARE.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program rocrand_mtgp32_normal_test
use iso_c_binding
use hipfort
use hipfort_check
use hipfort_rocrand
use hipfort_rocrand_enums
implicit none
integer(c_size_t), parameter :: N = 65536
integer(c_int64_t), parameter :: seed = 12345_c_int64_t
real(c_float), parameter :: mean = 0.0, stddev = 1.0, delta = 0.2
type(c_ptr) :: gen = c_null_ptr
real(c_float), allocatable, target, dimension(:) :: hx
real(c_float), pointer, dimension(:) :: dx
real(c_float) :: sample_mean
real(c_float) :: sample_std
write(*,"(a)",advance="no") "-- Running test 'MTGP32_NORMAL' (Fortran 2008 interfaces) - "
call rocrandCheck(rocrand_create_generator(gen, ROCRAND_RNG_PSEUDO_MTGP32))
call rocrandCheck(rocrand_set_seed(gen, seed))
allocate(hx(N))
call hipCheck(hipMalloc(dx, source=hx))
! Normal(mean, stddev) samples recover both moments.
call rocrandCheck(rocrand_generate_normal(gen, c_loc(dx(1)), N, mean, stddev))
call hipCheck(hipDeviceSynchronize())
call hipCheck(hipMemcpy(hx, dx, hipMemcpyDeviceToHost))
sample_mean = sum(hx) / real(N, kind(sample_mean))
sample_std = sqrt(sum((hx - sample_mean)**2) / real(N, kind(sample_mean)))
if (abs(sample_mean - mean) > delta) then
write(*,*) "FAILED! mean out of tolerance: ", sample_mean
call exit(1)
end if
if (abs(sample_std - stddev) > delta) then
write(*,*) "FAILED! stddev out of tolerance: ", sample_std
call exit(1)
end if
call hipCheck(hipFree(dx))
deallocate(hx)
call rocrandCheck(rocrand_destroy_generator(gen))
write(*,*) "PASSED!"
end program rocrand_mtgp32_normal_test
test/f2008/rocrand/mtgp32_uniform.f08, mtgp32_uniform_double.f08 and
mtgp32_normal_double.f08 cover the remaining distributions.
Quasi-random generators#
Sobol32#
ROCRAND_RNG_QUASI_SOBOL32 produces a low-discrepancy sequence, which fills
the sample space more evenly than a pseudo-random stream. It is configured
with a dimension count instead of a seed, so
rocrand_set_quasi_random_generator_dimensions replaces the
rocrand_set_seed call; everything else is unchanged.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Copyright (c) 2020-2026 Advanced Micro Devices, Inc.
!
! Permission is hereby granted, free of charge, to any person obtaining a copy
! of this software and associated documentation files (the "Software"), to deal
! in the Software without restriction, including without limitation the rights
! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! copies of the Software, and to permit persons to whom the Software is
! furnished to do so, subject to the following conditions:
!
! The above copyright notice and this permission notice shall be included in
! all copies or substantial portions of the Software.
!
! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! THE SOFTWARE.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program rocrand_sobol32_uniform_test
use iso_c_binding
use hipfort
use hipfort_check
use hipfort_rocrand
use hipfort_rocrand_enums
implicit none
integer(c_size_t), parameter :: N = 65536
integer(c_int), parameter :: dimensions = 1
real(c_float), parameter :: expected_mean = 0.5, delta = 0.1
type(c_ptr) :: gen = c_null_ptr
real(c_float), allocatable, target, dimension(:) :: hx
real(c_float), pointer, dimension(:) :: dx
real(c_float) :: sample_mean
write(*,"(a)",advance="no") "-- Running test 'SOBOL32_UNIFORM' (Fortran 2008 interfaces) - "
! Sobol32 is a quasi-random (low-discrepancy) generator: it takes a
! dimension count rather than a seed.
call rocrandCheck(rocrand_create_generator(gen, ROCRAND_RNG_QUASI_SOBOL32))
call rocrandCheck(rocrand_set_quasi_random_generator_dimensions(gen, dimensions))
allocate(hx(N))
call hipCheck(hipMalloc(dx, source=hx))
! Uniform (0,1] samples have mean 1/2.
call rocrandCheck(rocrand_generate_uniform(gen, c_loc(dx(1)), N))
call hipCheck(hipDeviceSynchronize())
call hipCheck(hipMemcpy(hx, dx, hipMemcpyDeviceToHost))
sample_mean = sum(hx) / real(N, kind(sample_mean))
if (abs(sample_mean - expected_mean) > delta) then
write(*,*) "FAILED! mean out of tolerance: ", sample_mean
call exit(1)
end if
call hipCheck(hipFree(dx))
deallocate(hx)
call rocrandCheck(rocrand_destroy_generator(gen))
write(*,*) "PASSED!"
end program rocrand_sobol32_uniform_test
test/f2008/rocrand/sobol32_uniform_double.f08, sobol32_normal.f08 and
sobol32_normal_double.f08 cover the remaining distributions.
Poisson and log-normal distributions#
These two distributions are exercised with the Philox generator only, so that a failure points at the distribution entry point rather than at the generator.
Poisson#
rocrand_generate_poisson draws from a Poisson distribution with parameter
lambda. Unlike the other distributions it produces unsigned 32-bit
integers rather than floating-point values, so the host and device buffers
are integer(c_int) while lambda remains real(c_double). A Poisson
distribution has mean lambda, which is what the program checks.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Copyright (c) 2020-2026 Advanced Micro Devices, Inc.
!
! Permission is hereby granted, free of charge, to any person obtaining a copy
! of this software and associated documentation files (the "Software"), to deal
! in the Software without restriction, including without limitation the rights
! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! copies of the Software, and to permit persons to whom the Software is
! furnished to do so, subject to the following conditions:
!
! The above copyright notice and this permission notice shall be included in
! all copies or substantial portions of the Software.
!
! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! THE SOFTWARE.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program rocrand_philox_poisson_test
use iso_c_binding
use hipfort
use hipfort_check
use hipfort_rocrand
use hipfort_rocrand_enums
implicit none
integer(c_size_t), parameter :: N = 65536
integer(c_int64_t), parameter :: seed = 12345_c_int64_t
real(c_double), parameter :: lambda = 10.0_c_double
real(c_double), parameter :: delta = 0.5_c_double
type(c_ptr) :: gen = c_null_ptr
integer(c_int), allocatable, target, dimension(:) :: hx
integer(c_int), pointer, dimension(:) :: dx
real(c_double) :: sample_mean
write(*,"(a)",advance="no") "-- Running test 'PHILOX_POISSON' (Fortran 2008 interfaces) - "
call rocrandCheck(rocrand_create_generator(gen, ROCRAND_RNG_PSEUDO_PHILOX4_32_10))
call rocrandCheck(rocrand_set_seed(gen, seed))
allocate(hx(N))
call hipCheck(hipMalloc(dx, source=hx))
! Poisson(lambda) samples are unsigned 32-bit integers with mean lambda.
call rocrandCheck(rocrand_generate_poisson(gen, c_loc(dx(1)), N, lambda))
call hipCheck(hipDeviceSynchronize())
call hipCheck(hipMemcpy(hx, dx, hipMemcpyDeviceToHost))
sample_mean = real(sum(hx), c_double) / real(N, c_double)
if (abs(sample_mean - lambda) > delta) then
write(*,*) "FAILED! mean out of tolerance: ", sample_mean
call exit(1)
end if
call hipCheck(hipFree(dx))
deallocate(hx)
call rocrandCheck(rocrand_destroy_generator(gen))
write(*,*) "PASSED!"
end program rocrand_philox_poisson_test
This is the only Poisson program in the test suite.
Log-normal#
rocrand_generate_log_normal produces values whose logarithm is normally
distributed with the given mean and standard deviation. Every sample is
therefore strictly positive, and the program verifies the distribution by
taking logs and checking the resulting mean and standard deviation.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Copyright (c) 2020-2026 Advanced Micro Devices, Inc.
!
! Permission is hereby granted, free of charge, to any person obtaining a copy
! of this software and associated documentation files (the "Software"), to deal
! in the Software without restriction, including without limitation the rights
! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! copies of the Software, and to permit persons to whom the Software is
! furnished to do so, subject to the following conditions:
!
! The above copyright notice and this permission notice shall be included in
! all copies or substantial portions of the Software.
!
! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! THE SOFTWARE.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
program rocrand_philox_log_normal_test
use iso_c_binding
use hipfort
use hipfort_check
use hipfort_rocrand
use hipfort_rocrand_enums
implicit none
integer(c_size_t), parameter :: N = 65536
integer(c_int64_t), parameter :: seed = 12345_c_int64_t
real(c_float), parameter :: mean = 0.0, stddev = 1.0, delta = 0.2
type(c_ptr) :: gen = c_null_ptr
real(c_float), allocatable, target, dimension(:) :: hx
real(c_float), pointer, dimension(:) :: dx
real(c_float) :: sample_mean
real(c_float) :: sample_std
write(*,"(a)",advance="no") "-- Running test 'PHILOX_LOG_NORMAL' (Fortran 2008 interfaces) - "
call rocrandCheck(rocrand_create_generator(gen, ROCRAND_RNG_PSEUDO_PHILOX4_32_10))
call rocrandCheck(rocrand_set_seed(gen, seed))
allocate(hx(N))
call hipCheck(hipMalloc(dx, source=hx))
! If x is log-normal with parameters (mean, stddev) then log(x) is
! normal with those moments. Log-normal samples are strictly
! positive, so the logarithm is always defined.
call rocrandCheck(rocrand_generate_log_normal(gen, c_loc(dx(1)), N, mean, stddev))
call hipCheck(hipDeviceSynchronize())
call hipCheck(hipMemcpy(hx, dx, hipMemcpyDeviceToHost))
if (any(hx <= 0.0)) then
write(*,*) "FAILED! log-normal sample was not positive"
call exit(1)
end if
sample_mean = sum(log(hx)) / real(N, kind(sample_mean))
sample_std = sqrt(sum((log(hx) - sample_mean)**2) / real(N, kind(sample_mean)))
if (abs(sample_mean - mean) > delta) then
write(*,*) "FAILED! mean of log(x) out of tolerance: ", sample_mean
call exit(1)
end if
if (abs(sample_std - stddev) > delta) then
write(*,*) "FAILED! stddev of log(x) out of tolerance: ", sample_std
call exit(1)
end if
call hipCheck(hipFree(dx))
deallocate(hx)
call rocrandCheck(rocrand_destroy_generator(gen))
write(*,*) "PASSED!"
end program rocrand_philox_log_normal_test
rocrand_generate_log_normal_double is the double-precision form; see
test/f2008/rocrand/philox_log_normal_double.f08.