ParaMonte Fortran 2.0.0
Parallel Monte Carlo and Machine Learning Library
See the latest version documentation.
pm_distUnif::xoshiro256ss_type Type Reference

This is the abstract base derived type for defining variants of Xoshiro256** Uniform Random Number Generator derived types.
More...

Inheritance diagram for pm_distUnif::xoshiro256ss_type:
Collaboration diagram for pm_distUnif::xoshiro256ss_type:

Public Attributes

integer(IK64), dimension(xoshiro256ssStateSizestate = [ -5952639272145821898_IK64 , -2790978430781836137_IK64 , -4872796757339724681_IK64 , -6638731986642513151_IK64 ]
 The vector of size xoshiro256ssStateSize of type integer of kind IK64, containing the most recent RNG state.
More...
 
integer(IK64) stream
 The scalar of type integer of kind IK64, containing the most recently generated random 64-bit stream. More...
 

Detailed Description

This is the abstract base derived type for defining variants of Xoshiro256** Uniform Random Number Generator derived types.

See also
rngu_type
splitmix64_type
xoshiro256ssg_type
xoshiro256ssw_type
getUnifRandStateSize
Benchmarks:


Benchmark :: The runtime performance of intrinsic random_number() vs. xoshiro256ssg_type vs. xoshiro256ssw_type.

1program benchmark
2
3 use pm_kind, only: SK, IK, LK, RKG => RK, IKG => IK, LKG => LK
6 use pm_distUnif, only: setUnifRand
7 use pm_bench, only: bench_type
8
9 implicit none
10
11 integer(IK) :: i, j, fileUnit
12 integer(IK) , parameter :: NSIM = 100000_IK
13 logical(LKG) :: dumm_LK = .false._LKG
14 logical(LKG) :: rand_LK(NSIM)
15 integer(IKG) :: rand_IK(NSIM)
16 real(RKG) :: rand_RK(NSIM)
17 type(bench_type) , allocatable :: bench(:)
18 type(xoshiro256ssg_type) :: xoshiro256ssg
19 type(xoshiro256ssw_type) :: xoshiro256ssw
20 xoshiro256ssg = xoshiro256ssg_type()
21 xoshiro256ssw = xoshiro256ssw_type()
22
23 bench = [ bench_type(name = SK_"random_number_LK", exec = random_number_LK, overhead = setOverhead_LK) &
24 , bench_type(name = SK_"xoshiro256ssg_type_LK", exec = xoshiro256ssg_type_LK, overhead = setOverhead_LK) &
25 , bench_type(name = SK_"xoshiro256ssw_type_LK", exec = xoshiro256ssw_type_LK, overhead = setOverhead_LK) &
26 , bench_type(name = SK_"random_number_IK", exec = random_number_IK, overhead = setOverhead_LK) &
27 , bench_type(name = SK_"xoshiro256ssg_type_IK", exec = xoshiro256ssg_type_IK, overhead = setOverhead_IK) &
28 , bench_type(name = SK_"xoshiro256ssw_type_IK", exec = xoshiro256ssw_type_IK, overhead = setOverhead_IK) &
29 , bench_type(name = SK_"random_number_RK", exec = random_number_RK, overhead = setOverhead_RK) &
30 , bench_type(name = SK_"xoshiro256ssg_type_RK", exec = xoshiro256ssg_type_RK, overhead = setOverhead_RK) &
31 , bench_type(name = SK_"xoshiro256ssw_type_RK", exec = xoshiro256ssw_type_RK, overhead = setOverhead_RK) &
32 ]
33
34 write(*,"(*(g0,:,' '))")
35 write(*,"(*(g0,:,' '))") "xoshiro256ssg_type() vs. xoshiro256ssw_type()."
36 write(*,"(*(g0,:,' '))")
37
38 open(newunit = fileUnit, file = "main.out", status = "replace")
39
40 write(fileUnit, "(*(g0,:,','))") (bench(i)%name, i = 1, size(bench))
41 do i = 1, size(bench)
42 bench(i)%timing = bench(i)%getTiming()
43 end do
44 do j = 1, minval([(size(bench(i)%timing%values), i = 1, size(bench))])
45 write(fileUnit,"(*(g0,:,','))") (bench(i)%timing%values(j) / NSIM, i = 1, size(bench))
46 end do
47 write(*,"(*(g0,:,' '))")
48
49 close(fileUnit)
50
51contains
52
53 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54 ! procedure wrappers.
55 !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56
57 subroutine setOverhead_LK()
58 call getDummy_LK()
59 end subroutine
60
61 subroutine setOverhead_IK()
62 call getDummy_IK()
63 end subroutine
64
65 subroutine setOverhead_RK()
66 call getDummy_RK()
67 end subroutine
68
69 subroutine getDummy_LK()
70 dumm_LK = dumm_LK .or. count(rand_LK) == 0
71 end subroutine
72
73 subroutine getDummy_IK()
74 dumm_LK = dumm_LK .or. any(rand_IK == 0_IKG)
75 end subroutine
76
77 subroutine getDummy_RK()
78 dumm_LK = dumm_LK .or. any(rand_RK == 0._RKG)
79 end subroutine
80
81 subroutine random_number_LK()
82 call setUnifRand(rand_LK)
83 !block
84 ! real :: rand
85 ! call random_number(rand)
86 ! rand_LK = logical(rand < 0.5, LKG)
87 ! call getDummy_LK()
88 !end block
89 end subroutine
90
91 subroutine xoshiro256ssg_type_LK()
92 call setUnifRand(xoshiro256ssg, rand_LK)
93 call getDummy_LK()
94 end subroutine
95
96 subroutine xoshiro256ssw_type_LK()
97 call setUnifRand(xoshiro256ssw, rand_LK)
98 call getDummy_LK()
99 end subroutine
100
101
102 subroutine random_number_IK()
103 call setUnifRand(rand_IK)
104 call getDummy_IK()
105 end subroutine
106
107 subroutine xoshiro256ssg_type_IK()
108 call setUnifRand(xoshiro256ssg, rand_IK)
109 call getDummy_IK()
110 end subroutine
111
112 subroutine xoshiro256ssw_type_IK()
113 call setUnifRand(xoshiro256ssw, rand_IK)
114 call getDummy_IK()
115 end subroutine
116
117
118 subroutine random_number_RK()
119 call setUnifRand(rand_RK)
120 call getDummy_RK()
121 end subroutine
122
123 subroutine xoshiro256ssg_type_RK()
124 call setUnifRand(xoshiro256ssg, rand_RK)
125 call getDummy_RK()
126 end subroutine
127
128 subroutine xoshiro256ssw_type_RK()
129 call setUnifRand(xoshiro256ssw, rand_RK)
130 call getDummy_RK()
131 end subroutine
132
133end program benchmark
Generate and return an object of type timing_type containing the benchmark timing information and sta...
Definition: pm_bench.F90:574
Return a uniform random scalar or contiguous array of arbitrary rank of randomly uniformly distribute...
This module contains abstract interfaces and types that facilitate benchmarking of different procedur...
Definition: pm_bench.F90:41
This module contains classes and procedures for computing various statistical quantities related to t...
This module defines the relevant Fortran kind type-parameters frequently used in the ParaMonte librar...
Definition: pm_kind.F90:268
integer, parameter RK
The default real kind in the ParaMonte library: real64 in Fortran, c_double in C-Fortran Interoperati...
Definition: pm_kind.F90:543
integer, parameter LK
The default logical kind in the ParaMonte library: kind(.true.) in Fortran, kind(....
Definition: pm_kind.F90:541
integer, parameter IK
The default integer kind in the ParaMonte library: int32 in Fortran, c_int32_t in C-Fortran Interoper...
Definition: pm_kind.F90:540
integer, parameter SK
The default character kind in the ParaMonte library: kind("a") in Fortran, c_char in C-Fortran Intero...
Definition: pm_kind.F90:539
This is the class for creating benchmark and performance-profiling objects.
Definition: pm_bench.F90:386
This is the derived type for declaring and generating objects of type xoshiro256ssg_type containing a...
This is the derived type for declaring and generating objects of type xoshiro256ssw_type containing a...

Example Unix compile command via Intel ifort compiler
1#!/usr/bin/env sh
2rm main.exe
3ifort -fpp -standard-semantics -O3 -Wl,-rpath,../../../lib -I../../../inc main.F90 ../../../lib/libparamonte* -o main.exe
4./main.exe

Example Windows Batch compile command via Intel ifort compiler
1del main.exe
2set PATH=..\..\..\lib;%PATH%
3ifort /fpp /standard-semantics /O3 /I:..\..\..\include main.F90 ..\..\..\lib\libparamonte*.lib /exe:main.exe
4main.exe

Example Unix / MinGW compile command via GNU gfortran compiler
1#!/usr/bin/env sh
2rm main.exe
3gfortran -cpp -ffree-line-length-none -O3 -Wl,-rpath,../../../lib -I../../../inc main.F90 ../../../lib/libparamonte* -o main.exe
4./main.exe

Postprocessing of the benchmark output
1#!/usr/bin/env python
2
3import matplotlib.pyplot as plt
4import pandas as pd
5import numpy as np
6
7import os
8dirname = os.path.basename(os.getcwd())
9
10fontsize = 14
11
12df = pd.read_csv("main.out", delimiter = ",")
13colnames = list(df.columns.values)
14
15df = pd.read_csv("main.out")
16
17
20
21ax = plt.figure(figsize = 1.25 * np.array([6.4,4.6]), dpi = 200)
22ax = plt.subplot()
23
24for colname in colnames:
25 plt.hist( np.log10(df[colname].values)
26 , histtype = "stepfilled"
27 #, density = True
28 , alpha = 0.7
29 #, bins = 30
30 )
31
32plt.xticks(fontsize = fontsize)
33plt.yticks(fontsize = fontsize)
34ax.set_xlabel("$\log_{10}$ ( Runtime [ seconds ] )", fontsize = fontsize)
35ax.set_ylabel("Count", fontsize = fontsize)
36#ax.set_title(" vs. ".join(colnames[1:])+"\nLower is better.", fontsize = fontsize)
37#ax.set_xscale("log")
38#ax.set_yscale("log")
39plt.minorticks_on()
40plt.grid(visible = True, which = "both", axis = "both", color = "0.85", linestyle = "-")
41ax.tick_params(axis = "y", which = "minor")
42ax.tick_params(axis = "x", which = "minor")
43ax.legend ( colnames
44 #, loc='center left'
45 #, bbox_to_anchor=(1, 0.5)
46 , fontsize = fontsize
47 )
48
49plt.tight_layout()
50plt.savefig("benchmark." + dirname + ".runtime.png")
51
52
55
56ax = plt.figure(figsize = 1.25 * np.array([6.4,4.6]), dpi = 200)
57ax = plt.subplot()
58
59for colname in colnames[0:]:
60 plt.hist( np.log10(df[colname].values / df[colnames[0]].values)
61 , histtype = "stepfilled"
62 #, density = True
63 , alpha = 0.7
64 #, bins = 30
65 )
66ax.legend ( colnames[1:]
67 #, loc='center left'
68 #, bbox_to_anchor=(1, 0.5)
69 , fontsize = fontsize
70 )
71
72plt.xticks(fontsize = fontsize)
73plt.yticks(fontsize = fontsize)
74ax.set_title("Runtime Ratio Comparison. Lower means faster.\nLower than 1 means faster than {}().".format(colnames[0]), fontsize = fontsize)
75ax.set_xlabel(r"$\log_{{10}}$ ( Runtime Ratio ) w.r.t. {}".format(colnames[0]), fontsize = fontsize)
76ax.set_ylabel("Count", fontsize = fontsize)
77plt.minorticks_on()
78plt.grid(visible = True, which = "both", axis = "both", color = "0.85", linestyle = "-")
79ax.tick_params(axis = "y", which = "minor")
80ax.tick_params(axis = "x", which = "minor")
81
82plt.tight_layout()
83plt.savefig("benchmark." + dirname + ".runtime.ratio.png")

Visualization of the benchmark output

Benchmark moral
  1. The xoshiro256ssg_type RNG greedily attempts to use as many randomly generated bits as possible in the output random values.
  2. The xoshiro256ssw_type RNG takes a wasteful approach of using at least one or more chunks of 64 randomly generated bits in the output random values.
  3. This fundamental difference between the two RNG types generally leads to faster random logical value generations with the greedy approach, because 64bits chunks translate to 64 logical values without updating the RNG state.
  4. However, the greedy approach leads to generally slower runtimes for real random value generation.
  5. Both greedy and wasteful RNGs appear to be much faster than the ParaMonte library wrappers for the implementations offered by GNU Fortran Compiler gfortran and Intel Classic Fortran Compiler ifort.
  6. Moral: If your application requires many logical random number generations, use the greedy xoshiro256ssg_type RNG. Conversely, if your application requires a mixture of random number generations of various types and kinds, use the wasteful xoshiro256ssw_type RNG.
Test:
test_pm_distUnif


Final Remarks


If you believe this algorithm or its documentation can be improved, we appreciate your contribution and help to edit this page's documentation and source file on GitHub.
For details on the naming abbreviations, see this page.
For details on the naming conventions, see this page.
This software is distributed under the MIT license with additional terms outlined below.

  1. If you use any parts or concepts from this library to any extent, please acknowledge the usage by citing the relevant publications of the ParaMonte library.
  2. If you regenerate any parts/ideas from this library in a programming environment other than those currently supported by this ParaMonte library (i.e., other than C, C++, Fortran, MATLAB, Python, R), please also ask the end users to cite this original ParaMonte library.

This software is available to the public under a highly permissive license.
Help us justify its continued development and maintenance by acknowledging its benefit to society, distributing it, and contributing to it.

Author:
Fatemeh Bagheri, Wednesday 12:20 AM, October 13, 2021, Dallas, TX

Definition at line 2984 of file pm_distUnif.F90.

Member Data Documentation

◆ state

integer(IK64), dimension(xoshiro256ssStateSize) pm_distUnif::xoshiro256ss_type::state = [ -5952639272145821898_IK64 , -2790978430781836137_IK64 , -4872796757339724681_IK64 , -6638731986642513151_IK64 ]

The vector of size xoshiro256ssStateSize of type integer of kind IK64, containing the most recent RNG state.

Definition at line 2988 of file pm_distUnif.F90.

◆ stream

integer(IK64) pm_distUnif::xoshiro256ss_type::stream

The scalar of type integer of kind IK64, containing the most recently generated random 64-bit stream.

Definition at line 2994 of file pm_distUnif.F90.


The documentation for this type was generated from the following file: