Skip to content

Commit 30c9931

Browse files
authored
[oneMath][RNG] Add PCG64 DXSM generator to Device API (#621)
The PCG is a family of random number generators based on linear congruential generator (LCG). The algorithm applies permutation function to improve statistical properties of LCG. PCG64 DXSM uses double xorshift multiply output function and has a period of 2^128. Added new page for the engine, modified bibliography and engines overview.
1 parent 456b00b commit 30c9931

File tree

3 files changed

+176
-3
lines changed

3 files changed

+176
-3
lines changed

source/elements/oneMath/source/domains/rng/bibliography.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,10 @@ Bibliography
9898

9999
[FIPS-197]
100100
Federal Information Processing Standards Publication 197, ADVANCED ENCRYPTION STANDARD (AES)
101+
102+
[pcg2014]
103+
Melissa E. O'Neill. PCG: A Family of Simple Fast Space-Efficient Statistically
104+
Good Algorithms for Random Number Generation.
105+
106+
107+
https://www.cs.hmc.edu/tr/hmc-cs-2014-0905.pdf

source/elements/oneMath/source/domains/rng/device_api/device-engines.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,20 @@ oneMath RNG provides following device pseudorandom number generators:
1919
- Description
2020

2121
* - :ref:`onemath_device_rng_mrg32k3a`
22-
- The combined multiple recursive pseudorandom number generator ``MRG32k3a`` [:ref:`L'Ecuyer99 <onemath_rng_bibliography>`]
22+
- The combined multiple recursive pseudorandom number generator ``MRG32k3a`` [:ref:`L'Ecuyer99 <onemath_rng_bibliography>`].
2323

2424
* - :ref:`onemath_device_rng_philox4x32x10`
25-
- Philox4x32-10 counter-based pseudorandom number generator with a period of :math:`2^{128}` ``PHILOX4X32X10`` [:ref:`Salmon11 <onemath_rng_bibliography>`]
25+
- Philox4x32-10 counter-based pseudorandom number generator with a period of :math:`2^{128}` ``PHILOX4X32X10`` [:ref:`Salmon11 <onemath_rng_bibliography>`].
2626

2727
* - :ref:`onemath_device_rng_mcg31m1`
2828
- The 31-bit multiplicative congruential pseudorandom number generator MCG(:math:`1132489760, 2^{32}-1`) :ref:`[L'Ecuyer99a] <onemath_rng_bibliography>`.
2929

3030
* - :ref:`onemath_device_rng_mcg59`
3131
- The 59-bit multiplicative congruential pseudorandom number generator MCG(:math:`13^{13}, 2^{59}`) from NAG Numerical Libraries :ref:`[NAG] <onemath_rng_bibliography>`.
3232

33+
* - :ref:`onemath_device_rng_pcg64_dxsm`
34+
- The permuted congruential pseudorandom number generator with a period of :math:`2^{128}` ``PCG64 DXSM`` :ref:`[pcg2014] <onemath_rng_bibliography>`.
35+
3336
**Parent topic:** :ref:`onemath_device_rng_routines`
3437

3538
.. toctree::
@@ -39,4 +42,5 @@ oneMath RNG provides following device pseudorandom number generators:
3942
device-rng-mrg32k3a.rst
4043
device-rng-philox4x32x10.rst
4144
device-rng-mcg31m1.rst
42-
device-rng-mcg59.rst
45+
device-rng-mcg59.rst
46+
device-rng-pcg64-dxsm.rst
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
.. SPDX-FileCopyrightText: 2025 Intel Corporation
2+
..
3+
.. SPDX-License-Identifier: CC-BY-4.0
4+
5+
.. _onemath_device_rng_pcg64_dxsm:
6+
7+
pcg64_dxsm
8+
==========
9+
10+
A permuted congruential pseudorandom number generator PCG64 DXSM with a period of :math:`2^{128}` :ref:`[pcg2014] <onemath_rng_bibliography>`.
11+
12+
.. rubric:: Description
13+
14+
The PCG is a family of random number generators based on linear congruential generator (LCG). The algorithm applies permutation function to improve statistical properties of LCG.
15+
PCG64 DXSM uses `double xorshift multiply` output function and has a period of :math:`2^{128}`.
16+
17+
.. container:: section
18+
19+
.. rubric:: Generation algorithm
20+
21+
:math:`x_n = x_{n-1} \cdot a + b`
22+
23+
:math:`hi_n = x_n \gg 64`
24+
25+
:math:`lo_n = x_n \land \left(2^{64} - 1\right) \lor 1`
26+
27+
:math:`hi_n = hi_n \oplus (hi_n \gg 32)`
28+
29+
:math:`hi_n = hi_n \cdot a`
30+
31+
:math:`hi_n = hi_n \oplus (hi_n \gg 48)`
32+
33+
:math:`u_n = hi_n \cdot lo_n`
34+
35+
:math:`a = \text{0xDA942042E4DD58B5}, b = \text{0x5851F42D4C957F2D14057B7EF767814F}`
36+
37+
class pcg64_dxsm
38+
----------------
39+
40+
.. rubric:: Syntax
41+
42+
.. code-block:: cpp
43+
44+
namespace oneapi::math::rng::device {
45+
template<std::int32_t VecSize = 1>
46+
class pcg64_dxsm {
47+
public:
48+
static constexpr std::uint64_t default_seed = 1;
49+
static constexpr std::int32_t vec_size = VecSize;
50+
51+
pcg64_dxsm();
52+
pcg64_dxsm(std::uint64_t seed, std::uint64_t offset = 0);
53+
pcg64_dxsm(std::initializer_list<std::uint64_t> seed, std::uint64_t offset = 0);
54+
pcg64_dxsm(std::uint64_t seed, std::initializer_list<std::uint64_t> offset);
55+
pcg64_dxsm(std::initializer_list<std::uint64_t> seed, std::initializer_list<std::uint64_t> offset);
56+
};
57+
}
58+
59+
.. container:: section
60+
61+
.. rubric:: Class Template Parameters
62+
63+
VecSize
64+
Describes the size of vector which will be produced by generate function by this engine. VecSize values
65+
may be 1, 2, 3, 4, 8, 16 as ``sycl::vec`` class size. By default VecSize = 1, for this case, a single
66+
random number is returned by the ``generate`` function.
67+
68+
.. container:: section
69+
70+
.. rubric:: Class Members
71+
72+
.. list-table::
73+
:header-rows: 1
74+
75+
* - Routine
76+
- Description
77+
* - `pcg64_dxsm()`_
78+
- Default constructor
79+
* - `pcg64_dxsm(std::uint64_t seed, std::uint64_t offset = 0)`_
80+
- Constructor for common seed initialization of the engine and common number of skipped elements
81+
* - `pcg64_dxsm(std::initializer_list<std::uint64_t> seed, std::uint64_t offset = 0)`_
82+
- Constructor for extended seed initialization of the engine and common number of skipped elements
83+
* - `pcg64_dxsm(std::uint64_t seed, std::initializer_list<std::uint64_t> offset)`_
84+
- Constructor for common seed initialization of the engine and extended number of skipped elements
85+
* - `pcg64_dxsm(std::initializer_list<std::uint64_t> seed, std::initializer_list<std::uint64_t> offset)`_
86+
- Constructor for extended seed initialization of the engine and extended number of skipped elements
87+
88+
.. container:: section
89+
90+
.. rubric:: Constructors
91+
92+
.. _`pcg64_dxsm()`:
93+
94+
.. code-block:: cpp
95+
96+
pcg64_dxsm::pcg64_dxsm()
97+
98+
.. _`pcg64_dxsm(std::uint64_t seed, std::uint64_t offset = 0)`:
99+
100+
.. code-block:: cpp
101+
102+
pcg64_dxsm::pcg64_dxsm(std::uint64_t seed, std::uint64_t offset = 0)
103+
104+
.. container:: section
105+
106+
.. rubric:: Input Parameters
107+
108+
seed
109+
The initial conditions of the generator state.
110+
111+
offset
112+
Number of skipped elements.
113+
114+
.. _`pcg64_dxsm(std::initializer_list<std::uint64_t> seed, std::uint64_t offset = 0)`:
115+
116+
.. code-block:: cpp
117+
118+
pcg64_dxsm::pcg64_dxsm(std::initializer_list<std::uint64_t> seed, std::uint64_t offset = 0)
119+
120+
.. container:: section
121+
122+
.. rubric:: Input Parameters
123+
124+
seed
125+
The initial conditions of the generator state.
126+
127+
offset
128+
Number of skipped elements.
129+
130+
.. _`pcg64_dxsm(std::uint64_t seed, std::initializer_list<std::uint64_t> offset)`:
131+
132+
.. code-block:: cpp
133+
134+
pcg64_dxsm::pcg64_dxsm(std::uint64_t seed, std::initializer_list<std::uint64_t> offset)
135+
136+
.. container:: section
137+
138+
.. rubric:: Input Parameters
139+
140+
seed
141+
The initial conditions of the generator state.
142+
143+
offset
144+
Number of skipped elements. Offset is calculated as: ``num_to_skip`` [0]+ ``num_to_skip`` [1]*2\ :sup:`64`.
145+
146+
.. _`pcg64_dxsm(std::initializer_list<std::uint64_t> seed, std::initializer_list<std::uint64_t> offset)`:
147+
148+
.. code-block:: cpp
149+
150+
pcg64_dxsm::pcg64_dxsm(std::initializer_list<std::uint64_t> seed, std::initializer_list<std::uint64_t> offset)
151+
152+
.. container:: section
153+
154+
.. rubric:: Input Parameters
155+
156+
seed
157+
The initial conditions of the generator state.
158+
159+
offset
160+
Number of skipped elements. Offset is calculated as: ``num_to_skip`` [0]+ ``num_to_skip`` [1]*2\ :sup:`64`.
161+
162+
**Parent topic:** :ref:`onemath_device_rng_engines`

0 commit comments

Comments
 (0)