MCKL
Monte Carlo Kernel Library
increment_avx2_64_f.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/increment_avx2_64_f.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef MCKL_RANDOM_INTERNAL_INCREMENT_AVX2_64_F_HPP
33 #define MCKL_RANDOM_INTERNAL_INCREMENT_AVX2_64_F_HPP
34 
36 
37 MCKL_PUSH_GCC_WARNING("-Wignored-attributes")
38 
39 namespace mckl {
40 
41 namespace internal {
42 
43 template <typename T>
44 class IncrementBlockSI256<T, 1, 64, 64>
45 {
46  static constexpr std::size_t K_ = 1;
47 
48  public:
49  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 16> &s)
50  {
51  __m256i c =
52  _mm256_set1_epi64x(static_cast<MCKL_INT64>(std::get<0>(ctr)));
53 
54  std::get<0x0>(s) =
55  _mm256_add_epi64(c, _mm256_set_epi64x(0x04, 0x03, 0x02, 0x01));
56  std::get<0x1>(s) =
57  _mm256_add_epi64(c, _mm256_set_epi64x(0x08, 0x07, 0x06, 0x05));
58  std::get<0x2>(s) =
59  _mm256_add_epi64(c, _mm256_set_epi64x(0x0C, 0x0B, 0x0A, 0x09));
60  std::get<0x3>(s) =
61  _mm256_add_epi64(c, _mm256_set_epi64x(0x10, 0x0F, 0x0E, 0x0D));
62  std::get<0x4>(s) =
63  _mm256_add_epi64(c, _mm256_set_epi64x(0x14, 0x13, 0x12, 0x11));
64  std::get<0x5>(s) =
65  _mm256_add_epi64(c, _mm256_set_epi64x(0x18, 0x17, 0x16, 0x15));
66  std::get<0x6>(s) =
67  _mm256_add_epi64(c, _mm256_set_epi64x(0x1C, 0x1B, 0x1A, 0x19));
68  std::get<0x7>(s) =
69  _mm256_add_epi64(c, _mm256_set_epi64x(0x20, 0x1F, 0x1E, 0x1D));
70 
71  __m256i d = _mm256_set1_epi64x(0x20);
72  std::get<0x8>(s) = _mm256_add_epi64(std::get<0x0>(s), d);
73  std::get<0x9>(s) = _mm256_add_epi64(std::get<0x1>(s), d);
74  std::get<0xA>(s) = _mm256_add_epi64(std::get<0x2>(s), d);
75  std::get<0xB>(s) = _mm256_add_epi64(std::get<0x3>(s), d);
76  std::get<0xC>(s) = _mm256_add_epi64(std::get<0x4>(s), d);
77  std::get<0xD>(s) = _mm256_add_epi64(std::get<0x5>(s), d);
78  std::get<0xE>(s) = _mm256_add_epi64(std::get<0x6>(s), d);
79  std::get<0xF>(s) = _mm256_add_epi64(std::get<0x7>(s), d);
80  }
81 }; // class IncrementBlockSI256
82 
83 template <typename T>
84 class IncrementBlockSI256<T, 2, 32, 64>
85 {
86  static constexpr std::size_t K_ = 2;
87 
88  public:
89  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 16> &s)
90  {
91  __m256i c =
92  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<1>(ctr)),
93  static_cast<MCKL_INT64>(std::get<0>(ctr)),
94  static_cast<MCKL_INT64>(std::get<1>(ctr)),
95  static_cast<MCKL_INT64>(std::get<0>(ctr)));
96 
97  std::get<0x0>(s) =
98  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x02, 0, 0x01));
99  std::get<0x1>(s) =
100  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x04, 0, 0x03));
101  std::get<0x2>(s) =
102  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x06, 0, 0x05));
103  std::get<0x3>(s) =
104  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x08, 0, 0x07));
105  std::get<0x4>(s) =
106  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x0A, 0, 0x09));
107  std::get<0x5>(s) =
108  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x0C, 0, 0x0B));
109  std::get<0x6>(s) =
110  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x0E, 0, 0x0D));
111  std::get<0x7>(s) =
112  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x10, 0, 0x0F));
113 
114  __m256i d = _mm256_set_epi64x(0, 0x10, 0, 0x10);
115  std::get<0x8>(s) = _mm256_add_epi64(std::get<0x0>(s), d);
116  std::get<0x9>(s) = _mm256_add_epi64(std::get<0x1>(s), d);
117  std::get<0xA>(s) = _mm256_add_epi64(std::get<0x2>(s), d);
118  std::get<0xB>(s) = _mm256_add_epi64(std::get<0x3>(s), d);
119  std::get<0xC>(s) = _mm256_add_epi64(std::get<0x4>(s), d);
120  std::get<0xD>(s) = _mm256_add_epi64(std::get<0x5>(s), d);
121  std::get<0xE>(s) = _mm256_add_epi64(std::get<0x6>(s), d);
122  std::get<0xF>(s) = _mm256_add_epi64(std::get<0x7>(s), d);
123  }
124 }; // class IncrementBlockSI256
125 
126 template <typename T>
127 class IncrementBlockSI256<T, 4, 16, 64>
128 {
129  static constexpr std::size_t K_ = 4;
130 
131  public:
132  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 16> &s)
133  {
134  __m256i c =
135  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<3>(ctr)),
136  static_cast<MCKL_INT64>(std::get<2>(ctr)),
137  static_cast<MCKL_INT64>(std::get<1>(ctr)),
138  static_cast<MCKL_INT64>(std::get<0>(ctr)));
139 
140  std::get<0x0>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 1));
141  std::get<0x1>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 2));
142  std::get<0x2>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 3));
143  std::get<0x3>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 4));
144  std::get<0x4>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 5));
145  std::get<0x5>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 6));
146  std::get<0x6>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 7));
147  std::get<0x7>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 8));
148 
149  __m256i d = _mm256_set_epi64x(0, 0, 0, 8);
150  std::get<0x8>(s) = _mm256_add_epi64(std::get<0x0>(s), d);
151  std::get<0x9>(s) = _mm256_add_epi64(std::get<0x1>(s), d);
152  std::get<0xA>(s) = _mm256_add_epi64(std::get<0x2>(s), d);
153  std::get<0xB>(s) = _mm256_add_epi64(std::get<0x3>(s), d);
154  std::get<0xC>(s) = _mm256_add_epi64(std::get<0x4>(s), d);
155  std::get<0xD>(s) = _mm256_add_epi64(std::get<0x5>(s), d);
156  std::get<0xE>(s) = _mm256_add_epi64(std::get<0x6>(s), d);
157  std::get<0xF>(s) = _mm256_add_epi64(std::get<0x7>(s), d);
158  }
159 }; // class IncrementBlockSI256
160 
161 template <typename T>
162 class IncrementBlockSI256<T, 8, 8, 64>
163 {
164  static constexpr std::size_t K_ = 8;
165 
166  public:
167  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 16> &s)
168  {
169  __m256i c =
170  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<3>(ctr)),
171  static_cast<MCKL_INT64>(std::get<2>(ctr)),
172  static_cast<MCKL_INT64>(std::get<1>(ctr)),
173  static_cast<MCKL_INT64>(std::get<0>(ctr)));
174 
175  std::get<0x0>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 1));
176  std::get<0x1>(s) =
177  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<7>(ctr)),
178  static_cast<MCKL_INT64>(std::get<6>(ctr)),
179  static_cast<MCKL_INT64>(std::get<5>(ctr)),
180  static_cast<MCKL_INT64>(std::get<4>(ctr)));
181  std::get<0x2>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 2));
182  std::get<0x3>(s) = std::get<0x1>(s);
183  std::get<0x4>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 3));
184  std::get<0x5>(s) = std::get<0x1>(s);
185  std::get<0x6>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 4));
186  std::get<0x7>(s) = std::get<0x1>(s);
187  std::get<0x8>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 5));
188  std::get<0x9>(s) = std::get<0x1>(s);
189  std::get<0xA>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 6));
190  std::get<0xB>(s) = std::get<0x1>(s);
191  std::get<0xC>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 7));
192  std::get<0xD>(s) = std::get<0x1>(s);
193  std::get<0xE>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 8));
194  std::get<0xF>(s) = std::get<0x1>(s);
195  }
196 }; // class IncrementBlockSI256
197 
198 template <typename T>
199 class IncrementBlockSI256<T, 16, 4, 64>
200 {
201  static constexpr std::size_t K_ = 16;
202 
203  public:
204  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 16> &s)
205  {
206  __m256i c =
207  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x3>(ctr)),
208  static_cast<MCKL_INT64>(std::get<0x2>(ctr)),
209  static_cast<MCKL_INT64>(std::get<0x1>(ctr)),
210  static_cast<MCKL_INT64>(std::get<0x0>(ctr)));
211 
212  std::get<0x0>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 1));
213  std::get<0x1>(s) =
214  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x7>(ctr)),
215  static_cast<MCKL_INT64>(std::get<0x6>(ctr)),
216  static_cast<MCKL_INT64>(std::get<0x5>(ctr)),
217  static_cast<MCKL_INT64>(std::get<0x4>(ctr)));
218  std::get<0x2>(s) =
219  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0xB>(ctr)),
220  static_cast<MCKL_INT64>(std::get<0xA>(ctr)),
221  static_cast<MCKL_INT64>(std::get<0x9>(ctr)),
222  static_cast<MCKL_INT64>(std::get<0x8>(ctr)));
223  std::get<0x3>(s) =
224  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0xF>(ctr)),
225  static_cast<MCKL_INT64>(std::get<0xE>(ctr)),
226  static_cast<MCKL_INT64>(std::get<0xD>(ctr)),
227  static_cast<MCKL_INT64>(std::get<0xC>(ctr)));
228  std::get<0x4>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 2));
229  std::get<0x5>(s) = std::get<1>(s);
230  std::get<0x6>(s) = std::get<2>(s);
231  std::get<0x7>(s) = std::get<3>(s);
232  std::get<0x8>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 3));
233  std::get<0x9>(s) = std::get<1>(s);
234  std::get<0xA>(s) = std::get<2>(s);
235  std::get<0xB>(s) = std::get<3>(s);
236  std::get<0xC>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 4));
237  std::get<0xD>(s) = std::get<1>(s);
238  std::get<0xE>(s) = std::get<2>(s);
239  std::get<0xF>(s) = std::get<3>(s);
240  }
241 }; // class IncrementBlockSI256
242 
243 template <typename T>
244 class IncrementBlockSI256<T, 32, 2, 64>
245 {
246  static constexpr std::size_t K_ = 32;
247 
248  public:
249  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 16> &s)
250  {
251  __m256i c =
252  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x03>(ctr)),
253  static_cast<MCKL_INT64>(std::get<0x02>(ctr)),
254  static_cast<MCKL_INT64>(std::get<0x01>(ctr)),
255  static_cast<MCKL_INT64>(std::get<0x00>(ctr)));
256 
257  std::get<0x0>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 1));
258  std::get<0x1>(s) =
259  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x07>(ctr)),
260  static_cast<MCKL_INT64>(std::get<0x06>(ctr)),
261  static_cast<MCKL_INT64>(std::get<0x05>(ctr)),
262  static_cast<MCKL_INT64>(std::get<0x04>(ctr)));
263  std::get<0x2>(s) =
264  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x0B>(ctr)),
265  static_cast<MCKL_INT64>(std::get<0x0A>(ctr)),
266  static_cast<MCKL_INT64>(std::get<0x09>(ctr)),
267  static_cast<MCKL_INT64>(std::get<0x08>(ctr)));
268  std::get<0x3>(s) =
269  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x0F>(ctr)),
270  static_cast<MCKL_INT64>(std::get<0x0E>(ctr)),
271  static_cast<MCKL_INT64>(std::get<0x0D>(ctr)),
272  static_cast<MCKL_INT64>(std::get<0x0C>(ctr)));
273  std::get<0x4>(s) =
274  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x13>(ctr)),
275  static_cast<MCKL_INT64>(std::get<0x12>(ctr)),
276  static_cast<MCKL_INT64>(std::get<0x11>(ctr)),
277  static_cast<MCKL_INT64>(std::get<0x10>(ctr)));
278  std::get<0x5>(s) =
279  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x17>(ctr)),
280  static_cast<MCKL_INT64>(std::get<0x16>(ctr)),
281  static_cast<MCKL_INT64>(std::get<0x15>(ctr)),
282  static_cast<MCKL_INT64>(std::get<0x14>(ctr)));
283  std::get<0x6>(s) =
284  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x1B>(ctr)),
285  static_cast<MCKL_INT64>(std::get<0x1A>(ctr)),
286  static_cast<MCKL_INT64>(std::get<0x19>(ctr)),
287  static_cast<MCKL_INT64>(std::get<0x18>(ctr)));
288  std::get<0x7>(s) =
289  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x1F>(ctr)),
290  static_cast<MCKL_INT64>(std::get<0x1E>(ctr)),
291  static_cast<MCKL_INT64>(std::get<0x1D>(ctr)),
292  static_cast<MCKL_INT64>(std::get<0x1C>(ctr)));
293  std::get<0x8>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 2));
294  std::get<0x9>(s) = std::get<0x1>(s);
295  std::get<0xA>(s) = std::get<0x2>(s);
296  std::get<0xB>(s) = std::get<0x3>(s);
297  std::get<0xC>(s) = std::get<0x4>(s);
298  std::get<0xD>(s) = std::get<0x5>(s);
299  std::get<0xE>(s) = std::get<0x6>(s);
300  std::get<0xF>(s) = std::get<0x7>(s);
301  }
302 }; // class IncrementBlockSI256
303 
304 template <typename T>
305 class IncrementBlockSI256<T, 64, 1, 64>
306 {
307  static constexpr std::size_t K_ = 64;
308 
309  public:
310  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 16> &s)
311  {
312  std::memcpy(s.data(), ctr.data(), 512);
313  std::get<0>(s) =
314  _mm256_add_epi64(std::get<0>(s), _mm256_set_epi64x(0, 0, 0, 1));
315  }
316 }; // class IncrementBlockSI256
317 
318 } // namespace internal
319 
320 } // namespace mckl
321 
323 
324 #endif // MCKL_RANDOM_INTERNAL_INCREMENT_AVX2_64_F_HPP
#define MCKL_PUSH_GCC_WARNING(warning)
Definition: compiler.h:78
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 16 > &s)
#define MCKL_INT64
Definition: clang.h:134
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 16 > &s)
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 16 > &s)
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 16 > &s)
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 16 > &s)
Definition: mcmc.hpp:40
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 16 > &s)
#define MCKL_POP_GCC_WARNING
Definition: compiler.h:79
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 16 > &s)