Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make QHybrid default engine type #462

Merged
merged 7 commits into from
Sep 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Qrack

[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3785646.svg)](https://zenodo.org/badge/latestdoi/114947047) [![Qrack Build Status](https://api.travis-ci.org/vm6502q/qrack.svg?branch=master)](https://travis-ci.org/vm6502q/qrack/builds) [![Mentioned in Awesome awesome-quantum-computing](https://awesome.re/mentioned-badge.svg)](https://github.com/desireevl/awesome-quantum-computing)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3842287.svg)](https://doi.org/10.5281/zenodo.3842287) [![Qrack Build Status](https://api.travis-ci.org/vm6502q/qrack.svg?branch=master)](https://travis-ci.org/vm6502q/qrack/builds) [![Mentioned in Awesome awesome-quantum-computing](https://awesome.re/mentioned-badge.svg)](https://github.com/desireevl/awesome-quantum-computing)

[![Unitary Fund](https://img.shields.io/badge/Supported%20By-UNITARY%20FUND-brightgreen.svg?style=for-the-badge)](http://unitary.fund)

Expand Down
6 changes: 4 additions & 2 deletions include/qfactory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ QInterfacePtr CreateQuantumInterface(
case QINTERFACE_HYBRID:
return std::make_shared<QHybrid>(args...);
case QINTERFACE_QUNIT_MULTI:
return std::make_shared<QUnitMulti>(subengine1, args...);
return std::make_shared<QUnitMulti>(args...);
#endif
default:
return NULL;
Expand All @@ -70,7 +70,7 @@ QInterfacePtr CreateQuantumInterface(QInterfaceEngine engine, QInterfaceEngine s
case QINTERFACE_HYBRID:
return std::make_shared<QHybrid>(args...);
case QINTERFACE_QUNIT_MULTI:
return std::make_shared<QUnitMulti>(subengine, args...);
return std::make_shared<QUnitMulti>(args...);
#endif
default:
return NULL;
Expand All @@ -87,6 +87,8 @@ template <typename... Ts> QInterfacePtr CreateQuantumInterface(QInterfaceEngine
return std::make_shared<QEngineOCL>(args...);
case QINTERFACE_HYBRID:
return std::make_shared<QHybrid>(args...);
case QINTERFACE_QUNIT_MULTI:
return std::make_shared<QUnitMulti>(args...);
#endif
default:
return NULL;
Expand Down
7 changes: 6 additions & 1 deletion include/qhybrid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class QHybrid : public QInterface {
QHybrid(bitLenInt qBitCount, bitCapInt initState = 0, qrack_rand_gen_ptr rgp = nullptr,
complex phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = true, bool randomGlobalPhase = true,
bool useHostMem = false, int deviceId = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
real1 norm_thresh = REAL1_DEFAULT_ARG, std::vector<int> ignored = {}, bitLenInt qubitThreshold = 13);
real1 norm_thresh = REAL1_DEFAULT_ARG, std::vector<int> ignored = {}, bitLenInt qubitThreshold = 0);

QEnginePtr MakeEngine(bool isOpenCL, bitCapInt initState = 0);

Expand All @@ -51,6 +51,11 @@ class QHybrid : public QInterface {
engine->SetConcurrency(concurrency);
}

/**
* Switches between CPU and GPU used modes. (This will not incur a performance penalty, if the chosen mode matches
* the current mode.) Mode switching happens automatically when qubit counts change, but Compose() and Decompose()
* might leave their destination QInterface parameters in the opposite mode.
*/
virtual void SwitchModes(bool useGpu)
{
if (!isGpu && useGpu) {
Expand Down
2 changes: 1 addition & 1 deletion include/qinterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ enum QInterfaceEngine {

QINTERFACE_FIRST = QINTERFACE_CPU,
#if ENABLE_OPENCL
QINTERFACE_OPTIMAL = QINTERFACE_OPENCL,
QINTERFACE_OPTIMAL = QINTERFACE_HYBRID,
#else
QINTERFACE_OPTIMAL = QINTERFACE_CPU,
#endif
Expand Down
10 changes: 1 addition & 9 deletions include/qunitmulti.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,7 @@ class QUnitMulti : public QUnit, public ParallelFor {
std::vector<DeviceInfo> deviceList;

public:
QUnitMulti(bitLenInt qBitCount, bitCapInt initState, qrack_rand_gen_ptr rgp, complex phaseFac, bool doNorm,
bool randomGlobalPhase, bool useHostMem, int deviceID, bool useHardwareRNG, bool useSparseStateVec,
real1 norm_thresh, std::vector<int> devList, bitLenInt qubitThreshold)
: QUnitMulti(QINTERFACE_OPENCL, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase, useHostMem, -1,
useHardwareRNG, qubitThreshold)
{
}

QUnitMulti(QInterfaceEngine eng, bitLenInt qBitCount, bitCapInt initState = 0, qrack_rand_gen_ptr rgp = nullptr,
QUnitMulti(bitLenInt qBitCount, bitCapInt initState = 0, qrack_rand_gen_ptr rgp = nullptr,
complex phaseFac = CMPLX_DEFAULT_ARG, bool doNorm = true, bool randomGlobalPhase = true,
bool useHostMem = false, int deviceID = -1, bool useHardwareRNG = true, bool useSparseStateVec = false,
real1 norm_thresh = REAL1_DEFAULT_ARG, std::vector<int> devList = {}, bitLenInt qubitThreshold = 0);
Expand Down
6 changes: 4 additions & 2 deletions src/qhybrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ QHybrid::QHybrid(bitLenInt qBitCount, bitCapInt initState, qrack_rand_gen_ptr rg
, useHostRam(useHostMem)
, useRDRAND(useHardwareRNG)
, isSparse(useSparseStateVec)
, isGpu(qubitCount >= qubitThreshold)
{
concurrency = std::thread::hardware_concurrency();
thresholdQubits = qubitThreshold ? qubitThreshold : log2(concurrency) + QBCAPPOW;
thresholdQubits = (qubitThreshold != 0)
? qubitThreshold
: (concurrency == 1 ? PSTRIDEPOW : (log2(concurrency - 1) + PSTRIDEPOW + 1));
isGpu = (qubitCount >= thresholdQubits);
engine = MakeEngine(qubitCount >= thresholdQubits, initState);
}

Expand Down
10 changes: 5 additions & 5 deletions src/qunitmulti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

namespace Qrack {

QUnitMulti::QUnitMulti(QInterfaceEngine eng, bitLenInt qBitCount, bitCapInt initState, qrack_rand_gen_ptr rgp,
complex phaseFac, bool doNorm, bool randomGlobalPhase, bool useHostMem, int deviceID, bool useHardwareRNG,
bool useSparseStateVec, real1 norm_thresh, std::vector<int> devList, bitLenInt qubitThreshold)
: QUnit(eng, QINTERFACE_OPENCL, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase, useHostMem, -1,
QUnitMulti::QUnitMulti(bitLenInt qBitCount, bitCapInt initState, qrack_rand_gen_ptr rgp, complex phaseFac, bool doNorm,
bool randomGlobalPhase, bool useHostMem, int deviceID, bool useHardwareRNG, bool useSparseStateVec,
real1 norm_thresh, std::vector<int> devList, bitLenInt qubitThreshold)
: QUnit(QINTERFACE_OPENCL, qBitCount, initState, rgp, phaseFac, doNorm, randomGlobalPhase, useHostMem, -1,
useHardwareRNG, useSparseStateVec, norm_thresh, devList, qubitThreshold)
{
// Notice that this constructor always passes QINTERFACE_OPENCL to the QUnit constructor. For QUnitMulti, the
Expand Down Expand Up @@ -199,7 +199,7 @@ QInterfacePtr QUnitMulti::Clone()
EndAllEmulation();

QUnitMultiPtr copyPtr = std::make_shared<QUnitMulti>(
engine, qubitCount, 0, rand_generator, complex(ONE_R1, ZERO_R1), doNormalize, randGlobalPhase, useHostRam);
qubitCount, 0, rand_generator, complex(ONE_R1, ZERO_R1), doNormalize, randGlobalPhase, useHostRam);

return CloneBody(copyPtr);
}
Expand Down