26 #include <boost/functional/hash.hpp>
28 #include <unordered_map>
29 #define SparseStateVecMap std::unordered_map<bitCapIntOcl, complex>
41 class StateVectorArray;
42 class StateVectorSparse;
90 #if defined(__APPLE__)
101 #if defined(__ANDROID__)
102 return std::unique_ptr<complex[], void (*)(complex*)>(
new complex[elemCount], [](
complex* c) {
delete c; });
105 size_t allocSize =
sizeof(
complex) * elemCount;
109 #if defined(__APPLE__)
110 return std::unique_ptr<complex[], void (*)(complex*)>(
111 _aligned_state_vec_alloc(allocSize), [](
complex* c) { free(c); });
112 #elif defined(_WIN32) && !defined(__CYGWIN__)
113 return std::unique_ptr<complex[], void (*)(complex*)>(
116 return std::unique_ptr<complex[], void (*)(complex*)>(
136 #if ENABLE_COMPLEX_X2
165 std::copy(copyIn, copyIn + length,
amplitudes.get() + offset);
175 complex const* copyIn = std::dynamic_pointer_cast<StateVectorArray>(copyInSv)->amplitudes.get() + srcOffset;
176 std::copy(copyIn, copyIn + length,
amplitudes.get() + dstOffset);
193 std::copy(toCopy->amplitudes.get(), toCopy->amplitudes.get() +
capacity,
amplitudes.get());
224 std::lock_guard<std::mutex> lock(
mtx);
237 #if ENABLE_COMPLEX_X2
252 SparseStateVecMap::iterator it;
256 std::lock_guard<std::mutex> lock(
mtx);
260 if (isCSet != isFound) {
269 if (isCSet == isFound) {
280 if (!isC1Set && !isC2Set) {
281 std::lock_guard<std::mutex> lock(
mtx);
284 }
else if (isC1Set && isC2Set) {
285 std::lock_guard<std::mutex> lock(
mtx);
288 }
else if (isC1Set) {
289 std::lock_guard<std::mutex> lock(
mtx);
293 std::lock_guard<std::mutex> lock(
mtx);
301 std::lock_guard<std::mutex> lock(
mtx);
312 std::lock_guard<std::mutex> lock(
mtx);
325 std::lock_guard<std::mutex> lock(
mtx);
333 std::lock_guard<std::mutex> lock(
mtx);
349 std::lock_guard<std::mutex> lock(
mtx);
357 std::lock_guard<std::mutex> lock(
mtx);
359 complex amp = copyIn->read(i + srcOffset);
371 copyOut[i] =
read(i);
378 copyOut[i] =
read(i + offset);
386 std::lock_guard<std::mutex> lock(
mtx);
395 std::lock_guard<std::mutex> lock(
mtx);
398 svp->write(i,
read(i + halfCap));
399 write(i + halfCap, amp);
415 std::vector<std::vector<bitCapIntOcl>>::iterator toRetIt;
419 std::lock_guard<std::mutex> lock(
mtx);
422 auto it = amplitudes.begin();
423 std::advance(it, lcv);
424 toRet[cpu].push_back(it->first);
428 for (int64_t i = (int64_t)(toRet.size() - 1U); i >= 0; i--) {
429 if (!toRet[i].size()) {
430 toRetIt = toRet.begin();
431 std::advance(toRetIt, i);
432 toRet.erase(toRetIt);
440 while (toRet.size() > 1U) {
442 if (toRet.size() & 1U) {
443 toRet[toRet.size() - 2U].insert(
444 toRet[toRet.size() - 2U].end(), toRet[toRet.size() - 1U].begin(), toRet[toRet.size() - 1U].end());
448 const int64_t combineCount = (int64_t)(toRet.size() >> 1U);
450 std::vector<std::future<void>> futures(combineCount);
451 for (int64_t i = (combineCount - 1); i >= 0; i--) {
452 futures[i] = std::async(std::launch::async, [i, combineCount, &toRet]() {
453 toRet[i].insert(toRet[i].end(), toRet[i + combineCount].begin(), toRet[i + combineCount].end());
454 toRet[i + combineCount].clear();
457 for (int64_t i = (combineCount - 1); i >= 0; i--) {
462 for (int64_t i = (combineCount - 1); i >= 0; i--) {
463 toRet[i].insert(toRet[i].end(), toRet[i + combineCount].begin(), toRet[i + combineCount].end());
476 if (!filterMask && filterValues) {
483 std::vector<std::set<bitCapIntOcl>>::iterator toRetIt;
487 std::lock_guard<std::mutex> lock(
mtx);
489 if (!filterMask && !filterValues) {
491 auto it = amplitudes.begin();
492 std::advance(it, lcv);
493 toRet[cpu].insert(it->first & unsetMask);
498 auto it = amplitudes.begin();
499 std::advance(it, lcv);
500 if ((it->first & filterMask) == filterValues) {
501 toRet[cpu].insert(it->first & unsetMask & unfilterMask);
507 for (int64_t i = (int64_t)(toRet.size() - 1U); i >= 0; i--) {
508 if (!toRet[i].size()) {
509 toRetIt = toRet.begin();
510 std::advance(toRetIt, i);
511 toRet.erase(toRetIt);
519 while (toRet.size() > 1U) {
521 if (toRet.size() & 1U) {
522 toRet[toRet.size() - 2U].insert(toRet[toRet.size() - 1U].begin(), toRet[toRet.size() - 1U].end());
526 const int64_t combineCount = (int64_t)(toRet.size() >> 1U);
528 std::vector<std::future<void>> futures(combineCount);
529 for (int64_t i = (combineCount - 1); i >= 0; i--) {
530 futures[i] = std::async(std::launch::async, [i, combineCount, &toRet]() {
531 toRet[i].insert(toRet[i + combineCount].begin(), toRet[i + combineCount].end());
532 toRet[i + combineCount].clear();
536 for (int64_t i = (combineCount - 1); i >= 0; i--) {
541 for (int64_t i = (combineCount - 1); i >= 0; i--) {
542 toRet[i].insert(toRet[i + combineCount].begin(), toRet[i + combineCount].end());
Definition: parallel_for.hpp:19
unsigned GetConcurrencyLevel()
Definition: parallel_for.hpp:38
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:51
Definition: statevector.hpp:83
std::unique_ptr< complex[], void(*)(complex *)> Alloc(bitCapIntOcl elemCount)
Definition: statevector.hpp:99
void copy(StateVectorArrayPtr toCopy)
Definition: statevector.hpp:191
virtual ~StateVectorArray()
Definition: statevector.hpp:132
std::unique_ptr< complex[], void(*)(complex *)> amplitudes
Definition: statevector.hpp:85
complex read(const bitCapIntOcl &i)
Definition: statevector.hpp:134
void write(const bitCapIntOcl &i, const complex &c)
Definition: statevector.hpp:143
void copy_out(complex *copyOut, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:184
static real1_f normHelper(const complex &c)
Definition: statevector.hpp:88
void clear()
Definition: statevector.hpp:151
virtual void Free()
Definition: statevector.hpp:122
void copy_in(StateVectorPtr copyInSv, const bitCapIntOcl srcOffset, const bitCapIntOcl dstOffset, const bitCapIntOcl length)
Definition: statevector.hpp:171
void get_probs(real1 *outArray)
Definition: statevector.hpp:203
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:145
void copy_out(complex *copyOut)
Definition: statevector.hpp:182
void shuffle(StateVectorArrayPtr svp)
Definition: statevector.hpp:198
void shuffle(StateVectorPtr svp)
Definition: statevector.hpp:196
bool is_sparse()
Definition: statevector.hpp:208
void copy(StateVectorPtr toCopy)
Definition: statevector.hpp:189
void copy_in(complex const *copyIn)
Definition: statevector.hpp:153
void copy_in(complex const *copyIn, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:162
StateVectorArray(bitCapIntOcl cap)
Definition: statevector.hpp:125
Definition: statevector.hpp:211
void get_probs(real1 *outArray)
Definition: statevector.hpp:403
void shuffle(StateVectorPtr svp)
Definition: statevector.hpp:390
complex readLocked(const bitCapIntOcl &i)
Definition: statevector.hpp:222
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:473
std::vector< bitCapIntOcl > iterable()
Definition: statevector.hpp:412
void copy_out(complex *copyOut)
Definition: statevector.hpp:368
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:276
void copy_out(complex *copyOut, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:375
void write(const bitCapIntOcl &i, const complex &c)
Definition: statevector.hpp:247
std::mutex mtx
Definition: statevector.hpp:214
void copy_in(complex const *copyIn)
Definition: statevector.hpp:305
SparseStateVecMap amplitudes
Definition: statevector.hpp:213
StateVectorSparse(bitCapIntOcl cap)
Definition: statevector.hpp:229
complex read(const bitCapIntOcl &i)
Definition: statevector.hpp:235
complex readUnlocked(const bitCapIntOcl &i)
Definition: statevector.hpp:216
void copy_in(StateVectorPtr copyInSv, const bitCapIntOcl srcOffset, const bitCapIntOcl dstOffset, const bitCapIntOcl length)
Definition: statevector.hpp:343
void copy_in(complex const *copyIn, const bitCapIntOcl offset, const bitCapIntOcl length)
Definition: statevector.hpp:322
void copy(StateVectorSparsePtr toCopy)
Definition: statevector.hpp:384
void clear()
Definition: statevector.hpp:299
bool is_sparse()
Definition: statevector.hpp:410
void shuffle(StateVectorSparsePtr svp)
Definition: statevector.hpp:392
void copy(const StateVectorPtr toCopy)
Definition: statevector.hpp:382
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(complex const *copyIn, const bitCapIntOcl offset, const bitCapIntOcl length)=0
virtual void copy_in(complex const *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
Definition: complex16x2simd.hpp:25
constexpr uint8_t ONE_BCI
Definition: qrack_types.hpp:90
std::complex< half_float::half > complex
Definition: qrack_types.hpp:62
std::shared_ptr< StateVectorSparse > StateVectorSparsePtr
Definition: qrack_types.hpp:137
double norm(const complex2 &c)
Definition: complex16x2simd.hpp:101
float real1_f
Definition: qrack_types.hpp:64
std::shared_ptr< StateVectorArray > StateVectorArrayPtr
Definition: qrack_types.hpp:136
std::shared_ptr< StateVector > StateVectorPtr
Definition: qrack_types.hpp:133
const real1 REAL1_EPSILON
Definition: qrack_types.hpp:157
QRACK_CONST complex ZERO_CMPLX
Definition: qrack_types.hpp:240
HALF_CONSTEXPR half abs(half arg)
Absolute value.
Definition: half.hpp:2975
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 bitCapIntOcl
Definition: qrack_types.hpp:91
#define QRACK_ALIGN_SIZE
Definition: qrack_types.hpp:147
#define SparseStateVecMap
Definition: statevector.hpp:29
SIMD implementation of the double precision complex vector type of 2 complex numbers,...
Definition: complex16x2simd.hpp:30