MCKL
Monte Carlo Kernel Library
philox_sse2_32_common.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/philox_sse2_32_common.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_PHILOX_SSE2_32_COMMON_HPP
33 #define MCKL_RANDOM_INTERNAL_PHILOX_SSE2_32_COMMON_HPP
34 
35 #define MCKL_RANDOM_INTERNAL_PHILOX_SSE2_32_RBOX(K, N, imm8) \
36  { \
37  constexpr int m0 = \
38  static_cast<int>(Constants::multiplier::value[0 % (K / 2)]); \
39  constexpr int m1 = \
40  static_cast<int>(Constants::multiplier::value[1 % (K / 2)]); \
41  const __m128i xmmm = _mm_set_epi32(0, m1, 0, m0); \
42  const __m128i xmm8 = _mm_mul_epu32(xmm0, xmmm); \
43  const __m128i xmm9 = _mm_mul_epu32(xmm1, xmmm); \
44  const __m128i xmmA = _mm_mul_epu32(xmm2, xmmm); \
45  const __m128i xmmB = _mm_mul_epu32(xmm3, xmmm); \
46  const __m128i xmmC = _mm_mul_epu32(xmm4, xmmm); \
47  const __m128i xmmD = _mm_mul_epu32(xmm5, xmmm); \
48  const __m128i xmmE = _mm_mul_epu32(xmm6, xmmm); \
49  const __m128i xmmF = _mm_mul_epu32(xmm7, xmmm); \
50  \
51  constexpr int ma = static_cast<int>(0xFFFFFFFF); \
52  const __m128i xmma = _mm_set_epi32(ma, 0, ma, 0); \
53  xmm0 = _mm_and_si128(xmm0, xmma); \
54  xmm1 = _mm_and_si128(xmm1, xmma); \
55  xmm2 = _mm_and_si128(xmm2, xmma); \
56  xmm3 = _mm_and_si128(xmm3, xmma); \
57  xmm4 = _mm_and_si128(xmm4, xmma); \
58  xmm5 = _mm_and_si128(xmm5, xmma); \
59  xmm6 = _mm_and_si128(xmm6, xmma); \
60  xmm7 = _mm_and_si128(xmm7, xmma); \
61  \
62  constexpr int w0 = \
63  static_cast<int>(Constants::weyl::value[0 % (K / 2)] * N); \
64  constexpr int w1 = \
65  static_cast<int>(Constants::weyl::value[1 % (K / 2)] * N); \
66  const __m128i xmmw = _mm_set_epi32(w1, 0, w0, 0); \
67  const __m128i xmmk = _mm_add_epi32(xmmk0, xmmw); \
68  xmm0 = _mm_xor_si128(xmm0, xmmk); \
69  xmm1 = _mm_xor_si128(xmm1, xmmk); \
70  xmm2 = _mm_xor_si128(xmm2, xmmk); \
71  xmm3 = _mm_xor_si128(xmm3, xmmk); \
72  xmm4 = _mm_xor_si128(xmm4, xmmk); \
73  xmm5 = _mm_xor_si128(xmm5, xmmk); \
74  xmm6 = _mm_xor_si128(xmm6, xmmk); \
75  xmm7 = _mm_xor_si128(xmm7, xmmk); \
76  \
77  xmm0 = _mm_xor_si128(xmm0, xmm8); \
78  xmm1 = _mm_xor_si128(xmm1, xmm9); \
79  xmm2 = _mm_xor_si128(xmm2, xmmA); \
80  xmm3 = _mm_xor_si128(xmm3, xmmB); \
81  xmm4 = _mm_xor_si128(xmm4, xmmC); \
82  xmm5 = _mm_xor_si128(xmm5, xmmD); \
83  xmm6 = _mm_xor_si128(xmm6, xmmE); \
84  xmm7 = _mm_xor_si128(xmm7, xmmF); \
85  \
86  xmm0 = _mm_shuffle_epi32(xmm0, imm8); \
87  xmm1 = _mm_shuffle_epi32(xmm1, imm8); \
88  xmm2 = _mm_shuffle_epi32(xmm2, imm8); \
89  xmm3 = _mm_shuffle_epi32(xmm3, imm8); \
90  xmm4 = _mm_shuffle_epi32(xmm4, imm8); \
91  xmm5 = _mm_shuffle_epi32(xmm5, imm8); \
92  xmm6 = _mm_shuffle_epi32(xmm6, imm8); \
93  xmm7 = _mm_shuffle_epi32(xmm7, imm8); \
94  }
95 
96 #endif // MCKL_RANDOM_INTERNAL_PHILOX_SSE2_32_COMMON_HPP