MCKL
Monte Carlo Kernel Library
increment_sse2_64_8.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/increment_sse2_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_SSE2_64_8_HPP
33 #define MCKL_RANDOM_INTERNAL_INCREMENT_SSE2_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 IncrementBlockSI128<T, 1, 16, 64>
45 {
46  static constexpr std::size_t K_ = 1;
47 
48  public:
49  static void eval(std::array<T, K_> &ctr, std::array<__m128i, 8> &s)
50  {
51  __m128i c = _mm_set1_epi64x(static_cast<MCKL_INT64>(std::get<0>(ctr)));
52 
53  std::get<0>(s) = _mm_add_epi64(c, _mm_set_epi64x(0x02, 0x01));
54  std::get<1>(s) = _mm_add_epi64(c, _mm_set_epi64x(0x04, 0x03));
55  std::get<2>(s) = _mm_add_epi64(c, _mm_set_epi64x(0x06, 0x05));
56  std::get<3>(s) = _mm_add_epi64(c, _mm_set_epi64x(0x08, 0x07));
57  std::get<4>(s) = _mm_add_epi64(c, _mm_set_epi64x(0x0A, 0x09));
58  std::get<5>(s) = _mm_add_epi64(c, _mm_set_epi64x(0x0C, 0x0B));
59  std::get<6>(s) = _mm_add_epi64(c, _mm_set_epi64x(0x0E, 0x0D));
60  std::get<7>(s) = _mm_add_epi64(c, _mm_set_epi64x(0x10, 0x0F));
61  }
62 }; // class IncrementBlockSI128
63 
64 template <typename T>
65 class IncrementBlockSI128<T, 2, 8, 64>
66 {
67  static constexpr std::size_t K_ = 2;
68 
69  public:
70  static void eval(std::array<T, K_> &ctr, std::array<__m128i, 8> &s)
71  {
72  __m128i c = _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<1>(ctr)),
73  static_cast<MCKL_INT64>(std::get<0>(ctr)));
74 
75  std::get<0>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 1));
76  std::get<1>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 2));
77  std::get<2>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 3));
78  std::get<3>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 4));
79  std::get<4>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 5));
80  std::get<5>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 6));
81  std::get<6>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 7));
82  std::get<7>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 8));
83  }
84 }; // class IncrementBlockSI128
85 
86 template <typename T>
87 class IncrementBlockSI128<T, 4, 4, 64>
88 {
89  static constexpr std::size_t K_ = 4;
90 
91  public:
92  static void eval(std::array<T, K_> &ctr, std::array<__m128i, 8> &s)
93  {
94  __m128i c = _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<1>(ctr)),
95  static_cast<MCKL_INT64>(std::get<0>(ctr)));
96 
97  std::get<0>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 1));
98  std::get<1>(s) =
99  _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<3>(ctr)),
100  static_cast<MCKL_INT64>(std::get<2>(ctr)));
101  std::get<2>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 2));
102  std::get<3>(s) = std::get<1>(s);
103  std::get<4>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 3));
104  std::get<5>(s) = std::get<1>(s);
105  std::get<6>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 4));
106  std::get<7>(s) = std::get<1>(s);
107  }
108 }; // class IncrementBlockSI128
109 
110 template <typename T>
111 class IncrementBlockSI128<T, 8, 2, 64>
112 {
113  static constexpr std::size_t K_ = 8;
114 
115  public:
116  static void eval(std::array<T, K_> &ctr, std::array<__m128i, 8> &s)
117  {
118  __m128i c = _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<1>(ctr)),
119  static_cast<MCKL_INT64>(std::get<0>(ctr)));
120 
121  std::get<0>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 1));
122  std::get<1>(s) =
123  _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<3>(ctr)),
124  static_cast<MCKL_INT64>(std::get<2>(ctr)));
125  std::get<2>(s) =
126  _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<5>(ctr)),
127  static_cast<MCKL_INT64>(std::get<4>(ctr)));
128  std::get<3>(s) =
129  _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<7>(ctr)),
130  static_cast<MCKL_INT64>(std::get<6>(ctr)));
131  std::get<4>(s) = _mm_add_epi64(c, _mm_set_epi64x(0, 2));
132  std::get<5>(s) = std::get<1>(s);
133  std::get<6>(s) = std::get<2>(s);
134  std::get<7>(s) = std::get<3>(s);
135  }
136 }; // class IncrementBlockSI128
137 
138 template <typename T>
139 class IncrementBlockSI128<T, 16, 1, 64>
140 {
141  static constexpr std::size_t K_ = 16;
142 
143  public:
144  static void eval(const std::array<T, K_> &ctr, std::array<__m128i, 8> &s)
145  {
146  std::memcpy(s.data(), ctr.data(), 128);
147  std::get<0>(s) = _mm_add_epi64(std::get<0>(s), _mm_set_epi64x(0, 1));
148  }
149 }; // class IncrementBlockSI128
150 
151 } // namespace internal
152 
153 } // namespace mckl
154 
156 
157 #endif // MCKL_RANDOM_INTERNAL_INCREMENT_SSE2_64_8_HPP
static void eval(std::array< T, K_ > &ctr, std::array< __m128i, 8 > &s)
#define MCKL_PUSH_GCC_WARNING(warning)
Definition: compiler.h:78
#define MCKL_INT64
Definition: clang.h:134
static void eval(std::array< T, K_ > &ctr, std::array< __m128i, 8 > &s)
static void eval(std::array< T, K_ > &ctr, std::array< __m128i, 8 > &s)
Definition: mcmc.hpp:40
static void eval(const std::array< T, K_ > &ctr, std::array< __m128i, 8 > &s)
static void eval(std::array< T, K_ > &ctr, std::array< __m128i, 8 > &s)
#define MCKL_POP_GCC_WARNING
Definition: compiler.h:79