Skip to content

Commit

Permalink
Ability to disable QUnit fidelity exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
WrathfulSpatula committed Nov 14, 2024
1 parent a32992b commit 5fcff6a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 32 deletions.
15 changes: 12 additions & 3 deletions include/qunit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ class QUnit : public QParity, public QInterface {
return abs(at) / PI_R1;
}

void CheckFidelity()
{
#if ENABLE_ENV_VARS
if ((!(bool)getenv("QRACK_DISABLE_QUNIT_FIDELITY_GUARD")) && (logFidelity <= FIDELITY_MIN)) {
#else
if (logFidelity <= FIDELITY_MIN) {
#endif
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
}

public:
QUnit(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,
Expand Down Expand Up @@ -727,9 +738,7 @@ class QUnit : public QParity, public QInterface {
SeparateBit(true, qubit);
}

if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
CheckFidelity();
}

void TransformX2x2(const complex* mtrxIn, complex* mtrxOut)
Expand Down
43 changes: 14 additions & 29 deletions src/qunit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,7 @@ void QUnit::SetQuantumState(const complex* inputState)
shard.amp1 = shard.amp0 / abs(shard.amp0);
shard.amp0 = ZERO_R1;
}
if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
CheckFidelity();
return;
}

Expand Down Expand Up @@ -408,6 +406,10 @@ bool QUnit::Detach(bitLenInt start, bitLenInt length, QUnitPtr dest, bool isTry,
QInterfacePtr QUnit::EntangleInCurrentBasis(
std::vector<bitLenInt*>::iterator first, std::vector<bitLenInt*>::iterator last)
{
if (std::distance(last, first) == 0U) {
throw std::invalid_argument("QUnit::EntangleInCurrentBasis() vector argument cannot be empty!");
}

const QUnitPtr backupCopy = std::dynamic_pointer_cast<QUnit>(Copy());

for (auto bit = first; bit < last; ++bit) {
Expand Down Expand Up @@ -743,10 +745,7 @@ bool QUnit::TrySeparate(bitLenInt qubit)
ShardAI(qubit, azimuth, inclination);

logFidelity += (double)log(clampProb(1.0 - oneMinR / 2));

if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
CheckFidelity();

return true;
}
Expand Down Expand Up @@ -977,9 +976,7 @@ real1_f QUnit::ProbBase(bitLenInt qubit)
amps[0U] = ZERO_CMPLX;
}

if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
CheckFidelity();

shard.amp0 = amps[0U];
shard.amp1 = amps[1U];
Expand Down Expand Up @@ -1010,9 +1007,7 @@ real1_f QUnit::ProbBase(bitLenInt qubit)
SeparateBit(true, qubit);
}

if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
CheckFidelity();

return clampProb(norm(shard.amp1));
}
Expand Down Expand Up @@ -1821,10 +1816,6 @@ void QUnit::EitherISwap(bitLenInt qubit1, bitLenInt qubit2, bool isInverse)
logFidelity += log(ONE_R1_F - pLo);
}

if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}

if (isInverse) {
Swap(qubit1, qubit2);
} else {
Expand All @@ -1834,6 +1825,7 @@ void QUnit::EitherISwap(bitLenInt qubit1, bitLenInt qubit2, bool isInverse)

return;
}

if (isInverse) {
unit->IISwap(shard1.mapped, shard2.mapped);
} else {
Expand All @@ -1846,6 +1838,7 @@ void QUnit::EitherISwap(bitLenInt qubit1, bitLenInt qubit2, bool isInverse)
TrySeparate(qubit1);
TrySeparate(qubit2);
}

return;
}

Expand Down Expand Up @@ -2783,9 +2776,7 @@ void QUnit::ApplyEitherControlled(
} else {
logFidelity += log(ONE_R1_F - p);
}
if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
CheckFidelity();

return;
}
Expand Down Expand Up @@ -4020,9 +4011,7 @@ void QUnit::ApplyBuffer(PhaseShardPtr phaseShard, bitLenInt control, bitLenInt t
bool pState = abs(pHi - HALF_R1) >= abs(pLo - HALF_R1);

logFidelity += angleFrac(polarBottom) * log(pState ? pHi : (ONE_R1_F - pLo));
if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
CheckFidelity();

if (pState) {
if (!ptHi) {
Expand All @@ -4041,9 +4030,7 @@ void QUnit::ApplyBuffer(PhaseShardPtr phaseShard, bitLenInt control, bitLenInt t
pState = abs(pHi - HALF_R1) >= abs(pLo - HALF_R1);

logFidelity += angleFrac(polarTop) * log(pState ? pHi : (ONE_R1_F - pLo));
if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
CheckFidelity();

if (!pState) {
if (ptHi) {
Expand All @@ -4066,9 +4053,7 @@ void QUnit::ApplyBuffer(PhaseShardPtr phaseShard, bitLenInt control, bitLenInt t
pState = abs(pHi - HALF_R1) >= abs(pLo - HALF_R1);

logFidelity += log(pState ? pHi : (ONE_R1_F - pLo));
if (logFidelity <= FIDELITY_MIN) {
throw std::runtime_error("QUnit fidelity is effectively 0!");
}
CheckFidelity();

if (pState) {
if (!ptHi) {
Expand Down

0 comments on commit 5fcff6a

Please sign in to comment.