28 #include <unordered_map>
29 #define SparseStateVecMap std::unordered_map<bitCapIntOcl, complex>
41 class StateVectorArray;
42 class StateVectorSparse;
88 #if defined(__APPLE__)
99 #if defined(__ANDROID__)
100 return std::unique_ptr<complex[], void (*)(complex*)>(
new complex[elemCount], [](
complex* c) {
delete c; });
103 size_t allocSize =
sizeof(
complex) * elemCount;
107 #if defined(__APPLE__)
108 return std::unique_ptr<complex[], void (*)(complex*)>(
109 _aligned_state_vec_alloc(allocSize), [](
complex* c) { free(c); });
110 #elif defined(_WIN32) && !defined(__CYGWIN__)
111 return std::unique_ptr<complex[], void (*)(complex*)>(
114 return std::unique_ptr<complex[], void (*)(complex*)>(
134 #if ENABLE_COMPLEX_X2
178 const complex* copyIn = std::dynamic_pointer_cast<StateVectorArray>(copyInSv)->amplitudes.get() + srcOffset;
195 0, length, [&](
const bitCapIntOcl& lcv,
const unsigned& cpu) { copyOut[lcv] =
amplitudes[lcv + offset]; });
213 amplitudes[lcv + offset] = svp->amplitudes[lcv];
214 svp->amplitudes[lcv] = tmp;
240 std::lock_guard<std::mutex> lock(
mtx);
267 std::multiset<real1> nrms;
270 if (nrms.size() < maxAmps) {
272 }
else if (*(nrms.begin()) < nrm) {
273 nrms.erase(nrms.begin());
278 const real1 limit = *(nrms.begin());
279 const real1 fidelity = std::accumulate(nrms.begin(), nrms.end(),
ZERO_R1);
285 if (
norm(it->second) >= limit) {
286 nAmplitudes[it->first] = it->second;
294 std::vector<bitCapIntOcl> indices;
296 if (
norm(it->second) == limit) {
297 indices.push_back(it->first);
300 std::random_device rd;
301 std::mt19937 g(rd());
302 std::shuffle(indices.begin(), indices.end(), g);
317 #if ENABLE_COMPLEX_X2
331 std::lock_guard<std::mutex> lock(
mtx);
334 std::lock_guard<std::mutex> lock(
mtx);
343 if (!isC1Set && !isC2Set) {
344 std::lock_guard<std::mutex> lock(
mtx);
347 }
else if (isC1Set && isC2Set) {
348 std::lock_guard<std::mutex> lock(
mtx);
351 }
else if (isC1Set) {
352 std::lock_guard<std::mutex> lock(
mtx);
356 std::lock_guard<std::mutex> lock(
mtx);
364 std::lock_guard<std::mutex> lock(
mtx);
375 std::lock_guard<std::mutex> lock(
mtx);
388 std::lock_guard<std::mutex> lock(
mtx);
396 std::lock_guard<std::mutex> lock(
mtx);
412 std::lock_guard<std::mutex> lock(
mtx);
420 std::lock_guard<std::mutex> lock(
mtx);
422 complex amp = copyIn->read(i + srcOffset);
434 copyOut[i] =
read(i);
441 copyOut[i] =
read(i + offset);
449 std::lock_guard<std::mutex> lock(
mtx);
457 const size_t halfCap = (size_t)(
capacity >> 1U);
458 std::lock_guard<std::mutex> lock(
mtx);
461 svp->write(i,
read(i + halfCap));
462 write(i + halfCap, amp);
478 std::vector<std::vector<bitCapIntOcl>>::iterator toRetIt;
482 std::lock_guard<std::mutex> lock(
mtx);
485 auto it = amplitudes.begin();
486 std::advance(it, lcv);
487 toRet[cpu].push_back(it->first);
491 for (int64_t i = (int64_t)(toRet.size() - 1U); i >= 0; i--) {
492 if (toRet[i].empty()) {
493 toRetIt = toRet.begin();
494 std::advance(toRetIt, i);
495 toRet.erase(toRetIt);
503 while (toRet.size() > 1U) {
505 if (toRet.size() & 1U) {
506 toRet[toRet.size() - 2U].insert(
507 toRet[toRet.size() - 2U].end(), toRet[toRet.size() - 1U].begin(), toRet[toRet.size() - 1U].end());
511 const int64_t combineCount = (int64_t)(toRet.size() >> 1U);
513 std::vector<std::future<void>> futures(combineCount);
514 for (int64_t i = (combineCount - 1); i >= 0; i--) {
515 futures[i] = std::async(std::launch::async, [i, combineCount, &toRet]() {
516 toRet[i].insert(toRet[i].end(), toRet[i + combineCount].begin(), toRet[i + combineCount].end());
517 toRet[i + combineCount].clear();
520 for (int64_t i = (combineCount - 1); i >= 0; i--) {
525 for (int64_t i = (combineCount - 1); i >= 0; i--) {
526 toRet[i].insert(toRet[i].end(), toRet[i + combineCount].begin(), toRet[i + combineCount].end());
539 if (!filterMask && filterValues) {
546 std::vector<std::set<bitCapIntOcl>>::iterator toRetIt;
550 std::lock_guard<std::mutex> lock(
mtx);
552 if (!filterMask && !filterValues) {
554 auto it = amplitudes.begin();
555 std::advance(it, lcv);
556 toRet[cpu].insert(it->first & unsetMask);
561 auto it = amplitudes.begin();
562 std::advance(it, lcv);
563 if ((it->first & filterMask) == filterValues) {
564 toRet[cpu].insert(it->first & unsetMask & unfilterMask);
570 for (int64_t i = (int64_t)(toRet.size() - 1U); i >= 0; i--) {
571 if (toRet[i].empty()) {
572 toRetIt = toRet.begin();
573 std::advance(toRetIt, i);
574 toRet.erase(toRetIt);
582 while (toRet.size() > 1U) {
584 if (toRet.size() & 1U) {
585 toRet[toRet.size() - 2U].insert(toRet[toRet.size() - 1U].begin(), toRet[toRet.size() - 1U].end());
589 const int64_t combineCount = (int64_t)(toRet.size() >> 1U);
591 std::vector<std::future<void>> futures(combineCount);
592 for (int64_t i = (combineCount - 1); i >= 0; i--) {
593 futures[i] = std::async(std::launch::async, [i, combineCount, &toRet]() {
594 toRet[i].insert(toRet[i + combineCount].begin(), toRet[i + combineCount].end());
595 toRet[i + combineCount].clear();
599 for (int64_t i = (combineCount - 1); i >= 0; i--) {
604 for (int64_t i = (combineCount - 1); i >= 0; i--) {
605 toRet[i].insert(toRet[i + combineCount].begin(), toRet[i + combineCount].end());
Definition: parallel_for.hpp:19
unsigned GetConcurrencyLevel()
Definition: parallel_for.hpp:41
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:83
std::unique_ptr< complex[], void(*)(complex *)> Alloc(bitCapIntOcl elemCount)
Definition: statevector.hpp:97
void copy(StateVectorArrayPtr toCopy)
Definition: statevector.hpp:200
virtual ~StateVectorArray()
Definition: statevector.hpp:130
std::unique_ptr< complex[], void(*)(complex *)> amplitudes
Definition: statevector.hpp:85
complex read(const bitCapIntOcl &i)
Definition: statevector.hpp:132
void write(const bitCapIntOcl &i, const complex &c)
Definition: statevector.hpp:141
void copy_out(complex *copyOut, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:192
void clear()
Definition: statevector.hpp:149
virtual void Free()
Definition: statevector.hpp:120
void copy_in(StateVectorPtr copyInSv, const bitCapIntOcl srcOffset, const bitCapIntOcl dstOffset, const bitCapIntOcl length)
Definition: statevector.hpp:174
void get_probs(real1 *outArray)
Definition: statevector.hpp:218
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:143
void copy_out(complex *copyOut)
Definition: statevector.hpp:187
void shuffle(StateVectorArrayPtr svp)
Definition: statevector.hpp:208
void shuffle(StateVectorPtr svp)
Definition: statevector.hpp:206
bool is_sparse()
Definition: statevector.hpp:224
void copy(StateVectorPtr toCopy)
Definition: statevector.hpp:198
void copy_in(const complex *copyIn, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:163
void copy_in(const complex *copyIn)
Definition: statevector.hpp:154
StateVectorArray(bitCapIntOcl cap)
Definition: statevector.hpp:123
Definition: statevector.hpp:227
void get_probs(real1 *outArray)
Definition: statevector.hpp:466
void shuffle(StateVectorPtr svp)
Definition: statevector.hpp:453
complex readLocked(const bitCapIntOcl &i)
Definition: statevector.hpp:238
size_t size()
Definition: statevector.hpp:251
std::set< bitCapIntOcl > iterable(const bitCapIntOcl &setMask, const bitCapIntOcl &filterMask=0, const bitCapIntOcl &filterValues=0)
Returns empty if iteration should be over full set, otherwise just the iterable elements:
Definition: statevector.hpp:536
std::vector< bitCapIntOcl > iterable()
Definition: statevector.hpp:475
real1_f truncate_to_size(size_t maxAmps)
Definition: statevector.hpp:261
void copy_out(complex *copyOut)
Definition: statevector.hpp:431
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:339
void copy_out(complex *copyOut, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:438
void copy_in(const complex *copyIn, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:385
void copy_in(const complex *copyIn)
Definition: statevector.hpp:368
void write(const bitCapIntOcl &i, const complex &c)
Definition: statevector.hpp:327
std::mutex mtx
Definition: statevector.hpp:230
SparseStateVecMap amplitudes
Definition: statevector.hpp:229
StateVectorSparse(bitCapIntOcl cap)
Definition: statevector.hpp:245
complex read(const bitCapIntOcl &i)
Definition: statevector.hpp:315
complex readUnlocked(const bitCapIntOcl &i)
Definition: statevector.hpp:232
void copy_in(StateVectorPtr copyInSv, const bitCapIntOcl srcOffset, const bitCapIntOcl dstOffset, const bitCapIntOcl length)
Definition: statevector.hpp:406
void copy(StateVectorSparsePtr toCopy)
Definition: statevector.hpp:447
void clear()
Definition: statevector.hpp:362
void mult(real1_f nrm)
Definition: statevector.hpp:253
bool is_sparse()
Definition: statevector.hpp:473
void shuffle(StateVectorSparsePtr svp)
Definition: statevector.hpp:455
void copy(const StateVectorPtr toCopy)
Definition: statevector.hpp:445
Definition: statevector.hpp:45
bitCapIntOcl capacity
Definition: statevector.hpp:47
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
StateVector(bitCapIntOcl cap)
Definition: statevector.hpp:52
bool isReadLocked
Definition: statevector.hpp:50
virtual void copy_in(StateVectorPtr copyInSv, const bitCapIntOcl srcOffset, const bitCapIntOcl dstOffset, const bitCapIntOcl length)=0
virtual ~StateVector()
Definition: statevector.hpp:57
virtual bool is_sparse()=0
Half-precision floating-point type.
Definition: half.hpp:2222
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:102
std::complex< real1 > complex
Definition: qrack_types.hpp:136
std::shared_ptr< StateVectorSparse > StateVectorSparsePtr
Definition: qrack_types.hpp:155
double norm(const complex2 &c)
Definition: complex16x2simd.hpp:122
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:208
QRACK_CONST real1 ONE_R1
Definition: qrack_types.hpp:193
QRACK_CONST real1 ZERO_R1
Definition: qrack_types.hpp:191
float real1_f
Definition: qrack_types.hpp:103
std::shared_ptr< StateVectorArray > StateVectorArrayPtr
Definition: qrack_types.hpp:154
float real1_s
Definition: qrack_types.hpp:104
std::shared_ptr< StateVector > StateVectorPtr
Definition: qrack_types.hpp:151
QRACK_CONST complex ZERO_CMPLX
Definition: qrack_types.hpp:263
uint32 sqrt(uint32 &r, int &exp)
Fixed point square root.
Definition: half.hpp:1654
HALF_CONSTEXPR half abs(half arg)
Absolute value.
Definition: half.hpp:2975
#define bitCapIntOcl
Definition: qrack_types.hpp:54
#define ONE_R1_F
Definition: qrack_types.hpp:171
#define QRACK_ALIGN_SIZE
Definition: qrack_types.hpp:165
#define SparseStateVecMap
Definition: statevector.hpp:29
SIMD implementation of the double precision complex vector type of 2 complex numbers,...
Definition: complex16x2simd.hpp:30