@@ -14,14 +14,16 @@ CPU-based platform.
1414
1515.. _`C++ Standard` : https://isocpp.org/std/the-standard
1616
17+
1718Random Number Generation
1819++++++++++++++++++++++++
1920
2021oneDPL provides a subset of the standard C++ pseudo-random number generation functionality
21- suitable to use within SYCL kernels. The APIs are defined in the :code: `<oneapi/dpl/random> ` header.
22+ suitable to use within SYCL kernels. The APIs are defined in the :code: `<oneapi/dpl/random> ` header.
2223
2324Supported functionality:
2425------------------------
26+
2527- Engine class templates:
2628 - ``linear_congruential_engine ``
2729 - ``subtract_with_carry_engine ``
@@ -46,17 +48,112 @@ Supported functionality:
4648 - ``cauchy_distribution ``
4749 - ``extreme_value_distribution ``
4850
49- Additionally, `` sycl::vec<> `` can be used as the result type for engines, engine adaptors, and distributions .
51+ `` linear_congruential_engine `` and `` subtract_with_carry_engine `` satisfy the uniform random bit generator requirements .
5052
5153Limitations:
5254------------
55+
5356The following deviations from the `C++ Standard `_ may apply:
5457
5558- ``random_device `` and ``seed_seq `` classes and related APIs in other classes are not required;
5659- ``operator>>() ``, ``operator<<() ``, ``operator==() `` are not required;
5760- specifying the size of a random number engine's state is not required;
5861- distributions are only required to operate with floating point types applicable to supported SYCL devices.
5962
63+ Extensions:
64+ -----------
65+
66+ As an extension to the `C++ Standard `_, ``sycl::vec<Type, N> `` can be used as the data type template parameter for
67+ engines, engine adaptors, and distributions, where ``Type `` is one of data types supported by the corresponding
68+ class template in the standard. For such template instantiations, the ``result_type `` is also defined to
69+ ``sycl::vec<Type, N> ``.
70+
71+ Engines, engine adaptors, and distributions additionally define ``scalar_type ``, equivalent to the following:
72+
73+ - ``using scalar_type = typename result_type::element_type; `` if ``result_type `` is ``sycl::vec<Type, N> ``,
74+ - otherwise, ``using scalar_type = result_type; ``
75+
76+ The ``scalar_type `` is used instead of ``result_type `` in all contexts where a scalar data type is expected, including
77+
78+ - the type of configuration parameters and properties,
79+ - the seed value type,
80+ - the input parameters of constructors,
81+ - the return value type of ``min() `` and ``max() `` methods, etc.
82+
83+ Since ``scalar_type `` is the same as ``result_type `` except for template instantiations with ``sycl::vec ``,
84+ class templates still meet the applicable requirements of the `C++ Standard `_.
85+
86+ When instantiated with ``sycl::vec<Type,N> ``, ``linear_congruential_engine `` and ``subtract_with_carry_engine `` may not
87+ formally satisfy the uniform random bit generator requirements defined by the `C++ Standard `_. Instead, the following
88+ alternative requirements apply: for an engine object ``g `` of type ``G ``,
89+
90+ - ``G::scalar_type `` is an unsigned integral type same as ``sycl::vec<Type,N>::element_type ``,
91+ - ``G::min() `` and ``G::max() `` return a value of ``G::scalar_type ``,
92+ - for each index ``i `` in the range [``0 ``, ``N ``), ``G::min() <= g()[i] `` and ``g()[i] <= G::max() ``.
93+
94+ Effectively, these engines satisfy the standard *uniform random bit generator * requirements for each element
95+ of a ``sycl::vec `` returned by their ``operator() ``.
96+
97+ Similarly, for a distribution object ``d `` of a type ``D `` that is a template instantiated with ``sycl::vec<Type,N> ``:
98+
99+ - ``D::scalar_type `` is the same as ``sycl::vec<Type,N>::element_type ``,
100+ - ``D::min() `` and ``D::max() `` return a value of ``D::scalar_type ``, and ``D::min() <= D::max() ``,
101+ - ``operator() `` of a distribution returns a ``sycl::vec<Type,N> `` filled with random values
102+ in the closed interval ``[D::min(), D::max()] ``;
103+
104+ The following engines and engine adaptors with predefined parameters are defined:
105+
106+ .. code :: cpp
107+
108+ template <int N>
109+ using minstd_rand0_vec = linear_congruential_engine<sycl::vec<::std::uint_fast32_t, N>, 16807, 0, 2147483647>;
110+
111+ template <int N>
112+ using minstd_rand_vec = linear_congruential_engine<sycl::vec<uint_fast32_t, N>, 48271, 0, 2147483647>;
113+
114+ template <int N>
115+ using ranlux24_base_vec = subtract_with_carry_engine<sycl::vec<uint_fast32_t, N>, 24, 10, 24>;
116+
117+ template <int N>
118+ using ranlux48_base_vec = subtract_with_carry_engine<sycl::vec<uint_fast64_t, N>, 48, 5, 12>;
119+
120+ template <int N>
121+ using ranlux24_vec = discard_block_engine<ranlux24_base_vec<N>, 223, 23>;
122+
123+ template <int N>
124+ using ranlux48_vec = discard_block_engine<ranlux48_base_vec<N>, 389, 11>;
125+
126+ Except for producing a ``sycl::vec `` of random values per invocation, the behavior of these engines is equivalent to
127+ the corresponding scalar engines, as described in the following table:
128+
129+ .. container :: tablenoborder
130+
131+ .. list-table ::
132+ :header-rows: 1
133+
134+ * - Engines and engine adaptors based on ``sycl::vec<> ``
135+ - C++ standard analogue
136+ - The 10000th scalar random value consecutively produced by a default-constructed object
137+ * - ``minstd_rand0_vec ``
138+ - ``minstd_rand0 ``
139+ - 1043618065
140+ * - ``minstd_rand_vec ``
141+ - ``minstd_rand ``
142+ - 399268537
143+ * - ``ranlux24_base_vec ``
144+ - ``ranlux24_base ``
145+ - 7937952
146+ * - ``ranlux48_base_vec ``
147+ - ``ranlux48_base ``
148+ - 61839128582725
149+ * - ``ranlux24_vec ``
150+ - ``ranlux24 ``
151+ - 9901578
152+ * - ``ranlux48_vec ``
153+ - ``ranlux48 ``
154+ - 1112339016
155+
156+
60157Function Objects
61158++++++++++++++++
62159
@@ -75,5 +172,5 @@ The oneDPL function objects are defined in the :code:`<oneapi/dpl/functional>` h
75172 }
76173 }
77174
78- The :code: `oneapi::dpl::identity ` class implements an identity operation. Its function operator
175+ The :code: `oneapi::dpl::identity ` class implements an identity operation. Its function operator
79176receives an instance of a type and returns the argument unchanged.
0 commit comments