SYCL Kernels API#
Supported C++ Standard Library APIs and Algorithms#
oneDPL defines a subset of the C++ Standard library APIs for use in SYCL kernels. These APIs can be employed in the kernels similarly to how they are employed in code for a typical CPU-based platform.
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 <oneapi/dpl/random>
header.
Supported functionality:#
- Engine class templates:
linear_congruential_engine
subtract_with_carry_engine
- Engine adaptor class templates:
discard_block_engine
- Engines and engine adaptors with predefined parameters:
minstd_rand0
minstd_rand
ranlux24_base
ranlux48_base
ranlux24
ranlux48
- Distribution class templates:
uniform_int_distribution
uniform_real_distribution
normal_distribution
exponential_distribution
bernoulli_distribution
geometric_distribution
weibull_distribuion
lognormal_distribution
cauchy_distribution
extreme_value_distribution
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
andseed_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;
ifresult_type
issycl::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()
andmax()
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 assycl::vec<Type,N>::element_type
,G::min()
andG::max()
return a value ofG::scalar_type
,for each index
i
in the range [0
,N
),G::min() <= g()[i]
andg()[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 assycl::vec<Type,N>::element_type
,D::min()
andD::max()
return a value ofD::scalar_type
, andD::min() <= D::max()
,operator()
of a distribution returns asycl::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:
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:
Engines and engine adaptors based on |
C++ standard analogue |
The 10000th scalar random value consecutively produced by a default-constructed object |
---|---|---|
|
|
1043618065 |
|
|
399268537 |
|
|
7937952 |
|
|
61839128582725 |
|
|
9901578 |
|
|
1112339016 |
Function Objects#
The oneDPL function objects are defined in the <oneapi/dpl/functional>
header.
namespace oneapi {
namespace dpl {
struct identity
{
template <typename T>
constexpr T&&
operator()(T&& t) const noexcept;
};
}
}
The oneapi::dpl::identity
class implements an identity operation. Its function operator
receives an instance of a type and returns the argument unchanged.