alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
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
9
11{
12 /** Common class for Philox family engines
13 *
14 * Relies on `PhiloxStateless` to provide the PRNG and adds state to handling the counting.
15 *
16 * @tparam T_Params Philox algorithm parameters \sa PhiloxParams
17 * @tparam T_Impl engine type implementation (CRTP)
18 *
19 * static const data members are transformed into functions, because GCC
20 * assumes types with static data members to be not mappable and makes not
21 * exception for constexpr ones. This is a valid interpretation of the
22 * OpenMP <= 4.5 standard. In OpenMP >= 5.0 types with any kind of static
23 * data member are mappable.
24 */
25 template<typename T_Params, typename T_Impl>
26 class PhiloxBaseCommon : public PhiloxStateless<T_Params>
27 {
28 public:
31 /// State type
33
34 /// Internal engine state
36 /// Distribution container type
37 template<typename TDistributionResultScalar>
39
40 constexpr explicit PhiloxBaseCommon(State&& state) : state(std::move(state))
41 {
42 }
43
44 protected:
45 /** Advance the \a counter to the next state
46 *
47 * Increments the passed-in \a counter by one with a 128-bit carry.
48 *
49 * @param counter reference to the counter which is to be advanced
50 */
51 template<typename T, auto N>
52 static constexpr void advanceCounter(alpaka::Vec<T, N>& counter)
53 {
54 ++counter[0];
55
56 /* 128-bit carry */
57 if(counter[0] == 0)
58 {
59 ++counter[1];
60 if(counter[1] == 0)
61 {
62 ++counter[2];
63 if(counter[2] == 0)
64 {
65 ++counter[3];
66 }
67 }
68 }
69 }
70
71 /** Advance the internal state counter by \a offset N-vectors (N = counter size)
72 *
73 * Advances the internal value of this->state.counter
74 *
75 * @param offset number of N-vectors to skip
76 */
77 constexpr void skip4(uint64_t offset)
78 {
79 Counter& counter = this->state.counter;
80 Counter temp = counter;
81 counter[0] += low32Bits(offset);
82 counter[1] += high32Bits(offset) + (counter[0] < temp[0] ? 1 : 0);
83 counter[2] += (counter[0] < temp[1] ? 1u : 0u);
84 counter[3] += (counter[0] < temp[2] ? 1u : 0u);
85 }
86
87 /** Advance the counter by the length of \a subsequence
88 *
89 * Advances the internal value of this->state.counter
90 *
91 * @param subsequence number of subsequences to skip
92 */
93 constexpr void skipSubsequence(uint64_t subsequence)
94 {
95 Counter& counter = this->state.counter;
96 Counter temp = counter;
97 counter[2] += low32Bits(subsequence);
98 counter[3] += high32Bits(subsequence) + (counter[2] < temp[2] ? 1 : 0);
99 }
100 };
101} // namespace alpaka::rand::engine::internal
typename PhiloxStateless< T_Params >::Counter Counter
typename PhiloxStateless< T_Params >::Key Key
PhiloxState< Counter, Key, T_Impl > State
State type.
constexpr void skip4(uint64_t offset)
Advance the internal state counter by offset N-vectors (N = counter size).
Vec< TDistributionResultScalar, T_Params::counterSize > ResultContainer
Distribution container type.
constexpr void skipSubsequence(uint64_t subsequence)
Advance the counter by the length of subsequence.
static constexpr void advanceCounter(alpaka::Vec< T, N > &counter)
Advance the counter to the next state.
Class basic Philox family counter-based PRNG.
alpaka::Vec< std::uint32_t, T_Params::counterSize/2 > Key
alpaka::Vec< std::uint32_t, T_Params::counterSize > Counter
constexpr auto low32Bits(std::uint64_t const x) -> std::uint32_t
Get low 32 bits of a 64-bit number.
constexpr auto high32Bits(std::uint64_t const x) -> std::uint32_t
Get high 32 bits of a 64-bit number.
STL namespace.