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
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 */
68 ALPAKA_FN_HOST_ACC void skip4(uint64_t offset)
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.
ALPAKA_FN_HOST_ACC constexpr auto high32Bits(std::uint64_t const x) -> std::uint32_t
Get high 32 bits of a 64-bit number.
ALPAKA_FN_HOST_ACC constexpr auto low32Bits(std::uint64_t const x) -> std::uint32_t
Get low 32 bits of a 64-bit number.