vSMC
vSMC: Scalable Monte Carlo
m128i.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/m128i.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, 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 VSMC_RNG_M128I_HPP
33 #define VSMC_RNG_M128I_HPP
34 
36 #include <emmintrin.h>
37 
38 #define VSMC_STATIC_ASSERT_RNG_M128I_PACK(Offset, T, N) \
39  VSMC_STATIC_ASSERT( \
40  ((Offset < N) && (sizeof(T) * (N - Offset) >= sizeof(__m128i))), \
41  TRY_TO_PACK_OR_UNPACK_A_TOO_SMALL_VECTOR_INTO_OR_FROM_m128i)
42 
43 namespace vsmc {
44 
47 template <std::size_t Offset, typename T, std::size_t N>
48 inline void m128i_pack_a (const Array<T, N> &c, __m128i &m)
49 {m = _mm_load_si128(reinterpret_cast<const __m128i *>(c.data() + Offset));}
50 
53 template <std::size_t Offset, typename T, std::size_t N>
54 inline void m128i_pack_u (const Array<T, N> &c, __m128i &m)
55 {m = _mm_loadu_si128(reinterpret_cast<const __m128i *>(c.data() + Offset));}
56 
59 template <std::size_t Offset, typename T, std::size_t N>
60 inline void m128i_unpack_a (const __m128i &m, Array<T, N> &c)
61 {_mm_store_si128(reinterpret_cast<__m128i *>(c.data() + Offset), m);}
62 
65 template <std::size_t Offset, typename T, std::size_t N>
66 inline void m128i_unpack_u (const __m128i &m, Array<T, N> &c)
67 {_mm_storeu_si128(reinterpret_cast<__m128i *>(c.data() + Offset), m);}
68 
71 template <std::size_t Offset, typename T, std::size_t N>
72 inline void m128i_pack (const Array<T, N> &c, __m128i &m)
73 {
75  m128i_pack_u<Offset>(c, m);
76 }
77 
80 template <std::size_t Offset, typename T, std::size_t N>
81 inline void m128i_unpack (const __m128i &m, Array<T, N> &c)
82 {
84  m128i_unpack_u<Offset>(m, c);
85 }
86 
89 inline bool m128i_is_equal (const __m128i &a, const __m128i &b)
90 {
93  m128i_unpack<0>(a, sa);
94  m128i_unpack<0>(b, sb);
95 
96  return sa == sb;
97 }
98 
102 template <typename CharT, typename Traits>
103 inline std::basic_ostream<CharT, Traits> &m128i_output (
104  std::basic_ostream<CharT, Traits> &os, const __m128i &a)
105 {
106  if (os.good()) {
108  m128i_unpack<0>(a, sa);
109  os << sa;
110  }
111 
112  return os;
113 }
114 
118 template <typename CharT, typename Traits>
119 inline std::basic_istream<CharT, Traits> &m128i_input (
120  std::basic_istream<CharT, Traits> &is, __m128i &a)
121 {
122  if (is.good()) {
124  is >> sa;
125  if (is) m128i_pack<0>(sa, a);
126  }
127 
128  return is;
129 }
130 
131 } // namespace vsmc
132 
133 #endif // VSMC_RNG_M128I_HPP
void m128i_unpack(const __m128i &m, Array< T, N > &c)
Unpack an __m128i object into an Array.
Definition: m128i.hpp:81
Definition: adapter.hpp:37
void m128i_pack_a(const Array< T, N > &c, __m128i &m)
Aligned pack.
Definition: m128i.hpp:48
void m128i_unpack_u(const __m128i &m, Array< T, N > &c)
Unaligned unpack.
Definition: m128i.hpp:66
std::basic_istream< CharT, Traits > & m128i_input(std::basic_istream< CharT, Traits > &is, __m128i &a)
Input an __m128i object from an input stream as 16 bytes unsigned integers written by m128i_output...
Definition: m128i.hpp:119
void m128i_unpack_a(const __m128i &m, Array< T, N > &c)
Aligned unpack.
Definition: m128i.hpp:60
#define VSMC_STATIC_ASSERT_RNG_M128I_PACK(Offset, T, N)
Definition: m128i.hpp:38
pointer data()
Definition: array.hpp:127
std::basic_ostream< CharT, Traits > & m128i_output(std::basic_ostream< CharT, Traits > &os, const __m128i &a)
Write an __m128i object into an output stream as 16 bytes unsigned integers.
Definition: m128i.hpp:103
void m128i_pack(const Array< T, N > &c, __m128i &m)
Pack an Array into an __m128i object.
Definition: m128i.hpp:72
Static array.
Definition: array.hpp:79
bool m128i_is_equal(const __m128i &a, const __m128i &b)
Compare two __m128i objects.
Definition: m128i.hpp:89
void m128i_pack_u(const Array< T, N > &c, __m128i &m)
Unaligned pack.
Definition: m128i.hpp:54