Skip to content

Commit

Permalink
[oneDPL][RNG][Spec] Added the extensions sections (uxlfoundation#492)
Browse files Browse the repository at this point in the history
* [oneDPL][RNG][Spec] Added the extensions sections

* Applying the comments

* Applying changes from Alexey

* Fixing the lines lengthexey

* Fix of the line

* Applying the comments from Ruslan
  • Loading branch information
paveldyakov authored and aepanchi committed Oct 31, 2023
1 parent 5316fab commit 7289e37
Showing 1 changed file with 100 additions and 3 deletions.
103 changes: 100 additions & 3 deletions source/elements/oneDPL/source/sycl_kernels_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ CPU-based platform.

.. _`C++ Standard`: https://isocpp.org/std/the-standard


Random Number Generation
++++++++++++++++++++++++

oneDPL provides a subset of the standard C++ pseudo-random number generation functionality
suitable to use within SYCL kernels. The APIs are defined in the :code:`<oneapi/dpl/random>` header.
suitable to use within SYCL kernels. The APIs are defined in the :code:`<oneapi/dpl/random>` header.

Supported functionality:
------------------------

- Engine class templates:
- ``linear_congruential_engine``
- ``subtract_with_carry_engine``
Expand All @@ -46,17 +48,112 @@ Supported functionality:
- ``cauchy_distribution``
- ``extreme_value_distribution``

Additionally, ``sycl::vec<>`` can be used as the result type for engines, engine adaptors, and distributions.
``linear_congruential_engine`` and ``subtract_with_carry_engine`` satisfy the uniform random bit generator requirements.

Limitations:
------------

The following deviations from the `C++ Standard`_ may apply:

- ``random_device`` and ``seed_seq`` classes and related APIs in other classes are not required;
- ``operator>>()``, ``operator<<()``, ``operator==()`` are not required;
- specifying the size of a random number engine's state is not required;
- distributions are only required to operate with floating point types applicable to supported SYCL devices.

Extensions:
-----------

As an extension to the `C++ Standard`_, ``sycl::vec<Type, N>`` can be used as the data type template parameter for
engines, engine adaptors, and distributions, where ``Type`` is one of data types supported by the corresponding
class template in the standard. For such template instantiations, the ``result_type`` is also defined to
``sycl::vec<Type, N>``.

Engines, engine adaptors, and distributions additionally define ``scalar_type``, equivalent to the following:

- ``using scalar_type = typename result_type::element_type;`` if ``result_type`` is ``sycl::vec<Type, N>``,
- otherwise, ``using scalar_type = result_type;``

The ``scalar_type`` is used instead of ``result_type`` in all contexts where a scalar data type is expected, including

- the type of configuration parameters and properties,
- the seed value type,
- the input parameters of constructors,
- the return value type of ``min()`` and ``max()`` methods, etc.

Since ``scalar_type`` is the same as ``result_type`` except for template instantiations with ``sycl::vec``,
class templates still meet the applicable requirements of the `C++ Standard`_.

When instantiated with ``sycl::vec<Type,N>``, ``linear_congruential_engine`` and ``subtract_with_carry_engine`` may not
formally satisfy the uniform random bit generator requirements defined by the `C++ Standard`_. Instead, the following
alternative requirements apply: for an engine object ``g`` of type ``G``,

- ``G::scalar_type`` is an unsigned integral type same as ``sycl::vec<Type,N>::element_type``,
- ``G::min()`` and ``G::max()`` return a value of ``G::scalar_type``,
- for each index ``i`` in the range [``0``, ``N``), ``G::min() <= g()[i]`` and ``g()[i] <= G::max()``.

Effectively, these engines satisfy the standard *uniform random bit generator* requirements for each element
of a ``sycl::vec`` returned by their ``operator()``.

Similarly, for a distribution object ``d`` of a type ``D`` that is a template instantiated with ``sycl::vec<Type,N>``:

- ``D::scalar_type`` is the same as ``sycl::vec<Type,N>::element_type``,
- ``D::min()`` and ``D::max()`` return a value of ``D::scalar_type``, and ``D::min() <= D::max()``,
- ``operator()`` of a distribution returns a ``sycl::vec<Type,N>`` filled with random values
in the closed interval ``[D::min(), D::max()]``;

The following engines and engine adaptors with predefined parameters are defined:

.. code:: cpp
template <int N>
using minstd_rand0_vec = linear_congruential_engine<sycl::vec<::std::uint_fast32_t, N>, 16807, 0, 2147483647>;
template <int N>
using minstd_rand_vec = linear_congruential_engine<sycl::vec<uint_fast32_t, N>, 48271, 0, 2147483647>;
template <int N>
using ranlux24_base_vec = subtract_with_carry_engine<sycl::vec<uint_fast32_t, N>, 24, 10, 24>;
template <int N>
using ranlux48_base_vec = subtract_with_carry_engine<sycl::vec<uint_fast64_t, N>, 48, 5, 12>;
template <int N>
using ranlux24_vec = discard_block_engine<ranlux24_base_vec<N>, 223, 23>;
template <int N>
using ranlux48_vec = discard_block_engine<ranlux48_base_vec<N>, 389, 11>;
Except for producing a ``sycl::vec`` of random values per invocation, the behavior of these engines is equivalent to
the corresponding scalar engines, as described in the following table:

.. container:: tablenoborder

.. list-table::
:header-rows: 1

* - Engines and engine adaptors based on ``sycl::vec<>``
- C++ standard analogue
- The 10000th scalar random value consecutively produced by a default-constructed object
* - ``minstd_rand0_vec``
- ``minstd_rand0``
- 1043618065
* - ``minstd_rand_vec``
- ``minstd_rand``
- 399268537
* - ``ranlux24_base_vec``
- ``ranlux24_base``
- 7937952
* - ``ranlux48_base_vec``
- ``ranlux48_base``
- 61839128582725
* - ``ranlux24_vec``
- ``ranlux24``
- 9901578
* - ``ranlux48_vec``
- ``ranlux48``
- 1112339016


Function Objects
++++++++++++++++

Expand All @@ -75,5 +172,5 @@ The oneDPL function objects are defined in the :code:`<oneapi/dpl/functional>` h
}
}
The :code:`oneapi::dpl::identity` class implements an identity operation. Its function operator
The :code:`oneapi::dpl::identity` class implements an identity operation. Its function operator
receives an instance of a type and returns the argument unchanged.

0 comments on commit 7289e37

Please sign in to comment.