28 #if ENABLE_CPP_INT && (QBCAPPOW > 6) && BOOST_AVAILABLE
30 #define SparseStateVecMap std::map<bitCapInt, complex>
32 #include <unordered_map>
33 #define SparseStateVecMap std::unordered_map<bitCapInt, complex>
46 class StateVectorArray;
47 class StateVectorSparse;
97 #if defined(__APPLE__)
108 #if defined(__ANDROID__)
109 return std::unique_ptr<complex[], void (*)(complex*)>(
new complex[elemCount], [](
complex* c) {
delete c; });
112 size_t allocSize =
sizeof(
complex) * elemCount;
116 #if defined(__APPLE__)
117 return std::unique_ptr<complex[], void (*)(complex*)>(
118 _aligned_state_vec_alloc(allocSize), [](
complex* c) { free(c); });
119 #elif defined(_WIN32) && !defined(__CYGWIN__)
120 return std::unique_ptr<complex[], void (*)(complex*)>(
123 return std::unique_ptr<complex[], void (*)(complex*)>(
144 #if ENABLE_COMPLEX_X2
155 #if ENABLE_COMPLEX_X2
199 const complex* copyIn = std::dynamic_pointer_cast<StateVectorArray>(copyInSv)->amplitudes.get() + srcOffset;
216 0, length, [&](
const bitCapIntOcl& lcv,
const unsigned& cpu) { copyOut[lcv] =
amplitudes[lcv + offset]; });
234 amplitudes[lcv + offset] = svp->amplitudes[lcv];
235 svp->amplitudes[lcv] = tmp;
261 std::lock_guard<std::mutex> lock(
mtx);
273 #if ENABLE_COMPLEX_X2
300 std::vector<std::pair<real1, bitCapInt>> nrmKeys;
303 nrmKeys.emplace_back(
norm(pair.second), pair.first);
309 std::nth_element(nrmKeys.begin(), nrmKeys.begin() + (nrmKeys.size() - maxAmps), nrmKeys.end(),
310 [](
const auto& a,
const auto& b) { return a.first < b.first; });
313 const real1 limit = nrmKeys[nrmKeys.size() - maxAmps].first;
317 for (
size_t i = nrmKeys.size() - maxAmps; i < nrmKeys.size(); ++i) {
318 fidelity += nrmKeys[i].first;
322 for (
size_t i = 0; i < nrmKeys.size() - maxAmps; ++i) {
328 std::vector<bitCapInt> ties;
330 if (
norm(pair.second) == limit) {
331 ties.push_back(pair.first);
334 std::random_device rd;
335 std::mt19937 g(rd());
336 std::shuffle(ties.begin(), ties.end(), g);
352 #if ENABLE_COMPLEX_X2
366 std::lock_guard<std::mutex> lock(
mtx);
369 std::lock_guard<std::mutex> lock(
mtx);
378 if (!isC1Set && !isC2Set) {
379 std::lock_guard<std::mutex> lock(
mtx);
382 }
else if (isC1Set && isC2Set) {
383 std::lock_guard<std::mutex> lock(
mtx);
386 }
else if (isC1Set) {
387 std::lock_guard<std::mutex> lock(
mtx);
391 std::lock_guard<std::mutex> lock(
mtx);
399 std::lock_guard<std::mutex> lock(
mtx);
410 std::lock_guard<std::mutex> lock(
mtx);
423 std::lock_guard<std::mutex> lock(
mtx);
431 std::lock_guard<std::mutex> lock(
mtx);
447 std::lock_guard<std::mutex> lock(
mtx);
455 std::lock_guard<std::mutex> lock(
mtx);
457 complex amp = copyIn->read(i + srcOffset);
469 copyOut[i] =
read(i);
476 copyOut[i] =
read(i + offset);
484 std::lock_guard<std::mutex> lock(
mtx);
492 const size_t halfCap = (size_t)(
capacity >> 1U);
493 std::lock_guard<std::mutex> lock(
mtx);
496 svp->write(i,
read(i + halfCap));
497 write(i + halfCap, amp);
513 std::vector<std::vector<bitCapInt>>::iterator toRetIt;
517 std::lock_guard<std::mutex> lock(
mtx);
520 auto it = amplitudes.begin();
521 std::advance(it, lcv);
522 toRet[cpu].push_back(it->first);
526 for (int64_t i = (int64_t)(toRet.size() - 1U); i >= 0; i--) {
527 if (toRet[i].empty()) {
528 toRetIt = toRet.begin();
529 std::advance(toRetIt, i);
530 toRet.erase(toRetIt);
538 while (toRet.size() > 1U) {
540 if (toRet.size() & 1U) {
541 toRet[toRet.size() - 2U].insert(
542 toRet[toRet.size() - 2U].end(), toRet[toRet.size() - 1U].begin(), toRet[toRet.size() - 1U].end());
546 const int64_t combineCount = (int64_t)(toRet.size() >> 1U);
548 std::vector<std::future<void>> futures(combineCount);
549 for (int64_t i = (combineCount - 1); i >= 0; i--) {
550 futures[i] = std::async(std::launch::async, [i, combineCount, &toRet]() {
551 toRet[i].insert(toRet[i].end(), toRet[i + combineCount].begin(), toRet[i + combineCount].end());
552 toRet[i + combineCount].clear();
555 for (int64_t i = (combineCount - 1); i >= 0; i--) {
560 for (int64_t i = (combineCount - 1); i >= 0; i--) {
561 toRet[i].insert(toRet[i].end(), toRet[i + combineCount].begin(), toRet[i + combineCount].end());
581 std::vector<std::set<bitCapInt>>::iterator toRetIt;
585 std::lock_guard<std::mutex> lock(
mtx);
589 auto it = amplitudes.begin();
590 std::advance(it, lcv);
591 toRet[cpu].insert(it->first & unsetMask);
594 const bitCapInt unfilterMask = ~filterMask;
596 auto it = amplitudes.begin();
597 std::advance(it, lcv);
598 if ((it->first & filterMask) == filterValues) {
599 toRet[cpu].insert(it->first & unsetMask & unfilterMask);
605 for (int64_t i = (int64_t)(toRet.size() - 1U); i >= 0; i--) {
606 if (toRet[i].empty()) {
607 toRetIt = toRet.begin();
608 std::advance(toRetIt, i);
609 toRet.erase(toRetIt);
617 while (toRet.size() > 1U) {
619 if (toRet.size() & 1U) {
620 toRet[toRet.size() - 2U].insert(toRet[toRet.size() - 1U].begin(), toRet[toRet.size() - 1U].end());
624 const int64_t combineCount = (int64_t)(toRet.size() >> 1U);
626 std::vector<std::future<void>> futures(combineCount);
627 for (int64_t i = (combineCount - 1); i >= 0; i--) {
628 futures[i] = std::async(std::launch::async, [i, combineCount, &toRet]() {
629 toRet[i].insert(toRet[i + combineCount].begin(), toRet[i + combineCount].end());
630 toRet[i + combineCount].clear();
634 for (int64_t i = (combineCount - 1); i >= 0; i--) {
639 for (int64_t i = (combineCount - 1); i >= 0; i--) {
640 toRet[i].insert(toRet[i + combineCount].begin(), toRet[i + combineCount].end());
Definition: parallel_for.hpp:27
unsigned GetConcurrencyLevel()
Definition: parallel_for.hpp:49
void par_for(const bitCapIntOcl begin, const bitCapIntOcl end, ParallelFunc fn)
Call fn once for every numerical value between begin and end.
Definition: parallel_for.cpp:50
Definition: statevector.hpp:92
void copy(StateVectorArrayPtr toCopy)
Definition: statevector.hpp:221
virtual ~StateVectorArray()
Definition: statevector.hpp:139
std::unique_ptr< complex[], void(*)(complex *)> amplitudes
Definition: statevector.hpp:94
complex read(const bitCapIntOcl &i)
Definition: statevector.hpp:153
void write(const bitCapIntOcl &i, const complex &c)
Definition: statevector.hpp:162
void copy_out(complex *copyOut, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:213
void clear()
Definition: statevector.hpp:170
virtual void Free()
Definition: statevector.hpp:129
complex * get_raw()
Definition: statevector.hpp:141
void copy_in(StateVectorPtr copyInSv, const bitCapIntOcl srcOffset, const bitCapIntOcl dstOffset, const bitCapIntOcl length)
Definition: statevector.hpp:195
void get_probs(real1 *outArray)
Definition: statevector.hpp:239
void write2(const bitCapIntOcl &i1, const complex &c1, const bitCapIntOcl &i2, const complex &c2)
Optimized "write" that is only guaranteed to write if either amplitude is nonzero.
Definition: statevector.hpp:164
void copy_out(complex *copyOut)
Definition: statevector.hpp:208
void shuffle(StateVectorArrayPtr svp)
Definition: statevector.hpp:229
void shuffle(StateVectorPtr svp)
Definition: statevector.hpp:227
static std::unique_ptr< complex[], void(*)(complex *)> Alloc(bitCapIntOcl elemCount)
Definition: statevector.hpp:106
bool is_sparse()
Definition: statevector.hpp:245
void copy(StateVectorPtr toCopy)
Definition: statevector.hpp:219
void copy_in(const complex *copyIn, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:184
void copy_in(const complex *copyIn)
Definition: statevector.hpp:175
void write(const bitCapInt &i, const complex &c)
Definition: statevector.hpp:147
StateVectorArray(bitCapIntOcl cap)
Definition: statevector.hpp:132
complex read(const bitCapInt &i)
Definition: statevector.hpp:143
void write2(const bitCapInt &i1, const complex &c1, const bitCapInt &i2, const complex &c2)
Definition: statevector.hpp:148
Definition: statevector.hpp:248
void get_probs(real1 *outArray)
Definition: statevector.hpp:501
void shuffle(StateVectorPtr svp)
Definition: statevector.hpp:488
complex read(const bitCapInt &i)
Definition: statevector.hpp:350
size_t size()
Definition: statevector.hpp:282
std::vector< bitCapInt > iterable()
Definition: statevector.hpp:510
real1_f truncate_to_size(size_t maxAmps)
Definition: statevector.hpp:293
void copy_out(complex *copyOut)
Definition: statevector.hpp:466
void write2(const bitCapInt &i1, const complex &c1, const bitCapInt &i2, const complex &c2)
Definition: statevector.hpp:374
void write2(const bitCapIntOcl &i1, const complex &c1, const bitCapIntOcl &i2, const complex &c2)
Optimized "write" that is only guaranteed to write if either amplitude is nonzero.
Definition: statevector.hpp:277
void write(const bitCapInt &i, const complex &c)
Definition: statevector.hpp:362
void copy_out(complex *copyOut, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:473
void copy_in(const complex *copyIn, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:420
void copy_in(const complex *copyIn)
Definition: statevector.hpp:403
void write(const bitCapIntOcl &i, const complex &c)
Definition: statevector.hpp:276
std::mutex mtx
Definition: statevector.hpp:251
SparseStateVecMap amplitudes
Definition: statevector.hpp:250
StateVectorSparse(bitCapIntOcl cap)
Definition: statevector.hpp:266
complex readUnlocked(const bitCapInt &i)
Definition: statevector.hpp:253
complex read(const bitCapIntOcl &i)
Definition: statevector.hpp:272
void copy_in(StateVectorPtr copyInSv, const bitCapIntOcl srcOffset, const bitCapIntOcl dstOffset, const bitCapIntOcl length)
Definition: statevector.hpp:441
std::set< bitCapInt > iterable(const bitCapInt &setMask, const bitCapInt &filterMask=0, const bitCapInt &filterValues=0)
Returns empty if iteration should be over full set, otherwise just the iterable elements:
Definition: statevector.hpp:571
void copy(StateVectorSparsePtr toCopy)
Definition: statevector.hpp:482
void clear()
Definition: statevector.hpp:397
void mult(real1_f nrm)
Definition: statevector.hpp:284
bool is_sparse()
Definition: statevector.hpp:508
void shuffle(StateVectorSparsePtr svp)
Definition: statevector.hpp:490
complex readLocked(const bitCapInt &i)
Definition: statevector.hpp:259
void copy(const StateVectorPtr toCopy)
Definition: statevector.hpp:480
Definition: statevector.hpp:50
bitCapIntOcl capacity
Definition: statevector.hpp:52
virtual void get_probs(real1 *outArray)=0
virtual void shuffle(StateVectorPtr svp)=0
virtual complex read(const bitCapIntOcl &i)=0
virtual void write(const bitCapIntOcl &i, const complex &c)=0
virtual void copy_out(complex *outArray)=0
virtual void copy_in(const complex *copyIn, const bitCapIntOcl offset, const bitCapIntOcl length)=0
virtual void copy_in(const complex *inArray)=0
virtual void copy_out(complex *copyIn, const bitCapIntOcl offset, const bitCapIntOcl length)=0
virtual void write2(const bitCapIntOcl &i1, const complex &c1, const bitCapIntOcl &i2, const complex &c2)=0
Optimized "write" that is only guaranteed to write if either amplitude is nonzero.
virtual void copy(StateVectorPtr toCopy)=0
virtual void write(const bitCapInt &i, const complex &c)=0
virtual void write2(const bitCapInt &i1, const complex &c1, const bitCapInt &i2, const complex &c2)=0
StateVector(bitCapIntOcl cap)
Definition: statevector.hpp:57
bool isReadLocked
Definition: statevector.hpp:55
virtual void copy_in(StateVectorPtr copyInSv, const bitCapIntOcl srcOffset, const bitCapIntOcl dstOffset, const bitCapIntOcl length)=0
virtual ~StateVector()
Definition: statevector.hpp:62
virtual bool is_sparse()=0
virtual complex read(const bitCapInt &i)=0
Half-precision floating-point type.
Definition: half.hpp:2206
GLOSSARY: bitLenInt - "bit-length integer" - unsigned integer ID of qubit position in register bitCap...
Definition: complex16x2simd.hpp:25
void U(quid sid, bitLenInt q, real1_f theta, real1_f phi, real1_f lambda)
(External API) 3-parameter unitary gate
Definition: wasm_api.cpp:1199
half_float::half real1
Definition: qrack_types.hpp:106
std::complex< real1 > complex
Definition: qrack_types.hpp:140
std::shared_ptr< StateVectorSparse > StateVectorSparsePtr
Definition: qrack_types.hpp:151
double norm(const complex2 &c)
Definition: complex16x2simd.hpp:122
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:203
QRACK_CONST real1 ONE_R1
Definition: qrack_types.hpp:188
QRACK_CONST real1 ZERO_R1
Definition: qrack_types.hpp:186
float real1_f
Definition: qrack_types.hpp:107
std::shared_ptr< StateVectorArray > StateVectorArrayPtr
Definition: qrack_types.hpp:150
float real1_s
Definition: qrack_types.hpp:108
std::shared_ptr< StateVector > StateVectorPtr
Definition: qrack_types.hpp:147
QRACK_CONST complex ZERO_CMPLX
Definition: qrack_types.hpp:258
const bitCapInt ZERO_BCI
Definition: qrack_types.hpp:142
uint32 sqrt(uint32 &r, int &exp)
Fixed point square root.
Definition: half.hpp:1638
HALF_CONSTEXPR half abs(half arg)
Absolute value.
Definition: half.hpp:2958
#define bitCapInt
Definition: qrack_types.hpp:65
#define bitCapIntOcl
Definition: qrack_types.hpp:53
#define ONE_R1_F
Definition: qrack_types.hpp:165
#define QRACK_ALIGN_SIZE
Definition: qrack_types.hpp:159
#define SparseStateVecMap
Definition: statevector.hpp:33
SIMD implementation of the double precision complex vector type of 2 complex numbers,...
Definition: complex16x2simd.hpp:30