From 0ed9b7a19a1cc71c1bcd0e9b0c60ed8686624adf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 04:54:45 +0000 Subject: [PATCH 01/10] Bump the submodules group with 2 updates Bumps the submodules group with 2 updates: [extern/mqt-core](https://github.com/cda-tum/mqt-core) and [extern/taskflow](https://github.com/taskflow/taskflow). Updates `extern/mqt-core` from `d39959e` to `f0517f0` - [Release notes](https://github.com/cda-tum/mqt-core/releases) - [Commits](https://github.com/cda-tum/mqt-core/compare/d39959ee774f9a8bf5c888958f223529eae43a01...f0517f0cc57e6262874ce3bd0dd91efe1552c87d) Updates `extern/taskflow` from `ac18be7` to `0ad3d2f` - [Release notes](https://github.com/taskflow/taskflow/releases) - [Commits](https://github.com/taskflow/taskflow/compare/ac18be7269732a3852d9117317eef87ae9c2660f...0ad3d2f31c4bd4feee6bfd0164775016f024f588) --- updated-dependencies: - dependency-name: extern/mqt-core dependency-type: direct:production dependency-group: submodules - dependency-name: extern/taskflow dependency-type: direct:production dependency-group: submodules ... Signed-off-by: dependabot[bot] --- extern/mqt-core | 2 +- extern/taskflow | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extern/mqt-core b/extern/mqt-core index d39959ee..f0517f0c 160000 --- a/extern/mqt-core +++ b/extern/mqt-core @@ -1 +1 @@ -Subproject commit d39959ee774f9a8bf5c888958f223529eae43a01 +Subproject commit f0517f0cc57e6262874ce3bd0dd91efe1552c87d diff --git a/extern/taskflow b/extern/taskflow index ac18be72..0ad3d2f3 160000 --- a/extern/taskflow +++ b/extern/taskflow @@ -1 +1 @@ -Subproject commit ac18be7269732a3852d9117317eef87ae9c2660f +Subproject commit 0ad3d2f31c4bd4feee6bfd0164775016f024f588 From 28978c2a5cdab6c0b8604cc7b2cd5a83d10b8a6d Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 20:39:27 +0100 Subject: [PATCH 02/10] =?UTF-8?q?=F0=9F=91=BD=20adapt=20to=20latest=20mqt-?= =?UTF-8?q?core=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- extern/mqt-core | 2 +- include/ShorFastSimulator.hpp | 2 +- src/CircuitSimulator.cpp | 6 +- src/DeterministicNoiseSimulator.cpp | 3 +- src/GroverSimulator.cpp | 6 +- src/HybridSchrodingerFeynmanSimulator.cpp | 2 +- src/PathSimulator.cpp | 4 +- src/ShorFastSimulator.cpp | 100 ++++++++-------------- src/Simulator.cpp | 24 ++---- src/StochasticNoiseSimulator.cpp | 10 ++- src/UnitarySimulator.cpp | 4 +- 11 files changed, 66 insertions(+), 97 deletions(-) diff --git a/extern/mqt-core b/extern/mqt-core index f0517f0c..6d9a08ed 160000 --- a/extern/mqt-core +++ b/extern/mqt-core @@ -1 +1 @@ -Subproject commit f0517f0cc57e6262874ce3bd0dd91efe1552c87d +Subproject commit 6d9a08ed81019bd120065ca511721a500bc52aca diff --git a/include/ShorFastSimulator.hpp b/include/ShorFastSimulator.hpp index 315a4d2c..344da337 100644 --- a/include/ShorFastSimulator.hpp +++ b/include/ShorFastSimulator.hpp @@ -44,7 +44,7 @@ class ShorFastSimulator: public Simulator { void applyGate(dd::GateMatrix matrix, dd::Qubit target); - std::vector> nodesOnLevel; + std::vector> nodesOnLevel; dd::mEdge addConst(std::uint64_t a); diff --git a/src/CircuitSimulator.cpp b/src/CircuitSimulator.cpp index 24817bc3..cf5772d7 100644 --- a/src/CircuitSimulator.cpp +++ b/src/CircuitSimulator.cpp @@ -92,7 +92,7 @@ dd::fp CircuitSimulator::expectationValue(const qc::QuantumComputation& singleShot(true); // construct the DD for the observable - const auto observableDD = dd::buildFunctionality(&observable, Simulator::dd); + const auto observableDD = dd::buildFunctionality(&observable, *Simulator::dd); // calculate the expectation value return Simulator::dd->expectationValue(observableDD, Simulator::rootEdge); @@ -136,7 +136,7 @@ std::map CircuitSimulator::singleShot(const bool igno // apply an X operation whenever the measured result is one if (bit == '1') { const auto x = qc::StandardOperation(qc->getNqubits(), qubit, qc::X); - auto tmp = Simulator::dd->multiply(dd::getDD(&x, Simulator::dd), Simulator::rootEdge); + auto tmp = Simulator::dd->multiply(dd::getDD(&x, *Simulator::dd), Simulator::rootEdge); Simulator::dd->incRef(tmp); Simulator::dd->decRef(Simulator::rootEdge); Simulator::rootEdge = tmp; @@ -176,7 +176,7 @@ std::map CircuitSimulator::singleShot(const bool igno << " #controls=" << op->getControls().size() << " statesize=" << dd->size(rootEdge) << "\n";//*/ - auto ddOp = dd::getDD(op.get(), Simulator::dd); + auto ddOp = dd::getDD(op.get(), *Simulator::dd); auto tmp = Simulator::dd->multiply(ddOp, Simulator::rootEdge); Simulator::dd->incRef(tmp); Simulator::dd->decRef(Simulator::rootEdge); diff --git a/src/DeterministicNoiseSimulator.cpp b/src/DeterministicNoiseSimulator.cpp index abc25648..1de8e7e9 100644 --- a/src/DeterministicNoiseSimulator.cpp +++ b/src/DeterministicNoiseSimulator.cpp @@ -1,6 +1,7 @@ #include "DeterministicNoiseSimulator.hpp" #include "dd/Export.hpp" +#include "dd/Operations.hpp" using CN = dd::ComplexNumbers; @@ -35,7 +36,7 @@ dd::SparsePVecStrKeys DeterministicNoiseSimulator::deterministicSimulate if (op->isClassicControlledOperation()) { throw std::runtime_error("Classical controlled operations are not supported."); } - auto operation = dd::getDD(op.get(), Simulator::dd); + auto operation = dd::getDD(op.get(), *Simulator::dd); // Applying the operation to the density matrix Simulator::dd->applyOperationToDensity(rootEdge, operation, useDensityMatrixType); diff --git a/src/GroverSimulator.cpp b/src/GroverSimulator.cpp index bfc796e5..3696a2b1 100644 --- a/src/GroverSimulator.cpp +++ b/src/GroverSimulator.cpp @@ -14,7 +14,7 @@ std::map GroverSimulator::simulate(std::size_t qcSetup.h(i); } - const dd::Edge setupOp{dd::buildFunctionality(&qcSetup, Simulator::dd)}; + const dd::Edge setupOp{dd::buildFunctionality(&qcSetup, *Simulator::dd)}; // Build the oracle qc::QuantumComputation qcOracle(nQubits + nAnciallae); @@ -24,7 +24,7 @@ std::map GroverSimulator::simulate(std::size_t } qcOracle.mcz(controls, nQubits); - const dd::Edge oracleOp{dd::buildFunctionality(&qcOracle, Simulator::dd)}; + const dd::Edge oracleOp{dd::buildFunctionality(&qcOracle, *Simulator::dd)}; // Build the diffusion stage. qc::QuantumComputation qcDiffusion(nQubits + nAnciallae); @@ -53,7 +53,7 @@ std::map GroverSimulator::simulate(std::size_t qcDiffusion.h(i); } - const dd::Edge diffusionOp{dd::buildFunctionality(&qcDiffusion, Simulator::dd)}; + const dd::Edge diffusionOp{dd::buildFunctionality(&qcDiffusion, *Simulator::dd)}; const dd::Edge fullIteration{Simulator::dd->multiply(oracleOp, diffusionOp)}; Simulator::dd->incRef(fullIteration); diff --git a/src/HybridSchrodingerFeynmanSimulator.cpp b/src/HybridSchrodingerFeynmanSimulator.cpp index 81c2cbdb..eea1be5e 100644 --- a/src/HybridSchrodingerFeynmanSimulator.cpp +++ b/src/HybridSchrodingerFeynmanSimulator.cpp @@ -112,7 +112,7 @@ bool HybridSchrodingerFeynmanSimulator::Slice::apply(std::unique_ptrgetParameter(); qc::StandardOperation newOp(nqubits, opControls, opTargets, op->getType(), param, start); sliceDD->decRef(edge); - edge = sliceDD->multiply(dd::getDD(&newOp, sliceDD), edge, static_cast(start)); + edge = sliceDD->multiply(dd::getDD(&newOp, *sliceDD), edge, static_cast(start)); sliceDD->incRef(edge); } } else { diff --git a/src/PathSimulator.cpp b/src/PathSimulator.cpp index 839f7f46..d604d71c 100644 --- a/src/PathSimulator.cpp +++ b/src/PathSimulator.cpp @@ -379,7 +379,7 @@ void PathSimulator::constructTaskGraph() { results.emplace(leftID, zeroState); } else { const auto& op = CircuitSimulator::qc->at(leftID - 1); - qc::MatrixDD opDD = dd::getDD(op.get(), Simulator::dd); + qc::MatrixDD opDD = dd::getDD(op.get(), *Simulator::dd); Simulator::dd->incRef(opDD); results.emplace(leftID, opDD); } @@ -390,7 +390,7 @@ void PathSimulator::constructTaskGraph() { throw std::runtime_error("Initial state must not appear on right side of the simulation path member."); } const auto& op = CircuitSimulator::qc->at(rightID - 1); - qc::MatrixDD opDD = dd::getDD(op.get(), Simulator::dd); + qc::MatrixDD opDD = dd::getDD(op.get(), *Simulator::dd); Simulator::dd->incRef(opDD); results.emplace(rightID, opDD); } diff --git a/src/ShorFastSimulator.cpp b/src/ShorFastSimulator.cpp index 9da7ebc0..cde9ff18 100644 --- a/src/ShorFastSimulator.cpp +++ b/src/ShorFastSimulator.cpp @@ -329,7 +329,6 @@ void ShorFastSimulator::applyGate(dd::GateMatrix matrix, dd::Qubit targe */ template void ShorFastSimulator::uAEmulate2(const std::uint64_t a) { - [[maybe_unused]] const std::size_t cacheCountBefore = Simulator::dd->cn.cacheCount(); dagEdges.clear(); dd::vEdge f = dd::vEdge::one(); @@ -349,7 +348,7 @@ void ShorFastSimulator::uAEmulate2(const std::uint64_t a) { // clear nodesOnLevel. TODO: make it a local variable? for (auto& m: nodesOnLevel) { - m = std::map(); + m = {}; } // initialize nodesOnLevel @@ -357,69 +356,48 @@ void ShorFastSimulator::uAEmulate2(const std::uint64_t a) { // special treatment for the nodes on first level for (const auto& entry: nodesOnLevel.at(0)) { - dd::vEdge left = f; - if (entry.first->e[0].w.exactlyZero()) { - left = dd::vEdge::zero(); - } else { - left.w = Simulator::dd->cn.mulCached(left.w, entry.first->e[0].w); - } - - dd::vEdge right = Simulator::dd->multiply(addConstMod(ts[static_cast(entry.first->v)]), f); - - if (entry.first->e[1].w.exactlyZero()) { - right = dd::vEdge::zero(); - } else { - right.w = Simulator::dd->cn.mulCached(right.w, entry.first->e[1].w); + auto left = dd::vCachedEdge::zero(); + if (!entry.first->e[0].w.exactlyZero()) { + left = {f.p, f.w * entry.first->e[0].w}; } - const dd::vEdge result = Simulator::dd->add(left, right); - - if (!left.w.exactlyZero()) { - Simulator::dd->cn.returnToCache(left.w); + auto right = dd::vCachedEdge::zero(); + if (!entry.first->e[1].w.exactlyZero()) { + auto tmp = Simulator::dd->multiply(addConstMod(ts[static_cast(entry.first->v)]), f); + right = {tmp.p, tmp.w * entry.first->e[1].w}; } - if (!right.w.exactlyZero()) { - Simulator::dd->cn.returnToCache(right.w); - } - - Simulator::dd->incRef(result); - nodesOnLevel[0][entry.first] = result; + nodesOnLevel[0][entry.first] = Simulator::dd->add2(left, right, 0); } // treat the nodes on the remaining levels for (std::size_t i = 1; i < nQubits - 1; i++) { - std::vector saveEdges; for (auto it = nodesOnLevel.at(i).begin(); it != nodesOnLevel.at(i).end(); it++) { - dd::vEdge left = dd::vEdge::zero(); + auto left = dd::vCachedEdge::zero(); if (!it->first->e.at(0).w.exactlyZero()) { left = nodesOnLevel.at(i - 1)[it->first->e.at(0).p]; - left.w = Simulator::dd->cn.mulCached(left.w, it->first->e.at(0).w); + left.w = left.w * it->first->e.at(0).w; } - dd::vEdge right = dd::vEdge::zero(); + auto right = dd::vCachedEdge::zero(); if (!it->first->e.at(1).w.exactlyZero()) { - right = Simulator::dd->multiply(addConstMod(ts.at(static_cast(it->first->v))), nodesOnLevel.at(i - 1)[it->first->e.at(1).p]); - right.w = Simulator::dd->cn.mulCached(right.w, it->first->e.at(1).w); + auto node0 = addConstMod(ts.at(static_cast(it->first->v))); + auto& node1 = nodesOnLevel.at(i - 1)[it->first->e.at(1).p]; + auto node2 = dd::vEdge{node1.p, Simulator::dd->cn.lookup(node1.w)}; + auto res = Simulator::dd->multiply(node0, node2); + right = {res.p, res.w * it->first->e.at(1).w}; } - const dd::vEdge result = Simulator::dd->add(left, right); - - if (!left.w.exactlyZero()) { - Simulator::dd->cn.returnToCache(left.w); + dd::Qubit level = 0; + if (left.p != nullptr) { + level = left.p->v; } - if (!right.w.exactlyZero()) { - Simulator::dd->cn.returnToCache(right.w); + if (right.p != nullptr && right.p->v > level) { + level = right.p->v; } - Simulator::dd->incRef(result); - nodesOnLevel.at(i)[it->first] = result; - saveEdges.push_back(result); - } - for (auto& it: nodesOnLevel.at(i - 1)) { - Simulator::dd->decRef(it.second); + nodesOnLevel.at(i)[it->first] = Simulator::dd->add2(left, right, level); } - Simulator::dd->garbageCollect(); - saveEdges.push_back(Simulator::rootEdge); nodesOnLevel.at(i - 1).clear(); } @@ -428,33 +406,29 @@ void ShorFastSimulator::uAEmulate2(const std::uint64_t a) { throw std::runtime_error("error occurred"); } - dd::vEdge result = nodesOnLevel.at(nQubits - 2)[Simulator::rootEdge.p->e[0].p]; - - Simulator::dd->decRef(result); + auto result = nodesOnLevel.at(nQubits - 2)[Simulator::rootEdge.p->e[0].p]; + result.w = result.w * Simulator::rootEdge.p->e[0].w; + auto tmp = dd::vCachedEdge{Simulator::rootEdge.p->e[0].p, Simulator::rootEdge.p->e[0].w}; + result = Simulator::dd->makeDDNode(Simulator::rootEdge.p->v, std::array{tmp, result}); - result.w = Simulator::dd->cn.mulCached(result.w, Simulator::rootEdge.p->e[0].w); - auto tmp = result.w; - - result = Simulator::dd->makeDDNode(Simulator::rootEdge.p->v, std::array{Simulator::rootEdge.p->e[0], result}); - Simulator::dd->cn.returnToCache(tmp); - - result.w = Simulator::dd->cn.mulCached(result.w, Simulator::rootEdge.w); - tmp = result.w; - result.w = Simulator::dd->cn.lookup(result.w); - Simulator::dd->cn.returnToCache(tmp); + result.w = result.w * Simulator::rootEdge.w; + auto res = dd::vEdge{result.p, Simulator::dd->cn.lookup(result.w)}; + Simulator::dd->incRef(res); Simulator::dd->decRef(Simulator::rootEdge); - Simulator::dd->incRef(result); - Simulator::rootEdge = result; + Simulator::rootEdge = res; Simulator::dd->garbageCollect(); - assert(Simulator::dd->cn.cacheCount() == cacheCountBefore); } template void ShorFastSimulator::uAEmulate2Rec(dd::vEdge e) { - if (e.isTerminal() || nodesOnLevel.at(static_cast(e.p->v)).find(e.p) != nodesOnLevel.at(static_cast(e.p->v)).end()) { + if (e.isTerminal()) { + return; + } + auto& nodes = nodesOnLevel.at(static_cast(e.p->v)); + if (nodes.find(e.p) != nodes.end()) { return; } - nodesOnLevel.at(static_cast(e.p->v))[e.p] = dd::vEdge::zero(); + nodes[e.p] = dd::vCachedEdge::zero(); uAEmulate2Rec(e.p->e[0]); uAEmulate2Rec(e.p->e[1]); } diff --git a/src/Simulator.cpp b/src/Simulator.cpp index 41e693cf..afe95aa5 100644 --- a/src/Simulator.cpp +++ b/src/Simulator.cpp @@ -143,9 +143,7 @@ double Simulator::approximateByFidelity(std::unique_ptrcn.getCached(std::sqrt(CN::mag2(newEdge.w)), 0); - CN::div(c, newEdge.w, c); - newEdge.w = localDD->cn.lookup(c); + newEdge.w = localDD->cn.lookup(newEdge.w / std::sqrt(CN::mag2(newEdge.w))); dd::fp fidelity = 0; if (edge.p->v == newEdge.p->v) { @@ -231,10 +229,8 @@ double Simulator::approximateBySampling(std::unique_ptrcn.getCached(std::sqrt(CN::mag2(newEdge.w)), 0); - CN::div(c, newEdge.w, c); - newEdge.w = localDD->cn.lookup(c); + dd::vEdge newEdge = removeNodes(localDD, edge, dagEdges); + newEdge.w = localDD->cn.lookup(newEdge.w / std::sqrt(CN::mag2(newEdge.w))); dd::fp fidelity = 0; if (edge.p->v == newEdge.p->v) { @@ -290,9 +286,7 @@ dd::vEdge Simulator::removeNodes(std::unique_ptr>& l dd::vEdge r = localDD->makeDDNode(e.p->v, edges, false); dagEdges[e.p] = r; - dd::Complex c = localDD->cn.getCached(); - CN::mul(c, e.w, r.w); - r.w = localDD->cn.lookup(c); + r.w = localDD->cn.lookup(r.w * e.w); return r; } @@ -307,9 +301,10 @@ std::pair Simulator::getPathOfLeastResist } std::string result(getNumberOfQubits(), '0'); - dd::Complex pathValue = dd->cn.getCached(dd::RealNumber::val(rootEdge.w.r), dd::RealNumber::val(rootEdge.w.i)); + auto pathValue = static_cast(rootEdge.w); dd::vEdge cur = rootEdge; for (dd::Qubit i = rootEdge.p->v + 1; i-- > 0;) { + pathValue = pathValue * cur.w; dd::fp p0 = dd::ComplexNumbers::mag2(cur.p->e.at(0).w); const dd::fp p1 = dd::ComplexNumbers::mag2(cur.p->e.at(1).w); const dd::fp tmp = p0 + p1; @@ -320,17 +315,14 @@ std::pair Simulator::getPathOfLeastResist p0 /= tmp; // TODO: should p1 be normalized as well? if (p0 >= p1) { - CN::mul(pathValue, pathValue, cur.w); cur = cur.p->e.at(0); } else { result[static_cast(cur.p->v)] = '1'; - CN::mul(pathValue, pathValue, cur.w); - cur = cur.p->e.at(1); + cur = cur.p->e.at(1); } } - return {{dd::RealNumber::val(pathValue.r), dd::RealNumber::val(pathValue.i)}, - std::string{result.rbegin(), result.rend()}}; + return {pathValue, std::string{result.rbegin(), result.rend()}}; } template diff --git a/src/StochasticNoiseSimulator.cpp b/src/StochasticNoiseSimulator.cpp index 4fa815b6..aed92721 100644 --- a/src/StochasticNoiseSimulator.cpp +++ b/src/StochasticNoiseSimulator.cpp @@ -1,5 +1,7 @@ #include "StochasticNoiseSimulator.hpp" +#include "dd/Operations.hpp" + #include #include @@ -79,7 +81,7 @@ void StochasticNoiseSimulator::perfectSimulationRun() { } } - auto operation = dd::getDD(op.get(), Simulator::dd); + auto operation = dd::getDD(op.get(), *Simulator::dd); auto tmp = Simulator::dd->multiply(operation, Simulator::rootEdge); Simulator::dd->incRef(tmp); Simulator::dd->decRef(Simulator::rootEdge); @@ -232,7 +234,7 @@ void StochasticNoiseSimulator::runStochSimulationForId(std::size_t } expValue = expValue >> 1U; } - operation = dd::getDD(classicOp->getOperation(), localDD); + operation = dd::getDD(classicOp->getOperation(), *localDD); targets = classicOp->getOperation()->getTargets(); controls = classicOp->getOperation()->getControls(); if (!executeOp) { @@ -245,13 +247,13 @@ void StochasticNoiseSimulator::runStochSimulationForId(std::size_t if (targets.size() == 1 && controls.empty()) { auto* oper = localDD->stochasticNoiseOperationCache.lookup(op->getType(), static_cast(targets.front())); if (oper == nullptr) { - operation = dd::getDD(op.get(), localDD); + operation = dd::getDD(op.get(), *localDD); localDD->stochasticNoiseOperationCache.insert(op->getType(), static_cast(targets.front()), operation); } else { operation = *oper; } } else { - operation = dd::getDD(op.get(), localDD); + operation = dd::getDD(op.get(), *localDD); } } diff --git a/src/UnitarySimulator.cpp b/src/UnitarySimulator.cpp index e0d65a5a..b1f75206 100644 --- a/src/UnitarySimulator.cpp +++ b/src/UnitarySimulator.cpp @@ -10,9 +10,9 @@ void UnitarySimulator::construct() { // carry out actual computation auto start = std::chrono::steady_clock::now(); if (mode == Mode::Sequential) { - e = dd::buildFunctionality(CircuitSimulator::qc.get(), Simulator::dd); + e = dd::buildFunctionality(CircuitSimulator::qc.get(), *Simulator::dd); } else if (mode == Mode::Recursive) { - e = dd::buildFunctionalityRecursive(CircuitSimulator::qc.get(), Simulator::dd); + e = dd::buildFunctionalityRecursive(CircuitSimulator::qc.get(), *Simulator::dd); } auto end = std::chrono::steady_clock::now(); constructionTime = std::chrono::duration(end - start).count(); From e998b4e56dad0c41f0d82d14d2005fe645d03cb4 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 21:24:01 +0100 Subject: [PATCH 03/10] =?UTF-8?q?=F0=9F=94=A5=20remove=20cmake-lint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- .pre-commit-config.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d3cd4972..301654cd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -72,8 +72,6 @@ repos: hooks: - id: cmake-format additional_dependencies: [pyyaml] - - id: cmake-lint - additional_dependencies: [pyyaml] # Clang-format the C++ part of the code base automatically - repo: https://github.com/pre-commit/mirrors-clang-format From 857001e8cf5b92db6939ee1091b71785d18b3899 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 21:24:09 +0100 Subject: [PATCH 04/10] =?UTF-8?q?=E2=9E=95=20explicitly=20add=20googletest?= =?UTF-8?q?=20dependency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- CMakeLists.txt | 2 ++ cmake/ExternalDependencies.cmake | 30 ++++++++++++++++++++++++++++++ test/CMakeLists.txt | 10 ---------- 3 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 cmake/ExternalDependencies.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 34690a26..22ac476c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,8 @@ if(BUILD_MQT_DDSIM_BINDINGS) OPTIONAL_COMPONENTS Development.SABIModule) endif() +include(cmake/ExternalDependencies.cmake) + add_subdirectory(src) option(BUILD_MQT_DDSIM_TESTS "Also build tests for the MQT DDSIM project" ON) diff --git a/cmake/ExternalDependencies.cmake b/cmake/ExternalDependencies.cmake new file mode 100644 index 00000000..9c21c178 --- /dev/null +++ b/cmake/ExternalDependencies.cmake @@ -0,0 +1,30 @@ +# Declare all external dependencies and make sure that they are available. + +include(FetchContent) +set(FETCH_PACKAGES "") + +if(BUILD_MQT_DDSIM_TESTS) + set(gtest_force_shared_crt + ON + CACHE BOOL "" FORCE) + set(GTEST_VERSION + 1.14.0 + CACHE STRING "Google Test version") + set(GTEST_URL + https://github.com/google/googletest/archive/refs/tags/v${GTEST_VERSION}.tar.gz + ) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) + FetchContent_Declare(googletest URL ${GTEST_URL} FIND_PACKAGE_ARGS + ${GTEST_VERSION} NAMES GTest) + list(APPEND FETCH_PACKAGES googletest) + else() + find_package(googletest ${GTEST_VERSION} QUIET NAMES GTest) + if(NOT googletest_FOUND) + FetchContent_Declare(googletest URL ${GTEST_URL}) + list(APPEND FETCH_PACKAGES googletest) + endif() + endif() +endif() + +# Make all declared dependencies available. +FetchContent_MakeAvailable(${FETCH_PACKAGES}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1ad67580..f2ddc7f7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,13 +1,3 @@ -if(NOT TARGET gtest OR NOT TARGET gmock) - # Prevent overriding the parent project's compiler/linker settings on Windows - # cmake-lint: disable=C0103 - set(gtest_force_shared_crt - ON - CACHE BOOL "" FORCE) - add_subdirectory("${PROJECT_SOURCE_DIR}/extern/mqt-core/extern/googletest" - "extern/mqt-core/extern/googletest" EXCLUDE_FROM_ALL) -endif() - package_add_test( ${PROJECT_NAME}_test ${PROJECT_NAME} From dad2993eae1bf8010f1d09f83d0079487246e436 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 21:24:58 +0100 Subject: [PATCH 05/10] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20update=20taskflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- extern/taskflow | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/taskflow b/extern/taskflow index 0ad3d2f3..b91df2c3 160000 --- a/extern/taskflow +++ b/extern/taskflow @@ -1 +1 @@ -Subproject commit 0ad3d2f31c4bd4feee6bfd0164775016f024f588 +Subproject commit b91df2c365c20fa4cb43951192f6939fbe876abf From c9fe202fda4e47093479566833d495fc633f3b41 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 21:36:02 +0100 Subject: [PATCH 06/10] =?UTF-8?q?=F0=9F=94=A7=20do=20not=20use=20system=20?= =?UTF-8?q?includes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- test/test_circuit_sim.cpp | 2 +- test/test_fast_shor_sim.cpp | 2 +- test/test_grover_sim.cpp | 2 +- test/test_hybridsim.cpp | 2 +- test/test_output_ddvis.cpp | 2 +- test/test_path_sim.cpp | 2 +- test/test_shor_sim.cpp | 2 +- test/test_stoch_noise_sim.cpp | 2 +- test/test_unitary_sim.cpp | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/test_circuit_sim.cpp b/test/test_circuit_sim.cpp index a19ca28f..1c80f7a1 100644 --- a/test/test_circuit_sim.cpp +++ b/test/test_circuit_sim.cpp @@ -4,7 +4,7 @@ #include "algorithms/QFT.hpp" #include "algorithms/QPE.hpp" -#include +#include "gtest/gtest.h" #include TEST(CircuitSimTest, SingleOneQubitGateOnTwoQubitCircuit) { diff --git a/test/test_fast_shor_sim.cpp b/test/test_fast_shor_sim.cpp index ad25b6a9..d4449f49 100644 --- a/test/test_fast_shor_sim.cpp +++ b/test/test_fast_shor_sim.cpp @@ -1,6 +1,6 @@ #include "ShorFastSimulator.hpp" -#include +#include "gtest/gtest.h" #include /** diff --git a/test/test_grover_sim.cpp b/test/test_grover_sim.cpp index bc870e35..5395fe7b 100644 --- a/test/test_grover_sim.cpp +++ b/test/test_grover_sim.cpp @@ -1,6 +1,6 @@ #include "GroverSimulator.hpp" -#include +#include "gtest/gtest.h" #include /** diff --git a/test/test_hybridsim.cpp b/test/test_hybridsim.cpp index cbc35e93..17926fda 100644 --- a/test/test_hybridsim.cpp +++ b/test/test_hybridsim.cpp @@ -1,6 +1,6 @@ #include "HybridSchrodingerFeynmanSimulator.hpp" -#include +#include "gtest/gtest.h" #include using namespace qc::literals; diff --git a/test/test_output_ddvis.cpp b/test/test_output_ddvis.cpp index 4ab5f3f4..9bc36cf0 100644 --- a/test/test_output_ddvis.cpp +++ b/test/test_output_ddvis.cpp @@ -2,8 +2,8 @@ #include "HybridSchrodingerFeynmanSimulator.hpp" #include "UnitarySimulator.hpp" +#include "gtest/gtest.h" #include -#include #include using namespace qc::literals; diff --git a/test/test_path_sim.cpp b/test/test_path_sim.cpp index 640ab52a..36036df2 100644 --- a/test/test_path_sim.cpp +++ b/test/test_path_sim.cpp @@ -3,7 +3,7 @@ #include "algorithms/Grover.hpp" #include "dd/Export.hpp" -#include +#include "gtest/gtest.h" #include using namespace qc::literals; diff --git a/test/test_shor_sim.cpp b/test/test_shor_sim.cpp index 3beff796..b82467cb 100644 --- a/test/test_shor_sim.cpp +++ b/test/test_shor_sim.cpp @@ -1,6 +1,6 @@ #include "ShorSimulator.hpp" -#include +#include "gtest/gtest.h" #include /** diff --git a/test/test_stoch_noise_sim.cpp b/test/test_stoch_noise_sim.cpp index 0567a27f..817ffb6a 100644 --- a/test/test_stoch_noise_sim.cpp +++ b/test/test_stoch_noise_sim.cpp @@ -1,6 +1,6 @@ #include "StochasticNoiseSimulator.hpp" -#include +#include "gtest/gtest.h" #include /** diff --git a/test/test_unitary_sim.cpp b/test/test_unitary_sim.cpp index 0df7fe12..e376143d 100644 --- a/test/test_unitary_sim.cpp +++ b/test/test_unitary_sim.cpp @@ -1,6 +1,6 @@ #include "UnitarySimulator.hpp" -#include +#include "gtest/gtest.h" #include using namespace qc::literals; From 72513c53947f16b420c32f1be8f0168966bd0e02 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 21:36:42 +0100 Subject: [PATCH 07/10] =?UTF-8?q?=F0=9F=A9=B9=20move=20option=20to=20right?= =?UTF-8?q?=20place?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22ac476c..85edbe30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ endmacro() check_submodule_present(mqt-core) check_submodule_present(taskflow) +option(BUILD_MQT_DDSIM_TESTS "Also build tests for the MQT DDSIM project" ON) option(BUILD_MQT_DDSIM_BINDINGS "Build the MQT DDSIM Python bindings" OFF) if(BUILD_MQT_DDSIM_BINDINGS) # ensure that the BINDINGS option is set @@ -47,7 +48,6 @@ include(cmake/ExternalDependencies.cmake) add_subdirectory(src) -option(BUILD_MQT_DDSIM_TESTS "Also build tests for the MQT DDSIM project" ON) if(BUILD_MQT_DDSIM_TESTS) enable_testing() include(GoogleTest) From b6aca1b3bea3dd86c580605686c70d9c55cb1bf9 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 21:46:00 +0100 Subject: [PATCH 08/10] =?UTF-8?q?=F0=9F=A9=B9=20fix=20leftover=20cache=20m?= =?UTF-8?q?ention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- apps/simple.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/simple.cpp b/apps/simple.cpp index fac3f473..d136781f 100644 --- a/apps/simple.cpp +++ b/apps/simple.cpp @@ -247,8 +247,7 @@ int main(int argc, char** argv) { // NOLINT(bugprone-exception-escape) } if (vm.count("pcomplex") > 0) { - outputObj["complex_stats"]["cache_count"] = ddsim->dd->cn.cacheCount(); - outputObj["complex_stats"]["real_count"] = ddsim->dd->cn.realCount(); + outputObj["complex_stats"]["real_count"] = ddsim->dd->cn.realCount(); } if (vm.count("dump_complex") > 0) { From ca7e94ae36040dd9facaaf8c9e5eab3166798b14 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 21:53:52 +0100 Subject: [PATCH 09/10] =?UTF-8?q?=F0=9F=A9=B9=20fix=20one=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- test/python/primitives/test_estimator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/primitives/test_estimator.py b/test/python/primitives/test_estimator.py index 8be42bf8..a26d2956 100644 --- a/test/python/primitives/test_estimator.py +++ b/test/python/primitives/test_estimator.py @@ -124,7 +124,7 @@ def test_estimator_run_multiple_circuits_observables_no_params( result = estimator.run([qc_x, qc_y, qc_z], [pauli_x, pauli_y, pauli_z]).result() assert isinstance(result, EstimatorResult) - assert np.array_equal(result.values, [1, 1, 1]) + np.testing.assert_allclose(result.values, [1.0, 1.0, 1.0], rtol=1e-7, atol=1e-7) def test_estimator_run_multiple_circuits_observables_with_params( From fbd9891bac08310f0735cfb28dcce42ba6643356 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 21:54:15 +0100 Subject: [PATCH 10/10] =?UTF-8?q?=F0=9F=A9=B9=20fix=20one=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- test/python/primitives/test_estimator.py | 46 ++++++++++++++++++------ 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/test/python/primitives/test_estimator.py b/test/python/primitives/test_estimator.py index a26d2956..ccb2b64b 100644 --- a/test/python/primitives/test_estimator.py +++ b/test/python/primitives/test_estimator.py @@ -56,11 +56,17 @@ def observables() -> list[SparsePauliOp]: hamiltonian_2 = SparsePauliOp.from_list([("IZ", 1)]) hamiltonian_3 = SparsePauliOp.from_list([("ZI", 1), ("ZZ", 1)]) - return [observable, [hamiltonian_1, hamiltonian_2, hamiltonian_3], [pauli_x, pauli_y, pauli_z]] + return [ + observable, + [hamiltonian_1, hamiltonian_2, hamiltonian_3], + [pauli_x, pauli_y, pauli_z], + ] def test_estimator_run_single_circuit__observable_no_params( - circuits: list[QuantumCircuit], observables: list[SparsePauliOp], estimator: Estimator + circuits: list[QuantumCircuit], + observables: list[SparsePauliOp], + estimator: Estimator, ) -> None: """test for estimator with a single circuit/observable and no parameters""" circuit = circuits[0].assign_parameters([0, 1, 1, 2, 3, 5]) @@ -95,7 +101,9 @@ def test_run_with_operator(circuits: list[QuantumCircuit], estimator: Estimator) def test_estimator_run_single_circuit__observable_with_params( - circuits: list[QuantumCircuit], observables: list[SparsePauliOp], estimator: Estimator + circuits: list[QuantumCircuit], + observables: list[SparsePauliOp], + estimator: Estimator, ) -> None: """test for estimator with a single circuit/observable and parameters""" circuit = circuits[0] @@ -115,7 +123,9 @@ def test_estimator_run_single_circuit__observable_with_params( def test_estimator_run_multiple_circuits_observables_no_params( - circuits: list[QuantumCircuit], observables: list[SparsePauliOp], estimator: Estimator + circuits: list[QuantumCircuit], + observables: list[SparsePauliOp], + estimator: Estimator, ) -> None: """test for estimator with multiple circuits/observables and no parameters""" qc_x, qc_y, qc_z = circuits[2] @@ -128,15 +138,23 @@ def test_estimator_run_multiple_circuits_observables_no_params( def test_estimator_run_multiple_circuits_observables_with_params( - circuits: list[QuantumCircuit], observables: list[SparsePauliOp], estimator: Estimator + circuits: list[QuantumCircuit], + observables: list[SparsePauliOp], + estimator: Estimator, ) -> None: """test for estimator with multiple circuits/observables with parameters""" psi1, psi2 = circuits[1] hamiltonian_1, hamiltonian_2, hamiltonian_3 = observables[1] - theta_1, theta_2, theta_3 = ([0, 1, 1, 2, 3, 5], [0, 1, 1, 2, 3, 5, 8, 13], [1, 2, 3, 4, 5, 6]) + theta_1, theta_2, theta_3 = ( + [0, 1, 1, 2, 3, 5], + [0, 1, 1, 2, 3, 5, 8, 13], + [1, 2, 3, 4, 5, 6], + ) result = estimator.run( - [psi1, psi2, psi1], [hamiltonian_1, hamiltonian_2, hamiltonian_3], [theta_1, theta_2, theta_3] + [psi1, psi2, psi1], + [hamiltonian_1, hamiltonian_2, hamiltonian_3], + [theta_1, theta_2, theta_3], ).result() assert isinstance(result, EstimatorResult) @@ -144,12 +162,18 @@ def test_estimator_run_multiple_circuits_observables_with_params( def test_estimator_sequenctial_run( - circuits: list[QuantumCircuit], observables: list[SparsePauliOp], estimator: Estimator + circuits: list[QuantumCircuit], + observables: list[SparsePauliOp], + estimator: Estimator, ) -> None: """test for estimator's sequenctial run""" psi1, psi2 = circuits[1] hamiltonian_1, hamiltonian_2, hamiltonian_3 = observables[1] - theta_1, theta_2, theta_3 = ([0, 1, 1, 2, 3, 5], [0, 1, 1, 2, 3, 5, 8, 13], [1, 2, 3, 4, 5, 6]) + theta_1, theta_2, theta_3 = ( + [0, 1, 1, 2, 3, 5], + [0, 1, 1, 2, 3, 5, 8, 13], + [1, 2, 3, 4, 5, 6], + ) # First run result = estimator.run([psi1], [hamiltonian_1], [theta_1]).result() @@ -171,7 +195,9 @@ def test_estimator_sequenctial_run( # Last run result4 = estimator.run( - [psi1, psi2, psi1], [hamiltonian_1, hamiltonian_2, hamiltonian_3], [theta_1, theta_2, theta_3] + [psi1, psi2, psi1], + [hamiltonian_1, hamiltonian_2, hamiltonian_3], + [theta_1, theta_2, theta_3], ).result() assert isinstance(result4, EstimatorResult)