diff --git a/source/elements/oneDPL/source/sycl_kernels_api.rst b/source/elements/oneDPL/source/sycl_kernels_api.rst index dc1a258af0..507e8a5ff3 100644 --- a/source/elements/oneDPL/source/sycl_kernels_api.rst +++ b/source/elements/oneDPL/source/sycl_kernels_api.rst @@ -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:`` header. +suitable to use within SYCL kernels. The APIs are defined in the :code:`` header. Supported functionality: ------------------------ + - Engine class templates: - ``linear_congruential_engine`` - ``subtract_with_carry_engine`` @@ -46,10 +48,11 @@ 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; @@ -57,6 +60,100 @@ The following deviations from the `C++ Standard`_ may apply: - 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`` 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``. + +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``, +- 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``, ``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::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``: + +- ``D::scalar_type`` is the same as ``sycl::vec::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`` 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 + using minstd_rand0_vec = linear_congruential_engine, 16807, 0, 2147483647>; + + template + using minstd_rand_vec = linear_congruential_engine, 48271, 0, 2147483647>; + + template + using ranlux24_base_vec = subtract_with_carry_engine, 24, 10, 24>; + + template + using ranlux48_base_vec = subtract_with_carry_engine, 48, 5, 12>; + + template + using ranlux24_vec = discard_block_engine, 223, 23>; + + template + using ranlux48_vec = discard_block_engine, 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 ++++++++++++++++ @@ -75,5 +172,5 @@ The oneDPL function objects are defined in the :code:`` 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.