OpenQMC API
Loading...
Searching...
No Matches
owen.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright Contributors to the OpenQMC Project.
3
9
10#pragma once
11
12#include "arch.h"
13#include "gpu.h"
14#include "permute.h"
15#include "reverse.h"
16#include "rotate.h"
17
18#include <cassert>
19#include <cstdint>
20
21#if defined(OQMC_ARCH_AVX)
22#include <immintrin.h>
23#endif
24
25#if defined(OQMC_ARCH_SSE)
26#include <emmintrin.h>
27#endif
28
29#if defined(OQMC_ARCH_ARM)
30#include <arm_neon.h>
31#endif
32
33namespace oqmc
34{
35
45OQMC_HOST_DEVICE inline std::uint16_t sobolReversedIndex(std::uint16_t index,
46 int dimension)
47{
48 assert(dimension >= 0);
49 assert(dimension <= 3);
50
51 if(dimension == 0)
52 {
53 return reverseBits16(index);
54 }
55
56 // Following matrices were produced using the matrices cli tool found in the
57 // source file src/tools/cli/matrices.cpp. This in turn uses matrices that
58 // were copied from MIT licensed code written by Leonhard Gruenschloss.
59
60 // clang-format off
61 constexpr std::uint16_t masks[16] = {
62 0b0000000000000001,
63 0b0000000000000010,
64 0b0000000000000100,
65 0b0000000000001000,
66 0b0000000000010000,
67 0b0000000000100000,
68 0b0000000001000000,
69 0b0000000010000000,
70 0b0000000100000000,
71 0b0000001000000000,
72 0b0000010000000000,
73 0b0000100000000000,
74 0b0001000000000000,
75 0b0010000000000000,
76 0b0100000000000000,
77 0b1000000000000000,
78 };
79
80 constexpr std::uint16_t directions[4][16] = {
81 {
82 0b1000000000000000,
83 0b0100000000000000,
84 0b0010000000000000,
85 0b0001000000000000,
86 0b0000100000000000,
87 0b0000010000000000,
88 0b0000001000000000,
89 0b0000000100000000,
90 0b0000000010000000,
91 0b0000000001000000,
92 0b0000000000100000,
93 0b0000000000010000,
94 0b0000000000001000,
95 0b0000000000000100,
96 0b0000000000000010,
97 0b0000000000000001,
98 },
99
100 {
101 0b1111111111111111,
102 0b0101010101010101,
103 0b0011001100110011,
104 0b0001000100010001,
105 0b0000111100001111,
106 0b0000010100000101,
107 0b0000001100000011,
108 0b0000000100000001,
109 0b0000000011111111,
110 0b0000000001010101,
111 0b0000000000110011,
112 0b0000000000010001,
113 0b0000000000001111,
114 0b0000000000000101,
115 0b0000000000000011,
116 0b0000000000000001,
117 },
118
119 {
120 0b1010101000001001,
121 0b0111011100000110,
122 0b0011100100000011,
123 0b0001011000000001,
124 0b0000100110101010,
125 0b0000011001110111,
126 0b0000001100111001,
127 0b0000000100010110,
128 0b0000000010100011,
129 0b0000000001110001,
130 0b0000000000111010,
131 0b0000000000010111,
132 0b0000000000001001,
133 0b0000000000000110,
134 0b0000000000000011,
135 0b0000000000000001,
136 },
137
138 {
139 0b1010000011000011,
140 0b0100000001000001,
141 0b0011000000101101,
142 0b0001000000011110,
143 0b0000101101100111,
144 0b0000011110011010,
145 0b0000001010100100,
146 0b0000000100011011,
147 0b0000000011001001,
148 0b0000000001000101,
149 0b0000000000101110,
150 0b0000000000011111,
151 0b0000000000001010,
152 0b0000000000000100,
153 0b0000000000000011,
154 0b0000000000000001,
155 },
156 };
157 // clang-format on
158
159 const auto matrix = directions[dimension];
160
161#if defined(OQMC_ARCH_AVX)
162 constexpr auto stride = 16;
164
165 __m256i bits = zero;
166 for(int i = 0; i < 16; i += stride)
167 {
168 const auto maskPtr = reinterpret_cast<const __m256i*>(masks + i);
170
171 const auto matrixPtr = reinterpret_cast<const __m256i*>(matrix + i);
173
176
178
181 }
182
186
188#endif
189
190#if defined(OQMC_ARCH_SSE)
191 constexpr auto stride = 8;
193
194 __m128i bits = zero;
195 for(int i = 0; i < 16; i += stride)
196 {
197 const auto maskPtr = reinterpret_cast<const __m128i*>(masks + i);
199
200 const auto matrixPtr = reinterpret_cast<const __m128i*>(matrix + i);
202
205
207
210 }
211
215
216 return _mm_extract_epi16(bits, 0);
217#endif
218
219#if defined(OQMC_ARCH_ARM)
220 constexpr auto stride = 8;
221 const uint16x8_t zero = vdupq_n_u16(0);
222
224 for(int i = 0; i < 16; i += stride)
225 {
226 const uint16x8_t mask = vld1q_u16(masks + i);
228
229 const uint16x8_t masked = vandq_u16(vdupq_n_u16(index), mask);
231
233
234 bits =
236 }
237
241
242 return vgetq_lane_u16(bits, 0);
243#endif
244
245#if defined(OQMC_ARCH_SCALAR)
246 std::uint16_t sample = 0;
247 for(int i = 0; i < 16; ++i)
248 {
249 if((index & masks[i]) != 0)
250 {
251 sample ^= matrix[i];
252 }
253 }
254
255 return sample;
256#endif
257}
258
269OQMC_HOST_DEVICE constexpr std::uint32_t scrambleAndReverse(std::uint32_t value,
270 std::uint32_t seed)
271{
274
275 return value;
276}
277
289template <int Depth>
290OQMC_HOST_DEVICE inline void shuffledScrambledSobol(std::uint32_t index,
291 std::uint32_t seed,
292 std::uint32_t sample[Depth])
293{
294 static_assert(Depth >= 1, "Pattern depth is greater or equal to one.");
295 static_assert(Depth <= 4, "Pattern depth is less or equal to four.");
296
297 index = reverseAndShuffle(index, seed);
298
299 for(int i = 0; i < Depth; ++i)
300 {
301 sample[i] = sobolReversedIndex(index >> 16, i);
303 }
304}
305
306} // namespace oqmc
#define OQMC_HOST_DEVICE
Definition gpu.h:13
constexpr std::uint32_t reverseAndShuffle(std::uint32_t value, std::uint32_t seed)
Reverse input bits and shuffle order.
Definition permute.h:54
constexpr std::uint32_t rotateBytes(std::uint32_t value, int distance)
Rotate bytes in an integer value.
Definition rotate.h:41
EncodeKey decodeBits16(std::uint16_t value)
Decode a value back into a key.
Definition encode.h:81
constexpr std::uint16_t reverseBits16(std::uint16_t value)
Reverse bits of an unsigned 16 bit integer.
Definition reverse.h:53
constexpr std::uint32_t laineKarrasPermutation(std::uint32_t value, std::uint32_t seed)
Laine and Karras style permutation.
Definition permute.h:34
constexpr std::uint32_t reverseBits32(std::uint32_t value)
Reverse bits of an unsigned 32 bit integer.
Definition reverse.h:25
Definition bntables.h:21
void shuffledScrambledSobol(std::uint32_t index, std::uint32_t seed, std::uint32_t sample[Depth])
Compute a randomised sobol sequence value.
Definition owen.h:290
constexpr std::uint32_t scrambleAndReverse(std::uint32_t value, std::uint32_t seed)
Permute an input integer and reverse the bits.
Definition owen.h:269
std::uint16_t sobolReversedIndex(std::uint16_t index, int dimension)
Compute sobol sequence value at an index with reversed bits.
Definition owen.h:45