36 #if ENABLE_OPENCL || ENABLE_CUDA
58 if (m.find(target) != m.end()) {
60 circuit.push_back(std::make_shared<QCircuit>());
66 for (
size_t j = 0
U; j < controls.size(); ++j) {
67 if (m.find(controls[j]) != m.end()) {
69 circuit.push_back(std::make_shared<QCircuit>());
83 throw std::invalid_argument(
"QTensorNetwork qubit index values must be within allocated qubit bounds!");
91 controls,
qubitCount,
"QTensorNetwork qubit index values must be within allocated qubit bounds!");
96 const std::map<bitLenInt, bool>& mLayer =
measurements[layerId];
97 std::vector<bitLenInt> bits;
98 bits.reserve(mLayer.size());
99 std::vector<bool> values;
100 values.reserve(mLayer.size());
102 for (
const auto& m : mLayer) {
103 bits.push_back(m.first);
104 values.push_back(m.second);
112 void MakeLayerStack(std::set<bitLenInt> qubits = std::set<bitLenInt>());
114 template <
typename Fn>
void RunAsAmplitudes(Fn fn,
const std::set<bitLenInt>& qubits = std::set<bitLenInt>())
116 if (qubits.empty()) {
135 throw std::domain_error(
"Can't TryDecompose() on QTensorNetwork! (QTensorNetwork does not allow Schmidt "
136 "decomposition in general!)");
142 bool randomGlobalPhase =
true,
bool useHostMem =
false, int64_t deviceId = -1,
bool useHardwareRNG =
true,
143 bool useSparseStateVec =
false,
real1_f norm_thresh =
REAL1_EPSILON, std::vector<int64_t> ignored = {},
148 bool useHostMem =
false, int64_t deviceId = -1,
bool useHardwareRNG =
true,
bool useSparseStateVec =
false,
151 :
QTensorNetwork({}, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase, useHostMem, deviceId,
152 useHardwareRNG, useSparseStateVec, norm_thresh, devList, qubitThreshold, separation_thresh)
200 layerStack->NormalizeState(nrm, norm_thresh, phaseArg);
206 return SumSqrDiff(std::dynamic_pointer_cast<QTensorNetwork>(toCompare));
211 toCompare->MakeLayerStack();
222 circuit.push_back(std::make_shared<QCircuit>());
248 throw std::domain_error(
"QTensorNetwork::SetQuantumState() not implemented!");
252 throw std::domain_error(
"QTensorNetwork::SetQuantumState() not implemented!");
267 throw std::domain_error(
"QTensorNetwork::SetAmplitude() not implemented!");
273 throw std::domain_error(
"QTensorNetwork::Compose() not implemented!");
277 throw std::domain_error(
"QTensorNetwork::Decompose() not implemented!");
281 throw std::domain_error(
"QTensorNetwork::Decompose() not implemented!");
285 throw std::domain_error(
"QTensorNetwork::Dispose() not implemented!");
289 throw std::domain_error(
"QTensorNetwork::Dispose() not implemented!");
296 throw std::invalid_argument(
"QTensorNetwork::Allocate() 'start' argument is out-of-bounds!");
309 for (
bitLenInt i = 0
U; i < movedQubits; ++i) {
310 const bitLenInt q = start + movedQubits - (i + 1U);
330 bool ForceM(
bitLenInt qubit,
bool result,
bool doForce =
true,
bool doApply =
true);
355 std::map<bitCapInt, int> toRet;
357 std::set<bitLenInt> qubits;
359 qubits.insert(
log2(qPow));
363 std::vector<bitLenInt> qubits;
364 qubits.reserve(qPowers.size());
366 qubits.push_back(
log2(qPow));
368 #if ENABLE_QBDT && !ENABLE_QBDT_CPU_PARALLEL
374 for (
size_t i = 0
U; i < qubits.size(); ++i) {
375 if (clone->M(qubits[i])) {
379 std::lock_guard<std::mutex> mapLock(mapMtx);
386 for (
unsigned shot = 0
U; shot < shots; ++shot) {
389 for (
size_t i = 0
U; i < qubits.size(); ++i) {
390 if (clone->M(qubits[i])) {
400 void MultiShotMeasureMask(
const std::vector<bitCapInt>& qPowers,
unsigned shots,
unsigned long long* shotsArray)
402 std::map<bitCapInt, int> toRet;
404 std::set<bitLenInt> qubits;
406 qubits.insert(
log2(qPow));
410 std::vector<bitLenInt> qubits;
411 qubits.reserve(qPowers.size());
413 qubits.push_back(
log2(qPow));
415 #if ENABLE_QBDT && !ENABLE_QBDT_CPU_PARALLEL
420 for (
size_t i = 0
U; i < qubits.size(); ++i) {
421 if (clone->M(qubits[i])) {
430 for (
unsigned shot = 0
U; shot < shots; ++shot) {
433 for (
size_t i = 0
U; i < qubits.size(); ++i) {
434 if (clone->M(qubits[i])) {
447 GetCircuit(target)->AppendGate(std::make_shared<QCircuitGate>(target, mtrx));
456 ->AppendGate(std::make_shared<QCircuitGate>(
457 target, mtrx, std::set<bitLenInt>{ controls.begin(), controls.end() }, m));
464 ->AppendGate(std::make_shared<QCircuitGate>(
465 target, mtrx, std::set<bitLenInt>{ controls.begin(), controls.end() },
ZERO_BCI));
472 std::shared_ptr<complex> lMtrx(
new complex[4U], std::default_delete<
complex[]>());
473 lMtrx.get()[0
U] = topLeft;
476 lMtrx.get()[3U] = bottomRight;
480 ->AppendGate(std::make_shared<QCircuitGate>(
481 target, lMtrx.get(), std::set<bitLenInt>{ controls.begin(), controls.end() }, m));
488 std::shared_ptr<complex> lMtrx(
new complex[4U], std::default_delete<
complex[]>());
489 lMtrx.get()[0
U] = topLeft;
492 lMtrx.get()[3U] = bottomRight;
494 ->AppendGate(std::make_shared<QCircuitGate>(
495 target, lMtrx.get(), std::set<bitLenInt>{ controls.begin(), controls.end() },
ZERO_BCI));
502 std::shared_ptr<complex> lMtrx(
new complex[4U], std::default_delete<
complex[]>());
504 lMtrx.get()[1U] = topRight;
505 lMtrx.get()[2U] = bottomLeft;
510 ->AppendGate(std::make_shared<QCircuitGate>(
511 target, lMtrx.get(), std::set<bitLenInt>{ controls.begin(), controls.end() }, m));
518 std::shared_ptr<complex> lMtrx(
new complex[4U], std::default_delete<
complex[]>());
520 lMtrx.get()[1U] = topRight;
521 lMtrx.get()[2U] = bottomLeft;
524 ->AppendGate(std::make_shared<QCircuitGate>(
525 target, lMtrx.get(), std::set<bitLenInt>{ controls.begin(), controls.end() },
ZERO_BCI));
541 if (
Rand() < lambda) {
544 if (
Rand() < lambda) {
547 if (
Rand() < lambda) {
void bi_or_ip(BigInteger *left, const BigInteger &right)
Definition: big_integer.hpp:429
void bi_decrement(BigInteger *pBigInt, const BIG_INTEGER_WORD &value)
Definition: big_integer.hpp:229
int bi_compare_0(const BigInteger &left)
Definition: big_integer.hpp:134
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
A "Qrack::QInterface" is an abstract interface exposing qubit permutation state vector with methods t...
Definition: qinterface.hpp:141
virtual bitLenInt Allocate(bitLenInt length)
Allocate new "length" count of |0> state qubits at end of qubit index position.
Definition: qinterface.hpp:470
virtual bitLenInt Compose(QInterfacePtr toCopy)
Combine another QInterface with this one, after the last bit index of this one.
Definition: qinterface.hpp:364
bool randGlobalPhase
Definition: qinterface.hpp:144
virtual void SetQubitCount(bitLenInt qb)
Definition: qinterface.hpp:268
bitLenInt qubitCount
Definition: qinterface.hpp:146
real1_f Rand()
Generate a random real number between 0 and 1.
Definition: qinterface.hpp:286
Definition: qtensornetwork.hpp:29
void GetProbs(real1 *outputProbs)
Get the pure quantum state representation.
Definition: qtensornetwork.hpp:254
bitLenInt GetThresholdQb()
Definition: qtensornetwork.cpp:109
QTensorNetwork(bitLenInt qBitCount, const bitCapInt &initState=ZERO_BCI, qrack_rand_gen_ptr rgp=nullptr, const complex &phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool randomGlobalPhase=true, bool useHostMem=false, int64_t deviceId=-1, bool useHardwareRNG=true, bool useSparseStateVec=false, real1_f norm_thresh=REAL1_EPSILON, std::vector< int64_t > devList={}, bitLenInt qubitThreshold=0U, real1_f separation_thresh=_qrack_qunit_sep_thresh)
Definition: qtensornetwork.hpp:146
bool useTGadget
Definition: qtensornetwork.hpp:34
void SetQuantumState(const complex *state)
Set an arbitrary pure quantum state representation.
Definition: qtensornetwork.hpp:246
void Decompose(bitLenInt start, QInterfacePtr dest)
Minimally decompose a set of contiguous bits from the separably composed unit, into "destination".
Definition: qtensornetwork.hpp:275
bool isSparse
Definition: qtensornetwork.hpp:32
void MCMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary control bits.
Definition: qtensornetwork.hpp:449
bool useHostRam
Definition: qtensornetwork.hpp:31
QCircuitPtr GetCircuit(bitLenInt target, std::vector< bitLenInt > controls=std::vector< bitLenInt >())
Definition: qtensornetwork.hpp:51
void CheckQubitCount(bitLenInt target)
Definition: qtensornetwork.hpp:80
real1_f Prob(bitLenInt qubit)
Direct measure of bit probability to be in |1> state.
Definition: qtensornetwork.hpp:317
void MCInvert(const std::vector< bitLenInt > &controls, const complex &topRight, const complex &bottomLeft, bitLenInt target)
Apply a single bit transformation that reverses bit probability and might effect phase,...
Definition: qtensornetwork.hpp:497
void MCPhase(const std::vector< bitLenInt > &controls, const complex &topLeft, const complex &bottomRight, bitLenInt target)
Apply a single bit transformation that only effects phase, with arbitrary control bits.
Definition: qtensornetwork.hpp:467
QInterfacePtr Clone()
Clone this QInterface.
Definition: qtensornetwork.cpp:197
void Mtrx(const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation.
Definition: qtensornetwork.hpp:443
bool isReactiveSeparate
Definition: qtensornetwork.hpp:33
bitLenInt Allocate(bitLenInt start, bitLenInt length)
Allocate new "length" count of |0> state qubits at specified qubit index start position.
Definition: qtensornetwork.hpp:293
real1_f SumSqrDiff(QInterfacePtr toCompare)
Calculates (1 - <\psi_e|\psi_c>) between states |\psi_c> and |\psi_e>.
Definition: qtensornetwork.hpp:204
void MACPhase(const std::vector< bitLenInt > &controls, const complex &topLeft, const complex &bottomRight, bitLenInt target)
Apply a single bit transformation that only effects phase, with arbitrary (anti-)control bits.
Definition: qtensornetwork.hpp:483
bool isNearClifford
Definition: qtensornetwork.hpp:35
void Copy(QInterfacePtr orig)
Definition: qtensornetwork.hpp:133
void MACInvert(const std::vector< bitLenInt > &controls, const complex &topRight, const complex &bottomLeft, bitLenInt target)
Apply a single bit transformation that reverses bit probability and might effect phase,...
Definition: qtensornetwork.hpp:513
std::map< bitCapInt, int > MultiShotMeasureMask(const std::vector< bitCapInt > &qPowers, unsigned shots)
Statistical measure of masked permutation probability.
Definition: qtensornetwork.hpp:353
void FSim(real1_f theta, real1_f phi, bitLenInt qubit1, bitLenInt qubit2)
The 2-qubit "fSim" gate, (useful in the simulation of particles with fermionic statistics)
Definition: qtensornetwork.cpp:326
complex globalPhase
Definition: qtensornetwork.hpp:44
complex GetAmplitude(const bitCapInt &perm)
Get the representational amplitude of a full permutation.
Definition: qtensornetwork.hpp:259
real1_f ProbAll(const bitCapInt &fullRegister)
Direct measure of full permutation probability.
Definition: qtensornetwork.hpp:323
void GetQuantumState(complex *state)
Get the pure quantum state representation.
Definition: qtensornetwork.hpp:242
void SetPermutation(const bitCapInt &initState, const complex &phaseFac=CMPLX_DEFAULT_ARG)
Set to a specific permutation of all qubits.
Definition: qtensornetwork.hpp:216
void SetAmplitude(const bitCapInt &perm, const complex &)
Sets the representational amplitude of a full permutation.
Definition: qtensornetwork.hpp:265
void DepolarizingChannelWeak1Qb(bitLenInt qubit, real1_f lambda)
Simulate a local qubit depolarizing noise channel, under a stochastic "weak simulation condition....
Definition: qtensornetwork.hpp:530
QInterfacePtr Decompose(bitLenInt start, bitLenInt length)
Schmidt decompose a length of qubits.
Definition: qtensornetwork.hpp:279
int64_t devID
Definition: qtensornetwork.hpp:42
void NormalizeState(real1_f nrm=REAL1_DEFAULT_ARG, real1_f norm_thresh=REAL1_DEFAULT_ARG, real1_f phaseArg=ZERO_R1_F)
Apply the normalization factor found by UpdateRunningNorm() or on the fly by a single bit gate.
Definition: qtensornetwork.hpp:196
void SetDevice(int64_t dID)
Set the device index, if more than one device is available.
Definition: qtensornetwork.hpp:171
void CheckQubitCount(bitLenInt target, const std::vector< bitLenInt > &controls)
Definition: qtensornetwork.hpp:87
void SetQuantumState(QInterfacePtr eng)
Definition: qtensornetwork.hpp:250
std::vector< std::map< bitLenInt, bool > > measurements
Definition: qtensornetwork.hpp:49
void SetReactiveSeparate(bool isAggSep)
Set reactive separation option (on by default if available)
Definition: qtensornetwork.hpp:162
void SetSdrp(real1_f sdrp)
Set the "Schmidt decomposition rounding parameter" value, (between 0 and 1)
Definition: qtensornetwork.hpp:156
real1_f separabilityThreshold
Definition: qtensornetwork.hpp:43
double GetUnitaryFidelity()
When "Schmidt-decomposition rounding parameter" ("SDRP") is being used, starting from initial 1....
Definition: qtensornetwork.hpp:164
void MultiShotMeasureMask(const std::vector< bitCapInt > &qPowers, unsigned shots, unsigned long long *shotsArray)
Statistical measure of masked permutation probability (returned as array)
Definition: qtensornetwork.hpp:400
bitLenInt Compose(QInterfacePtr toCopy, bitLenInt start)
Compose() a QInterface peer, inserting its qubit into index order at start index.
Definition: qtensornetwork.hpp:271
void RunMeasurmentLayer(size_t layerId)
Definition: qtensornetwork.hpp:94
std::vector< int64_t > deviceIDs
Definition: qtensornetwork.hpp:46
void MakeLayerStack(std::set< bitLenInt > qubits=std::set< bitLenInt >())
Definition: qtensornetwork.cpp:147
QTensorNetwork(std::vector< QInterfaceEngine > eng, bitLenInt qBitCount, const bitCapInt &initState=ZERO_BCI, qrack_rand_gen_ptr rgp=nullptr, const complex &phaseFac=CMPLX_DEFAULT_ARG, bool doNorm=false, bool randomGlobalPhase=true, bool useHostMem=false, int64_t deviceId=-1, bool useHardwareRNG=true, bool useSparseStateVec=false, real1_f norm_thresh=REAL1_EPSILON, std::vector< int64_t > ignored={}, bitLenInt qubitThreshold=0, real1_f separation_thresh=_qrack_qunit_sep_thresh)
Definition: qtensornetwork.cpp:35
bitCapInt MAll()
Measure permutation state of all coherent bits.
Definition: qtensornetwork.hpp:332
QInterfacePtr layerStack
Definition: qtensornetwork.hpp:45
real1_f SumSqrDiff(QTensorNetworkPtr toCompare)
Definition: qtensornetwork.hpp:208
void Finish()
If asynchronous work is still running, block until it finishes.
Definition: qtensornetwork.hpp:173
bool isFinished()
Returns "false" if asynchronous work is still running, and "true" if all previously dispatched asynch...
Definition: qtensornetwork.hpp:180
void Dispose(bitLenInt start, bitLenInt length)
Minimally decompose a set of contiguous bits from the separably composed unit, and discard the separa...
Definition: qtensornetwork.hpp:283
void MACMtrx(const std::vector< bitLenInt > &controls, const complex *mtrx, bitLenInt target)
Apply an arbitrary single bit unitary transformation, with arbitrary (anti-)control bits.
Definition: qtensornetwork.hpp:459
bool ForceM(bitLenInt qubit, bool result, bool doForce=true, bool doApply=true)
Act as if is a measurement was applied, except force the (usually random) result.
Definition: qtensornetwork.cpp:218
void Dispose(bitLenInt start, bitLenInt length, const bitCapInt &disposedPerm)
Dispose a a contiguous set of qubits that are already in a permutation eigenstate.
Definition: qtensornetwork.hpp:287
std::vector< QInterfaceEngine > engines
Definition: qtensornetwork.hpp:47
std::vector< QCircuitPtr > circuit
Definition: qtensornetwork.hpp:48
void RunAsAmplitudes(Fn fn, const std::set< bitLenInt > &qubits=std::set< bitLenInt >())
Definition: qtensornetwork.hpp:114
void Dump()
If asynchronous work is still running, let the simulator know that it can be aborted.
Definition: qtensornetwork.hpp:182
void UpdateRunningNorm(real1_f norm_thresh=REAL1_DEFAULT_ARG)
Force a calculation of the norm of the state vector, in order to make it unit length before the next ...
Definition: qtensornetwork.hpp:189
Half-precision floating-point type.
Definition: half.hpp:2222
virtual void Y(bitLenInt qubit)
Y gate.
Definition: qinterface.hpp:1101
virtual void X(bitLenInt qubit)
X gate.
Definition: qinterface.hpp:1084
virtual void Z(bitLenInt qubit)
Z gate.
Definition: qinterface.hpp:1117
virtual void U(bitLenInt target, real1_f theta, real1_f phi, real1_f lambda)
General unitary gate.
Definition: rotational.cpp:18
virtual bool M(bitLenInt qubit)
Measurement gate.
Definition: qinterface.hpp:1013
GLOSSARY: bitLenInt - "bit-length integer" - unsigned integer ID of qubit position in register bitCap...
Definition: complex16x2simd.hpp:25
void ThrowIfQbIdArrayIsBad(const std::vector< bitLenInt > &controls, const bitLenInt &qubitCount, std::string message)
Definition: qrack_functions.hpp:178
QRACK_CONST real1_f FP_NORM_EPSILON_F
Definition: qrack_types.hpp:259
std::shared_ptr< QInterface > QInterfacePtr
Definition: qinterface.hpp:29
const real1_f _qrack_qunit_sep_thresh
Definition: qrack_functions.hpp:235
std::complex< real1 > complex
Definition: qrack_types.hpp:128
bitCapInt pow2(const bitLenInt &p)
Definition: qrack_functions.hpp:136
std::shared_ptr< QTensorNetwork > QTensorNetworkPtr
Definition: qtensornetwork.hpp:17
QRACK_CONST real1 REAL1_EPSILON
Definition: qrack_types.hpp:200
QRACK_CONST real1 ONE_R1
Definition: qrack_types.hpp:185
QRACK_CONST real1 ZERO_R1
Definition: qrack_types.hpp:183
float real1_f
Definition: qrack_types.hpp:95
QRACK_CONST complex CMPLX_DEFAULT_ARG
Definition: qrack_types.hpp:257
std::shared_ptr< QCircuit > QCircuitPtr
Definition: qcircuit.hpp:602
QRACK_CONST complex ZERO_CMPLX
Definition: qrack_types.hpp:253
QRACK_CONST real1 PI_R1
Definition: qrack_types.hpp:178
const bitCapInt ZERO_BCI
Definition: qrack_types.hpp:130
bitLenInt log2(bitCapInt n)
Definition: qrack_functions.hpp:134
half sin(half arg)
Sine function.
Definition: half.hpp:3885
half cos(half arg)
Cosine function.
Definition: half.hpp:3922
#define REAL1_DEFAULT_ARG
Definition: qrack_types.hpp:177
#define bitLenInt
Definition: qrack_types.hpp:38
#define ZERO_R1_F
Definition: qrack_types.hpp:160
#define qrack_rand_gen_ptr
Definition: qrack_types.hpp:156
#define bitCapInt
Definition: qrack_types.hpp:62
#define bitCapIntOcl
Definition: qrack_types.hpp:50