Expression Templates Library (ETL)
noise.hpp
1 //=======================================================================
2 // Copyright (c) 2014-2023 Baptiste Wicht
3 // Distributed under the terms of the MIT License.
4 // (See accompanying file LICENSE or copy at
5 // http://opensource.org/licenses/MIT)
6 //=======================================================================
7 
8 #pragma once
9 
11 
12 namespace etl {
13 
18 template <typename T>
20  static constexpr bool linear = true;
21  static constexpr bool thread_safe = false;
22 
28  template <vector_mode_t V>
29  static constexpr bool vectorizable = false;
30 
34  template <typename E>
35  static constexpr bool gpu_computable = false;
36 
41  static constexpr int complexity() {
42  return 1;
43  }
44 
50  static T apply(const T& x) {
51  static random_engine rand_engine(std::time(nullptr));
52  static std::uniform_real_distribution<double> real_distribution(0.0, 1.0);
53 
54  return x + real_distribution(rand_engine);
55  }
56 
61  static std::string desc() noexcept {
62  return "uniform_noise";
63  }
64 };
65 
70 template <typename G, typename T>
72  static constexpr bool linear = true;
73  static constexpr bool thread_safe = false;
74 
75 private:
76  G& rand_engine;
77 
78 public:
82  explicit uniform_noise_unary_g_op(G& rand_engine) : rand_engine(rand_engine) {
83  //Nothing else to init
84  }
85 
91  template <vector_mode_t V>
92  static constexpr bool vectorizable = false;
93 
97  template <typename E>
98  static constexpr bool gpu_computable = false;
99 
104  static constexpr int complexity() {
105  return 1;
106  }
107 
113  T apply(const T& x) const {
114  std::uniform_real_distribution<double> real_distribution(0.0, 1.0);
115 
116  return x + real_distribution(rand_engine);
117  }
118 
123  static std::string desc() noexcept {
124  return "uniform_noise";
125  }
126 };
127 
132 template <typename T>
134  static constexpr bool linear = true;
135  static constexpr bool thread_safe = false;
136 
142  template <vector_mode_t V>
143  static constexpr bool vectorizable = false;
144 
148  template <typename E>
149  static constexpr bool gpu_computable = false;
150 
155  static constexpr int complexity() {
156  return 1;
157  }
158 
164  static T apply(const T& x) {
165  static random_engine rand_engine(std::time(nullptr));
166  static std::normal_distribution<T> normal_distribution(0.0, 1.0);
167 
168  return x + normal_distribution(rand_engine);
169  }
170 
175  static std::string desc() noexcept {
176  return "normal_noise";
177  }
178 };
179 
184 template <typename G, typename T>
186  static constexpr bool linear = true;
187  static constexpr bool thread_safe = false;
188 
189 private:
190  G& rand_engine;
191 
192 public:
196  explicit normal_noise_unary_g_op(G& rand_engine) : rand_engine(rand_engine) {
197  //Nothing else to init
198  }
199 
205  template <vector_mode_t V>
206  static constexpr bool vectorizable = false;
207 
211  template <typename E>
212  static constexpr bool gpu_computable = false;
213 
218  static constexpr int complexity() {
219  return 1;
220  }
221 
227  T apply(const T& x) const {
228  std::normal_distribution<T> normal_distribution(0.0, 1.0);
229 
230  return x + normal_distribution(rand_engine);
231  }
232 
237  static std::string desc() noexcept {
238  return "normal_noise";
239  }
240 };
241 
246 template <typename T>
248  static constexpr bool linear = true;
249  static constexpr bool thread_safe = false;
250 
256  template <vector_mode_t V>
257  static constexpr bool vectorizable = false;
258 
262  template <typename E>
263  static constexpr bool gpu_computable = (is_single_precision_t<T> && impl::egblas::has_slogistic_noise_seed)
264  || (is_double_precision_t<T> && impl::egblas::has_dlogistic_noise_seed);
265 
270  static constexpr int complexity() {
271  return 1;
272  }
273 
279  static T apply(const T& x) {
280  static random_engine rand_engine(std::time(nullptr));
281 
282  std::normal_distribution<T> noise_distribution(0.0, math::logistic_sigmoid(x));
283 
284  return x + noise_distribution(rand_engine);
285  }
286 
294  template <typename X, typename Y>
295  static auto gpu_compute_hint(const X & x, Y& y) noexcept {
296  static random_engine rand_engine(std::time(nullptr));
297 
298  std::uniform_int_distribution<long> seed_dist;
299 
300  decltype(auto) t1 = smart_gpu_compute_hint(x, y);
301 
302  auto t2 = force_temporary_gpu_dim_only(t1);
303 
304  T alpha(1);
305  impl::egblas::logistic_noise_seed(etl::size(y), alpha, t1.gpu_memory(), 1, t2.gpu_memory(), 1, seed_dist(rand_engine));
306 
307  return t2;
308  }
315  template <typename X, typename Y>
316  static Y& gpu_compute(const X & x, Y& y) noexcept {
317  static random_engine rand_engine(std::time(nullptr));
318 
319  std::uniform_int_distribution<long> seed_dist;
320 
321  decltype(auto) t1 = select_smart_gpu_compute(x, y);
322 
323  T alpha(1);
324  impl::egblas::logistic_noise_seed(etl::size(y), alpha, t1.gpu_memory(), 1, y.gpu_memory(), 1, seed_dist(rand_engine));
325 
326  y.validate_gpu();
327  y.invalidate_cpu();
328 
329  return y;
330  }
331 
336  static std::string desc() noexcept {
337  return "logistic_noise";
338  }
339 };
340 
345 template <typename G, typename T>
347  static constexpr bool linear = true;
348  static constexpr bool thread_safe = false;
349 
350 private:
351  G& rand_engine;
352 
353 public:
357  explicit logistic_noise_unary_g_op(G& rand_engine) : rand_engine(rand_engine) {
358  //Nothing else to init
359  }
360 
366  template <vector_mode_t V>
367  static constexpr bool vectorizable = false;
368 
372  template <typename E>
373  static constexpr bool gpu_computable = (is_single_precision_t<T> && impl::egblas::has_slogistic_noise_seed)
374  || (is_double_precision_t<T> && impl::egblas::has_dlogistic_noise_seed);
375 
380  static constexpr int complexity() {
381  return 1;
382  }
383 
389  T apply(const T& x) const {
390  std::normal_distribution<T> noise_distribution(0.0, math::logistic_sigmoid(x));
391 
392  return x + noise_distribution(rand_engine);
393  }
394 
402  template <typename X, typename Y>
403  auto gpu_compute_hint(const X & x, Y& y) const noexcept {
404  std::uniform_int_distribution<long> seed_dist;
405 
406  decltype(auto) t1 = smart_gpu_compute_hint(x, y);
407 
408  auto t2 = force_temporary_gpu_dim_only(t1);
409 
410  T alpha(1);
411  impl::egblas::logistic_noise_seed(etl::size(y), alpha, t1.gpu_memory(), 1, t2.gpu_memory(), 1, seed_dist(rand_engine));
412 
413  return t2;
414  }
421  template <typename X, typename Y>
422  Y& gpu_compute(const X & x, Y& y) const noexcept {
423  std::uniform_int_distribution<long> seed_dist;
424 
425  decltype(auto) t1 = select_smart_gpu_compute(x, y);
426 
427  T alpha(1);
428  impl::egblas::logistic_noise_seed(etl::size(y), alpha, t1.gpu_memory(), 1, y.gpu_memory(), 1, seed_dist(rand_engine));
429 
430  y.validate_gpu();
431  y.invalidate_cpu();
432 
433  return y;
434  }
435 
440  static std::string desc() noexcept {
441  return "logistic_noise";
442  }
443 };
444 
453 template <typename T>
455  static constexpr bool linear = true;
456  static constexpr bool thread_safe = false;
457 
463  template <vector_mode_t V>
464  static constexpr bool vectorizable = false;
465 
469  template <typename E>
470  static constexpr bool gpu_computable = (is_single_precision_t<T> && impl::egblas::has_slogistic_noise_seed)
471  || (is_double_precision_t<T> && impl::egblas::has_dlogistic_noise_seed);
472 
477  static constexpr int complexity() {
478  return 1;
479  }
480 
482  std::shared_ptr<void*> states;
483 
487  state_logistic_noise_unary_op() : rand_engine(std::time(nullptr)) {
488  if constexpr (impl::egblas::has_logistic_noise_prepare) {
489  states = std::make_shared<void*>();
490  *states = impl::egblas::logistic_noise_prepare();
491  }
492  }
493 
497  explicit state_logistic_noise_unary_op(const std::shared_ptr<void*> states) : rand_engine(std::time(nullptr)) {
498  if constexpr (impl::egblas::has_logistic_noise_prepare) {
499  this->states = states;
500 
501  if (!*this->states) {
502  std::uniform_int_distribution<long> seed_dist;
503  *this->states = impl::egblas::logistic_noise_prepare_seed(seed_dist(rand_engine));
504  }
505  }
506  }
507 
513  T apply(const T& x) const {
514  std::normal_distribution<double> noise_distribution(0.0, math::logistic_sigmoid(x));
515 
516  return x + noise_distribution(rand_engine);
517  }
518 
526  template <typename X, typename Y>
527  auto gpu_compute_hint(const X & x, Y& y) const noexcept {
528  decltype(auto) t1 = smart_gpu_compute_hint(x, y);
529 
530  auto t2 = force_temporary_gpu_dim_only(t1);
531 
532  T alpha(1);
533  impl::egblas::logistic_noise_states(etl::size(y), alpha, t1.gpu_memory(), 1, t2.gpu_memory(), 1, *states);
534 
535  return t2;
536  }
543  template <typename X, typename Y>
544  Y& gpu_compute(const X & x, Y& y) const noexcept {
545  decltype(auto) t1 = select_smart_gpu_compute(x, y);
546 
547  T alpha(1);
548  impl::egblas::logistic_noise_states(etl::size(y), alpha, t1.gpu_memory(), 1, y.gpu_memory(), 1, *states);
549 
550  y.validate_gpu();
551  y.invalidate_cpu();
552 
553  return y;
554  }
555 
560  static std::string desc() noexcept {
561  return "state_logistic_noise";
562  }
563 };
564 
573 template <typename G, typename T>
575  static constexpr bool linear = true;
576  static constexpr bool thread_safe = false;
577 
578 private:
579  G& rand_engine;
580  std::shared_ptr<void*> states;
581 
582 public:
586  explicit state_logistic_noise_unary_g_op(G& rand_engine) : rand_engine(rand_engine) {
587  if constexpr (impl::egblas::has_logistic_noise_prepare) {
588  std::uniform_int_distribution<long> seed_dist;
589 
590  states = std::make_shared<void*>();
591  *states = impl::egblas::logistic_noise_prepare_seed(seed_dist(rand_engine));
592  }
593  }
594 
598  state_logistic_noise_unary_g_op(G& rand_engine, const std::shared_ptr<void*> & states) : rand_engine(rand_engine) {
599  if constexpr (impl::egblas::has_logistic_noise_prepare) {
600  this->states = states;
601 
602  if (!*this->states) {
603  std::uniform_int_distribution<long> seed_dist;
604  *this->states = impl::egblas::logistic_noise_prepare_seed(seed_dist(rand_engine));
605  }
606  }
607  }
608 
614  template <vector_mode_t V>
615  static constexpr bool vectorizable = false;
616 
620  template <typename E>
621  static constexpr bool gpu_computable = (is_single_precision_t<T> && impl::egblas::has_slogistic_noise_states)
622  || (is_double_precision_t<T> && impl::egblas::has_dlogistic_noise_states);
623 
628  static constexpr int complexity() {
629  return 1;
630  }
631 
637  T apply(const T& x) const {
638  std::normal_distribution<double> noise_distribution(0.0, math::logistic_sigmoid(x));
639 
640  return x + noise_distribution(rand_engine);
641  }
642 
650  template <typename X, typename Y>
651  auto gpu_compute_hint(const X & x, Y& y) const noexcept {
652  decltype(auto) t1 = smart_gpu_compute_hint(x, y);
653 
654  auto t2 = force_temporary_gpu_dim_only(t1);
655 
656  T alpha(1);
657  impl::egblas::logistic_noise_states(etl::size(y), alpha, t1.gpu_memory(), 1, t2.gpu_memory(), 1, *states);
658 
659  return t2;
660  }
667  template <typename X, typename Y>
668  Y& gpu_compute(const X & x, Y& y) const noexcept {
669  decltype(auto) t1 = select_smart_gpu_compute(x, y);
670 
671  T alpha(1);
672  impl::egblas::logistic_noise_states(etl::size(y), alpha, t1.gpu_memory(), 1, y.gpu_memory(), 1, *states);
673 
674  y.validate_gpu();
675  y.invalidate_cpu();
676 
677  return y;
678  }
679 
684  static std::string desc() noexcept {
685  return "state_logistic_noise";
686  }
687 };
688 
689 } //end of namespace etl
auto gpu_compute_hint(const X &x, Y &y) const noexcept
Compute the result of the operation using the GPU.
Definition: noise.hpp:651
static constexpr int complexity()
Estimate the complexity of operator.
Definition: noise.hpp:41
static constexpr bool thread_safe
Indicates if the operator is thread safe or not.
Definition: noise.hpp:21
EGBLAS wrappers for the logistic_noise operation.
Unary operation applying a normal noise.
Definition: noise.hpp:185
Y & gpu_compute(const X &x, Y &y) const noexcept
Compute the result of the operation using the GPU.
Definition: noise.hpp:544
Unary operation applying an uniform noise (0.0, 1.0(.
Definition: noise.hpp:71
T apply(const T &x) const
Apply the unary operator on x.
Definition: noise.hpp:113
static T apply(const T &x)
Apply the unary operator on x.
Definition: noise.hpp:164
Unary operation applying a normal noise.
Definition: noise.hpp:133
static constexpr int complexity()
Estimate the complexity of operator.
Definition: noise.hpp:155
static constexpr int complexity()
Estimate the complexity of operator.
Definition: noise.hpp:628
static constexpr int complexity()
Estimate the complexity of operator.
Definition: noise.hpp:218
static constexpr bool gpu_computable
Indicates if the operator can be computed on GPU.
Definition: noise.hpp:35
static T apply(const T &x)
Apply the unary operator on x.
Definition: noise.hpp:50
state_logistic_noise_unary_op()
Construct a new operator.
Definition: noise.hpp:487
static std::string desc() noexcept
Returns a textual representation of the operator.
Definition: noise.hpp:123
decltype(auto) select_smart_gpu_compute(X &x, Y &y)
Compute the expression into a representation that is GPU up to date and possibly store this represent...
Definition: helpers.hpp:434
auto gpu_compute_hint(const X &x, Y &y) const noexcept
Compute the result of the operation using the GPU.
Definition: noise.hpp:527
normal_noise_unary_g_op(G &rand_engine)
Construct a new normal_noise_unary_g_op.
Definition: noise.hpp:196
static constexpr int complexity()
Estimate the complexity of operator.
Definition: noise.hpp:477
T apply(const T &x) const
Apply the unary operator on x.
Definition: noise.hpp:637
static std::string desc() noexcept
Returns a textual representation of the operator.
Definition: noise.hpp:440
T apply(const T &x) const
Apply the unary operator on x.
Definition: noise.hpp:513
T apply(const T &x) const
Apply the unary operator on x.
Definition: noise.hpp:227
static constexpr bool linear
Indicates if the operator is linear.
Definition: noise.hpp:20
Unary operation applying a logistic noise.
Definition: noise.hpp:574
static constexpr bool vectorizable
Indicates if the expression is vectorizable using the given vector mode.
Definition: noise.hpp:29
static T apply(const T &x)
Apply the unary operator on x.
Definition: noise.hpp:279
Root namespace for the ETL library.
Definition: adapter.hpp:15
state_logistic_noise_unary_g_op(G &rand_engine)
Construct a new state_logistic_noise_unary_g_op.
Definition: noise.hpp:586
auto gpu_compute_hint(const X &x, Y &y) const noexcept
Compute the result of the operation using the GPU.
Definition: noise.hpp:403
T apply(const T &x) const
Apply the unary operator on x.
Definition: noise.hpp:389
static std::string desc() noexcept
Returns a textual representation of the operator.
Definition: noise.hpp:175
static constexpr int complexity()
Estimate the complexity of operator.
Definition: noise.hpp:270
static std::string desc() noexcept
Returns a textual representation of the operator.
Definition: noise.hpp:684
static constexpr int complexity()
Estimate the complexity of operator.
Definition: noise.hpp:380
Unary operation applying a logistic noise.
Definition: noise.hpp:454
static constexpr int complexity()
Estimate the complexity of operator.
Definition: noise.hpp:104
Unary operation applying a logistic noise.
Definition: noise.hpp:346
decltype(auto) force_temporary_gpu_dim_only(E &&expr)
Force a temporary out of the expression, without copying its content.
Definition: temporary.hpp:223
state_logistic_noise_unary_g_op(G &rand_engine, const std::shared_ptr< void *> &states)
Construct a new state_logistic_noise_unary_g_op.
Definition: noise.hpp:598
constexpr size_t size(const E &expr) noexcept
Returns the size of the given ETL expression.
Definition: helpers.hpp:108
logistic_noise_unary_g_op(G &rand_engine)
Construct a new logistic_noise_unary_g_op.
Definition: noise.hpp:357
std::shared_ptr< void * > states
The random generator extra states.
Definition: noise.hpp:482
static Y & gpu_compute(const X &x, Y &y) noexcept
Compute the result of the operation using the GPU.
Definition: noise.hpp:316
state_logistic_noise_unary_op(const std::shared_ptr< void *> states)
Construct a new operator.
Definition: noise.hpp:497
static std::string desc() noexcept
Returns a textual representation of the operator.
Definition: noise.hpp:237
random_engine rand_engine
The random generator.
Definition: noise.hpp:481
Unary operation applying an uniform noise (0.0, 1.0(.
Definition: noise.hpp:19
Y & gpu_compute(const X &x, Y &y) const noexcept
Compute the result of the operation using the GPU.
Definition: noise.hpp:422
static std::string desc() noexcept
Returns a textual representation of the operator.
Definition: noise.hpp:61
std::mt19937_64 random_engine
The random engine used by the library.
Definition: random.hpp:22
static std::string desc() noexcept
Returns a textual representation of the operator.
Definition: noise.hpp:560
uniform_noise_unary_g_op(G &rand_engine)
Construct a new uniform_noise_unary_g_op.
Definition: noise.hpp:82
decltype(auto) smart_gpu_compute_hint(E &expr, Y &y)
Compute the expression into a representation that is GPU up to date.
Definition: helpers.hpp:368
Unary operation applying a logistic noise.
Definition: noise.hpp:247
static auto gpu_compute_hint(const X &x, Y &y) noexcept
Compute the result of the operation using the GPU.
Definition: noise.hpp:295
Y & gpu_compute(const X &x, Y &y) const noexcept
Compute the result of the operation using the GPU.
Definition: noise.hpp:668
static std::string desc() noexcept
Returns a textual representation of the operator.
Definition: noise.hpp:336