alpaka
Abstraction Library for Parallel Kernel Acceleration
RandGenericSycl.hpp
Go to the documentation of this file.
1 /* Copyright 2023 Luca Ferragina, Aurora Perego, Jan Stephan, Andrea Bocci
2  * SPDX-License-Identifier: MPL-2.0
3  */
4 
5 #pragma once
6 
10 #include "alpaka/rand/Traits.hpp"
11 
12 #if defined(ALPAKA_ACC_SYCL_ENABLED) && !defined(ALPAKA_DISABLE_VENDOR_RNG)
13 
14 // Backend specific imports.
15 # include <sycl/sycl.hpp>
16 # if BOOST_COMP_CLANG
17 # pragma clang diagnostic push
18 # pragma clang diagnostic ignored "-Wcast-align"
19 # pragma clang diagnostic ignored "-Wcast-qual"
20 # pragma clang diagnostic ignored "-Wextra-semi"
21 # pragma clang diagnostic ignored "-Wfloat-equal"
22 # pragma clang diagnostic ignored "-Wold-style-cast"
23 # pragma clang diagnostic ignored "-Wreserved-identifier"
24 # pragma clang diagnostic ignored "-Wreserved-macro-identifier"
25 # pragma clang diagnostic ignored "-Wsign-compare"
26 # pragma clang diagnostic ignored "-Wundef"
27 # endif
28 # include <oneapi/dpl/random>
29 # if BOOST_COMP_CLANG
30 # pragma clang diagnostic pop
31 # endif
32 
33 # include <type_traits>
34 
35 namespace alpaka::rand
36 {
37  //! The SYCL rand implementation.
38  template<typename TDim>
39  struct RandGenericSycl : interface::Implements<ConceptRand, RandGenericSycl<TDim>>
40  {
41  explicit RandGenericSycl(sycl::nd_item<TDim::value> my_item) : m_item_rand{my_item}
42  {
43  }
44 
45  sycl::nd_item<TDim::value> m_item_rand;
46  };
47 
48 # if !defined(ALPAKA_HOST_ONLY)
49  namespace distribution::sycl_rand
50  {
51  //! The SYCL random number floating point normal distribution.
52  template<typename T>
53  struct NormalReal;
54 
55  //! The SYCL random number uniform distribution.
56  template<typename T>
57  struct Uniform;
58  } // namespace distribution::sycl_rand
59 
60  namespace engine::sycl_rand
61  {
62  //! The SYCL linear congruential random number generator engine.
63  template<typename TDim>
64  class Minstd
65  {
66  public:
67  // After calling this constructor the instance is not valid initialized and
68  // need to be overwritten with a valid object
69  Minstd() = default;
70 
71  Minstd(RandGenericSycl<TDim> rand, std::uint32_t const& seed)
72  {
73  oneapi::dpl::minstd_rand engine(seed, rand.m_item_rand.get_global_linear_id());
74  rng_engine = engine;
75  }
76 
77  private:
78  template<typename T>
79  friend struct distribution::sycl_rand::NormalReal;
80  template<typename T>
81  friend struct distribution::sycl_rand::Uniform;
82 
83  oneapi::dpl::minstd_rand rng_engine;
84 
85  public:
86  using result_type = float;
87 
88  ALPAKA_FN_HOST_ACC static result_type min()
89  {
91  }
92 
93  ALPAKA_FN_HOST_ACC static result_type max()
94  {
96  }
97 
98  result_type operator()()
99  {
100  oneapi::dpl::uniform_real_distribution<float> distr;
101  return distr(rng_engine);
102  }
103  };
104  } // namespace engine::sycl_rand
105 
106  namespace distribution::sycl_rand
107  {
108 
109  //! The SYCL random number double normal distribution.
110  template<typename F>
111  struct NormalReal
112  {
113  static_assert(std::is_floating_point_v<F>);
114 
115  template<typename TEngine>
116  auto operator()(TEngine& engine) -> F
117  {
118  oneapi::dpl::normal_distribution<F> distr;
119  return distr(engine.rng_engine);
120  }
121  };
122 
123  //! The SYCL random number float uniform distribution.
124  template<typename T>
125  struct Uniform
126  {
127  static_assert(std::is_floating_point_v<T> || std::is_unsigned_v<T>);
128 
129  template<typename TEngine>
130  auto operator()(TEngine& engine) -> T
131  {
132  if constexpr(std::is_floating_point_v<T>)
133  {
134  oneapi::dpl::uniform_real_distribution<T> distr;
135  return distr(engine.rng_engine);
136  }
137  else
138  {
139  oneapi::dpl::uniform_int_distribution<T> distr;
140  return distr(engine.rng_engine);
141  }
142  }
143  };
144  } // namespace distribution::sycl_rand
145 
146  namespace distribution::trait
147  {
148  //! The SYCL random number float normal distribution get trait specialization.
149  template<typename TDim, typename T>
150  struct CreateNormalReal<RandGenericSycl<TDim>, T, std::enable_if_t<std::is_floating_point_v<T>>>
151  {
152  static auto createNormalReal(RandGenericSycl<TDim> const& /*rand*/) -> sycl_rand::NormalReal<T>
153  {
154  return {};
155  }
156  };
157 
158  //! The SYCL random number float uniform distribution get trait specialization.
159  template<typename TDim, typename T>
160  struct CreateUniformReal<RandGenericSycl<TDim>, T, std::enable_if_t<std::is_floating_point_v<T>>>
161  {
162  static auto createUniformReal(RandGenericSycl<TDim> const& /*rand*/) -> sycl_rand::Uniform<T>
163  {
164  return {};
165  }
166  };
167 
168  //! The SYCL random number integer uniform distribution get trait specialization.
169  template<typename TDim, typename T>
170  struct CreateUniformUint<RandGenericSycl<TDim>, T, std::enable_if_t<std::is_integral_v<T>>>
171  {
172  static auto createUniformUint(RandGenericSycl<TDim> const& /*rand*/) -> sycl_rand::Uniform<T>
173  {
174  return {};
175  }
176  };
177  } // namespace distribution::trait
178 
179  namespace engine::trait
180  {
181  //! The SYCL random number default generator get trait specialization.
182  template<typename TDim>
183  struct CreateDefault<RandGenericSycl<TDim>>
184  {
185  static auto createDefault(
186  RandGenericSycl<TDim> const& rand,
187  std::uint32_t const& seed = 0,
188  std::uint32_t const& /* subsequence */ = 0,
189  std::uint32_t const& /* offset */ = 0) -> sycl_rand::Minstd<TDim>
190  {
191  return {rand, seed};
192  }
193  };
194  } // namespace engine::trait
195 # endif
196 } // namespace alpaka::rand
197 
198 #endif
#define ALPAKA_FN_HOST_ACC
Definition: Common.hpp:39
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto max(T const &max_ctx, Tx const &x, Ty const &y)
Returns the larger of two arguments. NaNs are treated as missing data (between a NaN and a numeric va...
Definition: Traits.hpp:1263
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto min(T const &min_ctx, Tx const &x, Ty const &y)
Returns the smaller of two arguments. NaNs are treated as missing data (between a NaN and a numeric v...
Definition: Traits.hpp:1280
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto createNormalReal(TRand const &rand)
Definition: Traits.hpp:41
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto createUniformUint(TRand const &rand)
Definition: Traits.hpp:63
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto createUniformReal(TRand const &rand)
Definition: Traits.hpp:52
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto createDefault(TRand const &rand, std::uint32_t const &seed=0, std::uint32_t const &subsequence=0, std::uint32_t const &offset=0)
Definition: Traits.hpp:90