A class that encapsulates all the states for a random number generator using the philox_4x32_10 algorithm. Each invocation returns a 128-bit random bits in the form of four uint32. There are multiple variants of this algorithm, we picked the 4x32_10 version that is most suited for our applications. Since this class is meant to be copied between CPU to GPU, it maintains a value semantics. For exam
| 101 | // 1. PhiloxRandom is trivially copyable. |
| 102 | // 2. PhiloxRandom is compilable by gcc and nvcc. |
| 103 | class PhiloxRandom { |
| 104 | public: |
| 105 | using ResultType = Array<uint32, 4>; |
| 106 | using ResultElementType = uint32; |
| 107 | // The number of elements that will be returned. |
| 108 | static const int kResultElementCount = 4; |
| 109 | // Cost of generation of a single element (in cycles). |
| 110 | static const int kElementCost = 10; |
| 111 | // The type for the 64-bit key stored in the form of two 32-bit uint |
| 112 | // that are used in the diffusion process. |
| 113 | using Key = Array<uint32, 2>; |
| 114 | |
| 115 | PHILOX_DEVICE_INLINE |
| 116 | PhiloxRandom() {} |
| 117 | |
| 118 | PHILOX_DEVICE_INLINE |
| 119 | explicit PhiloxRandom(uint64 seed) { |
| 120 | key_[0] = static_cast<uint32>(seed); |
| 121 | key_[1] = static_cast<uint32>(seed >> 32); |
| 122 | } |
| 123 | |
| 124 | PHILOX_DEVICE_INLINE |
| 125 | explicit PhiloxRandom(uint64 seed_lo, uint64 seed_hi) { |
| 126 | key_[0] = static_cast<uint32>(seed_lo); |
| 127 | key_[1] = static_cast<uint32>(seed_lo >> 32); |
| 128 | counter_[2] = static_cast<uint32>(seed_hi); |
| 129 | counter_[3] = static_cast<uint32>(seed_hi >> 32); |
| 130 | } |
| 131 | |
| 132 | PHILOX_DEVICE_INLINE |
| 133 | PhiloxRandom(ResultType counter, Key key) : counter_(counter), key_(key) {} |
| 134 | |
| 135 | PHILOX_DEVICE_INLINE |
| 136 | ResultType const& counter() const { return counter_; } |
| 137 | |
| 138 | PHILOX_DEVICE_INLINE |
| 139 | Key const& key() const { return key_; } |
| 140 | |
| 141 | // Skip the specified number of samples of 128-bits in the current stream. |
| 142 | PHILOX_DEVICE_INLINE |
| 143 | void Skip(uint64 count) { |
| 144 | const uint32 count_lo = static_cast<uint32>(count); |
| 145 | uint32 count_hi = static_cast<uint32>(count >> 32); |
| 146 | |
| 147 | counter_[0] += count_lo; |
| 148 | if (counter_[0] < count_lo) { |
| 149 | ++count_hi; |
| 150 | } |
| 151 | |
| 152 | counter_[1] += count_hi; |
| 153 | if (counter_[1] < count_hi) { |
| 154 | if (++counter_[2] == 0) { |
| 155 | ++counter_[3]; |
| 156 | } |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | // Returns a group of four random numbers using the underlying Philox |
no outgoing calls
no test coverage detected