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