alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
philox.hpp
Go to the documentation of this file.
1/* Copyright 2022 Jiří Vyskočil, Jan Stephan, Bernhard Manfred Gruber
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
10
11#include <cstdint>
12#include <limits>
13#include <random>
14#include <type_traits>
15
17{
18
19 /** Most common Philox engine variant, outputs single number
20 *
21 * This is a variant of the Philox engine generator which outputs a single float. The counter size is \f$4
22 * \times 32 = 128\f$ bits. A bit shuffle is performed 10 subsequent times.
23 * Since the engine returns a single number, the generated result, which has the same
24 * size as the counter, has to be stored between invocations. Additionally a 32 bit pointer is stored. The
25 * total size of the state is 352 bits = 44 bytes.
26 *
27 * Ref.: J. K. Salmon, M. A. Moraes, R. O. Dror and D. E. Shaw, "Parallel random numbers: As easy as 1, 2, 3,"
28 * SC '11: Proceedings of 2011 International Conference for High Performance Computing, Networking, Storage and
29 * Analysis, 2011, pp. 1-12, doi: 10.1145/2063384.2063405.
30 */
32 {
33 public:
34 /// Philox algorithm: 10 rounds, 4 numbers of size 32.
35 using EngineParams = internal::PhiloxParams<4, 32, 10>;
36 /// Engine outputs a single number
37 using EngineVariant = internal::PhiloxSingle<EngineParams>;
38
39 /** Initialize a new Philox engine
40 *
41 * @param seed Set the Philox generator key
42 * @param subsequence Select a subsequence of size 2^64
43 * @param offset Skip \a offset numbers form the start of the subsequence
44 */
45 constexpr explicit Philox4x32x10(
46 std::uint64_t const seed = 0,
47 std::uint64_t const subsequence = 0,
48 std::uint64_t const offset = 0)
49 : engineVariant(seed, subsequence, offset)
50 {
51 }
52
53 // STL UniformRandomBitGenerator concept
54 // See the functions min and max for the range of the generated numbers
55 // https://en.cppreference.com/w/cpp/named_req/UniformRandomBitGenerator
56 using result_type = std::uint32_t;
57
58 static constexpr auto min() -> result_type
59 {
60 return 0;
61 }
62
63 static constexpr auto max() -> result_type
64 {
65 return std::numeric_limits<result_type>::max();
66 }
67
68 constexpr auto operator()() -> result_type
69 {
70 return engineVariant();
71 }
72
73 private:
74 EngineVariant engineVariant;
75 };
76
77 /** Most common Philox engine variant, outputs a 4-vector of floats
78 *
79 * This is a variant of the Philox engine generator which outputs a vector containing 4 floats. The counter
80 * size is \f$4 \times 32 = 128\f$ bits. Since the engine returns the whole generated vector, it is up to the
81 * user to extract individual floats as they need. The benefit is smaller state size since the state does not
82 * contain the intermediate results. The total size of the state is 192 bits = 24 bytes.
83 *
84 * Ref.: J. K. Salmon, M. A. Moraes, R. O. Dror and D. E. Shaw, "Parallel random numbers: As easy as 1, 2, 3,"
85 * SC '11: Proceedings of 2011 International Conference for High Performance Computing, Networking, Storage and
86 * Analysis, 2011, pp. 1-12, doi: 10.1145/2063384.2063405.
87 */
89 {
90 public:
91 using EngineParams = internal::PhiloxParams<4, 32, 10>;
92 using EngineVariant = internal::PhiloxVector<EngineParams>;
93
94 /** Initialize a new Philox engine
95 *
96 * @param seed Set the Philox generator key
97 * @param subsequence Select a subsequence of size 2^64
98 * @param offset Number of numbers to skip form the start of the subsequence.
99 */
100 constexpr explicit Philox4x32x10Vector(
101 std::uint32_t const seed = 0,
102 std::uint32_t const subsequence = 0,
103 std::uint32_t const offset = 0)
104 : engineVariant(seed, subsequence, offset)
105 {
106 }
107
108 template<typename TScalar>
109 using ResultContainer = EngineVariant::ResultContainer<TScalar>;
110
111 using ResultInt = std::uint32_t;
112 using ResultVec = decltype(std::declval<EngineVariant>()());
113
114 static constexpr auto min() -> ResultInt
115 {
116 return 0;
117 }
118
119 static constexpr auto max() -> ResultInt
120 {
121 return std::numeric_limits<ResultInt>::max();
122 }
123
124 constexpr auto operator()() -> ResultVec
125 {
126 return engineVariant();
127 }
128
129 private:
130 EngineVariant engineVariant;
131 };
132
133
134} // namespace alpaka::rand::engine
constexpr Philox4x32x10Vector(std::uint32_t const seed=0, std::uint32_t const subsequence=0, std::uint32_t const offset=0)
Initialize a new Philox engine.
Definition philox.hpp:100
decltype(std::declval< EngineVariant >()()) ResultVec
Definition philox.hpp:112
internal::PhiloxVector< EngineParams > EngineVariant
Definition philox.hpp:92
static constexpr auto min() -> ResultInt
Definition philox.hpp:114
internal::PhiloxParams< 4, 32, 10 > EngineParams
Definition philox.hpp:91
static constexpr auto max() -> ResultInt
Definition philox.hpp:119
EngineVariant::ResultContainer< TScalar > ResultContainer
Definition philox.hpp:109
constexpr auto operator()() -> ResultVec
Definition philox.hpp:124
internal::PhiloxParams< 4, 32, 10 > EngineParams
Philox algorithm: 10 rounds, 4 numbers of size 32.
Definition philox.hpp:35
internal::PhiloxSingle< EngineParams > EngineVariant
Engine outputs a single number.
Definition philox.hpp:37
constexpr auto operator()() -> result_type
Definition philox.hpp:68
static constexpr auto max() -> result_type
Definition philox.hpp:63
constexpr Philox4x32x10(std::uint64_t const seed=0, std::uint64_t const subsequence=0, std::uint64_t const offset=0)
Initialize a new Philox engine.
Definition philox.hpp:45
static constexpr auto min() -> result_type
Definition philox.hpp:58