Qrack  9.0
General classical-emulating-quantum development framework
qrack_functions.hpp
Go to the documentation of this file.
1 //
3 // (C) Daniel Strano and the Qrack contributors 2017-2023. All rights reserved.
4 //
5 // This is a multithreaded, universal quantum register simulation, allowing
6 // (nonphysical) register cloning and direct measurement of probability and
7 // phase, to leverage what advantages classical emulation of qubits can have.
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 "qrack_types.hpp"
16 
17 #include <set>
18 #include <vector>
19 
20 namespace Qrack {
21 
22 inline bitCapInt pow2(const bitLenInt& p) { return (bitCapInt)ONE_BCI << p; }
23 inline bitCapIntOcl pow2Ocl(const bitLenInt& p) { return (bitCapIntOcl)ONE_BCI << p; }
24 inline bitCapInt pow2Mask(const bitLenInt& p) { return ((bitCapInt)ONE_BCI << p) - ONE_BCI; }
25 inline bitCapIntOcl pow2MaskOcl(const bitLenInt& p) { return ((bitCapIntOcl)ONE_BCI << p) - ONE_BCI; }
27 {
28 #if __GNUC__ && QBCAPPOW < 7
29 // Source: https://stackoverflow.com/questions/11376288/fast-computing-of-log2-for-64-bit-integers#answer-11376759
30 #if QBCAPPOW < 6
31  return (bitLenInt)(bitsInByte * sizeof(unsigned int) - __builtin_clz((unsigned int)n) - 1U);
32 #else
33  return (bitLenInt)(bitsInByte * sizeof(unsigned long long) - __builtin_clzll((unsigned long long)n) - 1U);
34 #endif
35 #else
36  bitLenInt pow = 0U;
37  bitCapInt p = n >> ONE_BCI;
38  while (p) {
39  p >>= ONE_BCI;
40  ++pow;
41  }
42  return pow;
43 #endif
44 }
45 inline bitCapInt bitSlice(const bitLenInt& bit, const bitCapInt& source)
46 {
47  return ((bitCapInt)ONE_BCI << bit) & source;
48 }
49 inline bitCapIntOcl bitSliceOcl(const bitLenInt& bit, const bitCapIntOcl& source)
50 {
51  return ((bitCapIntOcl)ONE_BCI << bit) & source;
52 }
53 inline bitCapInt bitRegMask(const bitLenInt& start, const bitLenInt& length)
54 {
55  return (((bitCapInt)ONE_BCI << length) - ONE_BCI) << start;
56 }
57 inline bitCapIntOcl bitRegMaskOcl(const bitLenInt& start, const bitLenInt& length)
58 {
59  return (((bitCapIntOcl)ONE_BCI << length) - ONE_BCI) << start;
60 }
61 // Source: https://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/
62 inline bool isPowerOfTwo(const bitCapInt& x) { return (x && !(x & (x - ONE_BCI))); }
63 inline bool isBadBitRange(const bitLenInt& start, const bitLenInt& length, const bitLenInt& qubitCount)
64 {
65  return ((start + length) > qubitCount) || ((bitLenInt)(start + length) < start);
66 }
67 inline bool isBadPermRange(const bitCapIntOcl& start, const bitCapIntOcl& length, const bitCapIntOcl& maxQPowerOcl)
68 {
69  return ((start + length) > maxQPowerOcl) || ((bitCapIntOcl)(start + length) < start);
70 }
72  const std::vector<bitLenInt>& controls, const bitLenInt& qubitCount, std::string message)
73 {
74  std::set<bitLenInt> dupes;
75  for (size_t i = 0U; i < controls.size(); ++i) {
76  if (controls[i] >= qubitCount) {
77  throw std::invalid_argument(message);
78  }
79 
80  if (dupes.find(controls[i]) == dupes.end()) {
81  dupes.insert(controls[i]);
82  } else {
83  throw std::invalid_argument(message + " (Found duplicate qubit indices!)");
84  }
85  }
86 }
87 
88 // These are utility functions defined in qinterface/protected.cpp:
89 unsigned char* cl_alloc(size_t ucharCount);
90 void cl_free(void* toFree);
91 void mul2x2(complex const* left, complex const* right, complex* out);
92 void exp2x2(complex const* matrix2x2, complex* outMatrix2x2);
93 void log2x2(complex const* matrix2x2, complex* outMatrix2x2);
94 void inv2x2(complex const* matrix2x2, complex* outMatrix2x2);
95 bool isOverflowAdd(bitCapInt inOutInt, bitCapInt inInt, const bitCapInt& signMask, const bitCapInt& lengthPower);
96 bool isOverflowSub(bitCapInt inOutInt, bitCapInt inInt, const bitCapInt& signMask, const bitCapInt& lengthPower);
97 bitCapInt pushApartBits(const bitCapInt& perm, const std::vector<bitCapInt>& skipPowers);
100 #if QBCAPPOW == 7U
101 std::ostream& operator<<(std::ostream& os, bitCapInt b);
102 std::istream& operator>>(std::istream& is, bitCapInt& b);
103 #endif
104 
105 #if ENABLE_ENV_VARS
106 const real1_f _qrack_qbdt_sep_thresh = getenv("QRACK_QBDT_SEPARABILITY_THRESHOLD")
107  ? (real1_f)std::stof(std::string(getenv("QRACK_QBDT_SEPARABILITY_THRESHOLD")))
108  : FP_NORM_EPSILON;
109 #else
111 #endif
112 } // namespace Qrack
Definition: complex16x2simd.hpp:25
void ThrowIfQbIdArrayIsBad(const std::vector< bitLenInt > &controls, const bitLenInt &qubitCount, std::string message)
Definition: qrack_functions.hpp:71
constexpr uint8_t ONE_BCI
Definition: qrack_types.hpp:90
bitCapInt bitRegMask(const bitLenInt &start, const bitLenInt &length)
Definition: qrack_functions.hpp:53
bool isOverflowSub(bitCapInt inOutInt, bitCapInt inInt, const bitCapInt &signMask, const bitCapInt &lengthPower)
Check if a subtraction with overflow sets the flag.
Definition: functions.cpp:222
std::complex< half_float::half > complex
Definition: qrack_types.hpp:62
void cl_free(void *toFree)
Definition: functions.cpp:49
bool isPowerOfTwo(const bitCapInt &x)
Definition: qrack_functions.hpp:62
unsigned char * cl_alloc(size_t ucharCount)
Definition: functions.cpp:27
void log2x2(complex const *matrix2x2, complex *outMatrix2x2)
Definition: functions.cpp:189
void mul2x2(complex const *left, complex const *right, complex *out)
Definition: functions.cpp:97
bitCapInt intPow(bitCapInt base, bitCapInt power)
std::istream & operator>>(std::istream &os, QCircuitGatePtr &g)
Definition: qcircuit.cpp:44
const real1_f _qrack_qbdt_sep_thresh
Definition: qrack_functions.hpp:110
QRACK_CONST real1 FP_NORM_EPSILON
Definition: qrack_types.hpp:243
bitCapInt pushApartBits(const bitCapInt &perm, const std::vector< bitCapInt > &skipPowers)
Definition: functions.cpp:240
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:22
bitCapIntOcl bitRegMaskOcl(const bitLenInt &start, const bitLenInt &length)
Definition: qrack_functions.hpp:57
void inv2x2(complex const *matrix2x2, complex *outMatrix2x2)
Definition: functions.cpp:191
void exp2x2(complex const *matrix2x2, complex *outMatrix2x2)
Definition: functions.cpp:187
bitCapInt bitSlice(const bitLenInt &bit, const bitCapInt &source)
Definition: qrack_functions.hpp:45
bitCapInt pow2Mask(const bitLenInt &p)
Definition: qrack_functions.hpp:24
float real1_f
Definition: qrack_types.hpp:64
bool isOverflowAdd(bitCapInt inOutInt, bitCapInt inInt, const bitCapInt &signMask, const bitCapInt &lengthPower)
Check if an addition with overflow sets the flag.
Definition: functions.cpp:201
bitCapIntOcl intPowOcl(bitCapIntOcl base, bitCapIntOcl power)
std::ostream & operator<<(std::ostream &os, const QCircuitGatePtr g)
Definition: qcircuit.cpp:19
bitCapIntOcl pow2MaskOcl(const bitLenInt &p)
Definition: qrack_functions.hpp:25
bool isBadPermRange(const bitCapIntOcl &start, const bitCapIntOcl &length, const bitCapIntOcl &maxQPowerOcl)
Definition: qrack_functions.hpp:67
bool isBadBitRange(const bitLenInt &start, const bitLenInt &length, const bitLenInt &qubitCount)
Definition: qrack_functions.hpp:63
bitCapIntOcl pow2Ocl(const bitLenInt &p)
Definition: qrack_functions.hpp:23
bitCapIntOcl bitSliceOcl(const bitLenInt &bit, const bitCapIntOcl &source)
Definition: qrack_functions.hpp:49
bitLenInt log2(bitCapInt n)
Definition: qrack_functions.hpp:26
half pow(half x, half y)
Power function.
Definition: half.hpp:3738
MICROSOFT_QUANTUM_DECL void U(_In_ uintq sid, _In_ uintq q, _In_ double theta, _In_ double phi, _In_ double lambda)
(External API) 3-parameter unitary gate
Definition: pinvoke_api.cpp:1362
#define bitsInByte
Definition: qrack_types.hpp:144
#define bitLenInt
Definition: qrack_types.hpp:44
#define bitCapInt
Definition: qrack_types.hpp:105
#define bitCapIntOcl
Definition: qrack_types.hpp:91