MCKL
Monte Carlo Kernel Library
philox_avx2_32_common.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/philox_avx2_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_AVX2_32_COMMON_HPP
33 #define MCKL_RANDOM_INTERNAL_PHILOX_AVX2_32_COMMON_HPP
34 
35 #define MCKL_RANDOM_INTERNAL_PHILOX_AVX2_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  constexpr int m2 = \
42  static_cast<int>(Constants::multiplier::value[2 % (K / 2)]); \
43  constexpr int m3 = \
44  static_cast<int>(Constants::multiplier::value[3 % (K / 2)]); \
45  const __m256i ymmm = _mm256_set_epi32(0, m3, 0, m2, 0, m1, 0, m0); \
46  const __m256i ymm8 = _mm256_mul_epu32(ymm0, ymmm); \
47  const __m256i ymm9 = _mm256_mul_epu32(ymm1, ymmm); \
48  const __m256i ymmA = _mm256_mul_epu32(ymm2, ymmm); \
49  const __m256i ymmB = _mm256_mul_epu32(ymm3, ymmm); \
50  const __m256i ymmC = _mm256_mul_epu32(ymm4, ymmm); \
51  const __m256i ymmD = _mm256_mul_epu32(ymm5, ymmm); \
52  const __m256i ymmE = _mm256_mul_epu32(ymm6, ymmm); \
53  const __m256i ymmF = _mm256_mul_epu32(ymm7, ymmm); \
54  \
55  constexpr int ma = static_cast<int>(0xFFFFFFFF); \
56  const __m256i ymma = _mm256_set_epi32(ma, 0, ma, 0, ma, 0, ma, 0); \
57  ymm0 = _mm256_and_si256(ymm0, ymma); \
58  ymm1 = _mm256_and_si256(ymm1, ymma); \
59  ymm2 = _mm256_and_si256(ymm2, ymma); \
60  ymm3 = _mm256_and_si256(ymm3, ymma); \
61  ymm4 = _mm256_and_si256(ymm4, ymma); \
62  ymm5 = _mm256_and_si256(ymm5, ymma); \
63  ymm6 = _mm256_and_si256(ymm6, ymma); \
64  ymm7 = _mm256_and_si256(ymm7, ymma); \
65  \
66  constexpr int w0 = \
67  static_cast<int>(Constants::weyl::value[0 % (K / 2)] * N); \
68  constexpr int w1 = \
69  static_cast<int>(Constants::weyl::value[1 % (K / 2)] * N); \
70  constexpr int w2 = \
71  static_cast<int>(Constants::weyl::value[2 % (K / 2)] * N); \
72  constexpr int w3 = \
73  static_cast<int>(Constants::weyl::value[3 % (K / 2)] * N); \
74  const __m256i ymmw = _mm256_set_epi32(w3, 0, w2, 0, w1, 0, w0, 0); \
75  const __m256i ymmk = _mm256_add_epi32(ymmk0, ymmw); \
76  ymm0 = _mm256_xor_si256(ymm0, ymmk); \
77  ymm1 = _mm256_xor_si256(ymm1, ymmk); \
78  ymm2 = _mm256_xor_si256(ymm2, ymmk); \
79  ymm3 = _mm256_xor_si256(ymm3, ymmk); \
80  ymm4 = _mm256_xor_si256(ymm4, ymmk); \
81  ymm5 = _mm256_xor_si256(ymm5, ymmk); \
82  ymm6 = _mm256_xor_si256(ymm6, ymmk); \
83  ymm7 = _mm256_xor_si256(ymm7, ymmk); \
84  \
85  ymm0 = _mm256_xor_si256(ymm0, ymm8); \
86  ymm1 = _mm256_xor_si256(ymm1, ymm9); \
87  ymm2 = _mm256_xor_si256(ymm2, ymmA); \
88  ymm3 = _mm256_xor_si256(ymm3, ymmB); \
89  ymm4 = _mm256_xor_si256(ymm4, ymmC); \
90  ymm5 = _mm256_xor_si256(ymm5, ymmD); \
91  ymm6 = _mm256_xor_si256(ymm6, ymmE); \
92  ymm7 = _mm256_xor_si256(ymm7, ymmF); \
93  \
94  ymm0 = _mm256_shuffle_epi32(ymm0, imm8); \
95  ymm1 = _mm256_shuffle_epi32(ymm1, imm8); \
96  ymm2 = _mm256_shuffle_epi32(ymm2, imm8); \
97  ymm3 = _mm256_shuffle_epi32(ymm3, imm8); \
98  ymm4 = _mm256_shuffle_epi32(ymm4, imm8); \
99  ymm5 = _mm256_shuffle_epi32(ymm5, imm8); \
100  ymm6 = _mm256_shuffle_epi32(ymm6, imm8); \
101  ymm7 = _mm256_shuffle_epi32(ymm7, imm8); \
102  }
103 
104 #endif // MCKL_RANDOM_INTERNAL_PHILOX_AVX2_32_COMMON_HPP