Skip to content

Commit

Permalink
VarianceBitsAll(); make format
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Strano committed Feb 25, 2024
1 parent d183c7d commit 3258ea4
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 70 deletions.
6 changes: 4 additions & 2 deletions include/qbdthybrid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ class QBdtHybrid : public QParity, public QInterface {

#if ENABLE_ENV_VARS
const bitLenInt pStridePow =
(((bitLenInt)(getenv("QRACK_PSTRIDEPOW") ? std::stoi(std::string(getenv("QRACK_PSTRIDEPOW"))) : PSTRIDEPOW)) +
7U) >> 1U;
(((bitLenInt)(getenv("QRACK_PSTRIDEPOW") ? std::stoi(std::string(getenv("QRACK_PSTRIDEPOW")))
: PSTRIDEPOW)) +
7U) >>
1U;
#else
const bitLenInt pStridePow = (PSTRIDEPOW + 7U) >> 1U;
#endif
Expand Down
12 changes: 11 additions & 1 deletion include/qinterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

#pragma once

#include "common/pauli.hpp"
#include "common/parallel_for.hpp"
#include "common/pauli.hpp"
#include "common/rdrandwrapper.hpp"
#include "hamiltonian.hpp"

Expand Down Expand Up @@ -2440,6 +2440,16 @@ class QInterface : public ParallelFor {
*/
virtual void ProbBitsAll(const std::vector<bitLenInt>& bits, real1* probsArray);

/**
* Direct measure of variance of listed permutation probability
*
* The (bit string) variance of all included permutations of bits, with bits valued from low to high as the order of
* the "bits" array parameter argument, are returned in the "probsArray" parameter.
*
* \warning PSEUDO-QUANTUM
*/
virtual real1_f VarianceBitsAll(const std::vector<bitLenInt>& bits);

/**
* Get permutation expectation value of bits
*
Expand Down
6 changes: 4 additions & 2 deletions include/qpager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,9 +455,11 @@ class QPager : public QEngine, public std::enable_shared_from_this<QPager> {
#if ENABLE_OPENCL || ENABLE_CUDA
if (rootEngine != QINTERFACE_CPU) {
#if ENABLE_OPENCL
maxPageQubits = log2Ocl(OCLEngine::Instance().GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
maxPageQubits =
log2Ocl(OCLEngine::Instance().GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
#else
maxPageQubits = log2Ocl(CUDAEngine::Instance().GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
maxPageQubits =
log2Ocl(CUDAEngine::Instance().GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
#endif
if (maxPageSetting < maxPageQubits) {
maxPageQubits = maxPageSetting;
Expand Down
3 changes: 2 additions & 1 deletion include/qtensornetwork.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ class QTensorNetwork : public QInterface {
{
}

void SetSdrp(real1_f sdrp){
void SetSdrp(real1_f sdrp)
{
separabilityThreshold = sdrp;
isReactiveSeparate = (separabilityThreshold > FP_NORM_EPSILON_F);
};
Expand Down
8 changes: 4 additions & 4 deletions include/qunit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ class QUnit : public QParity, public QInterface {
bool useHostMem = false, int64_t deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
real1_f norm_thresh = REAL1_EPSILON, std::vector<int64_t> devIDs = {}, bitLenInt qubitThreshold = 0U,
real1_f separation_thresh = FP_NORM_EPSILON_F)
: QUnit({ QINTERFACE_OPTIMAL_BASE }, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase,
useHostMem, deviceId, useHardwareRNG, useSparseStateVec, norm_thresh, devIDs, qubitThreshold,
separation_thresh)
: QUnit({ QINTERFACE_OPTIMAL_BASE }, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase, useHostMem,
deviceId, useHardwareRNG, useSparseStateVec, norm_thresh, devIDs, qubitThreshold, separation_thresh)
{
}

Expand Down Expand Up @@ -433,7 +432,8 @@ class QUnit : public QParity, public QInterface {
virtual bool TrySeparate(bitLenInt qubit1, bitLenInt qubit2);
virtual double GetUnitaryFidelity();
virtual void ResetUnitaryFidelity() { logFidelity = 0.0; }
virtual void SetSdrp(real1_f sdrp) {
virtual void SetSdrp(real1_f sdrp)
{
separabilityThreshold = sdrp;
isReactiveSeparate = (separabilityThreshold > FP_NORM_EPSILON_F);
};
Expand Down
63 changes: 37 additions & 26 deletions include/wasm_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@

#pragma once

#include "common/qrack_types.hpp"
#include "common/qneuron_activation_function.hpp"
#include "common/pauli.hpp"
#include "common/qneuron_activation_function.hpp"
#include "common/qrack_types.hpp"

#include <string>
#include <set>
#include <string>
#include <vector>

/**
* GLOSSARY:
* bitLenInt - "bit-length integer" - unsigned integer ID of qubit position in register
* bitCapInt - "bit-capacity integer" - unsigned integer single-permutation value of a qubit register (typically "big integer")
* real1 - "real number (1-dimensional)" - floating-point real-valued number
* complex - "complex number" - floating-point complex-valued number (with two real1 component dimensions)
* quid - "quantum (simulator) unique identifier" - unsigned integer that indexes and IDs running simulators, circuits, and neurons
* bitCapInt - "bit-capacity integer" - unsigned integer single-permutation value of a qubit register (typically
* "big integer") real1 - "real number (1-dimensional)" - floating-point real-valued number complex - "complex number" -
* floating-point complex-valued number (with two real1 component dimensions) quid - "quantum (simulator) unique
* identifier" - unsigned integer that indexes and IDs running simulators, circuits, and neurons
*/

namespace Qrack {
Expand Down Expand Up @@ -73,14 +73,15 @@ struct QubitPauliBasis {
/**
* Options for simulator type in initialization (any set of options theoretically functions together):
* tn - "Tensor network" layer - JIT local circuit simplification, light-cone optimization
* md - "Multi-device" (TURN OFF IN SERIAL BUILDS) - distribute Schmidt-decomposed or factorized subsytems to different OpenCL devices.
* sd - "Schmidt decomposition" - use state-factorization optimizations
* sh - "Stabilizer hybrid" - use ("hybrid") stabilizer and near-Clifford optimizations (does not work well with "tn," "tensor network")
* bdt - "Binary decision tree" - use "quantum binary decision diagram" (QBDD) optimization. This can optionally "hybridize" with state vector, for speed.
* pg - "Pager" (TURN OFF IN SERIAL BUILDS) - split large simulations into a power-of-2 of smaller simulation "pages," for multi-device distribution
* hy - "(State vector) Hybrid" (TURN OFF IN SERIAL BUILD) - for state vector, "hybridize" CPU/GPU/multi-GPU simulation qubit width thresholds, for speed.
* oc - "OpenCL" (TURN OFF IN SERIAL BUILD) - use OpenCL acceleration (in general)
* hp - "Host pointer" (TURN OFF IN SERIAL BUILD) - allocate OpenCL state vectors on "host" instead of "device" (useful for certain accelerators, like Intel HD)
* md - "Multi-device" (TURN OFF IN SERIAL BUILDS) - distribute Schmidt-decomposed or factorized subsytems to
* different OpenCL devices. sd - "Schmidt decomposition" - use state-factorization optimizations sh - "Stabilizer
* hybrid" - use ("hybrid") stabilizer and near-Clifford optimizations (does not work well with "tn," "tensor network")
* bdt - "Binary decision tree" - use "quantum binary decision diagram" (QBDD) optimization. This can optionally
* "hybridize" with state vector, for speed. pg - "Pager" (TURN OFF IN SERIAL BUILDS) - split large simulations into a
* power-of-2 of smaller simulation "pages," for multi-device distribution hy - "(State vector) Hybrid" (TURN OFF IN
* SERIAL BUILD) - for state vector, "hybridize" CPU/GPU/multi-GPU simulation qubit width thresholds, for speed. oc -
* "OpenCL" (TURN OFF IN SERIAL BUILD) - use OpenCL acceleration (in general) hp - "Host pointer" (TURN OFF IN SERIAL
* BUILD) - allocate OpenCL state vectors on "host" instead of "device" (useful for certain accelerators, like Intel HD)
*/
quid init_count_type(bitLenInt q, bool tn, bool md, bool sd, bool sh, bool bdt, bool pg, bool hy, bool oc, bool hp);

Expand Down Expand Up @@ -143,7 +144,8 @@ void SetPermutation(quid sid, bitCapInt p);
*/
void qstabilizer_out_to_file(quid sid, std::string f);
/**
* Initialize stabilizer simulation from a tableau file (or raise exception for "get_error()" if incompatible simulator type)
* Initialize stabilizer simulation from a tableau file (or raise exception for "get_error()" if incompatible simulator
* type)
*/
void qstabilizer_in_from_file(quid sid, std::string f);

Expand Down Expand Up @@ -176,15 +178,17 @@ real1_f PermutationExpectationRdm(quid sid, std::vector<bitLenInt> q, bool r);
*/
real1_f FactorizedExpectation(quid sid, std::vector<QubitIntegerExpectation> q);
/**
* "Reduced density matrix" Expectation value for bit-string integer from group of qubits with per-qubit integer expectation value
* "Reduced density matrix" Expectation value for bit-string integer from group of qubits with per-qubit integer
* expectation value
*/
real1_f FactorizedExpectationRdm(quid sid, std::vector<QubitIntegerExpectation> q, bool r);
/**
* Expectation value for bit-string integer from group of qubits with per-qubit real1 expectation value
*/
real1_f FactorizedExpectationFp(quid sid, std::vector<QubitRealExpectation> q);
/**
* "Reduced density matrix" Expectation value for bit-string integer from group of qubits with per-qubit real1 expectation value
* "Reduced density matrix" Expectation value for bit-string integer from group of qubits with per-qubit real1
* expectation value
*/
real1_f FactorizedExpectationFpRdm(quid sid, std::vector<QubitRealExpectation> q, bool r);

Expand Down Expand Up @@ -352,9 +356,12 @@ void POWN(quid sid, bitCapInt a, bitCapInt m, std::vector<bitLenInt> q, std::vec
void MCMUL(quid sid, bitCapInt a, std::vector<bitLenInt> c, std::vector<bitLenInt> q, std::vector<bitLenInt> o);
void MCDIV(quid sid, bitCapInt a, std::vector<bitLenInt> c, std::vector<bitLenInt> q, std::vector<bitLenInt> o);
// Controlled modulo, out-of-place
void MCMULN(quid sid, bitCapInt a, std::vector<bitLenInt> c, bitCapInt m, std::vector<bitLenInt> q, std::vector<bitLenInt> o);
void MCDIVN(quid sid, bitCapInt a, std::vector<bitLenInt> c, bitCapInt m, std::vector<bitLenInt> q, std::vector<bitLenInt> o);
void MCPOWN(quid sid, bitCapInt a, std::vector<bitLenInt> c, bitCapInt m, std::vector<bitLenInt> q, std::vector<bitLenInt> o);
void MCMULN(
quid sid, bitCapInt a, std::vector<bitLenInt> c, bitCapInt m, std::vector<bitLenInt> q, std::vector<bitLenInt> o);
void MCDIVN(
quid sid, bitCapInt a, std::vector<bitLenInt> c, bitCapInt m, std::vector<bitLenInt> q, std::vector<bitLenInt> o);
void MCPOWN(
quid sid, bitCapInt a, std::vector<bitLenInt> c, bitCapInt m, std::vector<bitLenInt> q, std::vector<bitLenInt> o);

#if 0
// Amplitude amplification
Expand All @@ -367,15 +374,18 @@ void Hash(quid sid, std::vector<bitLenInt> q, std::vector<unsigned char> t);

// Utility functions
/**
* Try to factorize a single-qubit subsystem out of "bulk" simulator state. (This can improve efficiency but has no logical effect.)
* Try to factorize a single-qubit subsystem out of "bulk" simulator state. (This can improve efficiency but has no
* logical effect.)
*/
bool TrySeparate1Qb(quid sid, bitLenInt qi1);
/**
* Try to factorize a two-qubit subsystem out of "bulk" simulator state. (This can improve efficiency but has no logical effect.)
* Try to factorize a two-qubit subsystem out of "bulk" simulator state. (This can improve efficiency but has no logical
* effect.)
*/
bool TrySeparate2Qb(quid sid, bitLenInt qi1, bitLenInt qi2);
/**
* Try to factorize a qubit subsystem out of "bulk" simulator state. (This can improve efficiency but has no logical effect.)
* Try to factorize a qubit subsystem out of "bulk" simulator state. (This can improve efficiency but has no logical
* effect.)
*/
bool TrySeparateTol(quid sid, std::vector<bitLenInt> q, real1_f tol);
/**
Expand Down Expand Up @@ -404,7 +414,8 @@ void SetReactiveSeparate(quid sid, bool irs);
void SetTInjection(quid sid, bool iti);

/**
* Initialize a "quantum neuron" that takes a list of qubit "controls" for input and acts on a single "target" output qubit.
* Initialize a "quantum neuron" that takes a list of qubit "controls" for input and acts on a single "target" output
* qubit.
*/
quid init_qneuron(quid sid, std::vector<bitLenInt> c, bitLenInt q, QNeuronActivationFn f, real1_f a, real1_f tol);
/**
Expand Down Expand Up @@ -473,4 +484,4 @@ void qcircuit_append_mc(quid cid, std::vector<complex> m, std::vector<bitLenInt>
void qcircuit_run(quid cid, quid sid);
void qcircuit_out_to_file(quid cid, std::string f);
void qcircuit_in_from_file(quid cid, std::string f);
}
} // namespace Qrack
3 changes: 2 additions & 1 deletion src/qbdt/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ const unsigned numThreads = std::thread::hardware_concurrency() << 1U;
#if ENABLE_ENV_VARS
const bitLenInt pStridePow =
(((bitLenInt)(getenv("QRACK_PSTRIDEPOW") ? std::stoi(std::string(getenv("QRACK_PSTRIDEPOW"))) : PSTRIDEPOW)) +
7U) >> 1U;
7U) >>
1U;
#else
const bitLenInt pStridePow = (PSTRIDEPOW + 7U) >> 1U;
#endif
Expand Down
20 changes: 20 additions & 0 deletions src/qinterface/qinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,26 @@ void QInterface::ProbBitsAll(const std::vector<bitLenInt>& bits, real1* probsArr
}
}

real1_f VarianceBitsAll(const std::vector<bitLenInt>& bits)
{
const real1_f mean = ExpectationBitsAll(bits);
std::vector<bitCapInt> bitPowers(bits.size());
std::transform(bits.begin(), bits.end(), bitPowers.begin(), pow2);
real1_f tot = ZERO_R1_F;
for (bitCapInt lcv = ZERO_BCI; bi_compare(lcv, maxQPower) < 0; bi_increment(&lcv, 1U)) {
bitCapIntOcl retIndex = 0U;
for (size_t p = 0U; p < bits.size(); ++p) {
if (bi_compare_0(lcv & bitPowers[p]) != 0) {
retIndex |= pow2Ocl(p);
}
}
const real1_f diff = ((real1_f)(retIndex.bi_to_double()) - mean);
tot += ProbAll(lcv) * diff * diff;
}

return tot;
}

real1_f QInterface::ExpectationBitsFactorized(
const std::vector<bitLenInt>& bits, const std::vector<bitCapInt>& perms, bitCapInt offset)
{
Expand Down
7 changes: 4 additions & 3 deletions src/qstabilizerhybrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ QStabilizerHybrid::QStabilizerHybrid(std::vector<QInterfaceEngine> eng, bitLenIn
if (isQPager) {
--maxEngineQubitCount;
const size_t devCount = QRACK_GPU_SINGLETON.GetDeviceCount();
const bitLenInt perPage = log2Ocl(QRACK_GPU_SINGLETON.GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
const bitLenInt perPage =
log2Ocl(QRACK_GPU_SINGLETON.GetDeviceContextPtr(devID)->GetMaxAlloc() / sizeof(complex)) - 1U;
#if ENABLE_OPENCL
maxAncillaCount = (devCount < 2U) ? (perPage + 3U) : (perPage + log2Ocl(devCount) + 2U);
#else
Expand All @@ -94,13 +95,13 @@ QStabilizerHybrid::QStabilizerHybrid(std::vector<QInterfaceEngine> eng, bitLenIn
}
#if ENABLE_OPENCL
else {
maxEngineQubitCount = (maxEngineQubitCount > 1U) ? (maxEngineQubitCount - 1U): 1U;
maxEngineQubitCount = (maxEngineQubitCount > 1U) ? (maxEngineQubitCount - 1U) : 1U;
}
#endif
if (getenv("QRACK_MAX_PAGING_QB")) {
const bitLenInt maxPageSetting = (bitLenInt)std::stoi(std::string(getenv("QRACK_MAX_PAGING_QB")));
if (maxPageSetting < maxAncillaCount) {
maxAncillaCount = maxAncillaCount;
maxAncillaCount = maxAncillaCount;
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/qunit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3919,7 +3919,8 @@ void QUnit::CPhaseFlipIfLess(bitCapInt greaterPerm, bitLenInt start, bitLenInt l
}
#endif

double QUnit::GetUnitaryFidelity() {
double QUnit::GetUnitaryFidelity()
{
double fidelity = exp(logFidelity);

std::vector<QInterfacePtr> units;
Expand Down
Loading

0 comments on commit 3258ea4

Please sign in to comment.