alpaka
Abstraction Library for Parallel Kernel Acceleration
PhiloxBaseCommon.hpp
Go to the documentation of this file.
1 /* Copyright 2022 Jiri Vyskocil, Bernhard Manfred Gruber, Jeffrey Kelling
2  * SPDX-License-Identifier: MPL-2.0
3  */
4 
5 #pragma once
6 
8 
9 #include <utility>
10 
12 {
13  /** Common class for Philox family engines
14  *
15  * Relies on `PhiloxStateless` to provide the PRNG and adds state to handling the counting.
16  *
17  * @tparam TParams Philox algorithm parameters \sa PhiloxParams
18  * @tparam TImpl engine type implementation (CRTP)
19  *
20  * static const data members are transformed into functions, because GCC
21  * assumes types with static data members to be not mappable and makes not
22  * exception for constexpr ones. This is a valid interpretation of the
23  * OpenMP <= 4.5 standard. In OpenMP >= 5.0 types with any kind of static
24  * data member are mappable.
25  */
26  template<typename TParams, typename TImpl>
27  class PhiloxBaseCommon : public PhiloxStateless<TParams>
28  {
29  public:
32 
33  /// Distribution container type
34  template<typename TDistributionResultScalar>
35  using ResultContainer = typename alpaka::Vec<alpaka::DimInt<TParams::counterSize>, TDistributionResultScalar>;
36 
37  protected:
38  /** Advance the \a counter to the next state
39  *
40  * Increments the passed-in \a counter by one with a 128-bit carry.
41  *
42  * @param counter reference to the counter which is to be advanced
43  */
45  {
46  counter[0]++;
47  /* 128-bit carry */
48  if(counter[0] == 0)
49  {
50  counter[1]++;
51  if(counter[1] == 0)
52  {
53  counter[2]++;
54  if(counter[2] == 0)
55  {
56  counter[3]++;
57  }
58  }
59  }
60  }
61 
62  /** Advance the internal state counter by \a offset N-vectors (N = counter size)
63  *
64  * Advances the internal value of this->state.counter
65  *
66  * @param offset number of N-vectors to skip
67  */
69  {
70  Counter& counter = static_cast<TImpl*>(this)->state.counter;
71  Counter temp = counter;
72  counter[0] += low32Bits(offset);
73  counter[1] += high32Bits(offset) + (counter[0] < temp[0] ? 1 : 0);
74  counter[2] += (counter[0] < temp[1] ? 1u : 0u);
75  counter[3] += (counter[0] < temp[2] ? 1u : 0u);
76  }
77 
78  /** Advance the counter by the length of \a subsequence
79  *
80  * Advances the internal value of this->state.counter
81  *
82  * @param subsequence number of subsequences to skip
83  */
84  ALPAKA_FN_HOST_ACC void skipSubsequence(uint64_t subsequence)
85  {
86  Counter& counter = static_cast<TImpl*>(this)->state.counter;
87  Counter temp = counter;
88  counter[2] += low32Bits(subsequence);
89  counter[3] += high32Bits(subsequence) + (counter[2] < temp[2] ? 1 : 0);
90  }
91  };
92 } // namespace alpaka::rand::engine
A n-dimensional vector.
Definition: Vec.hpp:38
ALPAKA_FN_HOST_ACC void advanceCounter(Counter &counter)
typename PhiloxStateless< TParams >::Counter Counter
ALPAKA_FN_HOST_ACC void skipSubsequence(uint64_t subsequence)
typename alpaka::Vec< alpaka::DimInt< TParams::counterSize >, TDistributionResultScalar > ResultContainer
Distribution container type.
typename PhiloxStateless< TParams >::Key Key
ALPAKA_FN_HOST_ACC void skip4(uint64_t offset)
#define ALPAKA_FN_HOST_ACC
Definition: Common.hpp:39
The random number generator engine specifics.
constexpr ALPAKA_FN_HOST_ACC auto high32Bits(std::uint64_t const x) -> std::uint32_t
Get high 32 bits of a 64-bit number.
constexpr ALPAKA_FN_HOST_ACC auto low32Bits(std::uint64_t const x) -> std::uint32_t
Get low 32 bits of a 64-bit number.
constexpr auto offset
Definition: Extent.hpp:34