MCKL
Monte Carlo Kernel Library
increment_avx2_64_8.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/increment_avx2_64_8.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_8_HPP
33 #define MCKL_RANDOM_INTERNAL_INCREMENT_AVX2_64_8_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, 32, 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, 8> &s)
50  {
51  __m256i c =
52  _mm256_set1_epi64x(static_cast<MCKL_INT64>(std::get<0>(ctr)));
53 
54  std::get<0>(s) =
55  _mm256_add_epi64(c, _mm256_set_epi64x(0x04, 0x03, 0x02, 0x01));
56  std::get<1>(s) =
57  _mm256_add_epi64(c, _mm256_set_epi64x(0x08, 0x07, 0x06, 0x05));
58  std::get<2>(s) =
59  _mm256_add_epi64(c, _mm256_set_epi64x(0x0C, 0x0B, 0x0A, 0x09));
60  std::get<3>(s) =
61  _mm256_add_epi64(c, _mm256_set_epi64x(0x10, 0x0F, 0x0E, 0x0D));
62  std::get<4>(s) =
63  _mm256_add_epi64(c, _mm256_set_epi64x(0x14, 0x13, 0x12, 0x11));
64  std::get<5>(s) =
65  _mm256_add_epi64(c, _mm256_set_epi64x(0x18, 0x17, 0x16, 0x15));
66  std::get<6>(s) =
67  _mm256_add_epi64(c, _mm256_set_epi64x(0x1C, 0x1B, 0x1A, 0x19));
68  std::get<7>(s) =
69  _mm256_add_epi64(c, _mm256_set_epi64x(0x20, 0x1F, 0x1E, 0x1D));
70  }
71 }; // class IncrementBlockSI256
72 
73 template <typename T>
74 class IncrementBlockSI256<T, 2, 16, 64>
75 {
76  static constexpr std::size_t K_ = 2;
77 
78  public:
79  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 8> &s)
80  {
81  __m256i c =
82  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<1>(ctr)),
83  static_cast<MCKL_INT64>(std::get<0>(ctr)),
84  static_cast<MCKL_INT64>(std::get<1>(ctr)),
85  static_cast<MCKL_INT64>(std::get<0>(ctr)));
86 
87  std::get<0>(s) =
88  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x02, 0, 0x01));
89  std::get<1>(s) =
90  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x04, 0, 0x03));
91  std::get<2>(s) =
92  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x06, 0, 0x05));
93  std::get<3>(s) =
94  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x08, 0, 0x07));
95  std::get<4>(s) =
96  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x0A, 0, 0x09));
97  std::get<5>(s) =
98  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x0C, 0, 0x0B));
99  std::get<6>(s) =
100  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x0E, 0, 0x0D));
101  std::get<7>(s) =
102  _mm256_add_epi64(c, _mm256_set_epi64x(0, 0x10, 0, 0x0F));
103  }
104 }; // class IncrementBlockSI256
105 
106 template <typename T>
107 class IncrementBlockSI256<T, 4, 8, 64>
108 {
109  static constexpr std::size_t K_ = 4;
110 
111  public:
112  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 8> &s)
113  {
114  __m256i c =
115  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<3>(ctr)),
116  static_cast<MCKL_INT64>(std::get<2>(ctr)),
117  static_cast<MCKL_INT64>(std::get<1>(ctr)),
118  static_cast<MCKL_INT64>(std::get<0>(ctr)));
119 
120  std::get<0>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 1));
121  std::get<1>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 2));
122  std::get<2>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 3));
123  std::get<3>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 4));
124  std::get<4>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 5));
125  std::get<5>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 6));
126  std::get<6>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 7));
127  std::get<7>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 8));
128  }
129 }; // class IncrementBlockSI256
130 
131 template <typename T>
132 class IncrementBlockSI256<T, 8, 4, 64>
133 {
134  static constexpr std::size_t K_ = 8;
135 
136  public:
137  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 8> &s)
138  {
139  __m256i c =
140  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<3>(ctr)),
141  static_cast<MCKL_INT64>(std::get<2>(ctr)),
142  static_cast<MCKL_INT64>(std::get<1>(ctr)),
143  static_cast<MCKL_INT64>(std::get<0>(ctr)));
144 
145  std::get<0>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 1));
146  std::get<1>(s) =
147  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<7>(ctr)),
148  static_cast<MCKL_INT64>(std::get<6>(ctr)),
149  static_cast<MCKL_INT64>(std::get<5>(ctr)),
150  static_cast<MCKL_INT64>(std::get<4>(ctr)));
151  std::get<2>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 2));
152  std::get<3>(s) = std::get<1>(s);
153  std::get<4>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 3));
154  std::get<5>(s) = std::get<1>(s);
155  std::get<6>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 4));
156  std::get<7>(s) = std::get<1>(s);
157  }
158 }; // class IncrementBlockSI256
159 
160 template <typename T>
161 class IncrementBlockSI256<T, 16, 2, 64>
162 {
163  static constexpr std::size_t K_ = 16;
164 
165  public:
166  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 8> &s)
167  {
168  __m256i c =
169  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x3>(ctr)),
170  static_cast<MCKL_INT64>(std::get<0x2>(ctr)),
171  static_cast<MCKL_INT64>(std::get<0x1>(ctr)),
172  static_cast<MCKL_INT64>(std::get<0x0>(ctr)));
173 
174  std::get<0>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 1));
175  std::get<1>(s) =
176  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0x7>(ctr)),
177  static_cast<MCKL_INT64>(std::get<6>(ctr)),
178  static_cast<MCKL_INT64>(std::get<5>(ctr)),
179  static_cast<MCKL_INT64>(std::get<4>(ctr)));
180  std::get<2>(s) =
181  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0xB>(ctr)),
182  static_cast<MCKL_INT64>(std::get<0xA>(ctr)),
183  static_cast<MCKL_INT64>(std::get<0x9>(ctr)),
184  static_cast<MCKL_INT64>(std::get<0x8>(ctr)));
185  std::get<3>(s) =
186  _mm256_set_epi64x(static_cast<MCKL_INT64>(std::get<0xF>(ctr)),
187  static_cast<MCKL_INT64>(std::get<0xE>(ctr)),
188  static_cast<MCKL_INT64>(std::get<0xD>(ctr)),
189  static_cast<MCKL_INT64>(std::get<0xC>(ctr)));
190  std::get<4>(s) = _mm256_add_epi64(c, _mm256_set_epi64x(0, 0, 0, 2));
191  std::get<5>(s) = std::get<1>(s);
192  std::get<6>(s) = std::get<2>(s);
193  std::get<7>(s) = std::get<3>(s);
194  }
195 }; // class IncrementBlockSI256
196 
197 template <typename T>
198 class IncrementBlockSI256<T, 32, 1, 64>
199 {
200  static constexpr std::size_t K_ = 32;
201 
202  public:
203  static void eval(const std::array<T, K_> &ctr, std::array<__m256i, 8> &s)
204  {
205  std::memcpy(s.data(), ctr.data(), 256);
206  std::get<0>(s) =
207  _mm256_add_epi64(std::get<0>(s), _mm256_set_epi64x(0, 0, 0, 1));
208  }
209 }; // class IncrementBlockSI256
210 
211 } // namespace internal
212 
213 } // namespace mckl
214 
216 
217 #endif // MCKL_RANDOM_INTERNAL_INCREMENT_AVX2_64_8_HPP
#define MCKL_PUSH_GCC_WARNING(warning)
Definition: compiler.h:78
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 8 > &s)
#define MCKL_INT64
Definition: clang.h:134
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 8 > &s)
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 8 > &s)
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 8 > &s)
Definition: mcmc.hpp:40
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 8 > &s)
static void eval(const std::array< T, K_ > &ctr, std::array< __m256i, 8 > &s)
#define MCKL_POP_GCC_WARNING
Definition: compiler.h:79