Qrack  1.7
General classical-emulating-quantum development framework
complex8x2simd.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017, 2018. All rights reserved.
4 //
5 // This is a SIMD implementation of the float precision complex type.
6 // The API is designed to (almost entirely) mirror that of the C++ standard library
7 // float precision complex type.
8 //
9 // Licensed under the GNU Lesser General Public License V3.
10 // See LICENSE.md in the project root or https://www.gnu.org/licenses/lgpl-3.0.en.html
11 // for details.
12 
13 #pragma once
14 
15 #include <xmmintrin.h>
16 
17 namespace Qrack {
18 
19 static const __m128 SIGNMASK = _mm_castsi128_ps(_mm_set_epi32(0, 0x80000000, 0, 0x80000000));
20 
24  __m128 _val2;
25 
26  inline Complex8x2Simd(){};
27  inline Complex8x2Simd(const __m128& v2) { _val2 = v2; }
28  inline Complex8x2Simd(const float& r1, const float& i1, const float& r2, const float& i2)
29  {
30  _val2 = _mm_set_ps(i1, r1, i2, r2);
31  }
32  inline Complex8x2Simd operator+(const Complex8x2Simd& other) const { return _mm_add_ps(_val2, other._val2); }
34  {
35  _val2 = _mm_add_ps(_val2, other._val2);
36  return _val2;
37  }
38  inline Complex8x2Simd operator-(const Complex8x2Simd& other) const { return _mm_sub_ps(_val2, other._val2); }
40  {
41  _val2 = _mm_sub_ps(_val2, other._val2);
42  return _val2;
43  }
44  inline Complex8x2Simd operator*(const Complex8x2Simd& other) const
45  {
46  return _mm_add_ps(_mm_mul_ps(_mm_shuffle_ps(_val2, _val2, 177),
47  _mm_xor_ps(SIGNMASK, _mm_shuffle_ps(other._val2, other._val2, 245))),
48  _mm_mul_ps(_val2, _mm_shuffle_ps(other._val2, other._val2, 160)));
49  }
51  {
52  _val2 = _mm_add_ps(_mm_mul_ps(_mm_shuffle_ps(_val2, _val2, 177),
53  _mm_xor_ps(SIGNMASK, _mm_shuffle_ps(other._val2, other._val2, 245))),
54  _mm_mul_ps(_val2, _mm_shuffle_ps(other._val2, other._val2, 160)));
55  return _val2;
56  }
57  inline Complex8x2Simd operator*(const float rhs) const { return _mm_mul_ps(_val2, _mm_set1_ps(rhs)); }
58  inline Complex8x2Simd operator-() const { return -_val2; }
59  inline Complex8x2Simd operator*=(const float& other)
60  {
61  _val2 = _mm_mul_ps(_val2, _mm_set1_ps(other));
62  return _val2;
63  }
64 };
65 
66 union _cmplx_union {
67  float comp[4];
69  _cmplx_union(const Complex8x2Simd& c2) { cmplx2 = c2; }
70 };
71 
72 inline Complex8x2Simd dupeLo(const Complex8x2Simd& cmplx2) { return _mm_shuffle_ps(cmplx2._val2, cmplx2._val2, 68); }
73 inline Complex8x2Simd dupeHi(const Complex8x2Simd& cmplx2) { return _mm_shuffle_ps(cmplx2._val2, cmplx2._val2, 238); }
75  const Complex8x2Simd& mtrxCol1, const Complex8x2Simd& mtrxCol2, const Complex8x2Simd& qubit)
76 {
77  __m128 dupeLo = _mm_shuffle_ps(qubit._val2, qubit._val2, 68);
78  __m128 dupeHi = _mm_shuffle_ps(qubit._val2, qubit._val2, 238);
79  return _mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle_ps(mtrxCol1._val2, mtrxCol1._val2, 177),
80  _mm_xor_ps(SIGNMASK, _mm_shuffle_ps(dupeLo, dupeLo, 245))),
81  _mm_mul_ps(mtrxCol1._val2, _mm_shuffle_ps(dupeLo, dupeLo, 160))),
82  _mm_add_ps(_mm_mul_ps(_mm_shuffle_ps(mtrxCol2._val2, mtrxCol2._val2, 177),
83  _mm_xor_ps(SIGNMASK, _mm_shuffle_ps(dupeHi, dupeHi, 245))),
84  _mm_mul_ps(mtrxCol2._val2, _mm_shuffle_ps(dupeHi, dupeHi, 160))));
85 }
87  const float& nrm, const Complex8x2Simd& mtrxCol1, const Complex8x2Simd& mtrxCol2, const Complex8x2Simd& qubit)
88 {
89  __m128 dupeLo = _mm_shuffle_ps(qubit._val2, qubit._val2, 68);
90  __m128 dupeHi = _mm_shuffle_ps(qubit._val2, qubit._val2, 238);
91  return _mm_mul_ps(_mm_set1_ps(nrm),
92  _mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle_ps(mtrxCol1._val2, mtrxCol1._val2, 177),
93  _mm_xor_ps(SIGNMASK, _mm_shuffle_ps(dupeLo, dupeLo, 245))),
94  _mm_mul_ps(mtrxCol1._val2, _mm_shuffle_ps(dupeLo, dupeLo, 160))),
95  _mm_add_ps(_mm_mul_ps(_mm_shuffle_ps(mtrxCol2._val2, mtrxCol2._val2, 177),
96  _mm_xor_ps(SIGNMASK, _mm_shuffle_ps(dupeHi, dupeHi, 245))),
97  _mm_mul_ps(mtrxCol2._val2, _mm_shuffle_ps(dupeHi, dupeHi, 160)))));
98 }
99 inline Complex8x2Simd operator*(const float lhs, const Complex8x2Simd& rhs)
100 {
101  return _mm_mul_ps(_mm_set1_ps(lhs), rhs._val2);
102 }
103 
104 inline float norm(const Complex8x2Simd& c)
105 {
106  _cmplx_union cu(_mm_mul_ps(c._val2, c._val2));
107  return (cu.comp[0] + cu.comp[1] + cu.comp[2] + cu.comp[3]);
108 }
109 } // namespace Qrack
Complex8x2Simd operator*=(const float &other)
Definition: complex8x2simd.hpp:59
Complex8x2Simd operator*(const float rhs) const
Definition: complex8x2simd.hpp:57
Complex16x2Simd dupeHi(const Complex16x2Simd &cmplx2)
Definition: complex16x2simd.hpp:69
Complex16x2Simd dupeLo(const Complex16x2Simd &cmplx2)
Definition: complex16x2simd.hpp:65
Complex8x2Simd()
Definition: complex8x2simd.hpp:26
Complex8x2Simd operator+(const Complex8x2Simd &other) const
Definition: complex8x2simd.hpp:32
Definition: complex8x2simd.hpp:66
Complex8x2Simd operator-(const Complex8x2Simd &other) const
Definition: complex8x2simd.hpp:38
Complex8x2Simd(const __m128 &v2)
Definition: complex8x2simd.hpp:27
static const __m128 SIGNMASK
Definition: complex8x2simd.hpp:19
Complex8x2Simd operator*=(const Complex8x2Simd &other)
Definition: complex8x2simd.hpp:50
_cmplx_union(const Complex8x2Simd &c2)
Definition: complex8x2simd.hpp:69
Complex8x2Simd operator+=(const Complex8x2Simd &other)
Definition: complex8x2simd.hpp:33
Complex8x2Simd(const float &r1, const float &i1, const float &r2, const float &i2)
Definition: complex8x2simd.hpp:28
SIMD implementation of the float precision complex vector type of 2 complex numbers, only for COMPLEX_X_2 Apply2x2.
Definition: complex8x2simd.hpp:23
Complex8x2Simd operator*(const Complex8x2Simd &other) const
Definition: complex8x2simd.hpp:44
Complex16x2Simd matrixMul(const Complex16x2Simd &mtrxCol1, const Complex16x2Simd &mtrxCol2, const Complex16x2Simd &qubit)
Definition: complex16x2simd.hpp:73
__m128 _val2
Definition: complex8x2simd.hpp:24
double norm(const Complex16Simd &cmplx)
Definition: complex16simd.hpp:130
float comp[4]
Definition: complex8x2simd.hpp:67
Complex8x2Simd cmplx2
Definition: complex8x2simd.hpp:68
Complex8x2Simd operator-=(const Complex8x2Simd &other)
Definition: complex8x2simd.hpp:39
Definition: complex16simd.hpp:21
Complex8x2Simd operator-() const
Definition: complex8x2simd.hpp:58