From 0a5651ab13a54761016af6c4dae176a4e1f75f03 Mon Sep 17 00:00:00 2001 From: Theresa Date: Thu, 8 Aug 2024 15:20:07 +0200 Subject: [PATCH 01/38] Added mqt-core as submodule --- .gitmodules | 3 +++ extern/mqt-core | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 extern/mqt-core diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..a1970e28 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "extern/mqt-core"] + path = extern/mqt-core + url = git@github.com:cda-tum/mqt-core.git diff --git a/extern/mqt-core b/extern/mqt-core new file mode 160000 index 00000000..8fbfaa52 --- /dev/null +++ b/extern/mqt-core @@ -0,0 +1 @@ +Subproject commit 8fbfaa5283e8a4c42ddb768a6bf59c3751ac4443 From dde15d3d93bb060b0457b602228df038dea938d8 Mon Sep 17 00:00:00 2001 From: Theresa Date: Thu, 8 Aug 2024 15:28:32 +0200 Subject: [PATCH 02/38] Update submodule to latest version --- extern/mqt-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/mqt-core b/extern/mqt-core index 8fbfaa52..2a7a9295 160000 --- a/extern/mqt-core +++ b/extern/mqt-core @@ -1 +1 @@ -Subproject commit 8fbfaa5283e8a4c42ddb768a6bf59c3751ac4443 +Subproject commit 2a7a92951fb67d0c4e795afbd17449063aa42d20 From 3541a8e4a2e8a9a5ff484da9d36748a8d71eb90f Mon Sep 17 00:00:00 2001 From: Theresa Date: Thu, 8 Aug 2024 16:17:40 +0200 Subject: [PATCH 03/38] :sparkles: Approximate equivalence checking for construction checker --- include/Configuration.hpp | 2 + src/checker/dd/DDEquivalenceChecker.cpp | 61 ++++++++++++++----------- test/test_equality.cpp | 28 ++++++++++++ 3 files changed, 65 insertions(+), 26 deletions(-) diff --git a/include/Configuration.hpp b/include/Configuration.hpp index 87ce7118..b0eea0a0 100644 --- a/include/Configuration.hpp +++ b/include/Configuration.hpp @@ -62,7 +62,9 @@ class Configuration { struct Functionality { double traceThreshold = 1e-8; + double approximateCheckingThreshold = 0.8; bool checkPartialEquivalence = false; + bool checkApproximateEquivalence = false; }; // configuration options for the simulation scheme diff --git a/src/checker/dd/DDEquivalenceChecker.cpp b/src/checker/dd/DDEquivalenceChecker.cpp index 3639a984..9018aa22 100644 --- a/src/checker/dd/DDEquivalenceChecker.cpp +++ b/src/checker/dd/DDEquivalenceChecker.cpp @@ -5,6 +5,7 @@ #include "checker/dd/DDEquivalenceChecker.hpp" +#include "Configuration.hpp" #include "EquivalenceCriterion.hpp" #include "checker/EquivalenceChecker.hpp" #include "checker/dd/DDPackageConfigs.hpp" @@ -15,6 +16,7 @@ #include "checker/dd/applicationscheme/OneToOneApplicationScheme.hpp" #include "checker/dd/applicationscheme/ProportionalApplicationScheme.hpp" #include "checker/dd/applicationscheme/SequentialApplicationScheme.hpp" +#include "dd/ComplexValue.hpp" #include "dd/DDpackageConfig.hpp" #include "dd/Package_fwd.hpp" @@ -48,34 +50,41 @@ DDEquivalenceChecker::equals(const DDType& e, const DDType& f) { // decision diagrams being extremely close (for some definition of `close`). if constexpr (std::is_same_v) { // for matrices this can be resolved by calculating their Frobenius inner - // product trace(U V^-1) and comparing it to some threshold. in a similar - // fashion, we can simply compare U V^-1 with the identity, which results in - // a much simpler check that is not prone to overflow. - bool isClose{}; - const bool eIsClose = - dd->isCloseToIdentity(e, configuration.functionality.traceThreshold); - const bool fIsClose = - dd->isCloseToIdentity(f, configuration.functionality.traceThreshold); - if (eIsClose || fIsClose) { - // if any of the DDs is close to the identity (structure), the result can - // be decided by whether both DDs are close enough to the identity. - isClose = eIsClose && fIsClose; - } else { - // otherwise, one DD needs to be inverted before multiplying both of them - // together and checking whether the resulting DD is close enough to the - // identity. + // product trace(U V^-1) and comparing it to some threshold. + if (configuration.functionality.checkApproximateEquivalence) { auto g = dd->multiply(e, dd->conjugateTranspose(f)); - isClose = - dd->isCloseToIdentity(g, configuration.functionality.traceThreshold); - } - - if (isClose) { - // whenever the top edge weights differ, both decision diagrams are only - // equivalent up to a global phase - if (!e.w.approximatelyEquals(f.w)) { - return EquivalenceCriterion::EquivalentUpToGlobalPhase; + auto trace = dd->trace(g, nqubits).mag(); + if (trace >= configuration.functionality.approximateCheckingThreshold) { + return EquivalenceCriterion::Equivalent; + } + } else { + // in a similar fashion, we can simply compare U V^-1 with the identity, + // which results in a much simpler check that is not prone to overflow. + bool isClose{}; + const bool eIsClose = + dd->isCloseToIdentity(e, configuration.functionality.traceThreshold); + const bool fIsClose = + dd->isCloseToIdentity(f, configuration.functionality.traceThreshold); + if (eIsClose || fIsClose) { + // if any of the DDs is close to the identity (structure), the result + // can be decided by whether both DDs are close enough to the identity. + isClose = eIsClose && fIsClose; + } else { + // otherwise, one DD needs to be inverted before multiplying both of + // them together and checking whether the resulting DD is close enough + // to the identity. + auto g = dd->multiply(e, dd->conjugateTranspose(f)); + isClose = dd->isCloseToIdentity( + g, configuration.functionality.traceThreshold); + } + if (isClose) { + // whenever the top edge weights differ, both decision diagrams are only + // equivalent up to a global phase + if (!e.w.approximatelyEquals(f.w)) { + return EquivalenceCriterion::EquivalentUpToGlobalPhase; + } + return EquivalenceCriterion::Equivalent; } - return EquivalenceCriterion::Equivalent; } } else { // for vectors this is resolved by computing the inner product (or fidelity) diff --git a/test/test_equality.cpp b/test/test_equality.cpp index 60c8270d..48a5e1b2 100644 --- a/test/test_equality.cpp +++ b/test/test_equality.cpp @@ -604,3 +604,31 @@ TEST_F(EqualityTest, StripIdleQubitInOutputPermutationWithAncilla) { EXPECT_EQ(ecm.getResults().numAncillae1, 0); EXPECT_EQ(ecm.getResults().numAncillae2, 0); } + +TEST_F(EqualityTest, ApproximateEquivalenceConstructionEqual) { + qc1 = qc::QuantumComputation(3); + qc2 = qc::QuantumComputation(3); + // Toffoli gate + qc1.mcx({0, 1}, 2); + qc2.i(0); + config.execution.runConstructionChecker = true; + config.functionality.checkApproximateEquivalence = true; + config.functionality.approximateCheckingThreshold = 0.7; + ec::EquivalenceCheckingManager ecm(qc1, qc2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); +} + +TEST_F(EqualityTest, ApproximateEquivalenceConstructionNotEqual) { + qc1 = qc::QuantumComputation(3); + qc2 = qc::QuantumComputation(3); + // Toffoli gate + qc1.mcx({0, 1}, 2); + qc2.i(0); + config.execution.runConstructionChecker = true; + config.functionality.checkApproximateEquivalence = true; + config.functionality.approximateCheckingThreshold = 0.8; + ec::EquivalenceCheckingManager ecm(qc1, qc2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); +} From b3e5bf274f32e1f8af913c765510183a759cb453 Mon Sep 17 00:00:00 2001 From: Theresa Date: Thu, 8 Aug 2024 16:52:44 +0200 Subject: [PATCH 04/38] :sparkles: Approximate equivalence checking for alternating checker --- src/checker/dd/DDAlternatingChecker.cpp | 35 +++++++++++++++---------- test/test_equality.cpp | 28 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/checker/dd/DDAlternatingChecker.cpp b/src/checker/dd/DDAlternatingChecker.cpp index 6ee0c313..c66e2b8e 100644 --- a/src/checker/dd/DDAlternatingChecker.cpp +++ b/src/checker/dd/DDAlternatingChecker.cpp @@ -102,21 +102,28 @@ EquivalenceCriterion DDAlternatingChecker::checkEquivalence() { garbage[static_cast(q)] = qc1->logicalQubitIsGarbage(q) && qc2->logicalQubitIsGarbage(q); } - const bool isClose = - configuration.functionality.checkPartialEquivalence - ? dd->isCloseToIdentity(functionality, - configuration.functionality.traceThreshold, - garbage, false) - : dd->isCloseToIdentity(functionality, - configuration.functionality.traceThreshold); - - if (isClose) { - // whenever the top edge weight is not one, both decision diagrams are only - // equivalent up to a global phase - if (!functionality.w.approximatelyEquals(dd::Complex::one())) { - return EquivalenceCriterion::EquivalentUpToGlobalPhase; + if (configuration.functionality.checkApproximateEquivalence) { + auto trace = dd->trace(functionality, nqubits).mag(); + if (trace >= configuration.functionality.approximateCheckingThreshold) { + return EquivalenceCriterion::Equivalent; + } + } else { + const bool isClose = + configuration.functionality.checkPartialEquivalence + ? dd->isCloseToIdentity(functionality, + configuration.functionality.traceThreshold, + garbage, false) + : dd->isCloseToIdentity(functionality, + configuration.functionality.traceThreshold); + + if (isClose) { + // whenever the top edge weight is not one, both decision diagrams are + // only equivalent up to a global phase + if (!functionality.w.approximatelyEquals(dd::Complex::one())) { + return EquivalenceCriterion::EquivalentUpToGlobalPhase; + } + return EquivalenceCriterion::Equivalent; } - return EquivalenceCriterion::Equivalent; } return EquivalenceCriterion::NotEquivalent; } diff --git a/test/test_equality.cpp b/test/test_equality.cpp index 48a5e1b2..0993dac5 100644 --- a/test/test_equality.cpp +++ b/test/test_equality.cpp @@ -632,3 +632,31 @@ TEST_F(EqualityTest, ApproximateEquivalenceConstructionNotEqual) { ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); } + +TEST_F(EqualityTest, ApproximateEquivalenceAlternatingEqual) { + qc1 = qc::QuantumComputation(3); + qc2 = qc::QuantumComputation(3); + // Toffoli gate + qc1.mcx({0, 1}, 2); + qc2.i(0); + config.execution.runAlternatingChecker = true; + config.functionality.checkApproximateEquivalence = true; + config.functionality.approximateCheckingThreshold = 0.7; + ec::EquivalenceCheckingManager ecm(qc1, qc2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); +} + +TEST_F(EqualityTest, ApproximateEquivalenceAlternatingNotEqual) { + qc1 = qc::QuantumComputation(3); + qc2 = qc::QuantumComputation(3); + // Toffoli gate + qc1.mcx({0, 1}, 2); + qc2.i(0); + config.execution.runAlternatingChecker = true; + config.functionality.checkApproximateEquivalence = true; + config.functionality.approximateCheckingThreshold = 0.8; + ec::EquivalenceCheckingManager ecm(qc1, qc2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); +} From b2d44a5c45a618dc9b584209f3dababeff55e5ac Mon Sep 17 00:00:00 2001 From: Theresa Date: Mon, 12 Aug 2024 09:45:58 +0200 Subject: [PATCH 05/38] :art: Change threshold --- include/Configuration.hpp | 2 +- src/checker/dd/DDAlternatingChecker.cpp | 3 ++- src/checker/dd/DDEquivalenceChecker.cpp | 3 ++- test/test_equality.cpp | 8 ++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/Configuration.hpp b/include/Configuration.hpp index b0eea0a0..3f4bb34b 100644 --- a/include/Configuration.hpp +++ b/include/Configuration.hpp @@ -62,7 +62,7 @@ class Configuration { struct Functionality { double traceThreshold = 1e-8; - double approximateCheckingThreshold = 0.8; + double approximateCheckingThreshold = 1e-8; bool checkPartialEquivalence = false; bool checkApproximateEquivalence = false; }; diff --git a/src/checker/dd/DDAlternatingChecker.cpp b/src/checker/dd/DDAlternatingChecker.cpp index c66e2b8e..d2efce0d 100644 --- a/src/checker/dd/DDAlternatingChecker.cpp +++ b/src/checker/dd/DDAlternatingChecker.cpp @@ -104,7 +104,8 @@ EquivalenceCriterion DDAlternatingChecker::checkEquivalence() { } if (configuration.functionality.checkApproximateEquivalence) { auto trace = dd->trace(functionality, nqubits).mag(); - if (trace >= configuration.functionality.approximateCheckingThreshold) { + if (std::abs(trace - 1.) < + configuration.functionality.approximateCheckingThreshold) { return EquivalenceCriterion::Equivalent; } } else { diff --git a/src/checker/dd/DDEquivalenceChecker.cpp b/src/checker/dd/DDEquivalenceChecker.cpp index 9018aa22..042986de 100644 --- a/src/checker/dd/DDEquivalenceChecker.cpp +++ b/src/checker/dd/DDEquivalenceChecker.cpp @@ -54,7 +54,8 @@ DDEquivalenceChecker::equals(const DDType& e, const DDType& f) { if (configuration.functionality.checkApproximateEquivalence) { auto g = dd->multiply(e, dd->conjugateTranspose(f)); auto trace = dd->trace(g, nqubits).mag(); - if (trace >= configuration.functionality.approximateCheckingThreshold) { + if (std::abs(trace - 1.) < + configuration.functionality.approximateCheckingThreshold) { return EquivalenceCriterion::Equivalent; } } else { diff --git a/test/test_equality.cpp b/test/test_equality.cpp index 0993dac5..54862780 100644 --- a/test/test_equality.cpp +++ b/test/test_equality.cpp @@ -613,7 +613,7 @@ TEST_F(EqualityTest, ApproximateEquivalenceConstructionEqual) { qc2.i(0); config.execution.runConstructionChecker = true; config.functionality.checkApproximateEquivalence = true; - config.functionality.approximateCheckingThreshold = 0.7; + config.functionality.approximateCheckingThreshold = 0.3; ec::EquivalenceCheckingManager ecm(qc1, qc2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); @@ -627,7 +627,7 @@ TEST_F(EqualityTest, ApproximateEquivalenceConstructionNotEqual) { qc2.i(0); config.execution.runConstructionChecker = true; config.functionality.checkApproximateEquivalence = true; - config.functionality.approximateCheckingThreshold = 0.8; + config.functionality.approximateCheckingThreshold = 0.2; ec::EquivalenceCheckingManager ecm(qc1, qc2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); @@ -641,7 +641,7 @@ TEST_F(EqualityTest, ApproximateEquivalenceAlternatingEqual) { qc2.i(0); config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; - config.functionality.approximateCheckingThreshold = 0.7; + config.functionality.approximateCheckingThreshold = 0.3; ec::EquivalenceCheckingManager ecm(qc1, qc2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); @@ -655,7 +655,7 @@ TEST_F(EqualityTest, ApproximateEquivalenceAlternatingNotEqual) { qc2.i(0); config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; - config.functionality.approximateCheckingThreshold = 0.8; + config.functionality.approximateCheckingThreshold = 0.2; ec::EquivalenceCheckingManager ecm(qc1, qc2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); From 797af78bf4f0b99ec46cb965d923387ac355f9cd Mon Sep 17 00:00:00 2001 From: Theresa Date: Mon, 12 Aug 2024 11:02:37 +0200 Subject: [PATCH 06/38] :white_check_mark: Add test files --- .../heisenberg16.qasm | 1032 +++++++++++++++++ .../heisenberg16_out_default_error.qasm | 635 ++++++++++ .../heisenberg16_out_high_error.qasm | 35 + .../heisenberg16_out_small_error.qasm | 864 ++++++++++++++ 4 files changed, 2566 insertions(+) create mode 100644 test/circuits/approximateEquivalenceTest/heisenberg16.qasm create mode 100644 test/circuits/approximateEquivalenceTest/heisenberg16_out_default_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/heisenberg16_out_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/heisenberg16_out_small_error.qasm diff --git a/test/circuits/approximateEquivalenceTest/heisenberg16.qasm b/test/circuits/approximateEquivalenceTest/heisenberg16.qasm new file mode 100644 index 00000000..7beafe49 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/heisenberg16.qasm @@ -0,0 +1,1032 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[16]; +creg c[16]; +x q[1]; +x q[3]; +x q[5]; +x q[7]; +x q[9]; +x q[11]; +x q[13]; +x q[15]; +h q[0]; +h q[1]; +cx q[0],q[1]; +rz(-0.25) q[1]; +cx q[0],q[1]; +h q[0]; +h q[1]; +h q[1]; +h q[2]; +cx q[1],q[2]; +rz(-0.25) q[2]; +cx q[1],q[2]; +h q[1]; +h q[2]; +h q[2]; +h q[3]; +cx q[2],q[3]; +rz(-0.25) q[3]; +cx q[2],q[3]; +h q[2]; +h q[3]; +h q[3]; +h q[4]; +cx q[3],q[4]; +rz(-0.25) q[4]; +cx q[3],q[4]; +h q[3]; +h q[4]; +h q[4]; +h q[5]; +cx q[4],q[5]; +rz(-0.25) q[5]; +cx q[4],q[5]; +h q[4]; +h q[5]; +h q[5]; +h q[6]; +cx q[5],q[6]; +rz(-0.25) q[6]; +cx q[5],q[6]; +h q[5]; +h q[6]; +h q[6]; +h q[7]; +cx q[6],q[7]; +rz(-0.25) q[7]; +cx q[6],q[7]; +h q[6]; +h q[7]; +h q[7]; +h q[8]; +cx q[7],q[8]; +rz(-0.25) q[8]; +cx q[7],q[8]; +h q[7]; +h q[8]; +h q[8]; +h q[9]; +cx q[8],q[9]; +rz(-0.25) q[9]; +cx q[8],q[9]; +h q[8]; +h q[9]; +h q[9]; +h q[10]; +cx q[9],q[10]; +rz(-0.25) q[10]; +cx q[9],q[10]; +h q[9]; +h q[10]; +h q[10]; +h q[11]; +cx q[10],q[11]; +rz(-0.25) q[11]; +cx q[10],q[11]; +h q[10]; +h q[11]; +h q[11]; +h q[12]; +cx q[11],q[12]; +rz(-0.25) q[12]; +cx q[11],q[12]; +h q[11]; +h q[12]; +h q[12]; +h q[13]; +cx q[12],q[13]; +rz(-0.25) q[13]; +cx q[12],q[13]; +h q[12]; +h q[13]; +h q[13]; +h q[14]; +cx q[13],q[14]; +rz(-0.25) q[14]; +cx q[13],q[14]; +h q[13]; +h q[14]; +h q[14]; +h q[15]; +cx q[14],q[15]; +rz(-0.25) q[15]; +cx q[14],q[15]; +h q[14]; +h q[15]; +rx(-pi/2) q[0]; +rx(-pi/2) q[1]; +cx q[0],q[1]; +rz(-0.25) q[1]; +cx q[0],q[1]; +rx(pi/2) q[0]; +rx(pi/2) q[1]; +rx(-pi/2) q[1]; +rx(-pi/2) q[2]; +cx q[1],q[2]; +rz(-0.25) q[2]; +cx q[1],q[2]; +rx(pi/2) q[1]; +rx(pi/2) q[2]; +rx(-pi/2) q[2]; +rx(-pi/2) q[3]; +cx q[2],q[3]; +rz(-0.25) q[3]; +cx q[2],q[3]; +rx(pi/2) q[2]; +rx(pi/2) q[3]; +rx(-pi/2) q[3]; +rx(-pi/2) q[4]; +cx q[3],q[4]; +rz(-0.25) q[4]; +cx q[3],q[4]; +rx(pi/2) q[3]; +rx(pi/2) q[4]; +rx(-pi/2) q[4]; +rx(-pi/2) q[5]; +cx q[4],q[5]; +rz(-0.25) q[5]; +cx q[4],q[5]; +rx(pi/2) q[4]; +rx(pi/2) q[5]; +rx(-pi/2) q[5]; +rx(-pi/2) q[6]; +cx q[5],q[6]; +rz(-0.25) q[6]; +cx q[5],q[6]; +rx(pi/2) q[5]; +rx(pi/2) q[6]; +rx(-pi/2) q[6]; +rx(-pi/2) q[7]; +cx q[6],q[7]; +rz(-0.25) q[7]; +cx q[6],q[7]; +rx(pi/2) q[6]; +rx(pi/2) q[7]; +rx(-pi/2) q[7]; +rx(-pi/2) q[8]; +cx q[7],q[8]; +rz(-0.25) q[8]; +cx q[7],q[8]; +rx(pi/2) q[7]; +rx(pi/2) q[8]; +rx(-pi/2) q[8]; +rx(-pi/2) q[9]; +cx q[8],q[9]; +rz(-0.25) q[9]; +cx q[8],q[9]; +rx(pi/2) q[8]; +rx(pi/2) q[9]; +rx(-pi/2) q[9]; +rx(-pi/2) q[10]; +cx q[9],q[10]; +rz(-0.25) q[10]; +cx q[9],q[10]; +rx(pi/2) q[9]; +rx(pi/2) q[10]; +rx(-pi/2) q[10]; +rx(-pi/2) q[11]; +cx q[10],q[11]; +rz(-0.25) q[11]; +cx q[10],q[11]; +rx(pi/2) q[10]; +rx(pi/2) q[11]; +rx(-pi/2) q[11]; +rx(-pi/2) q[12]; +cx q[11],q[12]; +rz(-0.25) q[12]; +cx q[11],q[12]; +rx(pi/2) q[11]; +rx(pi/2) q[12]; +rx(-pi/2) q[12]; +rx(-pi/2) q[13]; +cx q[12],q[13]; +rz(-0.25) q[13]; +cx q[12],q[13]; +rx(pi/2) q[12]; +rx(pi/2) q[13]; +rx(-pi/2) q[13]; +rx(-pi/2) q[14]; +cx q[13],q[14]; +rz(-0.25) q[14]; +cx q[13],q[14]; +rx(pi/2) q[13]; +rx(pi/2) q[14]; +rx(-pi/2) q[14]; +rx(-pi/2) q[15]; +cx q[14],q[15]; +rz(-0.25) q[15]; +cx q[14],q[15]; +rx(pi/2) q[14]; +rx(pi/2) q[15]; +cx q[0],q[1]; +rz(0) q[1]; +cx q[0],q[1]; +cx q[1],q[2]; +rz(0) q[2]; +cx q[1],q[2]; +cx q[2],q[3]; +rz(0) q[3]; +cx q[2],q[3]; +cx q[3],q[4]; +rz(0) q[4]; +cx q[3],q[4]; +cx q[4],q[5]; +rz(0) q[5]; +cx q[4],q[5]; +cx q[5],q[6]; +rz(0) q[6]; +cx q[5],q[6]; +cx q[6],q[7]; +rz(0) q[7]; +cx q[6],q[7]; +cx q[7],q[8]; +rz(0) q[8]; +cx q[7],q[8]; +cx q[8],q[9]; +rz(0) q[9]; +cx q[8],q[9]; +cx q[9],q[10]; +rz(0) q[10]; +cx q[9],q[10]; +cx q[10],q[11]; +rz(0) q[11]; +cx q[10],q[11]; +cx q[11],q[12]; +rz(0) q[12]; +cx q[11],q[12]; +cx q[12],q[13]; +rz(0) q[13]; +cx q[12],q[13]; +cx q[13],q[14]; +rz(0) q[14]; +cx q[13],q[14]; +cx q[14],q[15]; +rz(0) q[15]; +cx q[14],q[15]; +h q[0]; +h q[1]; +cx q[0],q[1]; +rz(-0.25) q[1]; +cx q[0],q[1]; +h q[0]; +h q[1]; +h q[1]; +h q[2]; +cx q[1],q[2]; +rz(-0.25) q[2]; +cx q[1],q[2]; +h q[1]; +h q[2]; +h q[2]; +h q[3]; +cx q[2],q[3]; +rz(-0.25) q[3]; +cx q[2],q[3]; +h q[2]; +h q[3]; +h q[3]; +h q[4]; +cx q[3],q[4]; +rz(-0.25) q[4]; +cx q[3],q[4]; +h q[3]; +h q[4]; +h q[4]; +h q[5]; +cx q[4],q[5]; +rz(-0.25) q[5]; +cx q[4],q[5]; +h q[4]; +h q[5]; +h q[5]; +h q[6]; +cx q[5],q[6]; +rz(-0.25) q[6]; +cx q[5],q[6]; +h q[5]; +h q[6]; +h q[6]; +h q[7]; +cx q[6],q[7]; +rz(-0.25) q[7]; +cx q[6],q[7]; +h q[6]; +h q[7]; +h q[7]; +h q[8]; +cx q[7],q[8]; +rz(-0.25) q[8]; +cx q[7],q[8]; +h q[7]; +h q[8]; +h q[8]; +h q[9]; +cx q[8],q[9]; +rz(-0.25) q[9]; +cx q[8],q[9]; +h q[8]; +h q[9]; +h q[9]; +h q[10]; +cx q[9],q[10]; +rz(-0.25) q[10]; +cx q[9],q[10]; +h q[9]; +h q[10]; +h q[10]; +h q[11]; +cx q[10],q[11]; +rz(-0.25) q[11]; +cx q[10],q[11]; +h q[10]; +h q[11]; +h q[11]; +h q[12]; +cx q[11],q[12]; +rz(-0.25) q[12]; +cx q[11],q[12]; +h q[11]; +h q[12]; +h q[12]; +h q[13]; +cx q[12],q[13]; +rz(-0.25) q[13]; +cx q[12],q[13]; +h q[12]; +h q[13]; +h q[13]; +h q[14]; +cx q[13],q[14]; +rz(-0.25) q[14]; +cx q[13],q[14]; +h q[13]; +h q[14]; +h q[14]; +h q[15]; +cx q[14],q[15]; +rz(-0.25) q[15]; +cx q[14],q[15]; +h q[14]; +h q[15]; +rx(-pi/2) q[0]; +rx(-pi/2) q[1]; +cx q[0],q[1]; +rz(-0.25) q[1]; +cx q[0],q[1]; +rx(pi/2) q[0]; +rx(pi/2) q[1]; +rx(-pi/2) q[1]; +rx(-pi/2) q[2]; +cx q[1],q[2]; +rz(-0.25) q[2]; +cx q[1],q[2]; +rx(pi/2) q[1]; +rx(pi/2) q[2]; +rx(-pi/2) q[2]; +rx(-pi/2) q[3]; +cx q[2],q[3]; +rz(-0.25) q[3]; +cx q[2],q[3]; +rx(pi/2) q[2]; +rx(pi/2) q[3]; +rx(-pi/2) q[3]; +rx(-pi/2) q[4]; +cx q[3],q[4]; +rz(-0.25) q[4]; +cx q[3],q[4]; +rx(pi/2) q[3]; +rx(pi/2) q[4]; +rx(-pi/2) q[4]; +rx(-pi/2) q[5]; +cx q[4],q[5]; +rz(-0.25) q[5]; +cx q[4],q[5]; +rx(pi/2) q[4]; +rx(pi/2) q[5]; +rx(-pi/2) q[5]; +rx(-pi/2) q[6]; +cx q[5],q[6]; +rz(-0.25) q[6]; +cx q[5],q[6]; +rx(pi/2) q[5]; +rx(pi/2) q[6]; +rx(-pi/2) q[6]; +rx(-pi/2) q[7]; +cx q[6],q[7]; +rz(-0.25) q[7]; +cx q[6],q[7]; +rx(pi/2) q[6]; +rx(pi/2) q[7]; +rx(-pi/2) q[7]; +rx(-pi/2) q[8]; +cx q[7],q[8]; +rz(-0.25) q[8]; +cx q[7],q[8]; +rx(pi/2) q[7]; +rx(pi/2) q[8]; +rx(-pi/2) q[8]; +rx(-pi/2) q[9]; +cx q[8],q[9]; +rz(-0.25) q[9]; +cx q[8],q[9]; +rx(pi/2) q[8]; +rx(pi/2) q[9]; +rx(-pi/2) q[9]; +rx(-pi/2) q[10]; +cx q[9],q[10]; +rz(-0.25) q[10]; +cx q[9],q[10]; +rx(pi/2) q[9]; +rx(pi/2) q[10]; +rx(-pi/2) q[10]; +rx(-pi/2) q[11]; +cx q[10],q[11]; +rz(-0.25) q[11]; +cx q[10],q[11]; +rx(pi/2) q[10]; +rx(pi/2) q[11]; +rx(-pi/2) q[11]; +rx(-pi/2) q[12]; +cx q[11],q[12]; +rz(-0.25) q[12]; +cx q[11],q[12]; +rx(pi/2) q[11]; +rx(pi/2) q[12]; +rx(-pi/2) q[12]; +rx(-pi/2) q[13]; +cx q[12],q[13]; +rz(-0.25) q[13]; +cx q[12],q[13]; +rx(pi/2) q[12]; +rx(pi/2) q[13]; +rx(-pi/2) q[13]; +rx(-pi/2) q[14]; +cx q[13],q[14]; +rz(-0.25) q[14]; +cx q[13],q[14]; +rx(pi/2) q[13]; +rx(pi/2) q[14]; +rx(-pi/2) q[14]; +rx(-pi/2) q[15]; +cx q[14],q[15]; +rz(-0.25) q[15]; +cx q[14],q[15]; +rx(pi/2) q[14]; +rx(pi/2) q[15]; +cx q[0],q[1]; +rz(0) q[1]; +cx q[0],q[1]; +cx q[1],q[2]; +rz(0) q[2]; +cx q[1],q[2]; +cx q[2],q[3]; +rz(0) q[3]; +cx q[2],q[3]; +cx q[3],q[4]; +rz(0) q[4]; +cx q[3],q[4]; +cx q[4],q[5]; +rz(0) q[5]; +cx q[4],q[5]; +cx q[5],q[6]; +rz(0) q[6]; +cx q[5],q[6]; +cx q[6],q[7]; +rz(0) q[7]; +cx q[6],q[7]; +cx q[7],q[8]; +rz(0) q[8]; +cx q[7],q[8]; +cx q[8],q[9]; +rz(0) q[9]; +cx q[8],q[9]; +cx q[9],q[10]; +rz(0) q[10]; +cx q[9],q[10]; +cx q[10],q[11]; +rz(0) q[11]; +cx q[10],q[11]; +cx q[11],q[12]; +rz(0) q[12]; +cx q[11],q[12]; +cx q[12],q[13]; +rz(0) q[13]; +cx q[12],q[13]; +cx q[13],q[14]; +rz(0) q[14]; +cx q[13],q[14]; +cx q[14],q[15]; +rz(0) q[15]; +cx q[14],q[15]; +h q[0]; +h q[1]; +cx q[0],q[1]; +rz(-0.25) q[1]; +cx q[0],q[1]; +h q[0]; +h q[1]; +h q[1]; +h q[2]; +cx q[1],q[2]; +rz(-0.25) q[2]; +cx q[1],q[2]; +h q[1]; +h q[2]; +h q[2]; +h q[3]; +cx q[2],q[3]; +rz(-0.25) q[3]; +cx q[2],q[3]; +h q[2]; +h q[3]; +h q[3]; +h q[4]; +cx q[3],q[4]; +rz(-0.25) q[4]; +cx q[3],q[4]; +h q[3]; +h q[4]; +h q[4]; +h q[5]; +cx q[4],q[5]; +rz(-0.25) q[5]; +cx q[4],q[5]; +h q[4]; +h q[5]; +h q[5]; +h q[6]; +cx q[5],q[6]; +rz(-0.25) q[6]; +cx q[5],q[6]; +h q[5]; +h q[6]; +h q[6]; +h q[7]; +cx q[6],q[7]; +rz(-0.25) q[7]; +cx q[6],q[7]; +h q[6]; +h q[7]; +h q[7]; +h q[8]; +cx q[7],q[8]; +rz(-0.25) q[8]; +cx q[7],q[8]; +h q[7]; +h q[8]; +h q[8]; +h q[9]; +cx q[8],q[9]; +rz(-0.25) q[9]; +cx q[8],q[9]; +h q[8]; +h q[9]; +h q[9]; +h q[10]; +cx q[9],q[10]; +rz(-0.25) q[10]; +cx q[9],q[10]; +h q[9]; +h q[10]; +h q[10]; +h q[11]; +cx q[10],q[11]; +rz(-0.25) q[11]; +cx q[10],q[11]; +h q[10]; +h q[11]; +h q[11]; +h q[12]; +cx q[11],q[12]; +rz(-0.25) q[12]; +cx q[11],q[12]; +h q[11]; +h q[12]; +h q[12]; +h q[13]; +cx q[12],q[13]; +rz(-0.25) q[13]; +cx q[12],q[13]; +h q[12]; +h q[13]; +h q[13]; +h q[14]; +cx q[13],q[14]; +rz(-0.25) q[14]; +cx q[13],q[14]; +h q[13]; +h q[14]; +h q[14]; +h q[15]; +cx q[14],q[15]; +rz(-0.25) q[15]; +cx q[14],q[15]; +h q[14]; +h q[15]; +rx(-pi/2) q[0]; +rx(-pi/2) q[1]; +cx q[0],q[1]; +rz(-0.25) q[1]; +cx q[0],q[1]; +rx(pi/2) q[0]; +rx(pi/2) q[1]; +rx(-pi/2) q[1]; +rx(-pi/2) q[2]; +cx q[1],q[2]; +rz(-0.25) q[2]; +cx q[1],q[2]; +rx(pi/2) q[1]; +rx(pi/2) q[2]; +rx(-pi/2) q[2]; +rx(-pi/2) q[3]; +cx q[2],q[3]; +rz(-0.25) q[3]; +cx q[2],q[3]; +rx(pi/2) q[2]; +rx(pi/2) q[3]; +rx(-pi/2) q[3]; +rx(-pi/2) q[4]; +cx q[3],q[4]; +rz(-0.25) q[4]; +cx q[3],q[4]; +rx(pi/2) q[3]; +rx(pi/2) q[4]; +rx(-pi/2) q[4]; +rx(-pi/2) q[5]; +cx q[4],q[5]; +rz(-0.25) q[5]; +cx q[4],q[5]; +rx(pi/2) q[4]; +rx(pi/2) q[5]; +rx(-pi/2) q[5]; +rx(-pi/2) q[6]; +cx q[5],q[6]; +rz(-0.25) q[6]; +cx q[5],q[6]; +rx(pi/2) q[5]; +rx(pi/2) q[6]; +rx(-pi/2) q[6]; +rx(-pi/2) q[7]; +cx q[6],q[7]; +rz(-0.25) q[7]; +cx q[6],q[7]; +rx(pi/2) q[6]; +rx(pi/2) q[7]; +rx(-pi/2) q[7]; +rx(-pi/2) q[8]; +cx q[7],q[8]; +rz(-0.25) q[8]; +cx q[7],q[8]; +rx(pi/2) q[7]; +rx(pi/2) q[8]; +rx(-pi/2) q[8]; +rx(-pi/2) q[9]; +cx q[8],q[9]; +rz(-0.25) q[9]; +cx q[8],q[9]; +rx(pi/2) q[8]; +rx(pi/2) q[9]; +rx(-pi/2) q[9]; +rx(-pi/2) q[10]; +cx q[9],q[10]; +rz(-0.25) q[10]; +cx q[9],q[10]; +rx(pi/2) q[9]; +rx(pi/2) q[10]; +rx(-pi/2) q[10]; +rx(-pi/2) q[11]; +cx q[10],q[11]; +rz(-0.25) q[11]; +cx q[10],q[11]; +rx(pi/2) q[10]; +rx(pi/2) q[11]; +rx(-pi/2) q[11]; +rx(-pi/2) q[12]; +cx q[11],q[12]; +rz(-0.25) q[12]; +cx q[11],q[12]; +rx(pi/2) q[11]; +rx(pi/2) q[12]; +rx(-pi/2) q[12]; +rx(-pi/2) q[13]; +cx q[12],q[13]; +rz(-0.25) q[13]; +cx q[12],q[13]; +rx(pi/2) q[12]; +rx(pi/2) q[13]; +rx(-pi/2) q[13]; +rx(-pi/2) q[14]; +cx q[13],q[14]; +rz(-0.25) q[14]; +cx q[13],q[14]; +rx(pi/2) q[13]; +rx(pi/2) q[14]; +rx(-pi/2) q[14]; +rx(-pi/2) q[15]; +cx q[14],q[15]; +rz(-0.25) q[15]; +cx q[14],q[15]; +rx(pi/2) q[14]; +rx(pi/2) q[15]; +cx q[0],q[1]; +rz(0) q[1]; +cx q[0],q[1]; +cx q[1],q[2]; +rz(0) q[2]; +cx q[1],q[2]; +cx q[2],q[3]; +rz(0) q[3]; +cx q[2],q[3]; +cx q[3],q[4]; +rz(0) q[4]; +cx q[3],q[4]; +cx q[4],q[5]; +rz(0) q[5]; +cx q[4],q[5]; +cx q[5],q[6]; +rz(0) q[6]; +cx q[5],q[6]; +cx q[6],q[7]; +rz(0) q[7]; +cx q[6],q[7]; +cx q[7],q[8]; +rz(0) q[8]; +cx q[7],q[8]; +cx q[8],q[9]; +rz(0) q[9]; +cx q[8],q[9]; +cx q[9],q[10]; +rz(0) q[10]; +cx q[9],q[10]; +cx q[10],q[11]; +rz(0) q[11]; +cx q[10],q[11]; +cx q[11],q[12]; +rz(0) q[12]; +cx q[11],q[12]; +cx q[12],q[13]; +rz(0) q[13]; +cx q[12],q[13]; +cx q[13],q[14]; +rz(0) q[14]; +cx q[13],q[14]; +cx q[14],q[15]; +rz(0) q[15]; +cx q[14],q[15]; +h q[0]; +h q[1]; +cx q[0],q[1]; +rz(-0.25) q[1]; +cx q[0],q[1]; +h q[0]; +h q[1]; +h q[1]; +h q[2]; +cx q[1],q[2]; +rz(-0.25) q[2]; +cx q[1],q[2]; +h q[1]; +h q[2]; +h q[2]; +h q[3]; +cx q[2],q[3]; +rz(-0.25) q[3]; +cx q[2],q[3]; +h q[2]; +h q[3]; +h q[3]; +h q[4]; +cx q[3],q[4]; +rz(-0.25) q[4]; +cx q[3],q[4]; +h q[3]; +h q[4]; +h q[4]; +h q[5]; +cx q[4],q[5]; +rz(-0.25) q[5]; +cx q[4],q[5]; +h q[4]; +h q[5]; +h q[5]; +h q[6]; +cx q[5],q[6]; +rz(-0.25) q[6]; +cx q[5],q[6]; +h q[5]; +h q[6]; +h q[6]; +h q[7]; +cx q[6],q[7]; +rz(-0.25) q[7]; +cx q[6],q[7]; +h q[6]; +h q[7]; +h q[7]; +h q[8]; +cx q[7],q[8]; +rz(-0.25) q[8]; +cx q[7],q[8]; +h q[7]; +h q[8]; +h q[8]; +h q[9]; +cx q[8],q[9]; +rz(-0.25) q[9]; +cx q[8],q[9]; +h q[8]; +h q[9]; +h q[9]; +h q[10]; +cx q[9],q[10]; +rz(-0.25) q[10]; +cx q[9],q[10]; +h q[9]; +h q[10]; +h q[10]; +h q[11]; +cx q[10],q[11]; +rz(-0.25) q[11]; +cx q[10],q[11]; +h q[10]; +h q[11]; +h q[11]; +h q[12]; +cx q[11],q[12]; +rz(-0.25) q[12]; +cx q[11],q[12]; +h q[11]; +h q[12]; +h q[12]; +h q[13]; +cx q[12],q[13]; +rz(-0.25) q[13]; +cx q[12],q[13]; +h q[12]; +h q[13]; +h q[13]; +h q[14]; +cx q[13],q[14]; +rz(-0.25) q[14]; +cx q[13],q[14]; +h q[13]; +h q[14]; +h q[14]; +h q[15]; +cx q[14],q[15]; +rz(-0.25) q[15]; +cx q[14],q[15]; +h q[14]; +h q[15]; +rx(-pi/2) q[0]; +rx(-pi/2) q[1]; +cx q[0],q[1]; +rz(-0.25) q[1]; +cx q[0],q[1]; +rx(pi/2) q[0]; +rx(pi/2) q[1]; +rx(-pi/2) q[1]; +rx(-pi/2) q[2]; +cx q[1],q[2]; +rz(-0.25) q[2]; +cx q[1],q[2]; +rx(pi/2) q[1]; +rx(pi/2) q[2]; +rx(-pi/2) q[2]; +rx(-pi/2) q[3]; +cx q[2],q[3]; +rz(-0.25) q[3]; +cx q[2],q[3]; +rx(pi/2) q[2]; +rx(pi/2) q[3]; +rx(-pi/2) q[3]; +rx(-pi/2) q[4]; +cx q[3],q[4]; +rz(-0.25) q[4]; +cx q[3],q[4]; +rx(pi/2) q[3]; +rx(pi/2) q[4]; +rx(-pi/2) q[4]; +rx(-pi/2) q[5]; +cx q[4],q[5]; +rz(-0.25) q[5]; +cx q[4],q[5]; +rx(pi/2) q[4]; +rx(pi/2) q[5]; +rx(-pi/2) q[5]; +rx(-pi/2) q[6]; +cx q[5],q[6]; +rz(-0.25) q[6]; +cx q[5],q[6]; +rx(pi/2) q[5]; +rx(pi/2) q[6]; +rx(-pi/2) q[6]; +rx(-pi/2) q[7]; +cx q[6],q[7]; +rz(-0.25) q[7]; +cx q[6],q[7]; +rx(pi/2) q[6]; +rx(pi/2) q[7]; +rx(-pi/2) q[7]; +rx(-pi/2) q[8]; +cx q[7],q[8]; +rz(-0.25) q[8]; +cx q[7],q[8]; +rx(pi/2) q[7]; +rx(pi/2) q[8]; +rx(-pi/2) q[8]; +rx(-pi/2) q[9]; +cx q[8],q[9]; +rz(-0.25) q[9]; +cx q[8],q[9]; +rx(pi/2) q[8]; +rx(pi/2) q[9]; +rx(-pi/2) q[9]; +rx(-pi/2) q[10]; +cx q[9],q[10]; +rz(-0.25) q[10]; +cx q[9],q[10]; +rx(pi/2) q[9]; +rx(pi/2) q[10]; +rx(-pi/2) q[10]; +rx(-pi/2) q[11]; +cx q[10],q[11]; +rz(-0.25) q[11]; +cx q[10],q[11]; +rx(pi/2) q[10]; +rx(pi/2) q[11]; +rx(-pi/2) q[11]; +rx(-pi/2) q[12]; +cx q[11],q[12]; +rz(-0.25) q[12]; +cx q[11],q[12]; +rx(pi/2) q[11]; +rx(pi/2) q[12]; +rx(-pi/2) q[12]; +rx(-pi/2) q[13]; +cx q[12],q[13]; +rz(-0.25) q[13]; +cx q[12],q[13]; +rx(pi/2) q[12]; +rx(pi/2) q[13]; +rx(-pi/2) q[13]; +rx(-pi/2) q[14]; +cx q[13],q[14]; +rz(-0.25) q[14]; +cx q[13],q[14]; +rx(pi/2) q[13]; +rx(pi/2) q[14]; +rx(-pi/2) q[14]; +rx(-pi/2) q[15]; +cx q[14],q[15]; +rz(-0.25) q[15]; +cx q[14],q[15]; +rx(pi/2) q[14]; +rx(pi/2) q[15]; +cx q[0],q[1]; +rz(0) q[1]; +cx q[0],q[1]; +cx q[1],q[2]; +rz(0) q[2]; +cx q[1],q[2]; +cx q[2],q[3]; +rz(0) q[3]; +cx q[2],q[3]; +cx q[3],q[4]; +rz(0) q[4]; +cx q[3],q[4]; +cx q[4],q[5]; +rz(0) q[5]; +cx q[4],q[5]; +cx q[5],q[6]; +rz(0) q[6]; +cx q[5],q[6]; +cx q[6],q[7]; +rz(0) q[7]; +cx q[6],q[7]; +cx q[7],q[8]; +rz(0) q[8]; +cx q[7],q[8]; +cx q[8],q[9]; +rz(0) q[9]; +cx q[8],q[9]; +cx q[9],q[10]; +rz(0) q[10]; +cx q[9],q[10]; +cx q[10],q[11]; +rz(0) q[11]; +cx q[10],q[11]; +cx q[11],q[12]; +rz(0) q[12]; +cx q[11],q[12]; +cx q[12],q[13]; +rz(0) q[13]; +cx q[12],q[13]; +cx q[13],q[14]; +rz(0) q[14]; +cx q[13],q[14]; +cx q[14],q[15]; +rz(0) q[15]; +cx q[14],q[15]; diff --git a/test/circuits/approximateEquivalenceTest/heisenberg16_out_default_error.qasm b/test/circuits/approximateEquivalenceTest/heisenberg16_out_default_error.qasm new file mode 100644 index 00000000..38109161 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/heisenberg16_out_default_error.qasm @@ -0,0 +1,635 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[16]; +u3(4.712388980338651, 6.108692489801767, 4.7123889807722685) q[0]; +u3(1.5707963114451298, 3.1415926409139647, 3.14159269212614) q[3]; +u3(1.5707963266029188, 3.141592653587166, 3.1415926536385554) q[4]; +u3(14.137166918233161, 9.424777967586467, -3.460391726645931) q[5]; +u3(1.5707963297916603, 6.28318531143497, 6.283185311029583) q[7]; +u3(7.85398163379915, -4.923495534880917e-10, 7.550168597420008) q[8]; +u3(1.570796326757235, 3.1415926535280803, 2.879623478289598) q[10]; +u3(1.5707963267947944, 6.283185307179829, 2.6238589031468934e-13) q[11]; +u3(1.570796326785829, 4.498162220944756e-11, -1.1557677690197726e-11) q[12]; +u3(4.712388980176627, 6.283185307044667, 8.796843038979018) q[13]; +u3(3.1415926753577583, 3.8306870188659343, 2.2598906860899493) q[15]; +cx q[0], q[1]; +u3(3.391592653592361, 1.407742778744646, 0.1744928433958416) q[0]; +cx q[1], q[2]; +u3(6.03318530717976, 0.9237606614242946, 7.853981634407427) q[1]; +u3(8.235816978506982, 4.7123889815219755, -1.5707963256558046) q[2]; +cx q[1], q[2]; +u3(1.5707963267958784, 1.3207963275048504, -0.9237606611402817) q[1]; +u3(4.712388980522579, 5.094224325097181, 3.1415926545626007) q[2]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(4.712388980428976, 1.5707963271322587, 4.875442554455431) q[0]; +u3(6.283185289103343, 5.015527273802983, 1.017658007183826) q[3]; +cx q[2], q[3]; +u3(4.712388980234035, 3.1415926536531718, -1.5707963266724412) q[2]; +cx q[3], q[4]; +cx q[1], q[2]; +u3(6.283185307135298, -0.2700129356774333, 3.1616055892380204) q[4]; +u3(6.283185307179579, -0.04720677484100478, -0.2027932252522013) q[2]; +cx q[3], q[4]; +cx q[1], q[2]; +cx q[4], q[5]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(1.2622407934345188, 11.077050952995299, -4.975066551247192) q[5]; +u3(-1.5707962709643932, -136.65928061289824, 142.94246592045118) q[1]; +u3(1.570796326813926, 4.462388980393381, 4.712388980395613) q[3]; +cx q[4], q[5]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(1.5707963267949028, 6.283185306349956, 1.5707963259652657) q[4]; +cx q[5], q[6]; +u3(4.712388995025831, 3.7922444472394923, 1.6057500112892966) q[0]; +u3(4.712388980374177, 1.5707963267913827, 1.5707963268307907) q[2]; +u3(2.7377042359901217e-11, 8.299261613459564, -0.4452799795456747) q[3]; +u3(0.24999999999829775, 1.570796343548059, 6.283185266234632) q[5]; +u3(4.67743529104079, 4.915586642731732, 0.9201445650964967) q[0]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(1.6374439006687632e-10, 4.312649826941624, 1.7205354806524713) q[4]; +u3(1.5707963267949028, 6.283185306349956, 3.141592652760162) q[6]; +cx q[3], q[4]; +cx q[6], q[7]; +u3(-1.5707963262683062, 7.8539816340455655, -1.5707963274059769) q[3]; +cx q[4], q[5]; +u3(3.141592655118776, 6.033185302504917, 6.283185303714076) q[7]; +cx q[2], q[3]; +u3(6.283185307179586, 4.060608545123188, 1.972576768528883) q[5]; +cx q[6], q[7]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[7], q[8]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(-2.7506200921481225, 11.663645318556787, -4.005850646971005) q[8]; +u3(0.2499999999948803, 0.7513409081231701, 4.712388983114875) q[1]; +u3(6.163609419406038, -1.5707963263084919, 1.5707963263025646) q[2]; +u3(4.712388964806967, 1.570796347226618, 4.712389000815068) q[4]; +u3(4.712388980382085, 4.462388980374244, 1.570796326784184) q[6]; +cx q[7], q[8]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(-1.5707963267948966, -3.1415926535985585, 10.995574287555511) q[7]; +cx q[8], q[9]; +u3(1.5950591855259293, 7.853981653240218, 2.425205432323785) q[1]; +u3(4.712388980160136, 3.261168541726658, -2.593572087237919e-10) q[2]; +u3(1.5707963463232513, 6.283185280277563, 9.424777933864334) q[3]; +u3(4.712388980508581, 1.5707963266058786, -1.570796326535146) q[5]; +u3(6.283185307181674, 5.043027055541347, 5.952547232015244) q[6]; +u3(6.033185307182977, -1.5707963268884435, 3.1415926531627036) q[8]; +u3(-1.5284828102268035, 9.420329922783646, -3.643372119093463) q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[0], q[1]; +u3(1.3381441909567546, 4.712388980392859, 1.3207963268030656) q[3]; +cx q[4], q[5]; +u3(4.083936641847744e-15, 1.0340443650945896, 4.999140942082864) q[7]; +u3(4.712388980384691, -8.76574613204147e-12, -8.765444125124192e-12) q[9]; +u3(0.24999999999099856, 4.362450364576354, 6.0799876448475185) q[0]; +u3(4.592995194517522, -1.0817112024035576, 6.063011669800696) q[1]; +cx q[2], q[3]; +u3(4.712388980367525, 3.141592653628056, 2.5163884682619672e-11) q[4]; +cx q[6], q[7]; +cx q[9], q[10]; +u3(1.5707963267948963, 1.0116070946167267e-11, 1.570796326805013) q[2]; +u3(1.3381441909536418, 7.068494484924477, 4.712388980750062) q[3]; +u3(1.5707963267833216, 4.712388980392686, 1.5707963267906797) q[6]; +cx q[7], q[8]; +u3(0.26196916750817983, -1.8207962920563365, 4.712388943314608) q[10]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(1.6783309683523674e-15, 2.6951998397256705, 3.3379854674504923) q[8]; +cx q[9], q[10]; +u3(3.141592653589793, 1.7304227620747568, 1.9804227620747568) q[2]; +u3(6.283185307179586, 5.726343079888337, 6.590027534480789) q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +cx q[10], q[11]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(4.7123889803725625, 3.1415926535628844, 6.283185307151702) q[5]; +u3(-1.5707963267602998, 1.5707963267989227, 4.712388980386236) q[7]; +cx q[8], q[9]; +u3(3.141592653589788, 6.033185307179192, 6.283185307179262) q[11]; +cx q[0], q[1]; +u3(3.141592653589793, 5.564230676897185, 5.564230676897185) q[2]; +u3(7.853981633971339, -3.4599044527925016e-10, 2.356283475769213) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(-0.267152038440406, 2.7852742596358544, 3.509880214624671) q[9]; +cx q[10], q[11]; +u3(1.5707963275163437, 1.5707963267084348, 6.28318530715287) q[1]; +cx q[2], q[3]; +u3(4.313031625572251e-19, 4.957985107742158, 1.075200199437309) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(4.712388980384814, 3.141592653589843, 1.570796326794983) q[10]; +cx q[11], q[12]; +cx q[0], q[1]; +u3(5.010509235633584e-22, 2.09858620570588, 3.934599101473708) q[3]; +cx q[4], q[5]; +u3(4.712388980383562, 6.28318530717825, 3.1415926535885057) q[6]; +u3(1.5707962443031274, -45.553093520251956, 51.8362788380424) q[8]; +u3(1.6659796375973477, 6.205007286610215e-13, 4.712388980385237) q[9]; +u3(3.141592653601239, 0.29200097119469065, 3.683593624773304) q[12]; +u3(2.784633459170521, 2.0228213506017703, 5.062327676864471) q[0]; +cx q[2], q[3]; +cx q[5], q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(1.5707963267948952, 4.7123889803846915, 7.853981633974479) q[2]; +cx q[3], q[4]; +u3(3.1415926535910232, 2.8915926536013075, 3.141592653599843) q[6]; +cx q[7], q[8]; +u3(6.283185307179573, 3.7793839792923016, 2.2538013274575914) q[10]; +cx q[12], q[13]; +u3(1.5707963267949672, 1.3207963267951686, 1.5707963267953982) q[4]; +cx q[5], q[6]; +u3(1.5707963238195657, -6.2831853028227815, 9.424777961750316) q[7]; +cx q[9], q[10]; +u3(0.9652495793800103, 4.534679123214922, 1.8764411040602869) q[13]; +cx q[3], q[4]; +u3(1.57079632680116, 6.283185307161517, -1.5707963267960379) q[5]; +cx q[6], q[7]; +u3(4.7123889927546, 7.853981675644601, -1.5707963676056476) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +u3(4.71238898038469, 7.853981633974365, 1.5707963267947775) q[3]; +u3(6.283185307179282, -0.2087107962817523, 11.204285083845733) q[4]; +u3(1.9185097214975007e-27, 3.2870023786115894, 2.7461829285679955) q[7]; +cx q[8], q[9]; +u3(4.7123890323813615, 4.962388975104747, 1.5707963469268156) q[11]; +u3(1.570796326794897, 6.2831853071962485, 7.853981633991145) q[12]; +cx q[13], q[14]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(2.8915926535898016, -1.5707963260421018, 9.936866853723563e-10) q[13]; +cx q[2], q[3]; +u3(6.283185307179586, 5.9919559694464954, 6.324414644912669) q[5]; +u3(1.570796326794898, 6.283185307179588, -4.712388980384688) q[6]; +u3(1.5707963270815188, -1.3342189008826704e-09, 3.141592649650193) q[8]; +u3(4.712388980255731, 1.5707963267497478, 4.712388980262468) q[10]; +u3(3.1415925893237806, -0.7920009965156405, 7.061980673393106) q[11]; +cx q[13], q[14]; +cx q[1], q[2]; +cx q[4], q[5]; +cx q[7], q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(4.71238898038469, 1.6661559153557394e-11, 1.666155330958096e-11) q[14]; +u3(-0.24999999997997413, 12.51978386141599, -10.995574292803353) q[1]; +u3(6.03118639602438, 7.853981633974483, -7.853981633974483) q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(3.1415926597775217, 4.4623889826459715, 1.0707963289943847) q[8]; +cx q[9], q[10]; +u3(6.283185307177642, 4.718746436036806, 1.3144388708790546) q[12]; +cx q[14], q[15]; +cx q[1], q[2]; +u3(4.71238898038469, 1.5707963267948872, 4.712388980384681) q[4]; +u3(3.141592694686557, 1.3207963325342675, 7.353981633906259) q[6]; +cx q[7], q[8]; +u3(1.5707963267886862, -1.7164997965245286e-10, 3.1415926535940963) q[9]; +cx q[11], q[12]; +u3(3.5699742671787362, 5.350377870845741, 5.305744907902504) q[15]; +u3(0.658325223784651, 1.5707963234039595, 8.25752758612757) q[1]; +u3(4.71238898038469, 9.172779049623701, -1.3198707100303244e-16) q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(4.712388980384014, 3.1415926528118336, 4.712388979606771) q[7]; +cx q[8], q[9]; +u3(4.712388985118357, 1.570796324035087, 4.712388983655156) q[11]; +cx q[14], q[15]; +cx q[0], q[1]; +u3(1.5707963267919192, 6.283185307182214, 3.1415926535872023) q[3]; +u3(1.5707963267949019, 4.712388980384525, 4.712388980384525) q[5]; +cx q[6], q[7]; +u3(6.283185307179586, 2.798905179416842, 3.7342801270157486) q[9]; +cx q[10], q[11]; +u3(6.0331853071705295, 6.808132612328105, 5.831160384389506) q[0]; +u3(3.420016187813108, 5.504807681865693, -3.7846403531500177) q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(1.1313671838326655e-18, 1.8490832989614672, -1.5990833047691877) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +cx q[0], q[1]; +u3(6.283185312032781, 1.5168508814994683, 4.516334425686633) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963329825323, 3.1415926527947717, 4.712388979618908) q[8]; +u3(1.5707963235781648, 6.283185305511577, 3.1415926555626257) q[10]; +cx q[11], q[12]; +u3(4.55170653772111, 4.2627887403632485, 3.4617342308938137) q[1]; +cx q[2], q[3]; +u3(1.570796326819047, 18.849555921537046, -9.424777960790387) q[4]; +u3(1.5707963677811834, 1.5707963268745755, 1.5707963268522906) q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(4.71238898038036, 3.1415926535720384, 4.712388980366974) q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(6.283185307179575, 3.908556422155123, 2.1246288850753565) q[8]; +u3(-5.0462949844570624e-33, -0.3595330356451887, 0.10953303560316723) q[10]; +u3(1.5707963267948966, 1.5249239850176756e-16, 3.141592653589793) q[11]; +u3(3.141592654720821, 1.6003437029393948, -0.6324788680041107) q[12]; +cx q[1], q[2]; +u3(6.283185307179586, -1.2241546630906026, 0.9741546631239735) q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +cx q[12], q[13]; +u3(3.141592653560592, -0.8669566849192908, 5.16622862229754) q[2]; +cx q[3], q[4]; +u3(10.995574287564418, 12.566370614359016, -6.283185307179239) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(3.1415926597934054, 1.5013278337225884, -1.3902648199006566) q[13]; +cx q[1], q[2]; +u3(7.853981638828446, -6.873024184634143e-13, 1.5707963267866771) q[3]; +cx q[4], q[5]; +u3(4.712388981396684, 1.5707963250052448, 4.712388981977831) q[7]; +u3(7.8539816328254375, 7.603981633932298, -4.712388980132211) q[9]; +u3(6.28318530717958, 0.7631809132504355, 5.270004393929074) q[11]; +cx q[12], q[13]; +cx q[0], q[1]; +u3(3.141592653596396, 0.10705410753349598, 0.10705410753346574) q[2]; +u3(12.566370614359535, 1.7701862585059065, 7.404591702263441) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(4.7123889812932545, 1.5707963274673424, 0.9087700826604777) q[12]; +u3(3.1415926472087046, 9.01255294293237, 11.24104015541582) q[13]; +u3(1.5707963419553541, 4.7123889728273545, 7.853981636402672) q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(1.5707963267462566, 6.79540931666523e-11, 3.1415926536168097) q[6]; +u3(4.71238898038469, 14.137166941111863, -4.712388980426897) q[8]; +u3(12.566370615540011, 18.863004176623978, -7.86742988910172) q[9]; +u3(4.712388980390174, 3.1415926535700156, 4.712388980404622) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +cx q[0], q[1]; +u3(6.28318530699503, 3.9579930351919157, 2.075192272555294) q[3]; +u3(1.5707963267948966, -5.10640428605277e-14, 4.712388980384639) q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(0.0, -0.125, -0.125) q[12]; +u3(0.24999999993532587, 1.7859282991810113e-08, 6.283185289372053) q[14]; +u3(2.0273539889935437, 5.498610143445075, 4.187441674861881) q[0]; +cx q[2], q[3]; +u3(-3.021743632512119e-14, 1.0910680446186007, 1.8005246089712037) q[6]; +cx q[7], q[8]; +u3(6.283185304947202, 1.5335940482561428, 4.4995912589249425) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(4.712388982095585, 1.5707963243430445, 4.712388982084678) q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(1.5707963267958511, 6.283185307178808, 3.1415926535893632) q[7]; +cx q[9], q[10]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[11]; +u3(8.532843177179282e-17, 0.0, 0.0) q[12]; +u3(7.85398163400904, 1.5707963268366096, 2.2284872123065083) q[13]; +cx q[14], q[15]; +u3(3.4216150962729133e-10, 4.691236279996363, 4.483541680774887) q[4]; +u3(1.5707963267948972, 6.283185307179585, 4.712388980384689) q[5]; +cx q[6], q[7]; +u3(1.5707963267956748, 4.71238898037985, 1.570796326790056) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +u3(0.6062424926097941, -5.02767289173487, 10.466272770882865) q[14]; +u3(2.565564627986582, 5.152918690399027, 2.0350045677097115) q[15]; +cx q[3], q[4]; +u3(1.4096961731239396e-23, 4.127594477342756, 1.9055908298368351) q[7]; +cx q[8], q[9]; +u3(1.8038785064075254e-25, 4.663441476850374, 1.3697438303387766) q[11]; +u3(0.0, -0.125, -0.125) q[13]; +u3(4.7123889803829275, 1.5707963267957363, 1.570796326795736) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[2], q[3]; +u3(-1.873825681597388e-24, 3.4295619430439745, 2.603623364148929) q[5]; +u3(1.5707963267949236, -9.516095347907472e-15, 4.712388980384689) q[6]; +u3(1.570796326795694, 5.714057661107802e-13, 3.1415926535903145) q[8]; +u3(4.712388982617359, 1.5707963267968652, 4.712388980380003) q[10]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[12]; +u3(3.141592653541133, -0.00032981030183987237, 1.9080971677841019) q[13]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[7], q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +cx q[1], q[2]; +u3(4.712388980042436, 7.853981633955954, 7.853981633975307) q[4]; +cx q[5], q[6]; +u3(6.283185307179586, 4.641984245999261, 1.3912010592671007) q[8]; +cx q[9], q[10]; +u3(6.283185307179586, 2.5722829409919776, 3.4609023661876113) q[12]; +u3(2.8806660306536918, 5.433812571080732, 2.458251585132272) q[14]; +u3(0.24999999804657347, 7.4307178764344695, -1.5707962214519424) q[1]; +u3(-22.562926339732112, 1.5707963267952383, -4.712388980384248) q[2]; +cx q[3], q[4]; +u3(6.283185307179586, 5.932579317570467, 6.383791296788705) q[6]; +cx q[7], q[8]; +u3(1.5707963267933867, 6.283185307180978, 3.141592653588639) q[9]; +cx q[11], q[12]; +cx q[13], q[14]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(1.5707963268288219, 3.141592653677877, 2.0466890805186684) q[13]; +u3(5.341408973885494, -0.42526763458236927, 4.712388988512312) q[14]; +u3(0.9791475204795753, 1.5707963248067942, 1.8944615075385285) q[1]; +u3(26.703537555661512, 16.279741032546422, -2.899099506842461e-10) q[2]; +u3(1.570796326794775, -1.081669257305501e-13, 3.1415926535898993) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(6.283185307180287, 8.2241064391381, -2.1909211319584547) q[9]; +u3(4.712388980384689, 1.5707963267948999, 4.712388980384693) q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(4.712388980384706, 1.5707963267948963, 4.712388980384687) q[5]; +u3(-1.5707962745122797, 26.45353755360375, -20.420352236849926) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(-1.4325342243746337, 4.462388980389457, 7.853981633994874) q[13]; +u3(1.681197174508625, 5.085592148381548, 1.0877788500962067) q[14]; +u3(3.05390801403494, 1.5707965258251115, 7.853981836255417) q[15]; +u3(0.2499999990756757, 9.320256319204537, -10.210999107601783) q[0]; +u3(5.76421591966197, 1.2888734990958974, 1.6083381713328482) q[1]; +u3(3.141592653696557, 3.8893657572136164, 0.49777310362381944) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(4.712388980384689, 3.1415926535896883, -1.570796326795001) q[8]; +u3(1.5707963267949008, -4.208882534762952e-15, 3.1415926535897865) q[10]; +cx q[12], q[13]; +u3(4.580313070504743, -1.6821711562774864, 5.895255054139562) q[14]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(1.5707963267948613, -1.666479961328159e-13, 3.141592653589964) q[4]; +u3(4.712388980384626, 7.85398163205274, 4.712388978462947) q[6]; +u3(5.372844780615214e-08, 0.010616319430500395, 1.5601800054516664) q[7]; +cx q[9], q[10]; +u3(1.5707963267959737, 4.712388980411368, 1.5707963268216378) q[12]; +u3(-1.5707963269469314, 4.811987452920553, 6.387706934775383) q[0]; +u3(3.016798575787169, 2.4924310647482133, -0.6454060390837745) q[1]; +u3(1.5707963267948966, 2.3973922708835725e-11, 1.5707963268188707) q[2]; +u3(3.141592650539631, 3.0217253210406887, 2.3938195487696277) q[3]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(6.283185307179586, 7.375170544832559, 4.941200069526619) q[10]; +cx q[11], q[12]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(5.858166324098832e-14, 3.3557796870973298, 2.677405620074989) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(8.975260531530993e-23, 3.3566547374193814, 3.1765305697602084) q[2]; +u3(6.283185307179586, 3.549707805839418, 2.4834775013636508) q[4]; +u3(4.712388980370311, -6.283185307163165, 12.566370614358618) q[5]; +cx q[7], q[8]; +u3(4.712388985965147, 1.669140023856971e-08, 6.283185267031588) q[11]; +cx q[12], q[13]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[0], q[1]; +u3(1.5707963287773539, 6.283185309470529, 4.08448320812119) q[3]; +cx q[4], q[5]; +u3(1.5707963257443232, 4.712388980164934, 1.5707963270515581) q[7]; +u3(4.7123889803846986, 4.462388980384664, 4.712388980384701) q[9]; +u3(6.283185265851579, 1.034710330613965, 1.8568823270711108) q[11]; +u3(1.5707963267948966, 9.465292135612711e-14, 3.1415926535898877) q[12]; +cx q[13], q[14]; +u3(4.712388980385825, -1.5707963267888738, 4.712388980383788) q[1]; +cx q[2], q[3]; +u3(6.283185307173373, 3.68220882581984, 5.492569134900042) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(3.141592653090783, 1.0659994515108746, 3.957592104819475) q[14]; +cx q[0], q[1]; +u3(6.283185307179586, 5.330805205322357, 6.985565409035757) q[3]; +cx q[4], q[5]; +u3(1.5707963267936589, 6.283185307169811, 3.141592653576418) q[6]; +u3(1.5707963267948883, 4.712388980384695, 4.712388980384693) q[8]; +u3(-4.4216677884371613e-14, 14.138249962541822, -9.425860982157136) q[9]; +u3(1.5707963272250483, 6.579067323523864e-09, -1.57079632054516) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +cx q[2], q[3]; +u3(1.570796326805712, 4.921532301295885e-12, 4.7123889804203305) q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(3.7187289029140677e-13, 2.1267879445684064, 3.90639736214487) q[12]; +u3(4.7123889803914, 4.712388980387074, 6.283185307179901) q[13]; +u3(4.7123889790085105, 5.3851528767138666, -1.1691068171712667e-09) q[14]; +u3(4.712388980388931, 1.5707963268144387, -1.5707963268123206) q[2]; +cx q[3], q[4]; +u3(6.283185307179586, 1.9927561003293375, 4.040429206757706) q[6]; +cx q[7], q[8]; +u3(2.4619824903307766e-17, 1.7643431735788948, 4.268842133574542) q[10]; +cx q[11], q[12]; +cx q[14], q[15]; +cx q[1], q[2]; +u3(4.459020489543665e-25, 1.2057412371566993, 4.8274440700228824) q[4]; +cx q[5], q[6]; +u3(10.995574295051734, 6.283185327891937, 6.283185192392164) q[7]; +cx q[9], q[10]; +u3(1.5707962568857452, 6.283185282123618, 1.5707963527780955) q[11]; +cx q[12], q[13]; +u3(0.24999999999997577, 5.122297968899154e-10, 2.4688287562735343) q[14]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(3.141592653590111, 7.603981633974515, 4.212388980384692) q[13]; +cx q[14], q[15]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(6.2831851829677845, 7.5801335562702805, 1.5946444276606595) q[7]; +u3(4.712388980355799, 1.5707963267489065, 4.71238898033878) q[9]; +u3(3.1415926257510125, 7.603981659615794, 1.070796352364821) q[11]; +cx q[12], q[13]; +u3(5.269509040589788, 4.59026121610542, 3.313857069364759) q[15]; +u3(10.995574287564267, 1.5707963267949014, 10.99557428756428) q[3]; +u3(7.8539816314440305, 1.3207963267020317, 1.570796327350886) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(1.5707963267948966, -1.6370607425945088e-19, 1.570796326794897) q[12]; +cx q[13], q[14]; +u3(1.8494668206145122, 1.0547416550338033, 3.3972820768784686) q[15]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(4.71238898033274, -3.141592629003487, 1.5707963513812682) q[6]; +u3(4.712388980319434, 3.1415926536776535, 5.635991900702019e-11) q[8]; +u3(1.5707963268140606, 4.712388971285808, 4.712388971285841) q[10]; +cx q[11], q[12]; +u3(6.283185307179586, 1.1449864032652306, 5.3881989039143265) q[14]; +u3(-1.570796326794897, 1.5707963267019462, 1.570796326701946) q[4]; +u3(2.600464791903357e-09, 6.294814542315755, 4.700759745155982) q[5]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(1.9086121022637993e-15, 7.029592408686918, 5.78677819780205) q[12]; +cx q[13], q[14]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(3.1415926546903816, 1.3207963280006938, 4.21238898157219) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(1.5707963267945784, 3.14159265358979, -1.570796326794897) q[13]; +cx q[14], q[15]; +cx q[3], q[4]; +u3(3.1415926535883187, 0.8594722222734463, 6.892657529453033) q[6]; +cx q[7], q[8]; +u3(1.570796326790211, 7.159210044929763e-12, 3.141592653582606) q[9]; +u3(1.5707962989820599, 1.5707963174451802, 1.570796317764147) q[11]; +cx q[12], q[13]; +u3(1.0542383688630381, 1.5707963267962146, 1.320796326796093) q[15]; +cx q[5], q[6]; +u3(-1.5707963267953342, 9.424777960344457, -1.570796327219812) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(6.283185307179582, 3.954144487274061, 2.079040819716407) q[13]; +cx q[14], q[15]; +u3(1.5707963267948963, -1.570796326794871, 4.712388980384715) q[5]; +u3(3.14159265356704, 5.00671351937, 2.2821204313235692) q[6]; +u3(6.283185307179586, 3.1899486062386946, 3.343236700555033) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +u3(2.671968966292046, 1.530037418275777, 1.5669225564487055) q[15]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(1.5707963293767255, 3.141592651893826, -4.087110817381425e-09) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(4.722867219144817, 9.378990801435284, 9.199961209105565) q[15]; +cx q[4], q[5]; +u3(4.682056612390999e-24, 1.8557453679769396, 4.177439939216025) q[7]; +u3(1.5707963256936261, 3.141592653171025, 4.712388979964359) q[8]; +cx q[9], q[10]; +u3(4.712388980364331, 1.570796326475961, 4.7123889801571535) q[12]; +u3(3.968874033261966, 4.369612020789568, 1.333782343238115) q[14]; +cx q[6], q[7]; +u3(3.141592651129228, 2.891592659997906, 3.1415926591411085) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(1.5707963267687723, 4.712388980382545, 5.129388545902299) q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(-1.5707963269927483, 3.1415926536455268, 6.283185308048834) q[11]; +u3(4.71238898038469, 1.5707963267968055, 4.712388980386598) q[13]; +u3(-0.7781230015346349, 4.6522030172925275, 0.20004338950627756) q[14]; +cx q[5], q[6]; +u3(6.283185307164732, 0.28589229167756014, 5.747292976738335) q[8]; +u3(7.853981635654209, 12.566370609437419, -1.5707963266001237) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(-9.062922887556289e-09, 4.685338700957432, 1.3478466062218897) q[11]; +cx q[12], q[13]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(4.712388980379848, 3.1415926275035164, -2.6091663891692748e-08) q[12]; +cx q[13], q[14]; +u3(4.7123888744891715, 7.853981643223037, 4.712389048657581) q[7]; +u3(6.283185307179529, 1.8248392988582633, 4.208346008321186) q[9]; +u3(4.7123889803846675, 3.1415926535881735, 4.71238898038307) q[10]; +cx q[11], q[12]; +u3(2.132580211077979, 4.712388912306628, 4.712388912369782) q[14]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(6.283185307179586, -0.7451743477470611, 0.49517434774929775) q[12]; +cx q[13], q[14]; +u3(1.5707963267949137, 4.712388980384617, 1.5707963267948235) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(7.853981633906384, 37.69911181692914, -31.415926561939717) q[13]; +u3(3.9474101932937837, 2.3466177252769094, 3.0706668150355823) q[14]; +cx q[7], q[8]; +u3(6.283185307179586, 1.5447896439857054, 4.488395663193877) q[10]; +u3(1.5707963358577706, 2.350255959075901e-12, 7.853981633973489) q[11]; +cx q[12], q[13]; +u3(1.5707963291690366, 6.283185307187803, 3.607209331434205) q[14]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(1.493113309942708e-14, 4.044282014408981, 1.9889032927783443) q[13]; +cx q[14], q[15]; +u3(1.570796326794918, 4.712388980385101, 1.5707963267948448) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +u3(12.317812214730726, -3.381945368057696, 6.596994766383803) q[15]; +cx q[8], q[9]; +u3(-4.606094765347848e-11, 7.243810012736379, -1.2106247055422545) q[11]; +u3(1.5707963257915336, 6.283185307976412, 1.5707963259826574) q[12]; +cx q[13], q[14]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(-0.24999999998525482, 1.3207963268142597, -1.570796326799556) q[14]; +u3(4.712388980383907, 1.5707963267887826, -1.5707963268010106) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +cx q[9], q[10]; +u3(6.283185307179586, 1.3044115378990389, 4.72877376928197) q[12]; +u3(1.5707963267948963, 6.2831853071941275, 1.570796326809438) q[13]; +cx q[14], q[15]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(1.5707963290767155, 7.500208145704392e-12, 3.199034645325397e-11) q[14]; +u3(4.252931007668044, 6.941317159811333, -0.5207845388892177) q[15]; +u3(1.5707963267592906, 4.7123889803920855, 1.570796326789873) q[11]; +cx q[12], q[13]; +cx q[10], q[11]; +u3(8.677989509847878e-14, 0.08526886649462191, -0.3352688664354618) q[13]; +cx q[10], q[11]; +cx q[12], q[13]; +u3(1.570796321691643, 4.712389000223492, 1.5707963068378006) q[12]; +cx q[11], q[12]; +cx q[11], q[12]; +cx q[12], q[13]; +cx q[12], q[13]; +cx q[13], q[14]; +u3(6.283185307050697, 2.2573451302603353, 6.917432831932345) q[14]; +cx q[13], q[14]; +u3(1.5707963273090904, 4.712388982083521, 4.712388982086903) q[13]; +u3(3.1415926534603518, 5.718688059797338, 2.2356565553810444) q[14]; +cx q[14], q[15]; +u3(3.6339079010077664, 14.472611946181283, -10.501535530782315) q[15]; +cx q[14], q[15]; +u3(1.5707963267949188, 1.5707963267952751, 4.370950129548484) q[14]; +u3(2.5197270331333153, 7.096876966982337, 6.993536083219166) q[15]; diff --git a/test/circuits/approximateEquivalenceTest/heisenberg16_out_high_error.qasm b/test/circuits/approximateEquivalenceTest/heisenberg16_out_high_error.qasm new file mode 100644 index 00000000..7d87b42f --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/heisenberg16_out_high_error.qasm @@ -0,0 +1,35 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[16]; +u3(0.00013467339313029555, 0.06252028380218476, -0.06273794617931498) q[0]; +u3(0.0, 0.0, 0.0) q[1]; +u3(0.00030096490486351964, -1.1617477011729667, -5.120997537215747) q[2]; +u3(3.1415487498634187, -3.410767223362413, -0.2691754228466807) q[3]; +u3(0.00023293221517120639, 5.6164351648785535, 0.6666892784775138) q[4]; +u3(3.14150268434272, 0.8484718224539403, 3.9899328528489137) q[5]; +u3(7.184975071086315e-05, -4.274595385824681, -2.0085820307879043) q[6]; +u3(3.1414543401175727, 4.519357945881856, 1.3776785172276091) q[7]; +u3(0.00013614361401208293, -1.4627023338724077, 1.4626414736667082) q[8]; +u3(3.1414760532426476, -0.8540226475337821, 2.287358551122577) q[9]; +u3(0.00019348001721546448, 3.5786104876421923, 2.7043090230175264) q[10]; +u3(3.1413860371361615, -1.333061295987569, 1.8085163275548886) q[11]; +u3(2.2630913225614746, 5.0287579692620055, 2.7646443016213094) q[12]; +u3(3.1396110890804074, 2.6074696906578216, 4.466655672127682) q[13]; +u3(0.00016514867159772367, 3.5372026283870923, 2.745950728547381) q[14]; +u3(3.1414644319540708, -1.2647946924950193, -4.406388877768999) q[15]; +u3(0.0, 0.0, 0.0) q[0]; +u3(3.1413292420004835, 2.010234453162399, -1.1315301809968428) q[1]; +u3(5.406389045178313, 5.910704178547237, 4.387480216831034) q[12]; +u3(3.1410400525063493, 0.6289090814854731, 5.6277391743811025) q[13]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; diff --git a/test/circuits/approximateEquivalenceTest/heisenberg16_out_small_error.qasm b/test/circuits/approximateEquivalenceTest/heisenberg16_out_small_error.qasm new file mode 100644 index 00000000..1d9159f8 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/heisenberg16_out_small_error.qasm @@ -0,0 +1,864 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[16]; +u3(1.5707963268013796, 3.698629342944752, -0.9721872384823051) q[0]; +u3(1.3240512523628656, -4.150710758062049, 1.5707963268012235) q[1]; +u3(3.1415926533569594, 2.510312365348886, 2.51031236533479) q[2]; +u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[3]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[4]; +u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[5]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[6]; +u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[7]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[8]; +u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[9]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[10]; +u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[11]; +u3(1.5707963267948966, 2.220446049250313e-16, -3.141592653589793) q[12]; +u3(1.5707963267948966, 3.141592653589793, -3.141592653589793) q[13]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[14]; +u3(1.5707963267948966, 3.141592653589793, -3.141592653589793) q[15]; +cx q[1], q[2]; +u3(0.24999999999999845, -2.658849721384721, -2.1324745491152024) q[1]; +u3(3.141592653296536, -1.365903695330139, -1.3659036953301318) q[2]; +cx q[1], q[2]; +u3(2.5093956798996886, 0.39052821881924293, -4.888365866816978) q[1]; +u3(1.5707963269788476, 4.3391490400779276e-10, -3.1415926535753425) q[2]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(0.2500000000000003, -1.2380780130046798, -3.698629342945577) q[0]; +u3(3.1354350518873244, -0.2674459248497576, 3.124072825983004) q[1]; +u3(0.0, 0.0, 0.0) q[2]; +u3(0.0, -0.125, -0.125) q[3]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(1.5707963268012426, 4.113779892072544, -1.9035146405836303) q[0]; +u3(0.5990629440969317, -3.0974459246263017, 3.105125913167815) q[1]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[2]; +u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[3]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(0.0, -0.125, -0.125) q[2]; +u3(0.0, 0.0, 0.0) q[3]; +u3(0.0, -0.125, -0.125) q[4]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; +u3(0.0, 0.0, 0.0) q[2]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[3]; +u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[4]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(0.0, 0.0, 0.0) q[4]; +u3(0.0, 0.0, 0.0) q[1]; +u3(0.0, -0.125, -0.125) q[3]; +cx q[4], q[5]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(0.0, 0.0, 0.0) q[4]; +u3(0.0, -0.125, -0.125) q[5]; +u3(1.5707963267950213, -0.6317295459958326, 1.5707963267944058) q[0]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; +u3(0.0, 0.0, 0.0) q[3]; +cx q[4], q[5]; +cx q[1], q[2]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[4]; +u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[5]; +u3(0.0, 0.0, 0.0) q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[1], q[2]; +u3(0.0, 0.0, 0.0) q[3]; +u3(0.0, -0.125, -0.125) q[4]; +u3(0.0, 0.0, 0.0) q[5]; +u3(0.0, -0.125, -0.125) q[6]; +u3(1.8127572697279888, -1.57079632679488, 4.712388980384309) q[1]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[0], q[1]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; +u3(6.123233995736766e-17, -3.0616169978683824e-17, -3.0616169978683824e-17) q[4]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[5]; +u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[6]; +u3(0.25000000000000044, -3.4855086130902952, 0.631729545995831) q[0]; +u3(1.570796326794877, -1.1513394185562236, 3.341771304121721e-14) q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(0.0, 0.0, 0.0) q[3]; +u3(0.0, -0.125, -0.125) q[5]; +u3(0.0, 0.0, 0.0) q[6]; +u3(0.0, -0.125, -0.125) q[7]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963215885818, 1.409820957414135, 3.1415926530450693) q[2]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; +u3(0.0, 0.0, 0.0) q[5]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[6]; +u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[7]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(3.141592653589793, -2.0860896208594104, 1.2695127015734753) q[1]; +u3(1.2696868602872497e-09, -0.16030889941082146, -0.08969110058929466) q[2]; +u3(0.0, 0.0, 0.0) q[4]; +u3(0.0, -0.125, -0.125) q[6]; +u3(0.0, -0.125, -0.125) q[8]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(1.5385373536124667, -3.3895458235962157, -1.3060097758917473) q[1]; +u3(3.1415926483112355, 3.0442350365316697, 1.3124633403560093) q[2]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[3]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; +u3(0.0, 0.0, 0.0) q[6]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[7]; +u3(8.532843177179282e-17, 0.0, 0.0) q[8]; +cx q[0], q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(1.5707963267950198, 1.5707963267953868, 3.485508613090298) q[0]; +u3(3.0108532527160725, 4.7123889803817445, 1.5707963267919416) q[1]; +u3(0.0, -0.125, -0.125) q[3]; +u3(0.0, 0.0, 0.0) q[5]; +u3(0.0, -0.125, -0.125) q[7]; +u3(0.0, 0.0, 0.0) q[8]; +u3(0.0, -0.125, -0.125) q[9]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[2]; +u3(8.532843177179282e-17, 0.0, 0.0) q[3]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[4]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; +u3(0.0, 0.0, 0.0) q[7]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[8]; +u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[9]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(0.0, -0.125, -0.125) q[2]; +u3(0.0, -0.125, -0.125) q[4]; +u3(0.0, 0.0, 0.0) q[6]; +u3(0.0, -0.125, -0.125) q[8]; +u3(0.0, 0.0, 0.0) q[9]; +u3(0.0, -0.125, -0.125) q[10]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; +u3(0.0, 0.0, 0.0) q[2]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[3]; +u3(8.532843177179282e-17, 0.0, 0.0) q[4]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[5]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; +u3(0.0, 0.0, 0.0) q[8]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[9]; +u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[10]; +cx q[0], q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.0) q[10]; +u3(0.0, 0.0, 0.0) q[1]; +u3(0.0, -0.125, -0.125) q[3]; +u3(0.0, -0.125, -0.125) q[5]; +u3(0.0, 0.0, 0.0) q[7]; +u3(0.0, -0.125, -0.125) q[9]; +cx q[10], q[11]; +cx q[0], q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.0) q[10]; +u3(0.0, -0.125, -0.125) q[11]; +u3(1.5707963270346463, 4.905536215506974, 0.9523732089951065) q[0]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; +u3(0.0, 0.0, 0.0) q[3]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[4]; +u3(8.532843177179282e-17, 0.0, 0.0) q[5]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[6]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[8]; +u3(0.0, 0.0, 0.0) q[9]; +cx q[10], q[11]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[10]; +u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[11]; +u3(0.0, 0.0, 0.0) q[2]; +u3(0.0, -0.125, -0.125) q[4]; +u3(0.0, -0.125, -0.125) q[6]; +u3(0.0, 0.0, 0.0) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(0.0, -0.125, -0.125) q[10]; +u3(0.0, 0.0, 0.0) q[11]; +u3(0.0, -0.125, -0.125) q[12]; +u3(1.570796325242758, -2.458773818116612, 3.141592652536968) q[1]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; +u3(0.0, 0.0, 0.0) q[4]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[5]; +u3(8.532843177179282e-17, 0.0, 0.0) q[6]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[7]; +cx q[9], q[10]; +cx q[11], q[12]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[9]; +u3(0.0, 0.0, 0.0) q[10]; +u3(1.5707963267948968, 0.0, 1.5707963267948968) q[11]; +u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[12]; +u3(0.0, 0.0, 0.0) q[3]; +u3(0.0, -0.125, -0.125) q[5]; +u3(0.0, -0.125, -0.125) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(0.0, 0.0, 0.0) q[12]; +cx q[2], q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(0.0, 0.0, 0.0) q[9]; +u3(0.0, -0.125, -0.125) q[11]; +cx q[12], q[13]; +u3(1.5707963267948966, -2.4885287017487396, 3.141592653589793) q[2]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; +u3(0.0, 0.0, 0.0) q[5]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[6]; +u3(8.532843177179282e-17, 0.0, 0.0) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(0.0, 0.0, 0.0) q[12]; +u3(0.0, -0.125, -0.125) q[13]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[8]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[10]; +u3(0.0, 0.0, 0.0) q[11]; +cx q[12], q[13]; +u3(3.141592653589793, 1.2060252812431997, 1.5752346792533398) q[1]; +u3(3.141592653589793, -1.018998629292777, 1.8725940242970547) q[2]; +u3(0.0, 0.0, 0.0) q[4]; +u3(0.0, -0.125, -0.125) q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(1.5707963267948968, 0.0, 1.5707963267948968) q[12]; +u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[13]; +cx q[1], q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(0.0, -0.125, -0.125) q[8]; +u3(0.0, 0.0, 0.0) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(4.12280138366313, 6.084349441609635, 2.2751502149617964) q[1]; +u3(-1.1816407439491567e-16, 3.390880583826311, 5.380833425112225) q[2]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[3]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; +u3(0.0, 0.0, 0.0) q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(0.0, -0.125, -0.125) q[12]; +u3(0.0, 0.0, 0.0) q[13]; +u3(0.0, -0.125, -0.125) q[14]; +cx q[0], q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[7]; +u3(8.532843177179282e-17, 0.0, 0.0) q[8]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[9]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(0.24999999999997935, 5.637144911985536, 4.519241745169825) q[0]; +u3(0.17481009696066513, 1.985413270930268, -1.7396173911305366) q[1]; +u3(0.0, -0.125, -0.125) q[3]; +u3(0.0, 0.0, 0.0) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[11]; +u3(0.0, 0.0, 0.0) q[12]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[13]; +u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[14]; +cx q[0], q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(0.0, -0.125, -0.125) q[7]; +u3(0.0, -0.125, -0.125) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +u3(0.0, 0.0, 0.0) q[14]; +u3(4.712388980150148, 5.330812098192436, 3.7876330488846137) q[0]; +u3(-0.6281943376678667, 3.3439556855346355, 2.977090663618331) q[1]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[2]; +u3(8.532843177179282e-17, 0.0, 0.0) q[3]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[4]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.0) q[11]; +u3(0.0, -0.125, -0.125) q[13]; +cx q[14], q[15]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; +u3(0.0, 0.0, 0.0) q[7]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[8]; +u3(8.532843177179282e-17, 0.0, 0.0) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +u3(0.0, 0.0, 0.0) q[14]; +u3(0.0, -0.125, -0.125) q[15]; +u3(0.0, -0.125, -0.125) q[2]; +u3(0.0, -0.125, -0.125) q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[10]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[12]; +u3(0.0, 0.0, 0.0) q[13]; +cx q[14], q[15]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(0.0, 0.0, 0.0) q[6]; +u3(0.0, -0.125, -0.125) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(1.5707963267948968, 0.0, 1.5707963267948968) q[14]; +u3(1.001954908788063e-08, -0.6750953106187336, 5.387484244257511) q[15]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; +u3(0.0, 0.0, 0.0) q[2]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[3]; +u3(8.532843177179282e-17, 0.0, 0.0) q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(0.0, -0.125, -0.125) q[10]; +u3(0.0, 0.0, 0.0) q[12]; +cx q[13], q[14]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[5]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; +u3(0.0, 0.0, 0.0) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(0.0, 0.0, 0.0) q[13]; +u3(0.0, -0.125, -0.125) q[14]; +u3(0.0, 0.0, 0.0) q[1]; +u3(0.0, -0.125, -0.125) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[9]; +u3(8.532843177179282e-17, 0.0, 0.0) q[10]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[11]; +cx q[13], q[14]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(0.0, -0.125, -0.125) q[5]; +u3(0.0, 0.0, 0.0) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[13]; +u3(1.2349848074883556, 0.5458175086869241, -4.040731003943112) q[14]; +u3(1.5707963267949017, 3.376774268847033, -1.3012636636582287) q[0]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; +u3(0.0, 0.0, 0.0) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(0.0, -0.125, -0.125) q[9]; +u3(0.0, -0.125, -0.125) q[11]; +cx q[12], q[13]; +cx q[1], q[2]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[4]; +u3(8.532843177179282e-17, 0.0, 0.0) q[5]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[6]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(0.0, 0.0, 0.0) q[13]; +u3(0.0, 0.0, 0.0) q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[8]; +u3(0.0, 0.0, 0.0) q[9]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[10]; +u3(8.532843177179282e-17, 0.0, 0.0) q[11]; +cx q[12], q[13]; +cx q[1], q[2]; +u3(0.0, -0.125, -0.125) q[4]; +u3(0.0, -0.125, -0.125) q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[12]; +u3(-0.34461501668122707, 2.2611057321048413, -2.3691113297768562) q[13]; +u3(1.5707963267948946, -1.5288134904768458, -3.141592653589792) q[1]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(0.0, 0.0, 0.0) q[8]; +u3(0.0, -0.125, -0.125) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; +u3(0.0, 0.0, 0.0) q[4]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[5]; +u3(8.532843177179282e-17, 0.0, 0.0) q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(0.0, -0.125, -0.125) q[12]; +u3(3.141592653589793, 2.0126881177894114, 5.879517113613691) q[13]; +u3(0.8633056785714065, 1.5707963268287566, -1.5707963267556666) q[14]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[7]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[9]; +u3(0.0, 0.0, 0.0) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(0.0, 0.0, 0.0) q[3]; +u3(0.0, -0.125, -0.125) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[11]; +u3(8.532843177179282e-17, 0.0, 0.0) q[12]; +u3(4.95676464593379, -0.24545667690278367, 0.6475226547767313) q[13]; +u3(4.6666486860473775, 5.711974154042495, -0.94931678633701) q[14]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(0.0, -0.125, -0.125) q[7]; +u3(0.0, 0.0, 0.0) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +u3(1.5707964966280614, -2.298938807345055, 3.14159251806691) q[2]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; +u3(0.0, 0.0, 0.0) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(0.0, -0.125, -0.125) q[11]; +u3(0.0, -0.125, -0.125) q[13]; +u3(3.39159264971765, 7.250340276500068, 0.730362773605577) q[14]; +u3(3.141592653524296, 2.5476369456609755, 5.689229597619214) q[15]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[6]; +u3(8.532843177179282e-17, 0.0, 0.0) q[7]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[8]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +u3(6.283185307179586, 5.98256536880236, 6.237343371549365) q[1]; +u3(3.141592448435295, 4.976052187927914, 1.584459534336365) q[2]; +u3(0.0, 0.0, 0.0) q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[10]; +u3(0.0, 0.0, 0.0) q[11]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[12]; +u3(8.532843177179282e-17, 0.0, 0.0) q[13]; +u3(6.2831853139022416, 4.884794643671604, 3.5728283439785207) q[14]; +u3(6.283185299907338, 0.7892067253236354, 7.064774956772292) q[15]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(0.0, -0.125, -0.125) q[6]; +u3(0.0, -0.125, -0.125) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(0.0, 0.0, 0.0) q[15]; +u3(4.9813321723799024, 6.301221304215631, 3.3782905271773154) q[1]; +u3(3.1415926703140804, 3.118361062867952, 3.9610149091052045) q[2]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[3]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(0.0, 0.0, 0.0) q[10]; +u3(0.0, -0.125, -0.125) q[12]; +u3(0.0, -0.125, -0.125) q[14]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; +u3(0.0, 0.0, 0.0) q[6]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[7]; +u3(8.532843177179282e-17, 0.0, 0.0) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(0.24999999999999992, 1.044794366240841, 6.04800369192235) q[0]; +u3(6.299379513583522, 3.2113345378857074, 3.3213300471071174) q[1]; +u3(0.0, -0.125, -0.125) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[9]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[11]; +u3(0.0, 0.0, 0.0) q[12]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[13]; +u3(8.532843177179282e-17, 0.0, 0.0) q[14]; +cx q[0], q[1]; +cx q[2], q[3]; +u3(0.0, 0.0, 0.0) q[5]; +u3(0.0, -0.125, -0.125) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +u3(1.5707963267949012, 4.4428563172480215, 5.238390940938742) q[0]; +u3(3.418539905419923, 3.3793585212795367, 3.370617726457057) q[1]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[2]; +u3(8.532843177179282e-17, 0.0, 0.0) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(0.0, -0.125, -0.125) q[9]; +u3(0.0, 0.0, 0.0) q[11]; +u3(0.0, -0.125, -0.125) q[13]; +u3(0.0, 0.0, 0.0) q[14]; +u3(0.0, -0.125, -0.125) q[15]; +cx q[1], q[2]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[4]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; +u3(0.0, 0.0, 0.0) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +u3(0.0, -0.125, -0.125) q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[8]; +u3(8.532843177179282e-17, 0.0, 0.0) q[9]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[10]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[12]; +u3(0.0, 0.0, 0.0) q[13]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[14]; +u3(6.212470744432521e-09, -3.91904003601071, 2.3482437086679377) q[15]; +cx q[1], q[2]; +u3(0.0, -0.125, -0.125) q[4]; +u3(0.0, 0.0, 0.0) q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(0.0, 0.0, 0.0) q[14]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; +u3(0.0, 0.0, 0.0) q[2]; +cx q[3], q[4]; +cx q[5], q[6]; +u3(0.0, -0.125, -0.125) q[8]; +u3(0.0, -0.125, -0.125) q[10]; +u3(0.0, 0.0, 0.0) q[12]; +cx q[13], q[14]; +cx q[0], q[1]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[3]; +u3(8.532843177179282e-17, 0.0, 0.0) q[4]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[5]; +cx q[7], q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(0.0, 0.0, 0.0) q[13]; +u3(0.0, -0.125, -0.125) q[14]; +u3(0.0, 0.0, 0.0) q[1]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; +u3(0.0, 0.0, 0.0) q[8]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[9]; +u3(8.532843177179282e-17, 0.0, 0.0) q[10]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[11]; +cx q[13], q[14]; +cx q[0], q[1]; +u3(0.0, -0.125, -0.125) q[3]; +u3(0.0, -0.125, -0.125) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[13]; +u3(1.9807995154418523, -2.078212939794722, 3.2956523905656794) q[14]; +cx q[2], q[3]; +cx q[4], q[5]; +u3(0.0, 0.0, 0.0) q[7]; +u3(0.0, -0.125, -0.125) q[9]; +u3(0.0, -0.125, -0.125) q[11]; +cx q[12], q[13]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; +u3(0.0, 0.0, 0.0) q[3]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[4]; +u3(8.532843177179282e-17, 0.0, 0.0) q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(0.0, 0.0, 0.0) q[13]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[6]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[8]; +u3(0.0, 0.0, 0.0) q[9]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[10]; +u3(8.532843177179282e-17, 0.0, 0.0) q[11]; +cx q[12], q[13]; +u3(0.0, 0.0, 0.0) q[2]; +u3(0.0, -0.125, -0.125) q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[12]; +u3(3.3879991213643272, 4.578193635810148, 9.503257427289979) q[13]; +cx q[1], q[2]; +cx q[3], q[4]; +u3(0.0, -0.125, -0.125) q[6]; +u3(0.0, 0.0, 0.0) q[8]; +u3(0.0, -0.125, -0.125) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; +u3(0.0, 0.0, 0.0) q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(0.0, -0.125, -0.125) q[12]; +u3(3.141592653589793, 3.0604454671441084, 4.144884159500745) q[13]; +u3(1.297098473972984, -1.5707963268003862, 4.7123889803792505) q[14]; +cx q[2], q[3]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[5]; +u3(8.532843177179282e-17, 0.0, 0.0) q[6]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[7]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[9]; +u3(0.0, 0.0, 0.0) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(0.0, 0.0, 0.0) q[3]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[11]; +u3(8.532843177179282e-17, 0.0, 0.0) q[12]; +u3(1.3251639380407203, 6.302901462052073, 2.4401264184284965) q[13]; +u3(7.3250471601395235, 1.9142345745043792, 5.098988495961082) q[14]; +cx q[2], q[3]; +u3(0.0, -0.125, -0.125) q[5]; +u3(0.0, -0.125, -0.125) q[7]; +u3(0.0, 0.0, 0.0) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +cx q[4], q[5]; +cx q[6], q[7]; +cx q[8], q[9]; +u3(0.0, -0.125, -0.125) q[11]; +u3(0.0, -0.125, -0.125) q[13]; +u3(0.2499999993454793, 4.536093485418275, 5.246360801466184) q[14]; +u3(6.283185306699073, 3.269589702959485, 6.1551882580101624) q[15]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; +u3(0.0, 0.0, 0.0) q[5]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[6]; +u3(8.532843177179282e-17, 0.0, 0.0) q[7]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[8]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[10]; +u3(0.0, 0.0, 0.0) q[11]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[12]; +u3(8.532843177179282e-17, 0.0, 0.0) q[13]; +u3(3.141592657286629, 5.34321853880259, 0.8071250531182803) q[14]; +u3(-6.0997096989931195e-09, 3.98219245075599, 0.7301965300386668) q[15]; +u3(0.0, 0.0, 0.0) q[4]; +u3(0.0, -0.125, -0.125) q[6]; +u3(0.0, -0.125, -0.125) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(0.0, 0.0, 0.0) q[15]; +cx q[3], q[4]; +cx q[5], q[6]; +cx q[7], q[8]; +u3(0.0, 0.0, 0.0) q[10]; +u3(0.0, -0.125, -0.125) q[12]; +u3(0.0, -0.125, -0.125) q[14]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; +u3(0.0, 0.0, 0.0) q[6]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[7]; +u3(8.532843177179282e-17, 0.0, 0.0) q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[9]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[11]; +u3(0.0, 0.0, 0.0) q[12]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[13]; +u3(8.532843177179282e-17, 0.0, 0.0) q[14]; +u3(0.0, 0.0, 0.0) q[5]; +u3(0.0, -0.125, -0.125) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +cx q[4], q[5]; +cx q[6], q[7]; +u3(0.0, -0.125, -0.125) q[9]; +u3(0.0, 0.0, 0.0) q[11]; +u3(0.0, -0.125, -0.125) q[13]; +u3(0.0, 0.0, 0.0) q[14]; +u3(0.0, -0.125, -0.125) q[15]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; +u3(0.0, 0.0, 0.0) q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +cx q[5], q[6]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[8]; +u3(8.532843177179282e-17, 0.0, 0.0) q[9]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[10]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[12]; +u3(0.0, 0.0, 0.0) q[13]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[14]; +u3(6.713171846466525e-10, 0.9063678041090947, 0.6644285226451768) q[15]; +u3(0.0, 0.0, 0.0) q[6]; +cx q[7], q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(0.0, 0.0, 0.0) q[14]; +cx q[5], q[6]; +u3(0.0, -0.125, -0.125) q[8]; +u3(0.0, -0.125, -0.125) q[10]; +u3(0.0, 0.0, 0.0) q[12]; +cx q[13], q[14]; +cx q[7], q[8]; +cx q[9], q[10]; +cx q[11], q[12]; +u3(0.0, 0.0, 0.0) q[13]; +u3(0.0, -0.125, -0.125) q[14]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; +u3(0.0, 0.0, 0.0) q[8]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[9]; +u3(8.532843177179282e-17, 0.0, 0.0) q[10]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[11]; +cx q[13], q[14]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[13]; +u3(1.949938345728355, -2.026116675699649, -0.8307035065756702) q[14]; +u3(0.0, 0.0, 0.0) q[7]; +u3(0.0, -0.125, -0.125) q[9]; +u3(0.0, -0.125, -0.125) q[11]; +cx q[12], q[13]; +cx q[6], q[7]; +cx q[8], q[9]; +cx q[10], q[11]; +u3(0.0, 0.0, 0.0) q[13]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[8]; +u3(0.0, 0.0, 0.0) q[9]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[10]; +u3(8.532843177179282e-17, 0.0, 0.0) q[11]; +cx q[12], q[13]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[12]; +u3(1.605335375884444, 4.457204268441797, -0.06292303420165449) q[13]; +u3(0.0, 0.0, 0.0) q[8]; +u3(0.0, -0.125, -0.125) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +cx q[7], q[8]; +cx q[9], q[10]; +u3(0.0, -0.125, -0.125) q[12]; +u3(6.283185307179586, 4.062345583219204, 4.598680286841274) q[13]; +u3(3.1415926535810836, 5.420189709808817, 5.420189709808819) q[14]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[9]; +u3(0.0, 0.0, 0.0) q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +cx q[8], q[9]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[11]; +u3(8.532843177179282e-17, 0.0, 0.0) q[12]; +u3(3.2133608860518774, 5.214840837722617, 4.661894196053515) q[13]; +u3(0.8937862065670165, 1.2440266896429848, 2.3603106410687906) q[14]; +u3(0.0, 0.0, 0.0) q[9]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +cx q[8], q[9]; +u3(0.0, -0.125, -0.125) q[11]; +u3(0.0, -0.125, -0.125) q[13]; +u3(0.24999999999968553, 5.611891912011103, 5.53395522837392) q[14]; +u3(3.1415926535902328, 6.16128022336242, 3.0196875697726195) q[15]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[10]; +u3(0.0, 0.0, 0.0) q[11]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[12]; +u3(8.532843177179282e-17, 0.0, 0.0) q[13]; +u3(6.2831853063337215, 0.5653734675032248, 6.389105234677195) q[14]; +u3(3.1415926529149787, 5.603644741575092, 4.032848414739265) q[15]; +cx q[9], q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(0.0, 0.0, 0.0) q[15]; +u3(0.0, 0.0, 0.0) q[10]; +u3(0.0, -0.125, -0.125) q[12]; +u3(0.0, -0.125, -0.125) q[14]; +cx q[9], q[10]; +cx q[11], q[12]; +cx q[13], q[14]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[11]; +u3(0.0, 0.0, 0.0) q[12]; +u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[13]; +u3(8.532843177179282e-17, 0.0, 0.0) q[14]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +u3(0.0, 0.0, 0.0) q[11]; +u3(0.0, -0.125, -0.125) q[13]; +u3(0.0, 0.0, 0.0) q[14]; +u3(0.0, -0.125, -0.125) q[15]; +cx q[10], q[11]; +cx q[12], q[13]; +cx q[14], q[15]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[12]; +u3(0.0, 0.0, 0.0) q[13]; +u3(1.5707963267948968, 0.0, -4.71238898038469) q[14]; +u3(2.1965156326459443, -2.8222790205050905, -2.627670694261884) q[15]; +cx q[11], q[12]; +u3(0.0, 0.0, 0.0) q[14]; +u3(0.0, 0.0, 0.0) q[12]; +cx q[13], q[14]; +cx q[11], q[12]; +u3(0.0, 0.0, 0.0) q[13]; +u3(0.0, -0.125, -0.125) q[14]; +cx q[13], q[14]; +u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[13]; +u3(1.0277339916976553, 0.14659123773901017, -1.4327029342332407) q[14]; +cx q[12], q[13]; +u3(0.0, 0.0, 0.0) q[13]; +cx q[12], q[13]; +u3(2.6795523880654355, 4.953912199856304, 13.708133806449572) q[13]; +cx q[13], q[14]; +u3(3.141592653589793, 5.965349845280416, 9.198382981006143) q[13]; +u3(6.283185314874866, 0.36918853068220286, 2.7724041170758302) q[14]; +cx q[13], q[14]; +u3(0.4620402655243577, 5.141422114821867, 5.0453526822314965) q[13]; +u3(5.25545131442516, 6.274253533786785, 0.14659119102044613) q[14]; +cx q[14], q[15]; +u3(-1.5970406745757394e-09, 4.735814519429113, 1.8289194382804266) q[14]; +u3(3.4305321712208463, 2.492071817710516, -0.7714176214060169) q[15]; +cx q[14], q[15]; +u3(4.7123890176797145, 4.712389005059283, 3.007069173802136) q[14]; +u3(4.0238360530750805, 2.3224104472296476, 2.5445026374178767) q[15]; From 6e5e33ddfc80b1abcd8572fd9925808db2683acb Mon Sep 17 00:00:00 2001 From: Theresa Date: Mon, 12 Aug 2024 18:50:05 +0200 Subject: [PATCH 07/38] :white_check_mark: Test circuits synthesized with BQSKit --- .../heisenberg16.qasm | 1032 ----------------- .../heisenberg16_out_default_error.qasm | 635 ---------- .../heisenberg16_out_high_error.qasm | 35 - .../heisenberg16_out_small_error.qasm | 864 -------------- .../approximateEquivalenceTest/toffoli.qasm | 4 + .../toffoli_out_default_error.qasm | 27 + .../toffoli_out_high_error.qasm | 10 + .../toffoli_out_small_error.qasm | 28 + test/test_equality.cpp | 48 + 9 files changed, 117 insertions(+), 2566 deletions(-) delete mode 100644 test/circuits/approximateEquivalenceTest/heisenberg16.qasm delete mode 100644 test/circuits/approximateEquivalenceTest/heisenberg16_out_default_error.qasm delete mode 100644 test/circuits/approximateEquivalenceTest/heisenberg16_out_high_error.qasm delete mode 100644 test/circuits/approximateEquivalenceTest/heisenberg16_out_small_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/toffoli.qasm create mode 100644 test/circuits/approximateEquivalenceTest/toffoli_out_default_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/toffoli_out_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/toffoli_out_small_error.qasm diff --git a/test/circuits/approximateEquivalenceTest/heisenberg16.qasm b/test/circuits/approximateEquivalenceTest/heisenberg16.qasm deleted file mode 100644 index 7beafe49..00000000 --- a/test/circuits/approximateEquivalenceTest/heisenberg16.qasm +++ /dev/null @@ -1,1032 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[16]; -creg c[16]; -x q[1]; -x q[3]; -x q[5]; -x q[7]; -x q[9]; -x q[11]; -x q[13]; -x q[15]; -h q[0]; -h q[1]; -cx q[0],q[1]; -rz(-0.25) q[1]; -cx q[0],q[1]; -h q[0]; -h q[1]; -h q[1]; -h q[2]; -cx q[1],q[2]; -rz(-0.25) q[2]; -cx q[1],q[2]; -h q[1]; -h q[2]; -h q[2]; -h q[3]; -cx q[2],q[3]; -rz(-0.25) q[3]; -cx q[2],q[3]; -h q[2]; -h q[3]; -h q[3]; -h q[4]; -cx q[3],q[4]; -rz(-0.25) q[4]; -cx q[3],q[4]; -h q[3]; -h q[4]; -h q[4]; -h q[5]; -cx q[4],q[5]; -rz(-0.25) q[5]; -cx q[4],q[5]; -h q[4]; -h q[5]; -h q[5]; -h q[6]; -cx q[5],q[6]; -rz(-0.25) q[6]; -cx q[5],q[6]; -h q[5]; -h q[6]; -h q[6]; -h q[7]; -cx q[6],q[7]; -rz(-0.25) q[7]; -cx q[6],q[7]; -h q[6]; -h q[7]; -h q[7]; -h q[8]; -cx q[7],q[8]; -rz(-0.25) q[8]; -cx q[7],q[8]; -h q[7]; -h q[8]; -h q[8]; -h q[9]; -cx q[8],q[9]; -rz(-0.25) q[9]; -cx q[8],q[9]; -h q[8]; -h q[9]; -h q[9]; -h q[10]; -cx q[9],q[10]; -rz(-0.25) q[10]; -cx q[9],q[10]; -h q[9]; -h q[10]; -h q[10]; -h q[11]; -cx q[10],q[11]; -rz(-0.25) q[11]; -cx q[10],q[11]; -h q[10]; -h q[11]; -h q[11]; -h q[12]; -cx q[11],q[12]; -rz(-0.25) q[12]; -cx q[11],q[12]; -h q[11]; -h q[12]; -h q[12]; -h q[13]; -cx q[12],q[13]; -rz(-0.25) q[13]; -cx q[12],q[13]; -h q[12]; -h q[13]; -h q[13]; -h q[14]; -cx q[13],q[14]; -rz(-0.25) q[14]; -cx q[13],q[14]; -h q[13]; -h q[14]; -h q[14]; -h q[15]; -cx q[14],q[15]; -rz(-0.25) q[15]; -cx q[14],q[15]; -h q[14]; -h q[15]; -rx(-pi/2) q[0]; -rx(-pi/2) q[1]; -cx q[0],q[1]; -rz(-0.25) q[1]; -cx q[0],q[1]; -rx(pi/2) q[0]; -rx(pi/2) q[1]; -rx(-pi/2) q[1]; -rx(-pi/2) q[2]; -cx q[1],q[2]; -rz(-0.25) q[2]; -cx q[1],q[2]; -rx(pi/2) q[1]; -rx(pi/2) q[2]; -rx(-pi/2) q[2]; -rx(-pi/2) q[3]; -cx q[2],q[3]; -rz(-0.25) q[3]; -cx q[2],q[3]; -rx(pi/2) q[2]; -rx(pi/2) q[3]; -rx(-pi/2) q[3]; -rx(-pi/2) q[4]; -cx q[3],q[4]; -rz(-0.25) q[4]; -cx q[3],q[4]; -rx(pi/2) q[3]; -rx(pi/2) q[4]; -rx(-pi/2) q[4]; -rx(-pi/2) q[5]; -cx q[4],q[5]; -rz(-0.25) q[5]; -cx q[4],q[5]; -rx(pi/2) q[4]; -rx(pi/2) q[5]; -rx(-pi/2) q[5]; -rx(-pi/2) q[6]; -cx q[5],q[6]; -rz(-0.25) q[6]; -cx q[5],q[6]; -rx(pi/2) q[5]; -rx(pi/2) q[6]; -rx(-pi/2) q[6]; -rx(-pi/2) q[7]; -cx q[6],q[7]; -rz(-0.25) q[7]; -cx q[6],q[7]; -rx(pi/2) q[6]; -rx(pi/2) q[7]; -rx(-pi/2) q[7]; -rx(-pi/2) q[8]; -cx q[7],q[8]; -rz(-0.25) q[8]; -cx q[7],q[8]; -rx(pi/2) q[7]; -rx(pi/2) q[8]; -rx(-pi/2) q[8]; -rx(-pi/2) q[9]; -cx q[8],q[9]; -rz(-0.25) q[9]; -cx q[8],q[9]; -rx(pi/2) q[8]; -rx(pi/2) q[9]; -rx(-pi/2) q[9]; -rx(-pi/2) q[10]; -cx q[9],q[10]; -rz(-0.25) q[10]; -cx q[9],q[10]; -rx(pi/2) q[9]; -rx(pi/2) q[10]; -rx(-pi/2) q[10]; -rx(-pi/2) q[11]; -cx q[10],q[11]; -rz(-0.25) q[11]; -cx q[10],q[11]; -rx(pi/2) q[10]; -rx(pi/2) q[11]; -rx(-pi/2) q[11]; -rx(-pi/2) q[12]; -cx q[11],q[12]; -rz(-0.25) q[12]; -cx q[11],q[12]; -rx(pi/2) q[11]; -rx(pi/2) q[12]; -rx(-pi/2) q[12]; -rx(-pi/2) q[13]; -cx q[12],q[13]; -rz(-0.25) q[13]; -cx q[12],q[13]; -rx(pi/2) q[12]; -rx(pi/2) q[13]; -rx(-pi/2) q[13]; -rx(-pi/2) q[14]; -cx q[13],q[14]; -rz(-0.25) q[14]; -cx q[13],q[14]; -rx(pi/2) q[13]; -rx(pi/2) q[14]; -rx(-pi/2) q[14]; -rx(-pi/2) q[15]; -cx q[14],q[15]; -rz(-0.25) q[15]; -cx q[14],q[15]; -rx(pi/2) q[14]; -rx(pi/2) q[15]; -cx q[0],q[1]; -rz(0) q[1]; -cx q[0],q[1]; -cx q[1],q[2]; -rz(0) q[2]; -cx q[1],q[2]; -cx q[2],q[3]; -rz(0) q[3]; -cx q[2],q[3]; -cx q[3],q[4]; -rz(0) q[4]; -cx q[3],q[4]; -cx q[4],q[5]; -rz(0) q[5]; -cx q[4],q[5]; -cx q[5],q[6]; -rz(0) q[6]; -cx q[5],q[6]; -cx q[6],q[7]; -rz(0) q[7]; -cx q[6],q[7]; -cx q[7],q[8]; -rz(0) q[8]; -cx q[7],q[8]; -cx q[8],q[9]; -rz(0) q[9]; -cx q[8],q[9]; -cx q[9],q[10]; -rz(0) q[10]; -cx q[9],q[10]; -cx q[10],q[11]; -rz(0) q[11]; -cx q[10],q[11]; -cx q[11],q[12]; -rz(0) q[12]; -cx q[11],q[12]; -cx q[12],q[13]; -rz(0) q[13]; -cx q[12],q[13]; -cx q[13],q[14]; -rz(0) q[14]; -cx q[13],q[14]; -cx q[14],q[15]; -rz(0) q[15]; -cx q[14],q[15]; -h q[0]; -h q[1]; -cx q[0],q[1]; -rz(-0.25) q[1]; -cx q[0],q[1]; -h q[0]; -h q[1]; -h q[1]; -h q[2]; -cx q[1],q[2]; -rz(-0.25) q[2]; -cx q[1],q[2]; -h q[1]; -h q[2]; -h q[2]; -h q[3]; -cx q[2],q[3]; -rz(-0.25) q[3]; -cx q[2],q[3]; -h q[2]; -h q[3]; -h q[3]; -h q[4]; -cx q[3],q[4]; -rz(-0.25) q[4]; -cx q[3],q[4]; -h q[3]; -h q[4]; -h q[4]; -h q[5]; -cx q[4],q[5]; -rz(-0.25) q[5]; -cx q[4],q[5]; -h q[4]; -h q[5]; -h q[5]; -h q[6]; -cx q[5],q[6]; -rz(-0.25) q[6]; -cx q[5],q[6]; -h q[5]; -h q[6]; -h q[6]; -h q[7]; -cx q[6],q[7]; -rz(-0.25) q[7]; -cx q[6],q[7]; -h q[6]; -h q[7]; -h q[7]; -h q[8]; -cx q[7],q[8]; -rz(-0.25) q[8]; -cx q[7],q[8]; -h q[7]; -h q[8]; -h q[8]; -h q[9]; -cx q[8],q[9]; -rz(-0.25) q[9]; -cx q[8],q[9]; -h q[8]; -h q[9]; -h q[9]; -h q[10]; -cx q[9],q[10]; -rz(-0.25) q[10]; -cx q[9],q[10]; -h q[9]; -h q[10]; -h q[10]; -h q[11]; -cx q[10],q[11]; -rz(-0.25) q[11]; -cx q[10],q[11]; -h q[10]; -h q[11]; -h q[11]; -h q[12]; -cx q[11],q[12]; -rz(-0.25) q[12]; -cx q[11],q[12]; -h q[11]; -h q[12]; -h q[12]; -h q[13]; -cx q[12],q[13]; -rz(-0.25) q[13]; -cx q[12],q[13]; -h q[12]; -h q[13]; -h q[13]; -h q[14]; -cx q[13],q[14]; -rz(-0.25) q[14]; -cx q[13],q[14]; -h q[13]; -h q[14]; -h q[14]; -h q[15]; -cx q[14],q[15]; -rz(-0.25) q[15]; -cx q[14],q[15]; -h q[14]; -h q[15]; -rx(-pi/2) q[0]; -rx(-pi/2) q[1]; -cx q[0],q[1]; -rz(-0.25) q[1]; -cx q[0],q[1]; -rx(pi/2) q[0]; -rx(pi/2) q[1]; -rx(-pi/2) q[1]; -rx(-pi/2) q[2]; -cx q[1],q[2]; -rz(-0.25) q[2]; -cx q[1],q[2]; -rx(pi/2) q[1]; -rx(pi/2) q[2]; -rx(-pi/2) q[2]; -rx(-pi/2) q[3]; -cx q[2],q[3]; -rz(-0.25) q[3]; -cx q[2],q[3]; -rx(pi/2) q[2]; -rx(pi/2) q[3]; -rx(-pi/2) q[3]; -rx(-pi/2) q[4]; -cx q[3],q[4]; -rz(-0.25) q[4]; -cx q[3],q[4]; -rx(pi/2) q[3]; -rx(pi/2) q[4]; -rx(-pi/2) q[4]; -rx(-pi/2) q[5]; -cx q[4],q[5]; -rz(-0.25) q[5]; -cx q[4],q[5]; -rx(pi/2) q[4]; -rx(pi/2) q[5]; -rx(-pi/2) q[5]; -rx(-pi/2) q[6]; -cx q[5],q[6]; -rz(-0.25) q[6]; -cx q[5],q[6]; -rx(pi/2) q[5]; -rx(pi/2) q[6]; -rx(-pi/2) q[6]; -rx(-pi/2) q[7]; -cx q[6],q[7]; -rz(-0.25) q[7]; -cx q[6],q[7]; -rx(pi/2) q[6]; -rx(pi/2) q[7]; -rx(-pi/2) q[7]; -rx(-pi/2) q[8]; -cx q[7],q[8]; -rz(-0.25) q[8]; -cx q[7],q[8]; -rx(pi/2) q[7]; -rx(pi/2) q[8]; -rx(-pi/2) q[8]; -rx(-pi/2) q[9]; -cx q[8],q[9]; -rz(-0.25) q[9]; -cx q[8],q[9]; -rx(pi/2) q[8]; -rx(pi/2) q[9]; -rx(-pi/2) q[9]; -rx(-pi/2) q[10]; -cx q[9],q[10]; -rz(-0.25) q[10]; -cx q[9],q[10]; -rx(pi/2) q[9]; -rx(pi/2) q[10]; -rx(-pi/2) q[10]; -rx(-pi/2) q[11]; -cx q[10],q[11]; -rz(-0.25) q[11]; -cx q[10],q[11]; -rx(pi/2) q[10]; -rx(pi/2) q[11]; -rx(-pi/2) q[11]; -rx(-pi/2) q[12]; -cx q[11],q[12]; -rz(-0.25) q[12]; -cx q[11],q[12]; -rx(pi/2) q[11]; -rx(pi/2) q[12]; -rx(-pi/2) q[12]; -rx(-pi/2) q[13]; -cx q[12],q[13]; -rz(-0.25) q[13]; -cx q[12],q[13]; -rx(pi/2) q[12]; -rx(pi/2) q[13]; -rx(-pi/2) q[13]; -rx(-pi/2) q[14]; -cx q[13],q[14]; -rz(-0.25) q[14]; -cx q[13],q[14]; -rx(pi/2) q[13]; -rx(pi/2) q[14]; -rx(-pi/2) q[14]; -rx(-pi/2) q[15]; -cx q[14],q[15]; -rz(-0.25) q[15]; -cx q[14],q[15]; -rx(pi/2) q[14]; -rx(pi/2) q[15]; -cx q[0],q[1]; -rz(0) q[1]; -cx q[0],q[1]; -cx q[1],q[2]; -rz(0) q[2]; -cx q[1],q[2]; -cx q[2],q[3]; -rz(0) q[3]; -cx q[2],q[3]; -cx q[3],q[4]; -rz(0) q[4]; -cx q[3],q[4]; -cx q[4],q[5]; -rz(0) q[5]; -cx q[4],q[5]; -cx q[5],q[6]; -rz(0) q[6]; -cx q[5],q[6]; -cx q[6],q[7]; -rz(0) q[7]; -cx q[6],q[7]; -cx q[7],q[8]; -rz(0) q[8]; -cx q[7],q[8]; -cx q[8],q[9]; -rz(0) q[9]; -cx q[8],q[9]; -cx q[9],q[10]; -rz(0) q[10]; -cx q[9],q[10]; -cx q[10],q[11]; -rz(0) q[11]; -cx q[10],q[11]; -cx q[11],q[12]; -rz(0) q[12]; -cx q[11],q[12]; -cx q[12],q[13]; -rz(0) q[13]; -cx q[12],q[13]; -cx q[13],q[14]; -rz(0) q[14]; -cx q[13],q[14]; -cx q[14],q[15]; -rz(0) q[15]; -cx q[14],q[15]; -h q[0]; -h q[1]; -cx q[0],q[1]; -rz(-0.25) q[1]; -cx q[0],q[1]; -h q[0]; -h q[1]; -h q[1]; -h q[2]; -cx q[1],q[2]; -rz(-0.25) q[2]; -cx q[1],q[2]; -h q[1]; -h q[2]; -h q[2]; -h q[3]; -cx q[2],q[3]; -rz(-0.25) q[3]; -cx q[2],q[3]; -h q[2]; -h q[3]; -h q[3]; -h q[4]; -cx q[3],q[4]; -rz(-0.25) q[4]; -cx q[3],q[4]; -h q[3]; -h q[4]; -h q[4]; -h q[5]; -cx q[4],q[5]; -rz(-0.25) q[5]; -cx q[4],q[5]; -h q[4]; -h q[5]; -h q[5]; -h q[6]; -cx q[5],q[6]; -rz(-0.25) q[6]; -cx q[5],q[6]; -h q[5]; -h q[6]; -h q[6]; -h q[7]; -cx q[6],q[7]; -rz(-0.25) q[7]; -cx q[6],q[7]; -h q[6]; -h q[7]; -h q[7]; -h q[8]; -cx q[7],q[8]; -rz(-0.25) q[8]; -cx q[7],q[8]; -h q[7]; -h q[8]; -h q[8]; -h q[9]; -cx q[8],q[9]; -rz(-0.25) q[9]; -cx q[8],q[9]; -h q[8]; -h q[9]; -h q[9]; -h q[10]; -cx q[9],q[10]; -rz(-0.25) q[10]; -cx q[9],q[10]; -h q[9]; -h q[10]; -h q[10]; -h q[11]; -cx q[10],q[11]; -rz(-0.25) q[11]; -cx q[10],q[11]; -h q[10]; -h q[11]; -h q[11]; -h q[12]; -cx q[11],q[12]; -rz(-0.25) q[12]; -cx q[11],q[12]; -h q[11]; -h q[12]; -h q[12]; -h q[13]; -cx q[12],q[13]; -rz(-0.25) q[13]; -cx q[12],q[13]; -h q[12]; -h q[13]; -h q[13]; -h q[14]; -cx q[13],q[14]; -rz(-0.25) q[14]; -cx q[13],q[14]; -h q[13]; -h q[14]; -h q[14]; -h q[15]; -cx q[14],q[15]; -rz(-0.25) q[15]; -cx q[14],q[15]; -h q[14]; -h q[15]; -rx(-pi/2) q[0]; -rx(-pi/2) q[1]; -cx q[0],q[1]; -rz(-0.25) q[1]; -cx q[0],q[1]; -rx(pi/2) q[0]; -rx(pi/2) q[1]; -rx(-pi/2) q[1]; -rx(-pi/2) q[2]; -cx q[1],q[2]; -rz(-0.25) q[2]; -cx q[1],q[2]; -rx(pi/2) q[1]; -rx(pi/2) q[2]; -rx(-pi/2) q[2]; -rx(-pi/2) q[3]; -cx q[2],q[3]; -rz(-0.25) q[3]; -cx q[2],q[3]; -rx(pi/2) q[2]; -rx(pi/2) q[3]; -rx(-pi/2) q[3]; -rx(-pi/2) q[4]; -cx q[3],q[4]; -rz(-0.25) q[4]; -cx q[3],q[4]; -rx(pi/2) q[3]; -rx(pi/2) q[4]; -rx(-pi/2) q[4]; -rx(-pi/2) q[5]; -cx q[4],q[5]; -rz(-0.25) q[5]; -cx q[4],q[5]; -rx(pi/2) q[4]; -rx(pi/2) q[5]; -rx(-pi/2) q[5]; -rx(-pi/2) q[6]; -cx q[5],q[6]; -rz(-0.25) q[6]; -cx q[5],q[6]; -rx(pi/2) q[5]; -rx(pi/2) q[6]; -rx(-pi/2) q[6]; -rx(-pi/2) q[7]; -cx q[6],q[7]; -rz(-0.25) q[7]; -cx q[6],q[7]; -rx(pi/2) q[6]; -rx(pi/2) q[7]; -rx(-pi/2) q[7]; -rx(-pi/2) q[8]; -cx q[7],q[8]; -rz(-0.25) q[8]; -cx q[7],q[8]; -rx(pi/2) q[7]; -rx(pi/2) q[8]; -rx(-pi/2) q[8]; -rx(-pi/2) q[9]; -cx q[8],q[9]; -rz(-0.25) q[9]; -cx q[8],q[9]; -rx(pi/2) q[8]; -rx(pi/2) q[9]; -rx(-pi/2) q[9]; -rx(-pi/2) q[10]; -cx q[9],q[10]; -rz(-0.25) q[10]; -cx q[9],q[10]; -rx(pi/2) q[9]; -rx(pi/2) q[10]; -rx(-pi/2) q[10]; -rx(-pi/2) q[11]; -cx q[10],q[11]; -rz(-0.25) q[11]; -cx q[10],q[11]; -rx(pi/2) q[10]; -rx(pi/2) q[11]; -rx(-pi/2) q[11]; -rx(-pi/2) q[12]; -cx q[11],q[12]; -rz(-0.25) q[12]; -cx q[11],q[12]; -rx(pi/2) q[11]; -rx(pi/2) q[12]; -rx(-pi/2) q[12]; -rx(-pi/2) q[13]; -cx q[12],q[13]; -rz(-0.25) q[13]; -cx q[12],q[13]; -rx(pi/2) q[12]; -rx(pi/2) q[13]; -rx(-pi/2) q[13]; -rx(-pi/2) q[14]; -cx q[13],q[14]; -rz(-0.25) q[14]; -cx q[13],q[14]; -rx(pi/2) q[13]; -rx(pi/2) q[14]; -rx(-pi/2) q[14]; -rx(-pi/2) q[15]; -cx q[14],q[15]; -rz(-0.25) q[15]; -cx q[14],q[15]; -rx(pi/2) q[14]; -rx(pi/2) q[15]; -cx q[0],q[1]; -rz(0) q[1]; -cx q[0],q[1]; -cx q[1],q[2]; -rz(0) q[2]; -cx q[1],q[2]; -cx q[2],q[3]; -rz(0) q[3]; -cx q[2],q[3]; -cx q[3],q[4]; -rz(0) q[4]; -cx q[3],q[4]; -cx q[4],q[5]; -rz(0) q[5]; -cx q[4],q[5]; -cx q[5],q[6]; -rz(0) q[6]; -cx q[5],q[6]; -cx q[6],q[7]; -rz(0) q[7]; -cx q[6],q[7]; -cx q[7],q[8]; -rz(0) q[8]; -cx q[7],q[8]; -cx q[8],q[9]; -rz(0) q[9]; -cx q[8],q[9]; -cx q[9],q[10]; -rz(0) q[10]; -cx q[9],q[10]; -cx q[10],q[11]; -rz(0) q[11]; -cx q[10],q[11]; -cx q[11],q[12]; -rz(0) q[12]; -cx q[11],q[12]; -cx q[12],q[13]; -rz(0) q[13]; -cx q[12],q[13]; -cx q[13],q[14]; -rz(0) q[14]; -cx q[13],q[14]; -cx q[14],q[15]; -rz(0) q[15]; -cx q[14],q[15]; -h q[0]; -h q[1]; -cx q[0],q[1]; -rz(-0.25) q[1]; -cx q[0],q[1]; -h q[0]; -h q[1]; -h q[1]; -h q[2]; -cx q[1],q[2]; -rz(-0.25) q[2]; -cx q[1],q[2]; -h q[1]; -h q[2]; -h q[2]; -h q[3]; -cx q[2],q[3]; -rz(-0.25) q[3]; -cx q[2],q[3]; -h q[2]; -h q[3]; -h q[3]; -h q[4]; -cx q[3],q[4]; -rz(-0.25) q[4]; -cx q[3],q[4]; -h q[3]; -h q[4]; -h q[4]; -h q[5]; -cx q[4],q[5]; -rz(-0.25) q[5]; -cx q[4],q[5]; -h q[4]; -h q[5]; -h q[5]; -h q[6]; -cx q[5],q[6]; -rz(-0.25) q[6]; -cx q[5],q[6]; -h q[5]; -h q[6]; -h q[6]; -h q[7]; -cx q[6],q[7]; -rz(-0.25) q[7]; -cx q[6],q[7]; -h q[6]; -h q[7]; -h q[7]; -h q[8]; -cx q[7],q[8]; -rz(-0.25) q[8]; -cx q[7],q[8]; -h q[7]; -h q[8]; -h q[8]; -h q[9]; -cx q[8],q[9]; -rz(-0.25) q[9]; -cx q[8],q[9]; -h q[8]; -h q[9]; -h q[9]; -h q[10]; -cx q[9],q[10]; -rz(-0.25) q[10]; -cx q[9],q[10]; -h q[9]; -h q[10]; -h q[10]; -h q[11]; -cx q[10],q[11]; -rz(-0.25) q[11]; -cx q[10],q[11]; -h q[10]; -h q[11]; -h q[11]; -h q[12]; -cx q[11],q[12]; -rz(-0.25) q[12]; -cx q[11],q[12]; -h q[11]; -h q[12]; -h q[12]; -h q[13]; -cx q[12],q[13]; -rz(-0.25) q[13]; -cx q[12],q[13]; -h q[12]; -h q[13]; -h q[13]; -h q[14]; -cx q[13],q[14]; -rz(-0.25) q[14]; -cx q[13],q[14]; -h q[13]; -h q[14]; -h q[14]; -h q[15]; -cx q[14],q[15]; -rz(-0.25) q[15]; -cx q[14],q[15]; -h q[14]; -h q[15]; -rx(-pi/2) q[0]; -rx(-pi/2) q[1]; -cx q[0],q[1]; -rz(-0.25) q[1]; -cx q[0],q[1]; -rx(pi/2) q[0]; -rx(pi/2) q[1]; -rx(-pi/2) q[1]; -rx(-pi/2) q[2]; -cx q[1],q[2]; -rz(-0.25) q[2]; -cx q[1],q[2]; -rx(pi/2) q[1]; -rx(pi/2) q[2]; -rx(-pi/2) q[2]; -rx(-pi/2) q[3]; -cx q[2],q[3]; -rz(-0.25) q[3]; -cx q[2],q[3]; -rx(pi/2) q[2]; -rx(pi/2) q[3]; -rx(-pi/2) q[3]; -rx(-pi/2) q[4]; -cx q[3],q[4]; -rz(-0.25) q[4]; -cx q[3],q[4]; -rx(pi/2) q[3]; -rx(pi/2) q[4]; -rx(-pi/2) q[4]; -rx(-pi/2) q[5]; -cx q[4],q[5]; -rz(-0.25) q[5]; -cx q[4],q[5]; -rx(pi/2) q[4]; -rx(pi/2) q[5]; -rx(-pi/2) q[5]; -rx(-pi/2) q[6]; -cx q[5],q[6]; -rz(-0.25) q[6]; -cx q[5],q[6]; -rx(pi/2) q[5]; -rx(pi/2) q[6]; -rx(-pi/2) q[6]; -rx(-pi/2) q[7]; -cx q[6],q[7]; -rz(-0.25) q[7]; -cx q[6],q[7]; -rx(pi/2) q[6]; -rx(pi/2) q[7]; -rx(-pi/2) q[7]; -rx(-pi/2) q[8]; -cx q[7],q[8]; -rz(-0.25) q[8]; -cx q[7],q[8]; -rx(pi/2) q[7]; -rx(pi/2) q[8]; -rx(-pi/2) q[8]; -rx(-pi/2) q[9]; -cx q[8],q[9]; -rz(-0.25) q[9]; -cx q[8],q[9]; -rx(pi/2) q[8]; -rx(pi/2) q[9]; -rx(-pi/2) q[9]; -rx(-pi/2) q[10]; -cx q[9],q[10]; -rz(-0.25) q[10]; -cx q[9],q[10]; -rx(pi/2) q[9]; -rx(pi/2) q[10]; -rx(-pi/2) q[10]; -rx(-pi/2) q[11]; -cx q[10],q[11]; -rz(-0.25) q[11]; -cx q[10],q[11]; -rx(pi/2) q[10]; -rx(pi/2) q[11]; -rx(-pi/2) q[11]; -rx(-pi/2) q[12]; -cx q[11],q[12]; -rz(-0.25) q[12]; -cx q[11],q[12]; -rx(pi/2) q[11]; -rx(pi/2) q[12]; -rx(-pi/2) q[12]; -rx(-pi/2) q[13]; -cx q[12],q[13]; -rz(-0.25) q[13]; -cx q[12],q[13]; -rx(pi/2) q[12]; -rx(pi/2) q[13]; -rx(-pi/2) q[13]; -rx(-pi/2) q[14]; -cx q[13],q[14]; -rz(-0.25) q[14]; -cx q[13],q[14]; -rx(pi/2) q[13]; -rx(pi/2) q[14]; -rx(-pi/2) q[14]; -rx(-pi/2) q[15]; -cx q[14],q[15]; -rz(-0.25) q[15]; -cx q[14],q[15]; -rx(pi/2) q[14]; -rx(pi/2) q[15]; -cx q[0],q[1]; -rz(0) q[1]; -cx q[0],q[1]; -cx q[1],q[2]; -rz(0) q[2]; -cx q[1],q[2]; -cx q[2],q[3]; -rz(0) q[3]; -cx q[2],q[3]; -cx q[3],q[4]; -rz(0) q[4]; -cx q[3],q[4]; -cx q[4],q[5]; -rz(0) q[5]; -cx q[4],q[5]; -cx q[5],q[6]; -rz(0) q[6]; -cx q[5],q[6]; -cx q[6],q[7]; -rz(0) q[7]; -cx q[6],q[7]; -cx q[7],q[8]; -rz(0) q[8]; -cx q[7],q[8]; -cx q[8],q[9]; -rz(0) q[9]; -cx q[8],q[9]; -cx q[9],q[10]; -rz(0) q[10]; -cx q[9],q[10]; -cx q[10],q[11]; -rz(0) q[11]; -cx q[10],q[11]; -cx q[11],q[12]; -rz(0) q[12]; -cx q[11],q[12]; -cx q[12],q[13]; -rz(0) q[13]; -cx q[12],q[13]; -cx q[13],q[14]; -rz(0) q[14]; -cx q[13],q[14]; -cx q[14],q[15]; -rz(0) q[15]; -cx q[14],q[15]; diff --git a/test/circuits/approximateEquivalenceTest/heisenberg16_out_default_error.qasm b/test/circuits/approximateEquivalenceTest/heisenberg16_out_default_error.qasm deleted file mode 100644 index 38109161..00000000 --- a/test/circuits/approximateEquivalenceTest/heisenberg16_out_default_error.qasm +++ /dev/null @@ -1,635 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[16]; -u3(4.712388980338651, 6.108692489801767, 4.7123889807722685) q[0]; -u3(1.5707963114451298, 3.1415926409139647, 3.14159269212614) q[3]; -u3(1.5707963266029188, 3.141592653587166, 3.1415926536385554) q[4]; -u3(14.137166918233161, 9.424777967586467, -3.460391726645931) q[5]; -u3(1.5707963297916603, 6.28318531143497, 6.283185311029583) q[7]; -u3(7.85398163379915, -4.923495534880917e-10, 7.550168597420008) q[8]; -u3(1.570796326757235, 3.1415926535280803, 2.879623478289598) q[10]; -u3(1.5707963267947944, 6.283185307179829, 2.6238589031468934e-13) q[11]; -u3(1.570796326785829, 4.498162220944756e-11, -1.1557677690197726e-11) q[12]; -u3(4.712388980176627, 6.283185307044667, 8.796843038979018) q[13]; -u3(3.1415926753577583, 3.8306870188659343, 2.2598906860899493) q[15]; -cx q[0], q[1]; -u3(3.391592653592361, 1.407742778744646, 0.1744928433958416) q[0]; -cx q[1], q[2]; -u3(6.03318530717976, 0.9237606614242946, 7.853981634407427) q[1]; -u3(8.235816978506982, 4.7123889815219755, -1.5707963256558046) q[2]; -cx q[1], q[2]; -u3(1.5707963267958784, 1.3207963275048504, -0.9237606611402817) q[1]; -u3(4.712388980522579, 5.094224325097181, 3.1415926545626007) q[2]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(4.712388980428976, 1.5707963271322587, 4.875442554455431) q[0]; -u3(6.283185289103343, 5.015527273802983, 1.017658007183826) q[3]; -cx q[2], q[3]; -u3(4.712388980234035, 3.1415926536531718, -1.5707963266724412) q[2]; -cx q[3], q[4]; -cx q[1], q[2]; -u3(6.283185307135298, -0.2700129356774333, 3.1616055892380204) q[4]; -u3(6.283185307179579, -0.04720677484100478, -0.2027932252522013) q[2]; -cx q[3], q[4]; -cx q[1], q[2]; -cx q[4], q[5]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(1.2622407934345188, 11.077050952995299, -4.975066551247192) q[5]; -u3(-1.5707962709643932, -136.65928061289824, 142.94246592045118) q[1]; -u3(1.570796326813926, 4.462388980393381, 4.712388980395613) q[3]; -cx q[4], q[5]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(1.5707963267949028, 6.283185306349956, 1.5707963259652657) q[4]; -cx q[5], q[6]; -u3(4.712388995025831, 3.7922444472394923, 1.6057500112892966) q[0]; -u3(4.712388980374177, 1.5707963267913827, 1.5707963268307907) q[2]; -u3(2.7377042359901217e-11, 8.299261613459564, -0.4452799795456747) q[3]; -u3(0.24999999999829775, 1.570796343548059, 6.283185266234632) q[5]; -u3(4.67743529104079, 4.915586642731732, 0.9201445650964967) q[0]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(1.6374439006687632e-10, 4.312649826941624, 1.7205354806524713) q[4]; -u3(1.5707963267949028, 6.283185306349956, 3.141592652760162) q[6]; -cx q[3], q[4]; -cx q[6], q[7]; -u3(-1.5707963262683062, 7.8539816340455655, -1.5707963274059769) q[3]; -cx q[4], q[5]; -u3(3.141592655118776, 6.033185302504917, 6.283185303714076) q[7]; -cx q[2], q[3]; -u3(6.283185307179586, 4.060608545123188, 1.972576768528883) q[5]; -cx q[6], q[7]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[7], q[8]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(-2.7506200921481225, 11.663645318556787, -4.005850646971005) q[8]; -u3(0.2499999999948803, 0.7513409081231701, 4.712388983114875) q[1]; -u3(6.163609419406038, -1.5707963263084919, 1.5707963263025646) q[2]; -u3(4.712388964806967, 1.570796347226618, 4.712389000815068) q[4]; -u3(4.712388980382085, 4.462388980374244, 1.570796326784184) q[6]; -cx q[7], q[8]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(-1.5707963267948966, -3.1415926535985585, 10.995574287555511) q[7]; -cx q[8], q[9]; -u3(1.5950591855259293, 7.853981653240218, 2.425205432323785) q[1]; -u3(4.712388980160136, 3.261168541726658, -2.593572087237919e-10) q[2]; -u3(1.5707963463232513, 6.283185280277563, 9.424777933864334) q[3]; -u3(4.712388980508581, 1.5707963266058786, -1.570796326535146) q[5]; -u3(6.283185307181674, 5.043027055541347, 5.952547232015244) q[6]; -u3(6.033185307182977, -1.5707963268884435, 3.1415926531627036) q[8]; -u3(-1.5284828102268035, 9.420329922783646, -3.643372119093463) q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[0], q[1]; -u3(1.3381441909567546, 4.712388980392859, 1.3207963268030656) q[3]; -cx q[4], q[5]; -u3(4.083936641847744e-15, 1.0340443650945896, 4.999140942082864) q[7]; -u3(4.712388980384691, -8.76574613204147e-12, -8.765444125124192e-12) q[9]; -u3(0.24999999999099856, 4.362450364576354, 6.0799876448475185) q[0]; -u3(4.592995194517522, -1.0817112024035576, 6.063011669800696) q[1]; -cx q[2], q[3]; -u3(4.712388980367525, 3.141592653628056, 2.5163884682619672e-11) q[4]; -cx q[6], q[7]; -cx q[9], q[10]; -u3(1.5707963267948963, 1.0116070946167267e-11, 1.570796326805013) q[2]; -u3(1.3381441909536418, 7.068494484924477, 4.712388980750062) q[3]; -u3(1.5707963267833216, 4.712388980392686, 1.5707963267906797) q[6]; -cx q[7], q[8]; -u3(0.26196916750817983, -1.8207962920563365, 4.712388943314608) q[10]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(1.6783309683523674e-15, 2.6951998397256705, 3.3379854674504923) q[8]; -cx q[9], q[10]; -u3(3.141592653589793, 1.7304227620747568, 1.9804227620747568) q[2]; -u3(6.283185307179586, 5.726343079888337, 6.590027534480789) q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -cx q[10], q[11]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(4.7123889803725625, 3.1415926535628844, 6.283185307151702) q[5]; -u3(-1.5707963267602998, 1.5707963267989227, 4.712388980386236) q[7]; -cx q[8], q[9]; -u3(3.141592653589788, 6.033185307179192, 6.283185307179262) q[11]; -cx q[0], q[1]; -u3(3.141592653589793, 5.564230676897185, 5.564230676897185) q[2]; -u3(7.853981633971339, -3.4599044527925016e-10, 2.356283475769213) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(-0.267152038440406, 2.7852742596358544, 3.509880214624671) q[9]; -cx q[10], q[11]; -u3(1.5707963275163437, 1.5707963267084348, 6.28318530715287) q[1]; -cx q[2], q[3]; -u3(4.313031625572251e-19, 4.957985107742158, 1.075200199437309) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(4.712388980384814, 3.141592653589843, 1.570796326794983) q[10]; -cx q[11], q[12]; -cx q[0], q[1]; -u3(5.010509235633584e-22, 2.09858620570588, 3.934599101473708) q[3]; -cx q[4], q[5]; -u3(4.712388980383562, 6.28318530717825, 3.1415926535885057) q[6]; -u3(1.5707962443031274, -45.553093520251956, 51.8362788380424) q[8]; -u3(1.6659796375973477, 6.205007286610215e-13, 4.712388980385237) q[9]; -u3(3.141592653601239, 0.29200097119469065, 3.683593624773304) q[12]; -u3(2.784633459170521, 2.0228213506017703, 5.062327676864471) q[0]; -cx q[2], q[3]; -cx q[5], q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(1.5707963267948952, 4.7123889803846915, 7.853981633974479) q[2]; -cx q[3], q[4]; -u3(3.1415926535910232, 2.8915926536013075, 3.141592653599843) q[6]; -cx q[7], q[8]; -u3(6.283185307179573, 3.7793839792923016, 2.2538013274575914) q[10]; -cx q[12], q[13]; -u3(1.5707963267949672, 1.3207963267951686, 1.5707963267953982) q[4]; -cx q[5], q[6]; -u3(1.5707963238195657, -6.2831853028227815, 9.424777961750316) q[7]; -cx q[9], q[10]; -u3(0.9652495793800103, 4.534679123214922, 1.8764411040602869) q[13]; -cx q[3], q[4]; -u3(1.57079632680116, 6.283185307161517, -1.5707963267960379) q[5]; -cx q[6], q[7]; -u3(4.7123889927546, 7.853981675644601, -1.5707963676056476) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -u3(4.71238898038469, 7.853981633974365, 1.5707963267947775) q[3]; -u3(6.283185307179282, -0.2087107962817523, 11.204285083845733) q[4]; -u3(1.9185097214975007e-27, 3.2870023786115894, 2.7461829285679955) q[7]; -cx q[8], q[9]; -u3(4.7123890323813615, 4.962388975104747, 1.5707963469268156) q[11]; -u3(1.570796326794897, 6.2831853071962485, 7.853981633991145) q[12]; -cx q[13], q[14]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(2.8915926535898016, -1.5707963260421018, 9.936866853723563e-10) q[13]; -cx q[2], q[3]; -u3(6.283185307179586, 5.9919559694464954, 6.324414644912669) q[5]; -u3(1.570796326794898, 6.283185307179588, -4.712388980384688) q[6]; -u3(1.5707963270815188, -1.3342189008826704e-09, 3.141592649650193) q[8]; -u3(4.712388980255731, 1.5707963267497478, 4.712388980262468) q[10]; -u3(3.1415925893237806, -0.7920009965156405, 7.061980673393106) q[11]; -cx q[13], q[14]; -cx q[1], q[2]; -cx q[4], q[5]; -cx q[7], q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(4.71238898038469, 1.6661559153557394e-11, 1.666155330958096e-11) q[14]; -u3(-0.24999999997997413, 12.51978386141599, -10.995574292803353) q[1]; -u3(6.03118639602438, 7.853981633974483, -7.853981633974483) q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(3.1415926597775217, 4.4623889826459715, 1.0707963289943847) q[8]; -cx q[9], q[10]; -u3(6.283185307177642, 4.718746436036806, 1.3144388708790546) q[12]; -cx q[14], q[15]; -cx q[1], q[2]; -u3(4.71238898038469, 1.5707963267948872, 4.712388980384681) q[4]; -u3(3.141592694686557, 1.3207963325342675, 7.353981633906259) q[6]; -cx q[7], q[8]; -u3(1.5707963267886862, -1.7164997965245286e-10, 3.1415926535940963) q[9]; -cx q[11], q[12]; -u3(3.5699742671787362, 5.350377870845741, 5.305744907902504) q[15]; -u3(0.658325223784651, 1.5707963234039595, 8.25752758612757) q[1]; -u3(4.71238898038469, 9.172779049623701, -1.3198707100303244e-16) q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(4.712388980384014, 3.1415926528118336, 4.712388979606771) q[7]; -cx q[8], q[9]; -u3(4.712388985118357, 1.570796324035087, 4.712388983655156) q[11]; -cx q[14], q[15]; -cx q[0], q[1]; -u3(1.5707963267919192, 6.283185307182214, 3.1415926535872023) q[3]; -u3(1.5707963267949019, 4.712388980384525, 4.712388980384525) q[5]; -cx q[6], q[7]; -u3(6.283185307179586, 2.798905179416842, 3.7342801270157486) q[9]; -cx q[10], q[11]; -u3(6.0331853071705295, 6.808132612328105, 5.831160384389506) q[0]; -u3(3.420016187813108, 5.504807681865693, -3.7846403531500177) q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(1.1313671838326655e-18, 1.8490832989614672, -1.5990833047691877) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -cx q[0], q[1]; -u3(6.283185312032781, 1.5168508814994683, 4.516334425686633) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(1.5707963329825323, 3.1415926527947717, 4.712388979618908) q[8]; -u3(1.5707963235781648, 6.283185305511577, 3.1415926555626257) q[10]; -cx q[11], q[12]; -u3(4.55170653772111, 4.2627887403632485, 3.4617342308938137) q[1]; -cx q[2], q[3]; -u3(1.570796326819047, 18.849555921537046, -9.424777960790387) q[4]; -u3(1.5707963677811834, 1.5707963268745755, 1.5707963268522906) q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(4.71238898038036, 3.1415926535720384, 4.712388980366974) q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(6.283185307179575, 3.908556422155123, 2.1246288850753565) q[8]; -u3(-5.0462949844570624e-33, -0.3595330356451887, 0.10953303560316723) q[10]; -u3(1.5707963267948966, 1.5249239850176756e-16, 3.141592653589793) q[11]; -u3(3.141592654720821, 1.6003437029393948, -0.6324788680041107) q[12]; -cx q[1], q[2]; -u3(6.283185307179586, -1.2241546630906026, 0.9741546631239735) q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -cx q[12], q[13]; -u3(3.141592653560592, -0.8669566849192908, 5.16622862229754) q[2]; -cx q[3], q[4]; -u3(10.995574287564418, 12.566370614359016, -6.283185307179239) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(3.1415926597934054, 1.5013278337225884, -1.3902648199006566) q[13]; -cx q[1], q[2]; -u3(7.853981638828446, -6.873024184634143e-13, 1.5707963267866771) q[3]; -cx q[4], q[5]; -u3(4.712388981396684, 1.5707963250052448, 4.712388981977831) q[7]; -u3(7.8539816328254375, 7.603981633932298, -4.712388980132211) q[9]; -u3(6.28318530717958, 0.7631809132504355, 5.270004393929074) q[11]; -cx q[12], q[13]; -cx q[0], q[1]; -u3(3.141592653596396, 0.10705410753349598, 0.10705410753346574) q[2]; -u3(12.566370614359535, 1.7701862585059065, 7.404591702263441) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(4.7123889812932545, 1.5707963274673424, 0.9087700826604777) q[12]; -u3(3.1415926472087046, 9.01255294293237, 11.24104015541582) q[13]; -u3(1.5707963419553541, 4.7123889728273545, 7.853981636402672) q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(1.5707963267462566, 6.79540931666523e-11, 3.1415926536168097) q[6]; -u3(4.71238898038469, 14.137166941111863, -4.712388980426897) q[8]; -u3(12.566370615540011, 18.863004176623978, -7.86742988910172) q[9]; -u3(4.712388980390174, 3.1415926535700156, 4.712388980404622) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -cx q[0], q[1]; -u3(6.28318530699503, 3.9579930351919157, 2.075192272555294) q[3]; -u3(1.5707963267948966, -5.10640428605277e-14, 4.712388980384639) q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(0.0, -0.125, -0.125) q[12]; -u3(0.24999999993532587, 1.7859282991810113e-08, 6.283185289372053) q[14]; -u3(2.0273539889935437, 5.498610143445075, 4.187441674861881) q[0]; -cx q[2], q[3]; -u3(-3.021743632512119e-14, 1.0910680446186007, 1.8005246089712037) q[6]; -cx q[7], q[8]; -u3(6.283185304947202, 1.5335940482561428, 4.4995912589249425) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(4.712388982095585, 1.5707963243430445, 4.712388982084678) q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(1.5707963267958511, 6.283185307178808, 3.1415926535893632) q[7]; -cx q[9], q[10]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[11]; -u3(8.532843177179282e-17, 0.0, 0.0) q[12]; -u3(7.85398163400904, 1.5707963268366096, 2.2284872123065083) q[13]; -cx q[14], q[15]; -u3(3.4216150962729133e-10, 4.691236279996363, 4.483541680774887) q[4]; -u3(1.5707963267948972, 6.283185307179585, 4.712388980384689) q[5]; -cx q[6], q[7]; -u3(1.5707963267956748, 4.71238898037985, 1.570796326790056) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -u3(0.6062424926097941, -5.02767289173487, 10.466272770882865) q[14]; -u3(2.565564627986582, 5.152918690399027, 2.0350045677097115) q[15]; -cx q[3], q[4]; -u3(1.4096961731239396e-23, 4.127594477342756, 1.9055908298368351) q[7]; -cx q[8], q[9]; -u3(1.8038785064075254e-25, 4.663441476850374, 1.3697438303387766) q[11]; -u3(0.0, -0.125, -0.125) q[13]; -u3(4.7123889803829275, 1.5707963267957363, 1.570796326795736) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[2], q[3]; -u3(-1.873825681597388e-24, 3.4295619430439745, 2.603623364148929) q[5]; -u3(1.5707963267949236, -9.516095347907472e-15, 4.712388980384689) q[6]; -u3(1.570796326795694, 5.714057661107802e-13, 3.1415926535903145) q[8]; -u3(4.712388982617359, 1.5707963267968652, 4.712388980380003) q[10]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[12]; -u3(3.141592653541133, -0.00032981030183987237, 1.9080971677841019) q[13]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[7], q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -cx q[1], q[2]; -u3(4.712388980042436, 7.853981633955954, 7.853981633975307) q[4]; -cx q[5], q[6]; -u3(6.283185307179586, 4.641984245999261, 1.3912010592671007) q[8]; -cx q[9], q[10]; -u3(6.283185307179586, 2.5722829409919776, 3.4609023661876113) q[12]; -u3(2.8806660306536918, 5.433812571080732, 2.458251585132272) q[14]; -u3(0.24999999804657347, 7.4307178764344695, -1.5707962214519424) q[1]; -u3(-22.562926339732112, 1.5707963267952383, -4.712388980384248) q[2]; -cx q[3], q[4]; -u3(6.283185307179586, 5.932579317570467, 6.383791296788705) q[6]; -cx q[7], q[8]; -u3(1.5707963267933867, 6.283185307180978, 3.141592653588639) q[9]; -cx q[11], q[12]; -cx q[13], q[14]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(1.5707963268288219, 3.141592653677877, 2.0466890805186684) q[13]; -u3(5.341408973885494, -0.42526763458236927, 4.712388988512312) q[14]; -u3(0.9791475204795753, 1.5707963248067942, 1.8944615075385285) q[1]; -u3(26.703537555661512, 16.279741032546422, -2.899099506842461e-10) q[2]; -u3(1.570796326794775, -1.081669257305501e-13, 3.1415926535898993) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(6.283185307180287, 8.2241064391381, -2.1909211319584547) q[9]; -u3(4.712388980384689, 1.5707963267948999, 4.712388980384693) q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(4.712388980384706, 1.5707963267948963, 4.712388980384687) q[5]; -u3(-1.5707962745122797, 26.45353755360375, -20.420352236849926) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(-1.4325342243746337, 4.462388980389457, 7.853981633994874) q[13]; -u3(1.681197174508625, 5.085592148381548, 1.0877788500962067) q[14]; -u3(3.05390801403494, 1.5707965258251115, 7.853981836255417) q[15]; -u3(0.2499999990756757, 9.320256319204537, -10.210999107601783) q[0]; -u3(5.76421591966197, 1.2888734990958974, 1.6083381713328482) q[1]; -u3(3.141592653696557, 3.8893657572136164, 0.49777310362381944) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(4.712388980384689, 3.1415926535896883, -1.570796326795001) q[8]; -u3(1.5707963267949008, -4.208882534762952e-15, 3.1415926535897865) q[10]; -cx q[12], q[13]; -u3(4.580313070504743, -1.6821711562774864, 5.895255054139562) q[14]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(1.5707963267948613, -1.666479961328159e-13, 3.141592653589964) q[4]; -u3(4.712388980384626, 7.85398163205274, 4.712388978462947) q[6]; -u3(5.372844780615214e-08, 0.010616319430500395, 1.5601800054516664) q[7]; -cx q[9], q[10]; -u3(1.5707963267959737, 4.712388980411368, 1.5707963268216378) q[12]; -u3(-1.5707963269469314, 4.811987452920553, 6.387706934775383) q[0]; -u3(3.016798575787169, 2.4924310647482133, -0.6454060390837745) q[1]; -u3(1.5707963267948966, 2.3973922708835725e-11, 1.5707963268188707) q[2]; -u3(3.141592650539631, 3.0217253210406887, 2.3938195487696277) q[3]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(6.283185307179586, 7.375170544832559, 4.941200069526619) q[10]; -cx q[11], q[12]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(5.858166324098832e-14, 3.3557796870973298, 2.677405620074989) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(8.975260531530993e-23, 3.3566547374193814, 3.1765305697602084) q[2]; -u3(6.283185307179586, 3.549707805839418, 2.4834775013636508) q[4]; -u3(4.712388980370311, -6.283185307163165, 12.566370614358618) q[5]; -cx q[7], q[8]; -u3(4.712388985965147, 1.669140023856971e-08, 6.283185267031588) q[11]; -cx q[12], q[13]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[0], q[1]; -u3(1.5707963287773539, 6.283185309470529, 4.08448320812119) q[3]; -cx q[4], q[5]; -u3(1.5707963257443232, 4.712388980164934, 1.5707963270515581) q[7]; -u3(4.7123889803846986, 4.462388980384664, 4.712388980384701) q[9]; -u3(6.283185265851579, 1.034710330613965, 1.8568823270711108) q[11]; -u3(1.5707963267948966, 9.465292135612711e-14, 3.1415926535898877) q[12]; -cx q[13], q[14]; -u3(4.712388980385825, -1.5707963267888738, 4.712388980383788) q[1]; -cx q[2], q[3]; -u3(6.283185307173373, 3.68220882581984, 5.492569134900042) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(3.141592653090783, 1.0659994515108746, 3.957592104819475) q[14]; -cx q[0], q[1]; -u3(6.283185307179586, 5.330805205322357, 6.985565409035757) q[3]; -cx q[4], q[5]; -u3(1.5707963267936589, 6.283185307169811, 3.141592653576418) q[6]; -u3(1.5707963267948883, 4.712388980384695, 4.712388980384693) q[8]; -u3(-4.4216677884371613e-14, 14.138249962541822, -9.425860982157136) q[9]; -u3(1.5707963272250483, 6.579067323523864e-09, -1.57079632054516) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -cx q[2], q[3]; -u3(1.570796326805712, 4.921532301295885e-12, 4.7123889804203305) q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(3.7187289029140677e-13, 2.1267879445684064, 3.90639736214487) q[12]; -u3(4.7123889803914, 4.712388980387074, 6.283185307179901) q[13]; -u3(4.7123889790085105, 5.3851528767138666, -1.1691068171712667e-09) q[14]; -u3(4.712388980388931, 1.5707963268144387, -1.5707963268123206) q[2]; -cx q[3], q[4]; -u3(6.283185307179586, 1.9927561003293375, 4.040429206757706) q[6]; -cx q[7], q[8]; -u3(2.4619824903307766e-17, 1.7643431735788948, 4.268842133574542) q[10]; -cx q[11], q[12]; -cx q[14], q[15]; -cx q[1], q[2]; -u3(4.459020489543665e-25, 1.2057412371566993, 4.8274440700228824) q[4]; -cx q[5], q[6]; -u3(10.995574295051734, 6.283185327891937, 6.283185192392164) q[7]; -cx q[9], q[10]; -u3(1.5707962568857452, 6.283185282123618, 1.5707963527780955) q[11]; -cx q[12], q[13]; -u3(0.24999999999997577, 5.122297968899154e-10, 2.4688287562735343) q[14]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(3.141592653590111, 7.603981633974515, 4.212388980384692) q[13]; -cx q[14], q[15]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(6.2831851829677845, 7.5801335562702805, 1.5946444276606595) q[7]; -u3(4.712388980355799, 1.5707963267489065, 4.71238898033878) q[9]; -u3(3.1415926257510125, 7.603981659615794, 1.070796352364821) q[11]; -cx q[12], q[13]; -u3(5.269509040589788, 4.59026121610542, 3.313857069364759) q[15]; -u3(10.995574287564267, 1.5707963267949014, 10.99557428756428) q[3]; -u3(7.8539816314440305, 1.3207963267020317, 1.570796327350886) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(1.5707963267948966, -1.6370607425945088e-19, 1.570796326794897) q[12]; -cx q[13], q[14]; -u3(1.8494668206145122, 1.0547416550338033, 3.3972820768784686) q[15]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(4.71238898033274, -3.141592629003487, 1.5707963513812682) q[6]; -u3(4.712388980319434, 3.1415926536776535, 5.635991900702019e-11) q[8]; -u3(1.5707963268140606, 4.712388971285808, 4.712388971285841) q[10]; -cx q[11], q[12]; -u3(6.283185307179586, 1.1449864032652306, 5.3881989039143265) q[14]; -u3(-1.570796326794897, 1.5707963267019462, 1.570796326701946) q[4]; -u3(2.600464791903357e-09, 6.294814542315755, 4.700759745155982) q[5]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(1.9086121022637993e-15, 7.029592408686918, 5.78677819780205) q[12]; -cx q[13], q[14]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(3.1415926546903816, 1.3207963280006938, 4.21238898157219) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(1.5707963267945784, 3.14159265358979, -1.570796326794897) q[13]; -cx q[14], q[15]; -cx q[3], q[4]; -u3(3.1415926535883187, 0.8594722222734463, 6.892657529453033) q[6]; -cx q[7], q[8]; -u3(1.570796326790211, 7.159210044929763e-12, 3.141592653582606) q[9]; -u3(1.5707962989820599, 1.5707963174451802, 1.570796317764147) q[11]; -cx q[12], q[13]; -u3(1.0542383688630381, 1.5707963267962146, 1.320796326796093) q[15]; -cx q[5], q[6]; -u3(-1.5707963267953342, 9.424777960344457, -1.570796327219812) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(6.283185307179582, 3.954144487274061, 2.079040819716407) q[13]; -cx q[14], q[15]; -u3(1.5707963267948963, -1.570796326794871, 4.712388980384715) q[5]; -u3(3.14159265356704, 5.00671351937, 2.2821204313235692) q[6]; -u3(6.283185307179586, 3.1899486062386946, 3.343236700555033) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -u3(2.671968966292046, 1.530037418275777, 1.5669225564487055) q[15]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(1.5707963293767255, 3.141592651893826, -4.087110817381425e-09) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(4.722867219144817, 9.378990801435284, 9.199961209105565) q[15]; -cx q[4], q[5]; -u3(4.682056612390999e-24, 1.8557453679769396, 4.177439939216025) q[7]; -u3(1.5707963256936261, 3.141592653171025, 4.712388979964359) q[8]; -cx q[9], q[10]; -u3(4.712388980364331, 1.570796326475961, 4.7123889801571535) q[12]; -u3(3.968874033261966, 4.369612020789568, 1.333782343238115) q[14]; -cx q[6], q[7]; -u3(3.141592651129228, 2.891592659997906, 3.1415926591411085) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(1.5707963267687723, 4.712388980382545, 5.129388545902299) q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(-1.5707963269927483, 3.1415926536455268, 6.283185308048834) q[11]; -u3(4.71238898038469, 1.5707963267968055, 4.712388980386598) q[13]; -u3(-0.7781230015346349, 4.6522030172925275, 0.20004338950627756) q[14]; -cx q[5], q[6]; -u3(6.283185307164732, 0.28589229167756014, 5.747292976738335) q[8]; -u3(7.853981635654209, 12.566370609437419, -1.5707963266001237) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(-9.062922887556289e-09, 4.685338700957432, 1.3478466062218897) q[11]; -cx q[12], q[13]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(4.712388980379848, 3.1415926275035164, -2.6091663891692748e-08) q[12]; -cx q[13], q[14]; -u3(4.7123888744891715, 7.853981643223037, 4.712389048657581) q[7]; -u3(6.283185307179529, 1.8248392988582633, 4.208346008321186) q[9]; -u3(4.7123889803846675, 3.1415926535881735, 4.71238898038307) q[10]; -cx q[11], q[12]; -u3(2.132580211077979, 4.712388912306628, 4.712388912369782) q[14]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(6.283185307179586, -0.7451743477470611, 0.49517434774929775) q[12]; -cx q[13], q[14]; -u3(1.5707963267949137, 4.712388980384617, 1.5707963267948235) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(7.853981633906384, 37.69911181692914, -31.415926561939717) q[13]; -u3(3.9474101932937837, 2.3466177252769094, 3.0706668150355823) q[14]; -cx q[7], q[8]; -u3(6.283185307179586, 1.5447896439857054, 4.488395663193877) q[10]; -u3(1.5707963358577706, 2.350255959075901e-12, 7.853981633973489) q[11]; -cx q[12], q[13]; -u3(1.5707963291690366, 6.283185307187803, 3.607209331434205) q[14]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(1.493113309942708e-14, 4.044282014408981, 1.9889032927783443) q[13]; -cx q[14], q[15]; -u3(1.570796326794918, 4.712388980385101, 1.5707963267948448) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -u3(12.317812214730726, -3.381945368057696, 6.596994766383803) q[15]; -cx q[8], q[9]; -u3(-4.606094765347848e-11, 7.243810012736379, -1.2106247055422545) q[11]; -u3(1.5707963257915336, 6.283185307976412, 1.5707963259826574) q[12]; -cx q[13], q[14]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(-0.24999999998525482, 1.3207963268142597, -1.570796326799556) q[14]; -u3(4.712388980383907, 1.5707963267887826, -1.5707963268010106) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -cx q[9], q[10]; -u3(6.283185307179586, 1.3044115378990389, 4.72877376928197) q[12]; -u3(1.5707963267948963, 6.2831853071941275, 1.570796326809438) q[13]; -cx q[14], q[15]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(1.5707963290767155, 7.500208145704392e-12, 3.199034645325397e-11) q[14]; -u3(4.252931007668044, 6.941317159811333, -0.5207845388892177) q[15]; -u3(1.5707963267592906, 4.7123889803920855, 1.570796326789873) q[11]; -cx q[12], q[13]; -cx q[10], q[11]; -u3(8.677989509847878e-14, 0.08526886649462191, -0.3352688664354618) q[13]; -cx q[10], q[11]; -cx q[12], q[13]; -u3(1.570796321691643, 4.712389000223492, 1.5707963068378006) q[12]; -cx q[11], q[12]; -cx q[11], q[12]; -cx q[12], q[13]; -cx q[12], q[13]; -cx q[13], q[14]; -u3(6.283185307050697, 2.2573451302603353, 6.917432831932345) q[14]; -cx q[13], q[14]; -u3(1.5707963273090904, 4.712388982083521, 4.712388982086903) q[13]; -u3(3.1415926534603518, 5.718688059797338, 2.2356565553810444) q[14]; -cx q[14], q[15]; -u3(3.6339079010077664, 14.472611946181283, -10.501535530782315) q[15]; -cx q[14], q[15]; -u3(1.5707963267949188, 1.5707963267952751, 4.370950129548484) q[14]; -u3(2.5197270331333153, 7.096876966982337, 6.993536083219166) q[15]; diff --git a/test/circuits/approximateEquivalenceTest/heisenberg16_out_high_error.qasm b/test/circuits/approximateEquivalenceTest/heisenberg16_out_high_error.qasm deleted file mode 100644 index 7d87b42f..00000000 --- a/test/circuits/approximateEquivalenceTest/heisenberg16_out_high_error.qasm +++ /dev/null @@ -1,35 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[16]; -u3(0.00013467339313029555, 0.06252028380218476, -0.06273794617931498) q[0]; -u3(0.0, 0.0, 0.0) q[1]; -u3(0.00030096490486351964, -1.1617477011729667, -5.120997537215747) q[2]; -u3(3.1415487498634187, -3.410767223362413, -0.2691754228466807) q[3]; -u3(0.00023293221517120639, 5.6164351648785535, 0.6666892784775138) q[4]; -u3(3.14150268434272, 0.8484718224539403, 3.9899328528489137) q[5]; -u3(7.184975071086315e-05, -4.274595385824681, -2.0085820307879043) q[6]; -u3(3.1414543401175727, 4.519357945881856, 1.3776785172276091) q[7]; -u3(0.00013614361401208293, -1.4627023338724077, 1.4626414736667082) q[8]; -u3(3.1414760532426476, -0.8540226475337821, 2.287358551122577) q[9]; -u3(0.00019348001721546448, 3.5786104876421923, 2.7043090230175264) q[10]; -u3(3.1413860371361615, -1.333061295987569, 1.8085163275548886) q[11]; -u3(2.2630913225614746, 5.0287579692620055, 2.7646443016213094) q[12]; -u3(3.1396110890804074, 2.6074696906578216, 4.466655672127682) q[13]; -u3(0.00016514867159772367, 3.5372026283870923, 2.745950728547381) q[14]; -u3(3.1414644319540708, -1.2647946924950193, -4.406388877768999) q[15]; -u3(0.0, 0.0, 0.0) q[0]; -u3(3.1413292420004835, 2.010234453162399, -1.1315301809968428) q[1]; -u3(5.406389045178313, 5.910704178547237, 4.387480216831034) q[12]; -u3(3.1410400525063493, 0.6289090814854731, 5.6277391743811025) q[13]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; -u3(0.0, 0.0, 0.0) q[0]; diff --git a/test/circuits/approximateEquivalenceTest/heisenberg16_out_small_error.qasm b/test/circuits/approximateEquivalenceTest/heisenberg16_out_small_error.qasm deleted file mode 100644 index 1d9159f8..00000000 --- a/test/circuits/approximateEquivalenceTest/heisenberg16_out_small_error.qasm +++ /dev/null @@ -1,864 +0,0 @@ -OPENQASM 2.0; -include "qelib1.inc"; -qreg q[16]; -u3(1.5707963268013796, 3.698629342944752, -0.9721872384823051) q[0]; -u3(1.3240512523628656, -4.150710758062049, 1.5707963268012235) q[1]; -u3(3.1415926533569594, 2.510312365348886, 2.51031236533479) q[2]; -u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[3]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[4]; -u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[5]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[6]; -u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[7]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[8]; -u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[9]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[10]; -u3(1.5707963267948966, 3.141592653589793, 3.141592653589793) q[11]; -u3(1.5707963267948966, 2.220446049250313e-16, -3.141592653589793) q[12]; -u3(1.5707963267948966, 3.141592653589793, -3.141592653589793) q[13]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[14]; -u3(1.5707963267948966, 3.141592653589793, -3.141592653589793) q[15]; -cx q[1], q[2]; -u3(0.24999999999999845, -2.658849721384721, -2.1324745491152024) q[1]; -u3(3.141592653296536, -1.365903695330139, -1.3659036953301318) q[2]; -cx q[1], q[2]; -u3(2.5093956798996886, 0.39052821881924293, -4.888365866816978) q[1]; -u3(1.5707963269788476, 4.3391490400779276e-10, -3.1415926535753425) q[2]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(0.2500000000000003, -1.2380780130046798, -3.698629342945577) q[0]; -u3(3.1354350518873244, -0.2674459248497576, 3.124072825983004) q[1]; -u3(0.0, 0.0, 0.0) q[2]; -u3(0.0, -0.125, -0.125) q[3]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(1.5707963268012426, 4.113779892072544, -1.9035146405836303) q[0]; -u3(0.5990629440969317, -3.0974459246263017, 3.105125913167815) q[1]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[2]; -u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[3]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(0.0, -0.125, -0.125) q[2]; -u3(0.0, 0.0, 0.0) q[3]; -u3(0.0, -0.125, -0.125) q[4]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; -u3(0.0, 0.0, 0.0) q[2]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[3]; -u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[4]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(0.0, 0.0, 0.0) q[4]; -u3(0.0, 0.0, 0.0) q[1]; -u3(0.0, -0.125, -0.125) q[3]; -cx q[4], q[5]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(0.0, 0.0, 0.0) q[4]; -u3(0.0, -0.125, -0.125) q[5]; -u3(1.5707963267950213, -0.6317295459958326, 1.5707963267944058) q[0]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; -u3(0.0, 0.0, 0.0) q[3]; -cx q[4], q[5]; -cx q[1], q[2]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[4]; -u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[5]; -u3(0.0, 0.0, 0.0) q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[1], q[2]; -u3(0.0, 0.0, 0.0) q[3]; -u3(0.0, -0.125, -0.125) q[4]; -u3(0.0, 0.0, 0.0) q[5]; -u3(0.0, -0.125, -0.125) q[6]; -u3(1.8127572697279888, -1.57079632679488, 4.712388980384309) q[1]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[0], q[1]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; -u3(6.123233995736766e-17, -3.0616169978683824e-17, -3.0616169978683824e-17) q[4]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[5]; -u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[6]; -u3(0.25000000000000044, -3.4855086130902952, 0.631729545995831) q[0]; -u3(1.570796326794877, -1.1513394185562236, 3.341771304121721e-14) q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(0.0, 0.0, 0.0) q[3]; -u3(0.0, -0.125, -0.125) q[5]; -u3(0.0, 0.0, 0.0) q[6]; -u3(0.0, -0.125, -0.125) q[7]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(1.5707963215885818, 1.409820957414135, 3.1415926530450693) q[2]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; -u3(0.0, 0.0, 0.0) q[5]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[6]; -u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[7]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(3.141592653589793, -2.0860896208594104, 1.2695127015734753) q[1]; -u3(1.2696868602872497e-09, -0.16030889941082146, -0.08969110058929466) q[2]; -u3(0.0, 0.0, 0.0) q[4]; -u3(0.0, -0.125, -0.125) q[6]; -u3(0.0, -0.125, -0.125) q[8]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(1.5385373536124667, -3.3895458235962157, -1.3060097758917473) q[1]; -u3(3.1415926483112355, 3.0442350365316697, 1.3124633403560093) q[2]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[3]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; -u3(0.0, 0.0, 0.0) q[6]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[7]; -u3(8.532843177179282e-17, 0.0, 0.0) q[8]; -cx q[0], q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(1.5707963267950198, 1.5707963267953868, 3.485508613090298) q[0]; -u3(3.0108532527160725, 4.7123889803817445, 1.5707963267919416) q[1]; -u3(0.0, -0.125, -0.125) q[3]; -u3(0.0, 0.0, 0.0) q[5]; -u3(0.0, -0.125, -0.125) q[7]; -u3(0.0, 0.0, 0.0) q[8]; -u3(0.0, -0.125, -0.125) q[9]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[2]; -u3(8.532843177179282e-17, 0.0, 0.0) q[3]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[4]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; -u3(0.0, 0.0, 0.0) q[7]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[8]; -u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[9]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(0.0, -0.125, -0.125) q[2]; -u3(0.0, -0.125, -0.125) q[4]; -u3(0.0, 0.0, 0.0) q[6]; -u3(0.0, -0.125, -0.125) q[8]; -u3(0.0, 0.0, 0.0) q[9]; -u3(0.0, -0.125, -0.125) q[10]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; -u3(0.0, 0.0, 0.0) q[2]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[3]; -u3(8.532843177179282e-17, 0.0, 0.0) q[4]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[5]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; -u3(0.0, 0.0, 0.0) q[8]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[9]; -u3(3.2868123855849206e-16, -0.7417268800995684, 0.7417268800995682) q[10]; -cx q[0], q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 0.0) q[10]; -u3(0.0, 0.0, 0.0) q[1]; -u3(0.0, -0.125, -0.125) q[3]; -u3(0.0, -0.125, -0.125) q[5]; -u3(0.0, 0.0, 0.0) q[7]; -u3(0.0, -0.125, -0.125) q[9]; -cx q[10], q[11]; -cx q[0], q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 0.0) q[10]; -u3(0.0, -0.125, -0.125) q[11]; -u3(1.5707963270346463, 4.905536215506974, 0.9523732089951065) q[0]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; -u3(0.0, 0.0, 0.0) q[3]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[4]; -u3(8.532843177179282e-17, 0.0, 0.0) q[5]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[6]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[8]; -u3(0.0, 0.0, 0.0) q[9]; -cx q[10], q[11]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[10]; -u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[11]; -u3(0.0, 0.0, 0.0) q[2]; -u3(0.0, -0.125, -0.125) q[4]; -u3(0.0, -0.125, -0.125) q[6]; -u3(0.0, 0.0, 0.0) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(0.0, -0.125, -0.125) q[10]; -u3(0.0, 0.0, 0.0) q[11]; -u3(0.0, -0.125, -0.125) q[12]; -u3(1.570796325242758, -2.458773818116612, 3.141592652536968) q[1]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; -u3(0.0, 0.0, 0.0) q[4]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[5]; -u3(8.532843177179282e-17, 0.0, 0.0) q[6]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[7]; -cx q[9], q[10]; -cx q[11], q[12]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[9]; -u3(0.0, 0.0, 0.0) q[10]; -u3(1.5707963267948968, 0.0, 1.5707963267948968) q[11]; -u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[12]; -u3(0.0, 0.0, 0.0) q[3]; -u3(0.0, -0.125, -0.125) q[5]; -u3(0.0, -0.125, -0.125) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(0.0, 0.0, 0.0) q[12]; -cx q[2], q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(0.0, 0.0, 0.0) q[9]; -u3(0.0, -0.125, -0.125) q[11]; -cx q[12], q[13]; -u3(1.5707963267948966, -2.4885287017487396, 3.141592653589793) q[2]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; -u3(0.0, 0.0, 0.0) q[5]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[6]; -u3(8.532843177179282e-17, 0.0, 0.0) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(0.0, 0.0, 0.0) q[12]; -u3(0.0, -0.125, -0.125) q[13]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[8]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[10]; -u3(0.0, 0.0, 0.0) q[11]; -cx q[12], q[13]; -u3(3.141592653589793, 1.2060252812431997, 1.5752346792533398) q[1]; -u3(3.141592653589793, -1.018998629292777, 1.8725940242970547) q[2]; -u3(0.0, 0.0, 0.0) q[4]; -u3(0.0, -0.125, -0.125) q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(1.5707963267948968, 0.0, 1.5707963267948968) q[12]; -u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[13]; -cx q[1], q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(0.0, -0.125, -0.125) q[8]; -u3(0.0, 0.0, 0.0) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(4.12280138366313, 6.084349441609635, 2.2751502149617964) q[1]; -u3(-1.1816407439491567e-16, 3.390880583826311, 5.380833425112225) q[2]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[3]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; -u3(0.0, 0.0, 0.0) q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(0.0, -0.125, -0.125) q[12]; -u3(0.0, 0.0, 0.0) q[13]; -u3(0.0, -0.125, -0.125) q[14]; -cx q[0], q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[7]; -u3(8.532843177179282e-17, 0.0, 0.0) q[8]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[9]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(0.24999999999997935, 5.637144911985536, 4.519241745169825) q[0]; -u3(0.17481009696066513, 1.985413270930268, -1.7396173911305366) q[1]; -u3(0.0, -0.125, -0.125) q[3]; -u3(0.0, 0.0, 0.0) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[11]; -u3(0.0, 0.0, 0.0) q[12]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[13]; -u3(3.2868123855849206e-16, -0.7417268800995683, 0.7417268800995681) q[14]; -cx q[0], q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(0.0, -0.125, -0.125) q[7]; -u3(0.0, -0.125, -0.125) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -u3(0.0, 0.0, 0.0) q[14]; -u3(4.712388980150148, 5.330812098192436, 3.7876330488846137) q[0]; -u3(-0.6281943376678667, 3.3439556855346355, 2.977090663618331) q[1]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[2]; -u3(8.532843177179282e-17, 0.0, 0.0) q[3]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[4]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(0.0, 0.0, 0.0) q[11]; -u3(0.0, -0.125, -0.125) q[13]; -cx q[14], q[15]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; -u3(0.0, 0.0, 0.0) q[7]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[8]; -u3(8.532843177179282e-17, 0.0, 0.0) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -u3(0.0, 0.0, 0.0) q[14]; -u3(0.0, -0.125, -0.125) q[15]; -u3(0.0, -0.125, -0.125) q[2]; -u3(0.0, -0.125, -0.125) q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[10]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[12]; -u3(0.0, 0.0, 0.0) q[13]; -cx q[14], q[15]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(0.0, 0.0, 0.0) q[6]; -u3(0.0, -0.125, -0.125) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(1.5707963267948968, 0.0, 1.5707963267948968) q[14]; -u3(1.001954908788063e-08, -0.6750953106187336, 5.387484244257511) q[15]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; -u3(0.0, 0.0, 0.0) q[2]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[3]; -u3(8.532843177179282e-17, 0.0, 0.0) q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(0.0, -0.125, -0.125) q[10]; -u3(0.0, 0.0, 0.0) q[12]; -cx q[13], q[14]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[5]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; -u3(0.0, 0.0, 0.0) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(0.0, 0.0, 0.0) q[13]; -u3(0.0, -0.125, -0.125) q[14]; -u3(0.0, 0.0, 0.0) q[1]; -u3(0.0, -0.125, -0.125) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[9]; -u3(8.532843177179282e-17, 0.0, 0.0) q[10]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[11]; -cx q[13], q[14]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(0.0, -0.125, -0.125) q[5]; -u3(0.0, 0.0, 0.0) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[13]; -u3(1.2349848074883556, 0.5458175086869241, -4.040731003943112) q[14]; -u3(1.5707963267949017, 3.376774268847033, -1.3012636636582287) q[0]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; -u3(0.0, 0.0, 0.0) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(0.0, -0.125, -0.125) q[9]; -u3(0.0, -0.125, -0.125) q[11]; -cx q[12], q[13]; -cx q[1], q[2]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[4]; -u3(8.532843177179282e-17, 0.0, 0.0) q[5]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[6]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(0.0, 0.0, 0.0) q[13]; -u3(0.0, 0.0, 0.0) q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[8]; -u3(0.0, 0.0, 0.0) q[9]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[10]; -u3(8.532843177179282e-17, 0.0, 0.0) q[11]; -cx q[12], q[13]; -cx q[1], q[2]; -u3(0.0, -0.125, -0.125) q[4]; -u3(0.0, -0.125, -0.125) q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[12]; -u3(-0.34461501668122707, 2.2611057321048413, -2.3691113297768562) q[13]; -u3(1.5707963267948946, -1.5288134904768458, -3.141592653589792) q[1]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(0.0, 0.0, 0.0) q[8]; -u3(0.0, -0.125, -0.125) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; -u3(0.0, 0.0, 0.0) q[4]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[5]; -u3(8.532843177179282e-17, 0.0, 0.0) q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(0.0, -0.125, -0.125) q[12]; -u3(3.141592653589793, 2.0126881177894114, 5.879517113613691) q[13]; -u3(0.8633056785714065, 1.5707963268287566, -1.5707963267556666) q[14]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[7]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[9]; -u3(0.0, 0.0, 0.0) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(0.0, 0.0, 0.0) q[3]; -u3(0.0, -0.125, -0.125) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[11]; -u3(8.532843177179282e-17, 0.0, 0.0) q[12]; -u3(4.95676464593379, -0.24545667690278367, 0.6475226547767313) q[13]; -u3(4.6666486860473775, 5.711974154042495, -0.94931678633701) q[14]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(0.0, -0.125, -0.125) q[7]; -u3(0.0, 0.0, 0.0) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -u3(1.5707964966280614, -2.298938807345055, 3.14159251806691) q[2]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; -u3(0.0, 0.0, 0.0) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(0.0, -0.125, -0.125) q[11]; -u3(0.0, -0.125, -0.125) q[13]; -u3(3.39159264971765, 7.250340276500068, 0.730362773605577) q[14]; -u3(3.141592653524296, 2.5476369456609755, 5.689229597619214) q[15]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[6]; -u3(8.532843177179282e-17, 0.0, 0.0) q[7]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[8]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -u3(6.283185307179586, 5.98256536880236, 6.237343371549365) q[1]; -u3(3.141592448435295, 4.976052187927914, 1.584459534336365) q[2]; -u3(0.0, 0.0, 0.0) q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[10]; -u3(0.0, 0.0, 0.0) q[11]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[12]; -u3(8.532843177179282e-17, 0.0, 0.0) q[13]; -u3(6.2831853139022416, 4.884794643671604, 3.5728283439785207) q[14]; -u3(6.283185299907338, 0.7892067253236354, 7.064774956772292) q[15]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(0.0, -0.125, -0.125) q[6]; -u3(0.0, -0.125, -0.125) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(0.0, 0.0, 0.0) q[15]; -u3(4.9813321723799024, 6.301221304215631, 3.3782905271773154) q[1]; -u3(3.1415926703140804, 3.118361062867952, 3.9610149091052045) q[2]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[3]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(0.0, 0.0, 0.0) q[10]; -u3(0.0, -0.125, -0.125) q[12]; -u3(0.0, -0.125, -0.125) q[14]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; -u3(0.0, 0.0, 0.0) q[6]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[7]; -u3(8.532843177179282e-17, 0.0, 0.0) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(0.24999999999999992, 1.044794366240841, 6.04800369192235) q[0]; -u3(6.299379513583522, 3.2113345378857074, 3.3213300471071174) q[1]; -u3(0.0, -0.125, -0.125) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[9]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[11]; -u3(0.0, 0.0, 0.0) q[12]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[13]; -u3(8.532843177179282e-17, 0.0, 0.0) q[14]; -cx q[0], q[1]; -cx q[2], q[3]; -u3(0.0, 0.0, 0.0) q[5]; -u3(0.0, -0.125, -0.125) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -u3(1.5707963267949012, 4.4428563172480215, 5.238390940938742) q[0]; -u3(3.418539905419923, 3.3793585212795367, 3.370617726457057) q[1]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[2]; -u3(8.532843177179282e-17, 0.0, 0.0) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(0.0, -0.125, -0.125) q[9]; -u3(0.0, 0.0, 0.0) q[11]; -u3(0.0, -0.125, -0.125) q[13]; -u3(0.0, 0.0, 0.0) q[14]; -u3(0.0, -0.125, -0.125) q[15]; -cx q[1], q[2]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[4]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; -u3(0.0, 0.0, 0.0) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -u3(0.0, -0.125, -0.125) q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[8]; -u3(8.532843177179282e-17, 0.0, 0.0) q[9]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[10]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[12]; -u3(0.0, 0.0, 0.0) q[13]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[14]; -u3(6.212470744432521e-09, -3.91904003601071, 2.3482437086679377) q[15]; -cx q[1], q[2]; -u3(0.0, -0.125, -0.125) q[4]; -u3(0.0, 0.0, 0.0) q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(0.0, 0.0, 0.0) q[14]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[1]; -u3(0.0, 0.0, 0.0) q[2]; -cx q[3], q[4]; -cx q[5], q[6]; -u3(0.0, -0.125, -0.125) q[8]; -u3(0.0, -0.125, -0.125) q[10]; -u3(0.0, 0.0, 0.0) q[12]; -cx q[13], q[14]; -cx q[0], q[1]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[3]; -u3(8.532843177179282e-17, 0.0, 0.0) q[4]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[5]; -cx q[7], q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(0.0, 0.0, 0.0) q[13]; -u3(0.0, -0.125, -0.125) q[14]; -u3(0.0, 0.0, 0.0) q[1]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; -u3(0.0, 0.0, 0.0) q[8]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[9]; -u3(8.532843177179282e-17, 0.0, 0.0) q[10]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[11]; -cx q[13], q[14]; -cx q[0], q[1]; -u3(0.0, -0.125, -0.125) q[3]; -u3(0.0, -0.125, -0.125) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[13]; -u3(1.9807995154418523, -2.078212939794722, 3.2956523905656794) q[14]; -cx q[2], q[3]; -cx q[4], q[5]; -u3(0.0, 0.0, 0.0) q[7]; -u3(0.0, -0.125, -0.125) q[9]; -u3(0.0, -0.125, -0.125) q[11]; -cx q[12], q[13]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[2]; -u3(0.0, 0.0, 0.0) q[3]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[4]; -u3(8.532843177179282e-17, 0.0, 0.0) q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(0.0, 0.0, 0.0) q[13]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[6]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[8]; -u3(0.0, 0.0, 0.0) q[9]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[10]; -u3(8.532843177179282e-17, 0.0, 0.0) q[11]; -cx q[12], q[13]; -u3(0.0, 0.0, 0.0) q[2]; -u3(0.0, -0.125, -0.125) q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[12]; -u3(3.3879991213643272, 4.578193635810148, 9.503257427289979) q[13]; -cx q[1], q[2]; -cx q[3], q[4]; -u3(0.0, -0.125, -0.125) q[6]; -u3(0.0, 0.0, 0.0) q[8]; -u3(0.0, -0.125, -0.125) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[3]; -u3(0.0, 0.0, 0.0) q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(0.0, -0.125, -0.125) q[12]; -u3(3.141592653589793, 3.0604454671441084, 4.144884159500745) q[13]; -u3(1.297098473972984, -1.5707963268003862, 4.7123889803792505) q[14]; -cx q[2], q[3]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[5]; -u3(8.532843177179282e-17, 0.0, 0.0) q[6]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[7]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[9]; -u3(0.0, 0.0, 0.0) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(0.0, 0.0, 0.0) q[3]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[11]; -u3(8.532843177179282e-17, 0.0, 0.0) q[12]; -u3(1.3251639380407203, 6.302901462052073, 2.4401264184284965) q[13]; -u3(7.3250471601395235, 1.9142345745043792, 5.098988495961082) q[14]; -cx q[2], q[3]; -u3(0.0, -0.125, -0.125) q[5]; -u3(0.0, -0.125, -0.125) q[7]; -u3(0.0, 0.0, 0.0) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -cx q[4], q[5]; -cx q[6], q[7]; -cx q[8], q[9]; -u3(0.0, -0.125, -0.125) q[11]; -u3(0.0, -0.125, -0.125) q[13]; -u3(0.2499999993454793, 4.536093485418275, 5.246360801466184) q[14]; -u3(6.283185306699073, 3.269589702959485, 6.1551882580101624) q[15]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[4]; -u3(0.0, 0.0, 0.0) q[5]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[6]; -u3(8.532843177179282e-17, 0.0, 0.0) q[7]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[8]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[10]; -u3(0.0, 0.0, 0.0) q[11]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[12]; -u3(8.532843177179282e-17, 0.0, 0.0) q[13]; -u3(3.141592657286629, 5.34321853880259, 0.8071250531182803) q[14]; -u3(-6.0997096989931195e-09, 3.98219245075599, 0.7301965300386668) q[15]; -u3(0.0, 0.0, 0.0) q[4]; -u3(0.0, -0.125, -0.125) q[6]; -u3(0.0, -0.125, -0.125) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(0.0, 0.0, 0.0) q[15]; -cx q[3], q[4]; -cx q[5], q[6]; -cx q[7], q[8]; -u3(0.0, 0.0, 0.0) q[10]; -u3(0.0, -0.125, -0.125) q[12]; -u3(0.0, -0.125, -0.125) q[14]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[5]; -u3(0.0, 0.0, 0.0) q[6]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[7]; -u3(8.532843177179282e-17, 0.0, 0.0) q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[9]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[11]; -u3(0.0, 0.0, 0.0) q[12]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[13]; -u3(8.532843177179282e-17, 0.0, 0.0) q[14]; -u3(0.0, 0.0, 0.0) q[5]; -u3(0.0, -0.125, -0.125) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -cx q[4], q[5]; -cx q[6], q[7]; -u3(0.0, -0.125, -0.125) q[9]; -u3(0.0, 0.0, 0.0) q[11]; -u3(0.0, -0.125, -0.125) q[13]; -u3(0.0, 0.0, 0.0) q[14]; -u3(0.0, -0.125, -0.125) q[15]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[6]; -u3(0.0, 0.0, 0.0) q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -cx q[5], q[6]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[8]; -u3(8.532843177179282e-17, 0.0, 0.0) q[9]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[10]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[12]; -u3(0.0, 0.0, 0.0) q[13]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[14]; -u3(6.713171846466525e-10, 0.9063678041090947, 0.6644285226451768) q[15]; -u3(0.0, 0.0, 0.0) q[6]; -cx q[7], q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(0.0, 0.0, 0.0) q[14]; -cx q[5], q[6]; -u3(0.0, -0.125, -0.125) q[8]; -u3(0.0, -0.125, -0.125) q[10]; -u3(0.0, 0.0, 0.0) q[12]; -cx q[13], q[14]; -cx q[7], q[8]; -cx q[9], q[10]; -cx q[11], q[12]; -u3(0.0, 0.0, 0.0) q[13]; -u3(0.0, -0.125, -0.125) q[14]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[7]; -u3(0.0, 0.0, 0.0) q[8]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[9]; -u3(8.532843177179282e-17, 0.0, 0.0) q[10]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[11]; -cx q[13], q[14]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[13]; -u3(1.949938345728355, -2.026116675699649, -0.8307035065756702) q[14]; -u3(0.0, 0.0, 0.0) q[7]; -u3(0.0, -0.125, -0.125) q[9]; -u3(0.0, -0.125, -0.125) q[11]; -cx q[12], q[13]; -cx q[6], q[7]; -cx q[8], q[9]; -cx q[10], q[11]; -u3(0.0, 0.0, 0.0) q[13]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[8]; -u3(0.0, 0.0, 0.0) q[9]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[10]; -u3(8.532843177179282e-17, 0.0, 0.0) q[11]; -cx q[12], q[13]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(1.5707963267948966, 2.220446049250313e-16, 3.141592653589793) q[12]; -u3(1.605335375884444, 4.457204268441797, -0.06292303420165449) q[13]; -u3(0.0, 0.0, 0.0) q[8]; -u3(0.0, -0.125, -0.125) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -cx q[7], q[8]; -cx q[9], q[10]; -u3(0.0, -0.125, -0.125) q[12]; -u3(6.283185307179586, 4.062345583219204, 4.598680286841274) q[13]; -u3(3.1415926535810836, 5.420189709808817, 5.420189709808819) q[14]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[9]; -u3(0.0, 0.0, 0.0) q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -cx q[8], q[9]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[11]; -u3(8.532843177179282e-17, 0.0, 0.0) q[12]; -u3(3.2133608860518774, 5.214840837722617, 4.661894196053515) q[13]; -u3(0.8937862065670165, 1.2440266896429848, 2.3603106410687906) q[14]; -u3(0.0, 0.0, 0.0) q[9]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -cx q[8], q[9]; -u3(0.0, -0.125, -0.125) q[11]; -u3(0.0, -0.125, -0.125) q[13]; -u3(0.24999999999968553, 5.611891912011103, 5.53395522837392) q[14]; -u3(3.1415926535902328, 6.16128022336242, 3.0196875697726195) q[15]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[10]; -u3(0.0, 0.0, 0.0) q[11]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[12]; -u3(8.532843177179282e-17, 0.0, 0.0) q[13]; -u3(6.2831853063337215, 0.5653734675032248, 6.389105234677195) q[14]; -u3(3.1415926529149787, 5.603644741575092, 4.032848414739265) q[15]; -cx q[9], q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(0.0, 0.0, 0.0) q[15]; -u3(0.0, 0.0, 0.0) q[10]; -u3(0.0, -0.125, -0.125) q[12]; -u3(0.0, -0.125, -0.125) q[14]; -cx q[9], q[10]; -cx q[11], q[12]; -cx q[13], q[14]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[11]; -u3(0.0, 0.0, 0.0) q[12]; -u3(1.5707963267948966, 1.1102230246251565e-16, 1.570796326794897) q[13]; -u3(8.532843177179282e-17, 0.0, 0.0) q[14]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -u3(0.0, 0.0, 0.0) q[11]; -u3(0.0, -0.125, -0.125) q[13]; -u3(0.0, 0.0, 0.0) q[14]; -u3(0.0, -0.125, -0.125) q[15]; -cx q[10], q[11]; -cx q[12], q[13]; -cx q[14], q[15]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[12]; -u3(0.0, 0.0, 0.0) q[13]; -u3(1.5707963267948968, 0.0, -4.71238898038469) q[14]; -u3(2.1965156326459443, -2.8222790205050905, -2.627670694261884) q[15]; -cx q[11], q[12]; -u3(0.0, 0.0, 0.0) q[14]; -u3(0.0, 0.0, 0.0) q[12]; -cx q[13], q[14]; -cx q[11], q[12]; -u3(0.0, 0.0, 0.0) q[13]; -u3(0.0, -0.125, -0.125) q[14]; -cx q[13], q[14]; -u3(1.5707963267948966, -1.5707963267948966, 1.5707963267948966) q[13]; -u3(1.0277339916976553, 0.14659123773901017, -1.4327029342332407) q[14]; -cx q[12], q[13]; -u3(0.0, 0.0, 0.0) q[13]; -cx q[12], q[13]; -u3(2.6795523880654355, 4.953912199856304, 13.708133806449572) q[13]; -cx q[13], q[14]; -u3(3.141592653589793, 5.965349845280416, 9.198382981006143) q[13]; -u3(6.283185314874866, 0.36918853068220286, 2.7724041170758302) q[14]; -cx q[13], q[14]; -u3(0.4620402655243577, 5.141422114821867, 5.0453526822314965) q[13]; -u3(5.25545131442516, 6.274253533786785, 0.14659119102044613) q[14]; -cx q[14], q[15]; -u3(-1.5970406745757394e-09, 4.735814519429113, 1.8289194382804266) q[14]; -u3(3.4305321712208463, 2.492071817710516, -0.7714176214060169) q[15]; -cx q[14], q[15]; -u3(4.7123890176797145, 4.712389005059283, 3.007069173802136) q[14]; -u3(4.0238360530750805, 2.3224104472296476, 2.5445026374178767) q[15]; diff --git a/test/circuits/approximateEquivalenceTest/toffoli.qasm b/test/circuits/approximateEquivalenceTest/toffoli.qasm new file mode 100644 index 00000000..0bfd2336 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/toffoli.qasm @@ -0,0 +1,4 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[3]; +ccx q[0], q[1], q[2]; diff --git a/test/circuits/approximateEquivalenceTest/toffoli_out_default_error.qasm b/test/circuits/approximateEquivalenceTest/toffoli_out_default_error.qasm new file mode 100644 index 00000000..d39fa295 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/toffoli_out_default_error.qasm @@ -0,0 +1,27 @@ +OPENQASM 2.0; +include "qelib1.inc"; + +// This file was generated using the Berkeley Quantum Synthesis Toolkit (BQSKit) v1. (DOI: https://doi.org/10.11578/dc.20210603.2) + +qreg q[3]; +u3(4.7123889809248, 4.712388955012845, 1.1036158611244384) q[0]; +u3(4.712388980983968, 3.1415926545103003, 1.6662347254833414) q[1]; +u3(3.1415926535713226, 6.076357271163574, 6.076357271176827) q[2]; +cx q[0], q[1]; +u3(0.7853981560637512, 2.5155207028504378e-08, 3.141592653589793) q[0]; +u3(3.096013314602218, 1.570796327034668, -1.5707963265553742) q[1]; +cx q[0], q[2]; +u3(2.3561944901518754, 1.5119454577217084e-09, -3.141592653589793) q[0]; +u3(0.04474021300781862, 1.5707963267923022, 1.5707963267974883) q[2]; +cx q[0], q[1]; +u3(2.3561944900935923, 1.5707963290638949, -3.141592653589793) q[0]; +u3(1.5707963267948966, 3.1415926530420206, -1.5707963283920234) q[1]; +cx q[0], q[2]; +u3(1.5707963251287866, -0.31821769794434274, -2.7755575615628914e-17) q[0]; +u3(0.21244281346880747, 1.5707963270282943, -1.5707963270230474) q[2]; +cx q[1], q[2]; +u3(2.356194490294979, 4.7123889814189885, 0.0) q[1]; +u3(0.16671345369681514, 1.5707963268690999, -1.570796326868071) q[2]; +cx q[1], q[2]; +u3(1.5707963274803494, -2.4972122270998547, -3.141592653589793) q[1]; +u3(1.20929464362818, 4.712388980360432, 1.5707963268034766) q[2]; diff --git a/test/circuits/approximateEquivalenceTest/toffoli_out_high_error.qasm b/test/circuits/approximateEquivalenceTest/toffoli_out_high_error.qasm new file mode 100644 index 00000000..2b5ae6c9 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/toffoli_out_high_error.qasm @@ -0,0 +1,10 @@ +OPENQASM 2.0; +include "qelib1.inc"; + +// This file was generated using the Berkeley Quantum Synthesis Toolkit (BQSKit) v1. (DOI: https://doi.org/10.11578/dc.20210603.2) +// synthesis_epsilon = error_threshold = 0.5 + +qreg q[3]; +u3(3.2565196422859165e-22, 5.227237758848407, 1.0491742331388518) q[0]; +u3(1.8123414008865951e-28, 5.7511343861911515, 6.808462912975694) q[1]; +u3(0.008788638510032316, 1.5721676760940455, 4.7137603296838595) q[2]; diff --git a/test/circuits/approximateEquivalenceTest/toffoli_out_small_error.qasm b/test/circuits/approximateEquivalenceTest/toffoli_out_small_error.qasm new file mode 100644 index 00000000..fa0128a8 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/toffoli_out_small_error.qasm @@ -0,0 +1,28 @@ +OPENQASM 2.0; +include "qelib1.inc"; + +// This file was generated using the Berkeley Quantum Synthesis Toolkit (BQSKit) v1. (DOI: https://doi.org/10.11578/dc.20210603.2) +// synthesis_epsilon = 1e-3, error_threshold=5e-2 + +qreg q[3]; +u3(4.712388981642913, 6.283185304915111, 5.078180946914554) q[0]; +u3(1.5707963317928202, 4.712388855233761, 4.689633691840316) q[1]; +u3(3.1415926535897967, 4.148171623914443, 1.0065789703246502) q[2]; +cx q[0], q[2]; +u3(1.5707963280523778, 1.7073876520004871, -1.1102230246251565e-16) q[0]; +u3(2.757636203235623, 1.5707963267948961, -4.71238898038469) q[2]; +cx q[1], q[2]; +u3(0.7853981633285405, -3.1415925497946455, 0.0) q[1]; +u3(0.9632687407318458, -1.5707963267948966, 4.71238898038469) q[2]; +cx q[0], q[1]; +u3(3.1415926535897647, 2.492785815397919, 0.0) q[0]; +u3(0.7853981633696963, 3.1415925901703696, -3.1415925639011846) q[1]; +cx q[1], q[2]; +u3(2.35619449020584, 4.305645417979065e-08, -3.141592653589793) q[1]; +u3(2.7447560800167796, -4.71238898038469, -1.5707963267948961) q[2]; +cx q[0], q[1]; +u3(1.5707963285066946, -3.1415926535002154, 3.1415926535897936) q[0]; +u3(1.5707963559474336, 3.9497461051949427, -1.5707963546499848) q[1]; +cx q[0], q[2]; +u3(1.570796328506681, -1.1511901302727185, -3.141592653589793) q[0]; +u3(2.9508419530365497, -1.5707963267948901, 1.570796326794903) q[2]; diff --git a/test/test_equality.cpp b/test/test_equality.cpp index 54862780..ccb6d8e5 100644 --- a/test/test_equality.cpp +++ b/test/test_equality.cpp @@ -5,6 +5,7 @@ #include "EquivalenceCheckingManager.hpp" #include "EquivalenceCriterion.hpp" +#include "QuantumComputation.hpp" #include "checker/dd/applicationscheme/ApplicationScheme.hpp" #include "dd/DDDefinitions.hpp" #include "operations/Control.hpp" @@ -660,3 +661,50 @@ TEST_F(EqualityTest, ApproximateEquivalenceAlternatingNotEqual) { ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); } + +TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliDefaultError) { + const qc::QuantumComputation c1{ + "./mqt-qcec/test/circuits/approximateEquivalenceTest/toffoli.qasm"}; + qc::QuantumComputation c2{ + "./mqt-qcec/test/circuits/approximateEquivalenceTest/" + "toffoli_out_default_error.qasm"}; + config.execution.runAlternatingChecker = true; + config.functionality.checkApproximateEquivalence = true; + // using default error threshold + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); +} + +TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliSmallError) { + const qc::QuantumComputation c1{ + "./mqt-qcec/test/circuits/approximateEquivalenceTest/toffoli.qasm"}; + qc::QuantumComputation c2{ + "./mqt-qcec/test/circuits/approximateEquivalenceTest/" + "toffoli_out_small_error.qasm"}; + config.execution.runAlternatingChecker = true; + config.functionality.checkApproximateEquivalence = true; + config.functionality.approximateCheckingThreshold = 5e-2; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); +} + +TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliHighError) { + const qc::QuantumComputation c1{ + "./mqt-qcec/test/circuits/approximateEquivalenceTest/toffoli.qasm"}; + qc::QuantumComputation c2{ + "./mqt-qcec/test/circuits/approximateEquivalenceTest/" + "toffoli_out_high_error.qasm"}; + config.execution.runAlternatingChecker = true; + config.functionality.checkApproximateEquivalence = true; + // using default error threshold + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); + // using synthesis_epsilon + config.functionality.approximateCheckingThreshold = 0.5; + ec::EquivalenceCheckingManager ecm2(c1, c2, config); + ecm2.run(); + EXPECT_EQ(ecm2.equivalence(), ec::EquivalenceCriterion::Equivalent); +} From b0731f78a6c8377b4a66961d8e4489a123d9fb67 Mon Sep 17 00:00:00 2001 From: Theresa Date: Tue, 13 Aug 2024 14:08:23 +0200 Subject: [PATCH 08/38] :white_check_mark: Add tests --- .../approximateEquivalenceTest/bell.qasm | 5 ++ .../bell_out_default_error.qasm | 8 +++ .../bell_out_high_error.qasm | 11 ++++ test/test_equality.cpp | 51 ++++++++++++++----- 4 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 test/circuits/approximateEquivalenceTest/bell.qasm create mode 100644 test/circuits/approximateEquivalenceTest/bell_out_default_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/bell_out_high_error.qasm diff --git a/test/circuits/approximateEquivalenceTest/bell.qasm b/test/circuits/approximateEquivalenceTest/bell.qasm new file mode 100644 index 00000000..c8b3cff4 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/bell.qasm @@ -0,0 +1,5 @@ +OPENQASM 2.0; +//include "qelib1.inc"; +qreg q[2]; +U(pi/2,0,pi) q[0]; +CX q[0],q[1]; diff --git a/test/circuits/approximateEquivalenceTest/bell_out_default_error.qasm b/test/circuits/approximateEquivalenceTest/bell_out_default_error.qasm new file mode 100644 index 00000000..aec426e1 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/bell_out_default_error.qasm @@ -0,0 +1,8 @@ +OPENQASM 2.0; +include "qelib1.inc"; + +// This file was generated using the Berkeley Quantum Synthesis Toolkit (BQSKit) v1. (DOI: https://doi.org/10.11578/dc.20210603.2) + +qreg q[2]; +u3(1.5707963267948966, 0.0, 3.141592653589793) q[0]; +cx q[0], q[1]; diff --git a/test/circuits/approximateEquivalenceTest/bell_out_high_error.qasm b/test/circuits/approximateEquivalenceTest/bell_out_high_error.qasm new file mode 100644 index 00000000..a69afc4a --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/bell_out_high_error.qasm @@ -0,0 +1,11 @@ +OPENQASM 2.0; +include "qelib1.inc"; + +// This file was generated using the Berkeley Quantum Synthesis Toolkit (BQSKit) v1. (DOI: https://doi.org/10.11578/dc.20210603.2) +// synthesis_epsilon = error_threshold = 0.5 + +qreg q[2]; +u3(1.4247154207173944, 3.2723216017380983, 3.9165877165474567) q[0]; +u3(7.0635798455555285, 6.030167955846771, 2.233142840253472) q[1]; +u3(7.068920866489056, 6.076579311743602, 1.5874947689660417) q[0]; +u3(2.1594592649028512, 7.307161171725773, 2.562695121614239) q[1]; diff --git a/test/test_equality.cpp b/test/test_equality.cpp index ccb6d8e5..0252ae77 100644 --- a/test/test_equality.cpp +++ b/test/test_equality.cpp @@ -664,10 +664,9 @@ TEST_F(EqualityTest, ApproximateEquivalenceAlternatingNotEqual) { TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliDefaultError) { const qc::QuantumComputation c1{ - "./mqt-qcec/test/circuits/approximateEquivalenceTest/toffoli.qasm"}; - qc::QuantumComputation c2{ - "./mqt-qcec/test/circuits/approximateEquivalenceTest/" - "toffoli_out_default_error.qasm"}; + "./circuits/approximateEquivalenceTest/toffoli.qasm"}; + qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "toffoli_out_default_error.qasm"}; config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; // using default error threshold @@ -678,10 +677,9 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliDefaultError) { TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliSmallError) { const qc::QuantumComputation c1{ - "./mqt-qcec/test/circuits/approximateEquivalenceTest/toffoli.qasm"}; - qc::QuantumComputation c2{ - "./mqt-qcec/test/circuits/approximateEquivalenceTest/" - "toffoli_out_small_error.qasm"}; + "./circuits/approximateEquivalenceTest/toffoli.qasm"}; + qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "toffoli_out_small_error.qasm"}; config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; config.functionality.approximateCheckingThreshold = 5e-2; @@ -692,10 +690,39 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliSmallError) { TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliHighError) { const qc::QuantumComputation c1{ - "./mqt-qcec/test/circuits/approximateEquivalenceTest/toffoli.qasm"}; - qc::QuantumComputation c2{ - "./mqt-qcec/test/circuits/approximateEquivalenceTest/" - "toffoli_out_high_error.qasm"}; + "./circuits/approximateEquivalenceTest/toffoli.qasm"}; + qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "toffoli_out_high_error.qasm"}; + config.execution.runAlternatingChecker = true; + config.functionality.checkApproximateEquivalence = true; + // using default error threshold + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); + // using synthesis_epsilon + config.functionality.approximateCheckingThreshold = 0.5; + ec::EquivalenceCheckingManager ecm2(c1, c2, config); + ecm2.run(); + EXPECT_EQ(ecm2.equivalence(), ec::EquivalenceCriterion::Equivalent); +} + +TEST_F(EqualityTest, ApproximateEquivalenceBqskitBellDefaultError) { + const qc::QuantumComputation c1{"./approximateEquivalenceTest/bell.qasm"}; + qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "bell_out_default_error.qasm"}; + config.execution.runAlternatingChecker = true; + config.functionality.checkApproximateEquivalence = true; + // using default error threshold + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); +} + +TEST_F(EqualityTest, ApproximateEquivalenceBqskitBellHighError) { + const qc::QuantumComputation c1{ + "./circuits/approximateEquivalenceTest/bell.qasm"}; + qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "bell_out_high_error.qasm"}; config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; // using default error threshold From 5e463346f39a50ba23aec6c3be9ba952c63b1bdc Mon Sep 17 00:00:00 2001 From: Theresa Date: Tue, 13 Aug 2024 16:43:37 +0200 Subject: [PATCH 09/38] :memo: Add comments --- src/checker/dd/DDAlternatingChecker.cpp | 3 +++ test/test_equality.cpp | 24 ++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/checker/dd/DDAlternatingChecker.cpp b/src/checker/dd/DDAlternatingChecker.cpp index d2efce0d..fdb71e35 100644 --- a/src/checker/dd/DDAlternatingChecker.cpp +++ b/src/checker/dd/DDAlternatingChecker.cpp @@ -102,6 +102,8 @@ EquivalenceCriterion DDAlternatingChecker::checkEquivalence() { garbage[static_cast(q)] = qc1->logicalQubitIsGarbage(q) && qc2->logicalQubitIsGarbage(q); } + // For approximate equivalence checking, calculate the Frobenius inner + // product trace(U V^-1) and compare it to some threshold. if (configuration.functionality.checkApproximateEquivalence) { auto trace = dd->trace(functionality, nqubits).mag(); if (std::abs(trace - 1.) < @@ -109,6 +111,7 @@ EquivalenceCriterion DDAlternatingChecker::checkEquivalence() { return EquivalenceCriterion::Equivalent; } } else { + // Otherwise, we can simply compare U V^-1 with the identity const bool isClose = configuration.functionality.checkPartialEquivalence ? dd->isCloseToIdentity(functionality, diff --git a/test/test_equality.cpp b/test/test_equality.cpp index 0252ae77..7116091a 100644 --- a/test/test_equality.cpp +++ b/test/test_equality.cpp @@ -607,6 +607,8 @@ TEST_F(EqualityTest, StripIdleQubitInOutputPermutationWithAncilla) { } TEST_F(EqualityTest, ApproximateEquivalenceConstructionEqual) { + // Check that the difference between the circuits is below the + // approximateCheckingThreshold using the ConstructionChecker qc1 = qc::QuantumComputation(3); qc2 = qc::QuantumComputation(3); // Toffoli gate @@ -621,6 +623,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceConstructionEqual) { } TEST_F(EqualityTest, ApproximateEquivalenceConstructionNotEqual) { + // Check that the difference between the circuits is above the + // approximateCheckingThreshold using the ConstructionChecker qc1 = qc::QuantumComputation(3); qc2 = qc::QuantumComputation(3); // Toffoli gate @@ -635,6 +639,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceConstructionNotEqual) { } TEST_F(EqualityTest, ApproximateEquivalenceAlternatingEqual) { + // Check that the difference between the circuits is below the + // approximateCheckingThreshold using the AlternatingChecker qc1 = qc::QuantumComputation(3); qc2 = qc::QuantumComputation(3); // Toffoli gate @@ -649,6 +655,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceAlternatingEqual) { } TEST_F(EqualityTest, ApproximateEquivalenceAlternatingNotEqual) { + // Check that the difference between the circuits is above the + // approximateCheckingThreshold using the AlternatingChecker qc1 = qc::QuantumComputation(3); qc2 = qc::QuantumComputation(3); // Toffoli gate @@ -663,6 +671,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceAlternatingNotEqual) { } TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliDefaultError) { + // Check that the Toffoli gate is equivalent to itself after synthesizing it + // with the BQSKit compiler, which introduces by default a distance up to 1e-8 const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/toffoli.qasm"}; qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" @@ -676,6 +686,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliDefaultError) { } TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliSmallError) { + // Check that the Toffoli gate is equivalent to itself after synthesizing it + // with the BQSKit compiler, when setting the error_threshold to 5e-2 const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/toffoli.qasm"}; qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" @@ -689,6 +701,9 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliSmallError) { } TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliHighError) { + // Check that the Toffoli gate is equivalent to itself after synthesizing it + // with the BQSKit compiler, when setting the error_threshold to 0.5 Here, the + // computed distance indeed exceeds the default threshold of 1e-8. const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/toffoli.qasm"}; qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" @@ -699,7 +714,7 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliHighError) { ec::EquivalenceCheckingManager ecm(c1, c2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); - // using synthesis_epsilon + // using non-default error threshold config.functionality.approximateCheckingThreshold = 0.5; ec::EquivalenceCheckingManager ecm2(c1, c2, config); ecm2.run(); @@ -707,6 +722,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliHighError) { } TEST_F(EqualityTest, ApproximateEquivalenceBqskitBellDefaultError) { + // Check that the Bell circuit is equivalent to itself after synthesizing it + // with the BQSKit compiler, which introduces by default a distance up to 1e-8 const qc::QuantumComputation c1{"./approximateEquivalenceTest/bell.qasm"}; qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" "bell_out_default_error.qasm"}; @@ -719,6 +736,9 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitBellDefaultError) { } TEST_F(EqualityTest, ApproximateEquivalenceBqskitBellHighError) { + // Check that the Bell circuit is equivalent to itself after synthesizing it + // with the BQSKit compiler, when setting the error_threshold to 0.5 Here, the + // computed distance indeed exceeds the default threshold of 1e-8. const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/bell.qasm"}; qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" @@ -729,7 +749,7 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitBellHighError) { ec::EquivalenceCheckingManager ecm(c1, c2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NotEquivalent); - // using synthesis_epsilon + // using non-default error threshold config.functionality.approximateCheckingThreshold = 0.5; ec::EquivalenceCheckingManager ecm2(c1, c2, config); ecm2.run(); From 3c9f84ff4ddadba0663b2e11aa061b3738f57b9b Mon Sep 17 00:00:00 2001 From: Theresa Date: Wed, 14 Aug 2024 09:58:40 +0200 Subject: [PATCH 10/38] :rotating_light: Fix warnings --- test/test_equality.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/test/test_equality.cpp b/test/test_equality.cpp index 7116091a..93fa84d3 100644 --- a/test/test_equality.cpp +++ b/test/test_equality.cpp @@ -675,8 +675,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliDefaultError) { // with the BQSKit compiler, which introduces by default a distance up to 1e-8 const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/toffoli.qasm"}; - qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" - "toffoli_out_default_error.qasm"}; + const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "toffoli_out_default_error.qasm"}; config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; // using default error threshold @@ -690,8 +690,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliSmallError) { // with the BQSKit compiler, when setting the error_threshold to 5e-2 const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/toffoli.qasm"}; - qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" - "toffoli_out_small_error.qasm"}; + const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "toffoli_out_small_error.qasm"}; config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; config.functionality.approximateCheckingThreshold = 5e-2; @@ -706,8 +706,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliHighError) { // computed distance indeed exceeds the default threshold of 1e-8. const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/toffoli.qasm"}; - qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" - "toffoli_out_high_error.qasm"}; + const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "toffoli_out_high_error.qasm"}; config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; // using default error threshold @@ -724,9 +724,10 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitToffoliHighError) { TEST_F(EqualityTest, ApproximateEquivalenceBqskitBellDefaultError) { // Check that the Bell circuit is equivalent to itself after synthesizing it // with the BQSKit compiler, which introduces by default a distance up to 1e-8 - const qc::QuantumComputation c1{"./approximateEquivalenceTest/bell.qasm"}; - qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" - "bell_out_default_error.qasm"}; + const qc::QuantumComputation c1{ + "./circuits/approximateEquivalenceTest/bell.qasm"}; + const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "bell_out_default_error.qasm"}; config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; // using default error threshold @@ -741,8 +742,8 @@ TEST_F(EqualityTest, ApproximateEquivalenceBqskitBellHighError) { // computed distance indeed exceeds the default threshold of 1e-8. const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/bell.qasm"}; - qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" - "bell_out_high_error.qasm"}; + const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "bell_out_high_error.qasm"}; config.execution.runAlternatingChecker = true; config.functionality.checkApproximateEquivalence = true; // using default error threshold From 824e4390f67b07c2e4903a227a81e125e17a112f Mon Sep 17 00:00:00 2001 From: Theresa Date: Wed, 14 Aug 2024 10:53:23 +0200 Subject: [PATCH 11/38] :rotating_light: Fix warnings --- src/checker/dd/DDAlternatingChecker.cpp | 1 + src/checker/dd/DDEquivalenceChecker.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/checker/dd/DDAlternatingChecker.cpp b/src/checker/dd/DDAlternatingChecker.cpp index fdb71e35..20eb3197 100644 --- a/src/checker/dd/DDAlternatingChecker.cpp +++ b/src/checker/dd/DDAlternatingChecker.cpp @@ -11,6 +11,7 @@ #include "checker/dd/applicationscheme/ApplicationScheme.hpp" #include +#include #include #include #include diff --git a/src/checker/dd/DDEquivalenceChecker.cpp b/src/checker/dd/DDEquivalenceChecker.cpp index 042986de..34927d44 100644 --- a/src/checker/dd/DDEquivalenceChecker.cpp +++ b/src/checker/dd/DDEquivalenceChecker.cpp @@ -16,11 +16,11 @@ #include "checker/dd/applicationscheme/OneToOneApplicationScheme.hpp" #include "checker/dd/applicationscheme/ProportionalApplicationScheme.hpp" #include "checker/dd/applicationscheme/SequentialApplicationScheme.hpp" -#include "dd/ComplexValue.hpp" #include "dd/DDpackageConfig.hpp" #include "dd/Package_fwd.hpp" #include +#include #include #include From 313053a7d24644944c41aca6728a5be6f909dbfb Mon Sep 17 00:00:00 2001 From: Theresa Date: Fri, 4 Oct 2024 11:54:07 +0200 Subject: [PATCH 12/38] :sparkles: Introduce HSF checker --- cmake/ExternalDependencies.cmake | 24 ++ .../dd/HybridSchrodingerFeynmanChecker.hpp | 81 ++++++ src/CMakeLists.txt | 6 +- .../dd/HybridSchrodingerFeynmanChecker.cpp | 219 +++++++++++++++ test/CMakeLists.txt | 3 +- ...vegates_ibm_qiskit_opt3_10_high_error.qasm | 64 +++++ ...vegates_ibm_qiskit_opt3_10_high_error.qasm | 59 ++++ ...vegates_ibm_qiskit_opt3_10_high_error.qasm | 69 +++++ ...vegates_ibm_qiskit_opt3_10_no_measure.qasm | 227 +++++++++++++++ ...vegates_ibm_qiskit_opt3_10_no_measure.qasm | 254 +++++++++++++++++ ...vegates_ibm_qiskit_opt3_10_no_measure.qasm | 258 ++++++++++++++++++ .../dj_indep_qiskit_10_no_measure.qasm | 37 +++ ...vegates_ibm_qiskit_opt3_10_no_measure.qasm | 69 +++++ .../ghz_indep_qiskit_10_no_measure.qasm | 19 ++ ...vegates_ibm_qiskit_opt3_10_no_measure.qasm | 22 ++ ...graphstate_indep_qiskit_10_no_measure.qasm | 29 ++ ...vegates_ibm_qiskit_opt3_10_no_measure.qasm | 50 ++++ .../out_dj_indep_qiskit_10_high_error.qasm | 29 ++ ...vegates_ibm_qiskit_opt3_10_high_error.qasm | 29 ++ .../out_ghz_indep_qiskit_10_high_error.qasm | 23 ++ ...vegates_ibm_qiskit_opt3_10_high_error.qasm | 23 ++ ...graphstate_indep_qiskit_10_high_error.qasm | 31 +++ ...vegates_ibm_qiskit_opt3_10_high_error.qasm | 25 ++ .../out_qaoa_indep_qiskit_10_high_error.qasm | 30 ++ ...vegates_ibm_qiskit_opt3_10_high_error.qasm | 27 ++ .../out_vqe_indep_qiskit_10_high_error.qasm | 25 ++ ...vegates_ibm_qiskit_opt3_10_high_error.qasm | 25 ++ ...out_wstate_indep_qiskit_10_high_error.qasm | 42 +++ ...vegates_ibm_qiskit_opt3_10_high_error.qasm | 42 +++ .../qaoa_indep_qiskit_10_no_measure.qasm | 59 ++++ ...vegates_ibm_qiskit_opt3_10_no_measure.qasm | 194 +++++++++++++ .../vqe_indep_qiskit_10_no_measure.qasm | 57 ++++ ...vegates_ibm_qiskit_opt3_10_no_measure.qasm | 140 ++++++++++ .../wstate_indep_qiskit_10_no_measure.qasm | 46 ++++ ...vegates_ibm_qiskit_opt3_10_no_measure.qasm | 83 ++++++ test/test_hsf.cpp | 84 ++++++ 36 files changed, 2502 insertions(+), 2 deletions(-) create mode 100644 include/checker/dd/HybridSchrodingerFeynmanChecker.hpp create mode 100644 src/checker/dd/HybridSchrodingerFeynmanChecker.cpp create mode 100644 test/circuits/approximateEquivalenceTest/check/out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/check/out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/check/out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/check/qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/check/qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/check/qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/dj_indep_qiskit_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/dj_nativegates_ibm_qiskit_opt3_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/ghz_indep_qiskit_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/graphstate_indep_qiskit_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/graphstate_nativegates_ibm_qiskit_opt3_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_dj_indep_qiskit_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_dj_nativegates_ibm_qiskit_opt3_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_ghz_indep_qiskit_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_graphstate_indep_qiskit_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_graphstate_nativegates_ibm_qiskit_opt3_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_qaoa_indep_qiskit_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_qaoa_nativegates_ibm_qiskit_opt3_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_vqe_indep_qiskit_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_vqe_nativegates_ibm_qiskit_opt3_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_wstate_indep_qiskit_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/out_wstate_nativegates_ibm_qiskit_opt3_10_high_error.qasm create mode 100644 test/circuits/approximateEquivalenceTest/qaoa_indep_qiskit_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/qaoa_nativegates_ibm_qiskit_opt3_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/vqe_indep_qiskit_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/vqe_nativegates_ibm_qiskit_opt3_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/wstate_indep_qiskit_10_no_measure.qasm create mode 100644 test/circuits/approximateEquivalenceTest/wstate_nativegates_ibm_qiskit_opt3_10_no_measure.qasm create mode 100644 test/test_hsf.cpp diff --git a/cmake/ExternalDependencies.cmake b/cmake/ExternalDependencies.cmake index af856a12..637416ca 100644 --- a/cmake/ExternalDependencies.cmake +++ b/cmake/ExternalDependencies.cmake @@ -65,6 +65,30 @@ if(BUILD_MQT_QCEC_TESTS) endif() endif() +set(TF_BUILD_TESTS + OFF + CACHE INTERNAL "") +set(TF_BUILD_EXAMPLES + OFF + CACHE INTERNAL "") +set(TF_BUILD_PROFILER + OFF + CACHE INTERNAL "") +set(TF_VERSION + 3.6.0 + CACHE STRING "Taskflow version") +set(TF_URL https://github.com/taskflow/taskflow/archive/refs/tags/v${TF_VERSION}.tar.gz) +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) + FetchContent_Declare(taskflow URL ${TF_URL} FIND_PACKAGE_ARGS) + list(APPEND FETCH_PACKAGES taskflow) +else() + find_package(taskflow ${TF_VERSION} QUIET) + if(NOT taskflow_FOUND) + FetchContent_Declare(taskflow URL ${TF_URL}) + list(APPEND FETCH_PACKAGES taskflow) + endif() +endif() + if(BUILD_MQT_QCEC_BINDINGS) # add pybind11_json library if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp new file mode 100644 index 00000000..be77466c --- /dev/null +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include "CircuitOptimizer.hpp" +#include "Definitions.hpp" +#include "QuantumComputation.hpp" +#include "dd/ComplexValue.hpp" +#include "dd/Package.hpp" +#include "dd/Package_fwd.hpp" + +#include +#include +#include +#include + +namespace ec { +template class HybridSchrodingerFeynmanChecker final { +public: + HybridSchrodingerFeynmanChecker(qc::QuantumComputation& circ1, + qc::QuantumComputation& circ2, + const std::size_t nThreads) + : qc1(&circ1), qc2(&circ2), nthreads(nThreads) { + // remove final measurements + if (qc1->getNqubits() != qc2->getNqubits()) { + throw std::invalid_argument( + "The two circuits have a different number of qubits."); + } + qc::CircuitOptimizer::removeFinalMeasurements(*qc1); + qc::CircuitOptimizer::removeFinalMeasurements(*qc2); + qc2->invert(); + } + std::map check(); + + // Get # of decisions for given split_qubit, so that lower slice: q0 < i < + // qubit; upper slice: qubit <= i < nqubits + std::size_t getNDecisions(qc::Qubit splitQubit, qc::QuantumComputation& qc); + +protected: + using DDPackage = typename dd::Package; + qc::QuantumComputation* qc1; + qc::QuantumComputation* qc2; + +private: + std::size_t nthreads = 2; + + void approximateVerification(qc::Qubit splitQubit); + + dd::ComplexValue simulateSlicing(std::unique_ptr& sliceDD1, + std::unique_ptr& sliceDD2, + qc::Qubit splitQubit, std::size_t controls); + + class Slice { + protected: + qc::Qubit nextControlIdx = 0; + + std::size_t getNextControl() { + std::size_t idx = 1UL << nextControlIdx; + nextControlIdx++; + return controls & idx; + } + + public: + qc::Qubit start; + qc::Qubit end; + std::size_t controls; + qc::Qubit nqubits; + std::size_t nDecisionsExecuted = 0; + qc::MatrixDD matrix{}; + + explicit Slice(std::unique_ptr& dd, const qc::Qubit startQ, + const qc::Qubit endQ, const std::size_t controlQ) + : start(startQ), end(endQ), controls(controlQ), + nqubits(end - start + 1), matrix(dd->makeIdent()) { + dd->incRef(matrix); + } + + bool apply(std::unique_ptr& sliceDD, + const std::unique_ptr& op); + }; +}; + +} // namespace ec diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9cda5f61..06c56cc4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ add_library( checker/dd/DDConstructionChecker.cpp checker/dd/DDSimulationChecker.cpp checker/dd/DDAlternatingChecker.cpp + checker/dd/HybridSchrodingerFeynmanChecker.cpp checker/dd/applicationscheme/GateCostApplicationScheme.cpp checker/dd/simulation/StateGenerator.cpp checker/zx/ZXChecker.cpp) @@ -21,9 +22,12 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) # link to the MQT::Core libraries -target_link_libraries(${PROJECT_NAME} PUBLIC MQT::CoreDD MQT::CoreZX) +target_link_libraries(${PROJECT_NAME} PUBLIC MQT::CoreDD MQT::CoreZX Taskflow) target_link_libraries(${PROJECT_NAME} PRIVATE MQT::ProjectWarnings MQT::ProjectOptions) +set_target_properties(Taskflow PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + $) + # add MQT alias add_library(MQT::QCEC ALIAS ${PROJECT_NAME}) diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp new file mode 100644 index 00000000..15ce973e --- /dev/null +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -0,0 +1,219 @@ +#include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" + +#include "Definitions.hpp" +#include "dd/ComplexValue.hpp" +#include "dd/DDpackageConfig.hpp" +#include "dd/Operations.hpp" +#include "dd/Package.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template +std::size_t ec::HybridSchrodingerFeynmanChecker::getNDecisions( + qc::Qubit splitQubit, qc::QuantumComputation& qc) { + std::size_t ndecisions = 0; + // calculate number of decisions + for (const auto& op : qc) { + if (op->getType() == qc::Barrier) { + continue; + } + if (op->isStandardOperation()) { + bool targetInLowerSlice = false; + bool targetInUpperSlice = false; + bool controlInLowerSlice = false; + bool controlInUpperSlice = false; + for (const auto& target : op->getTargets()) { + targetInLowerSlice = targetInLowerSlice || target < splitQubit; + targetInUpperSlice = targetInUpperSlice || target >= splitQubit; + } + for (const auto& control : op->getControls()) { + controlInLowerSlice = controlInLowerSlice || control.qubit < splitQubit; + controlInUpperSlice = + controlInUpperSlice || control.qubit >= splitQubit; + } + if ((targetInLowerSlice && controlInUpperSlice) || + (targetInUpperSlice && controlInLowerSlice)) { + ndecisions++; + } + } else { + throw std::invalid_argument( + "Only StandardOperations are supported for now."); + } + } + return ndecisions; +} + +template +dd::ComplexValue ec::HybridSchrodingerFeynmanChecker::simulateSlicing( + std::unique_ptr>& sliceDD1, + std::unique_ptr>& sliceDD2, unsigned int splitQubit, + size_t controls) { + Slice lower(sliceDD1, 0, splitQubit - 1, controls); + Slice upper(sliceDD2, splitQubit, + static_cast(this->qc1->getNqubits() - 1), controls); + for (const auto& op : *this->qc1) { + if (op->isUnitary()) { + [[maybe_unused]] auto l = lower.apply(sliceDD1, op); + [[maybe_unused]] auto u = upper.apply(sliceDD2, op); + assert(l == u); + } + sliceDD1->garbageCollect(); + sliceDD2->garbageCollect(); + } + for (const auto& op : *this->qc2) { + if (op->isUnitary()) { + [[maybe_unused]] auto l = lower.apply(sliceDD1, op); + [[maybe_unused]] auto u = upper.apply(sliceDD2, op); + assert(l == u); + } + sliceDD1->garbageCollect(); + sliceDD2->garbageCollect(); + } + auto traceLower = sliceDD1->trace(lower.matrix, lower.nqubits); + auto traceUpper = sliceDD2->trace(upper.matrix, upper.nqubits); + auto result = traceLower * traceUpper; + return result; +} + +template +bool ec::HybridSchrodingerFeynmanChecker::Slice::apply( + std::unique_ptr>& sliceDD, + const std::unique_ptr& op) { + bool isSplitOp = false; + if (dynamic_cast(op.get()) != + nullptr) { // TODO change control and target if wrong direction + qc::Targets opTargets{}; + qc::Controls opControls{}; + + // check targets + bool targetInSplit = false; + bool targetInOtherSplit = false; + for (const auto& target : op->getTargets()) { + if (start <= target && target <= end) { + opTargets.push_back(target - start); + targetInSplit = true; + } else { + targetInOtherSplit = true; + } + } + + if (targetInSplit && targetInOtherSplit && !op->getControls().empty()) { + throw std::invalid_argument("Multiple Targets that are in different " + "slices are not supported at the moment"); + } + + // check controls + for (const auto& control : op->getControls()) { + if (start <= control.qubit && control.qubit <= end) { + opControls.emplace(control.qubit - start, control.type); + } else { // other controls are set to the corresponding value + if (targetInSplit) { + isSplitOp = true; + const bool nextControl = getNextControl(); + if ((control.type == qc::Control::Type::Pos && + !nextControl) || // break if control is not activated + (control.type == qc::Control::Type::Neg && nextControl)) { + nDecisionsExecuted++; + return true; + } + } + } + } + + if (targetInOtherSplit && !opControls.empty()) { // control slice for split + if (opControls.size() > 1) { + throw std::invalid_argument( + "Multiple controls in control slice of operation are not supported " + "at the moment"); + } + + isSplitOp = true; + const bool control = getNextControl(); + for (const auto& c : opControls) { + auto tmp = matrix; + auto project = control != (c.type == qc::Control::Type::Neg) ? 0 : 1; + auto projMatrix = project == 1 + ? sliceDD->makeGateDD(dd::MEAS_ZERO_MAT, c.qubit) + : sliceDD->makeGateDD(dd::MEAS_ONE_MAT, c.qubit); + matrix = sliceDD->multiply(projMatrix, matrix); + sliceDD->incRef(matrix); + sliceDD->decRef(tmp); + } + } else if (targetInSplit) { // target slice for split or operation in split + const auto& param = op->getParameter(); + qc::StandardOperation newOp(opControls, opTargets, op->getType(), param); + auto tmp = matrix; + matrix = sliceDD->multiply(dd::getDD(&newOp, *sliceDD), matrix); + sliceDD->incRef(matrix); + sliceDD->decRef(tmp); + } + } else { + throw std::invalid_argument( + "Only StandardOperations are supported for now."); + } + if (isSplitOp) { + nDecisionsExecuted++; + } + return isSplitOp; +} + +template +std::map +ec::HybridSchrodingerFeynmanChecker::check() { + auto nqubits = this->qc1->getNqubits(); + auto splitQubit = static_cast(nqubits / 2); + approximateVerification(splitQubit); + return {}; +} + +template +void ec::HybridSchrodingerFeynmanChecker::approximateVerification( + qc::Qubit splitQubit) { + const auto ndecisions = + getNDecisions(splitQubit, *qc1) + getNDecisions(splitQubit, *qc2); + const auto maxControl = 1ULL << ndecisions; + const auto actuallyUsedThreads = std::min(maxControl, nthreads); + const auto chunkSize = static_cast( + std::ceil(static_cast(maxControl) / + static_cast(actuallyUsedThreads))); + const auto nslicesOnOneCpu = std::min(64, chunkSize); + dd::ComplexValue trace{0.0, 0.0}; + std::mutex traceMutex; + tf::Executor executor(actuallyUsedThreads); + for (std::size_t control = 0; control < maxControl; + control += nslicesOnOneCpu) { + executor.silent_async([this, &trace, nslicesOnOneCpu, control, splitQubit, + maxControl, &traceMutex]() { + for (std::size_t localControl = 0; localControl < nslicesOnOneCpu; + localControl++) { + const std::size_t totalControl = control + localControl; + if (totalControl >= maxControl) { + break; + } + std::unique_ptr> sliceDD1 = + std::make_unique>(splitQubit); + std::unique_ptr> sliceDD2 = + std::make_unique>(this->qc1->getNqubits() - + splitQubit); + auto result = + simulateSlicing(sliceDD1, sliceDD2, splitQubit, totalControl); + std::lock_guard guard(traceMutex); + trace += result; + } + }); + } + executor.wait_for_all(); +} + +template class ec::HybridSchrodingerFeynmanChecker; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2d1374f1..b2ad5f45 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,4 +12,5 @@ package_add_test( test_equality.cpp test_zx.cpp test_symbolic.cpp - test_partial_equivalence.cpp) + test_partial_equivalence.cpp + test_hsf.cpp) diff --git a/test/circuits/approximateEquivalenceTest/check/out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/check/out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm new file mode 100644 index 00000000..afc005f9 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/check/out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm @@ -0,0 +1,64 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(1.5967129094740669, 4.4928594494509095, 5.150343955654042) q[0]; +u3(1.571277808724709, 5.1704480804551975, 4.7058109396384875) q[1]; +u3(5.128870313530324, 0.5759784277474378, 1.6601677063880982) q[2]; +u3(1.5722330814941592, 4.105088953129066, 4.688047235568617) q[3]; +u3(3.93193673603767, -0.06344516396092184, 4.328585545862223) q[4]; +u3(0.9684081152538433, 1.9765746111715055, 6.039859904633682) q[5]; +u3(1.6823833182557422, 4.2901034146354355, 5.277396922771205) q[6]; +u3(2.654986350734364, 4.088274687300487, 1.7562956033571526) q[7]; +u3(1.0544434612965976, 5.267772989707272, 1.7291064653658261) q[8]; +u3(0.641113142627662, 7.192075069135769, 3.9320337459461436) q[9]; +u3(1.9538389810638437, 4.964291458272374, 1.3652070123363917) q[0]; +u3(2.3843449472209897, 2.2010808705856357, 4.624028765483452) q[2]; +u3(5.447960841549981, 1.59476939119586, 2.746429606300692) q[4]; +u3(1.913584541620204, 1.6694216592928375, 4.489068317383709) q[5]; +u3(5.3082742737570845, 1.198573480013265, 5.768780198427521) q[6]; +u3(6.286963354044012, 1.4075489721153083, 3.671699319313141) q[7]; +u3(1.047222376635397, 0.9837428793073856, 1.523916289256121) q[8]; +u3(2.6087754794578792, 4.470984440851894, 5.914200407443676) q[9]; +u3(1.6853232648142211, 2.5691404081457856, 2.2170605385634814) q[0]; +cx q[3], q[2]; +u3(3.112813579869372, -0.005086569009791922, -0.6763638429222424) q[4]; +u3(3.266449635193457, 4.601084620131254, 5.01183142575176) q[5]; +u3(3.0035259768116305, 5.061947949359225, 3.333639359639256) q[7]; +cx q[1], q[0]; +u3(3.952973997039404, 0.9112613682939704, 5.66152617167672) q[2]; +u3(0.29398837848108766, 7.86152792254003, 0.7606379491757174) q[3]; +u3(-1.3261785086518214, 5.2550398411032875, 5.253001858310459) q[4]; +u3(1.1752031415272242, 2.965173505694305, 1.123681484443717) q[5]; +u3(4.022623069545801, 3.828491477785868, 7.2429270171472) q[7]; +u3(2.278615777897216, -0.26399318536482214, 6.078401211465244) q[0]; +u3(5.069329884285512, 3.35546281749432, 4.775259602606341) q[1]; +u3(2.1459139280808905, 6.47170317472704, 1.2024028631933765) q[2]; +u3(0.0039782718676524016, 1.851693751459628, 3.9622323749301116) q[3]; +u3(1.5325389620514507, 3.424619717923357, 0.18833473836150086) q[4]; +u3(5.792343024981983, -0.23465679736477632, 0.5440041655486838) q[0]; +u3(1.7322308875276524, 2.6759349370464793, 4.196159843736261) q[1]; +u3(3.139240058485812, 2.1966495705789795, 0.4694639031581532) q[2]; +u3(4.9960152145609, 0.1363522117966733, 0.1887355912029966) q[4]; +cx q[6], q[3]; +u3(5.197900698519211, -1.2291296220147176, 0.40674806317965656) q[0]; +u3(3.4453389891381576, 0.8973100918033137, 1.4899145259464557) q[1]; +u3(5.3195261132415546, -0.5952332112374324, 2.886544063800346) q[2]; +u3(0.004061041683970168, 4.223134090645838, 1.359673086994882) q[3]; +cx q[4], q[5]; +u3(3.721836476047589, 4.712346102669534, 2.497146967238639) q[6]; +cx q[0], q[9]; +cx q[1], q[8]; +u3(3.754162453789071, 2.830561068297695, 5.012748524871331) q[2]; +cx q[3], q[6]; +u3(1.332090168808036, 4.449428556036081, 4.59829167453284) q[4]; +u3(4.31195170608881, 4.473955935282206, 7.4871683820525385) q[5]; +u3(5.961566416233183, 8.086738331005916, -1.898209816603531) q[0]; +u3(0.14054336948585064, 11.824967064822681, -1.8073352027371405) q[1]; +u3(1.787075040639769, 7.175403463682723, 5.34180083961384) q[2]; +u3(3.1171525601684484, 3.3375756505299274, 6.445500896033654) q[3]; +u3(2.3900682383066765, 3.560341979592746, 1.9587280583634472) q[6]; +u3(1.1362056519130377, 5.462532178393413, 4.131028245070759) q[8]; +u3(4.297707522791769, 2.7910302083068954, -0.46261426812485057) q[9]; +cx q[2], q[7]; +u3(0.38022358447733623, -2.292165449828588, 5.9899941160723165) q[2]; +u3(6.215356564545466, 4.422976717855075, -1.0003804239044725) q[7]; diff --git a/test/circuits/approximateEquivalenceTest/check/out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/check/out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm new file mode 100644 index 00000000..e5cc3808 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/check/out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm @@ -0,0 +1,59 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(3.1457786349355605, 5.421761263017323, 4.008638617346886) q[0]; +u3(0.904683427787509, 4.3264218857676555, 3.253105757391102) q[1]; +u3(2.6348176194625625, 0.4108423236862732, 1.377231261112393) q[2]; +u3(6.282282095155324, 5.063584798718981, 1.21920143227369) q[3]; +u3(5.226936913602318, 4.445702468765694, 5.361808570806572) q[4]; +u3(3.431712019481757, 4.957274061917898, 4.0270273723347625) q[5]; +u3(5.192066717956585, -0.5085951158058518, 4.543388762153159) q[6]; +u3(4.908833247103972, 1.8216770953807266, 5.5682134564044805) q[7]; +u3(4.151805472836474, 0.2843423392797228, 1.081391082813205) q[8]; +u3(1.5724221312411957, 4.1340786573218455, 0.23487666351889958) q[9]; +u3(5.491260804387185, 3.8309387045422487, 5.225483590762154) q[0]; +u3(4.371229839526961, 1.2167597848486305, 5.0334366897438905) q[1]; +u3(6.329609332149668, 6.033062629680499, 4.66899412692601) q[2]; +u3(4.322466240681685, 2.634873057109232, 4.364392429852933) q[4]; +u3(1.8067768600586394, 3.3592837461860436, 2.2239574039094863) q[5]; +u3(5.95989390963119, 5.112910082303549, 2.7802425097780286) q[6]; +u3(0.6154107606056808, 0.47160276105126897, 0.29684090570252764) q[7]; +u3(1.0064518035388261, 2.3114408993721463, 1.2922756230884562) q[8]; +u3(1.3403519090262621, 1.7537404082568262, 2.271127405631342) q[9]; +cx q[0], q[8]; +u3(1.896254279309141, -0.15427072812476778, 3.663050265862602) q[1]; +cx q[6], q[2]; +u3(0.2588655148457335, 5.433198666092998, 4.033382161129801) q[9]; +u3(6.66941058173718, 5.023040879713362, 1.673243318092424) q[0]; +u3(3.8491189151064433, 0.44403968171469715, 4.165607581234752) q[1]; +u3(6.282912371652363, 4.608606790035007, 6.1516123929947275) q[2]; +u3(3.143017743540702, 5.226307488194178, 3.97761252075505) q[6]; +u3(5.425557372496884, 2.693578870290858, 6.50263298923416) q[8]; +cx q[9], q[3]; +u3(2.7634758054344144, 1.571006182519934, 4.68681636643541) q[0]; +u3(0.5661698017180979, 0.4565939096693895, 5.412531813552105) q[1]; +cx q[2], q[6]; +u3(2.7700865414472555, 6.833953728382238, 4.675168215118555) q[3]; +u3(0.00015248532059705712, 2.5891929496533495, 1.8975540979327976) q[9]; +cx q[1], q[7]; +u3(3.7289735608965806, 1.1876869133936214, 1.0062657745415329) q[2]; +u3(3.6953713477279053, 3.2501549101241243, 3.601982124113901) q[3]; +u3(0.2295229542231854, -0.22720771134856393, 7.180672912549948) q[6]; +u3(1.0246599123687141, -0.10615620726433331, 3.921461203140884) q[1]; +u3(0.8804565635436522, 4.712441051413684, 4.712332233827866) q[2]; +u3(-0.6382114918549516, 3.944721784132758, 1.9748244362030691) q[3]; +u3(6.662689056448501, 5.321449748742438, 0.9696017817824325) q[7]; +cx q[1], q[0]; +cx q[3], q[5]; +u3(-0.37826666343853843, 7.069913364639215, 1.5697293053874528) q[0]; +u3(3.1412590229022124, 2.442120727035348, 0.39170308864252407) q[1]; +u3(1.1655877434441426, 0.9449424980081808, 0.024306147074296704) q[3]; +u3(5.744555252633346, 4.272761840428961, 1.3738580140907444) q[5]; +cx q[1], q[0]; +cx q[3], q[2]; +u3(1.6222434212025327, 5.352379970315436, 3.8211760065446008) q[5]; +u3(-0.0005558739554070201, 1.5075823444855694, 2.092870689641878) q[0]; +u3(4.712368434652736, 4.724734742770601, 4.843247673458674) q[1]; +u3(1.5706995647081978, 1.5836777799903987, 3.14131659126619) q[2]; +u3(4.712705956583802, 1.6198357664326943, 0.5021959835739244) q[3]; +u3(2.3353937622138026, 6.551762026177583, 5.693194723242856) q[5]; diff --git a/test/circuits/approximateEquivalenceTest/check/out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/check/out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm new file mode 100644 index 00000000..5c8c38ee --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/check/out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm @@ -0,0 +1,69 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(4.686961865276838, 1.357046345610335, 3.6059379742589863) q[0]; +u3(2.7763007945083906, 4.874168232099246, 1.34389606222912) q[1]; +u3(1.074170682089161, 3.8754724145048454, 0.8599458997080227) q[2]; +u3(-0.6678330427275795, 6.135726206541356, 0.04871213149620333) q[3]; +u3(0.6412236318508795, 5.745358986659732, 2.211913162090944) q[4]; +u3(1.9429630160371687, 3.841707793175603, 3.1370799759773376) q[5]; +u3(0.12014767907268181, 4.386573451553275, 4.040587895725029) q[6]; +u3(3.127141902524777, 3.6438241676013123, 1.8284777423127205) q[7]; +u3(2.672549444309574, 6.19851250587084, 1.3951813093016705) q[8]; +u3(6.107199947787151, 0.5439235603794383, 1.8229586394855188) q[9]; +u3(3.905509221332195, 3.601428193000014, -0.22770460419531344) q[0]; +u3(1.870117194942164, 5.904545341629118, 1.7819512751714832) q[1]; +u3(4.799926791781231, 3.3407756322344637, 4.876679257405755) q[2]; +u3(1.1246278397487752, 0.6640502669749878, 4.174525788139747) q[3]; +u3(3.953893442300813, 1.0201793437786988, 6.003536159098982) q[5]; +u3(5.932426892537282, 3.7929253044356437, 2.6973946125665456) q[6]; +u3(5.838399304109481, 3.2542268544314434, 3.490373080216075) q[7]; +u3(2.110296125777016, 1.0886312117003818, 2.548664966467628) q[8]; +u3(1.8009778488643773, 2.334028773086897, 5.635879551967924) q[9]; +u3(2.5323208361839042, 3.4575599593292865, 4.470077674623373) q[1]; +cx q[2], q[6]; +cx q[3], q[5]; +u3(4.621382119661225, 4.394740982718423, 5.019927077591458) q[7]; +cx q[8], q[0]; +u3(4.2492831047970245, 1.5123247296571625, 4.958989236223148) q[9]; +u3(0.00017831793077354954, 3.8938923975898025, 6.915953679514266) q[0]; +u3(4.547164069892221, 0.7816895315461284, 2.4591992708875092) q[2]; +u3(1.6752722763666597, 1.732736022107561, 6.373084819044298) q[3]; +u3(5.029680804253102, 5.7442339350505245, 5.432700823102606) q[5]; +u3(1.4983648333153212, 4.918908321047535, 5.581725192639537) q[6]; +cx q[7], q[1]; +u3(5.910805374772858, 1.5707503838453503, 1.0703313773006158) q[8]; +u3(-1.0703146842309457, 3.382272862155488, 2.986386853004498) q[9]; +cx q[0], q[8]; +u3(4.497713688537638, 0.8385381577458554, 1.5710010780079438) q[1]; +u3(4.4206399777342105, 3.3982564172030645, 4.881911181175938) q[3]; +cx q[6], q[4]; +u3(0.4334902385698476, 1.569916302404894, 2.700378879563038) q[7]; +u3(3.1499523996255068, 2.033468882511722, 2.369338471133545) q[9]; +u3(7.340326258872505, 4.862620774859223, 3.5037014908936914) q[0]; +cx q[1], q[7]; +u3(3.4630749312836517, 3.45374430244687, 3.3286568137346295) q[3]; +u3(1.5695223320204397, 4.444334703404689, 3.1416498502526453) q[4]; +u3(6.281284569133057, 2.1424933442030127, 3.7969435713529274) q[6]; +u3(3.1529933261324756, 2.1703300473153884, 3.3500025245573943) q[8]; +u3(2.1165554283637533, 5.268124594621309, 0.46416419039101436) q[1]; +u3(3.1432898133639493, 3.3259154693965898, 4.959912477617047) q[3]; +u3(6.283167703381702, 0.6359863671367816, 2.158356885818126) q[6]; +u3(1.6041636869177707, 3.5924461888868766, -2.076006605998757) q[7]; +u3(5.452121167785458, 5.6743131817040355, 5.379184831251755) q[8]; +u3(1.5708061606267292, 2.445860726698459, 4.586272927132378) q[1]; +cx q[6], q[5]; +u3(4.864022583111293, 5.493838401359525, 0.08792325980658289) q[7]; +u3(3.9830546423229385, 5.841572669787988, 3.1328732288796726) q[8]; +cx q[1], q[0]; +u3(4.712715768864319, 1.8729143957482526, 3.1409258298654352) q[5]; +u3(4.712449472498667, 5.105679204852368, 1.1499386170077854) q[6]; +u3(3.3170876764172528, 0.895872060986512, 3.4054526477440423) q[7]; +u3(3.141621098536432, 2.369813173477838, 3.1552258411364824) q[0]; +u3(6.283175768200863, 2.0745578369894355, 3.4951717374175333) q[1]; +cx q[1], q[0]; +u3(-0.0006755683389837666, 3.440820444063311, 3.2550665958512925) q[0]; +u3(4.711590134358627, 1.5832541042569503, 4.55373362040219) q[1]; +u3(5.2123091349785735, 0.3224508630392817, 3.4248672896748085) q[0]; +u3(1.660516509853004, 1.4300323242496271, 5.600099709224268) q[0]; +u3(2.4580234168829036, 5.460416328980352, 4.340713718287529) q[0]; diff --git a/test/circuits/approximateEquivalenceTest/check/qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/check/qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm new file mode 100644 index 00000000..993bf7b2 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/check/qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm @@ -0,0 +1,227 @@ +// Benchmark was created by MQT Bench on 2024-03-18 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 +// Used Gate Set: ['id', 'rz', 'sx', 'x', 'cx', 'measure', 'barrier'] + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg c[10]; +creg meas[10]; +rz(pi/2) q[9]; +sx q[9]; +rz(3.1385246920140215) q[9]; +cx q[9],q[8]; +rz(-pi/4) q[8]; +cx q[9],q[8]; +rz(3*pi/4) q[8]; +sx q[8]; +rz(3.1354567304382504) q[8]; +cx q[9],q[7]; +rz(-pi/8) q[7]; +cx q[9],q[7]; +rz(pi/8) q[7]; +cx q[8],q[7]; +rz(-pi/4) q[7]; +cx q[8],q[7]; +rz(3*pi/4) q[7]; +sx q[7]; +rz(3.1293208072867076) q[7]; +cx q[9],q[6]; +rz(-pi/16) q[6]; +cx q[9],q[6]; +rz(pi/16) q[6]; +cx q[8],q[6]; +rz(-pi/8) q[6]; +cx q[8],q[6]; +rz(pi/8) q[6]; +cx q[7],q[6]; +rz(-pi/4) q[6]; +cx q[7],q[6]; +rz(3*pi/4) q[6]; +sx q[6]; +rz(3.1170489609836225) q[6]; +cx q[9],q[5]; +rz(-pi/32) q[5]; +cx q[9],q[5]; +rz(pi/32) q[5]; +cx q[8],q[5]; +rz(-pi/16) q[5]; +cx q[8],q[5]; +rz(pi/16) q[5]; +cx q[7],q[5]; +rz(-pi/8) q[5]; +cx q[7],q[5]; +rz(pi/8) q[5]; +cx q[6],q[5]; +rz(-pi/4) q[5]; +cx q[6],q[5]; +rz(3*pi/4) q[5]; +sx q[5]; +rz(3.0925052683774523) q[5]; +cx q[9],q[4]; +rz(-pi/64) q[4]; +cx q[9],q[4]; +rz(pi/64) q[4]; +cx q[8],q[4]; +rz(-pi/32) q[4]; +cx q[8],q[4]; +rz(pi/32) q[4]; +cx q[7],q[4]; +rz(-pi/16) q[4]; +cx q[7],q[4]; +rz(pi/16) q[4]; +cx q[6],q[4]; +rz(-pi/8) q[4]; +cx q[6],q[4]; +rz(pi/8) q[4]; +cx q[5],q[4]; +rz(-pi/4) q[4]; +cx q[5],q[4]; +rz(3*pi/4) q[4]; +sx q[4]; +rz(3.043417883165112) q[4]; +cx q[9],q[3]; +rz(-pi/128) q[3]; +cx q[9],q[3]; +rz(pi/128) q[3]; +cx q[8],q[3]; +rz(-pi/64) q[3]; +cx q[8],q[3]; +rz(pi/64) q[3]; +cx q[7],q[3]; +rz(-pi/32) q[3]; +cx q[7],q[3]; +rz(pi/32) q[3]; +cx q[6],q[3]; +rz(-pi/16) q[3]; +cx q[6],q[3]; +rz(pi/16) q[3]; +cx q[5],q[3]; +rz(-pi/8) q[3]; +cx q[5],q[3]; +rz(pi/8) q[3]; +cx q[4],q[3]; +rz(-pi/4) q[3]; +cx q[4],q[3]; +rz(3*pi/4) q[3]; +sx q[3]; +rz(15*pi/16) q[3]; +cx q[9],q[2]; +rz(-pi/256) q[2]; +cx q[9],q[2]; +rz(pi/256) q[2]; +cx q[8],q[2]; +rz(-pi/128) q[2]; +cx q[8],q[2]; +rz(pi/128) q[2]; +cx q[7],q[2]; +rz(-pi/64) q[2]; +cx q[7],q[2]; +rz(pi/64) q[2]; +cx q[6],q[2]; +rz(-pi/32) q[2]; +cx q[6],q[2]; +rz(pi/32) q[2]; +cx q[5],q[2]; +rz(-pi/16) q[2]; +cx q[5],q[2]; +rz(pi/16) q[2]; +cx q[4],q[2]; +rz(-pi/8) q[2]; +cx q[4],q[2]; +rz(pi/8) q[2]; +cx q[3],q[2]; +rz(-pi/4) q[2]; +cx q[3],q[2]; +rz(3*pi/4) q[2]; +sx q[2]; +rz(7*pi/8) q[2]; +cx q[9],q[1]; +rz(-pi/512) q[1]; +cx q[9],q[1]; +rz(pi/512) q[1]; +cx q[8],q[1]; +rz(-pi/256) q[1]; +cx q[8],q[1]; +rz(pi/256) q[1]; +cx q[7],q[1]; +rz(-pi/128) q[1]; +cx q[7],q[1]; +rz(pi/128) q[1]; +cx q[6],q[1]; +rz(-pi/64) q[1]; +cx q[6],q[1]; +rz(pi/64) q[1]; +cx q[5],q[1]; +rz(-pi/32) q[1]; +cx q[5],q[1]; +rz(pi/32) q[1]; +cx q[4],q[1]; +rz(-pi/16) q[1]; +cx q[4],q[1]; +rz(pi/16) q[1]; +cx q[3],q[1]; +rz(-pi/8) q[1]; +cx q[3],q[1]; +rz(pi/8) q[1]; +cx q[2],q[1]; +rz(-pi/4) q[1]; +cx q[2],q[1]; +rz(3*pi/4) q[1]; +sx q[1]; +rz(3*pi/4) q[1]; +cx q[9],q[0]; +rz(-pi/1024) q[0]; +cx q[9],q[0]; +rz(pi/1024) q[0]; +cx q[8],q[0]; +rz(-pi/512) q[0]; +cx q[8],q[0]; +rz(pi/512) q[0]; +cx q[7],q[0]; +rz(-pi/256) q[0]; +cx q[7],q[0]; +rz(pi/256) q[0]; +cx q[6],q[0]; +rz(-pi/128) q[0]; +cx q[6],q[0]; +rz(pi/128) q[0]; +cx q[5],q[0]; +rz(-pi/64) q[0]; +cx q[5],q[0]; +rz(pi/64) q[0]; +cx q[4],q[0]; +rz(-pi/32) q[0]; +cx q[4],q[0]; +rz(pi/32) q[0]; +cx q[3],q[0]; +rz(-pi/16) q[0]; +cx q[3],q[0]; +rz(pi/16) q[0]; +cx q[2],q[0]; +rz(-pi/8) q[0]; +cx q[2],q[0]; +rz(pi/8) q[0]; +cx q[1],q[0]; +rz(-pi/4) q[0]; +cx q[1],q[0]; +rz(3*pi/4) q[0]; +sx q[0]; +rz(pi/2) q[0]; +cx q[0],q[9]; +cx q[1],q[8]; +cx q[2],q[7]; +cx q[3],q[6]; +cx q[4],q[5]; +cx q[5],q[4]; +cx q[4],q[5]; +cx q[6],q[3]; +cx q[3],q[6]; +cx q[7],q[2]; +cx q[2],q[7]; +cx q[8],q[1]; +cx q[1],q[8]; +cx q[9],q[0]; +cx q[0],q[9]; diff --git a/test/circuits/approximateEquivalenceTest/check/qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/check/qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm new file mode 100644 index 00000000..9a0b170a --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/check/qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm @@ -0,0 +1,254 @@ +// Benchmark was created by MQT Bench on 2024-03-18 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 +// Used Gate Set: ['id', 'rz', 'sx', 'x', 'cx', 'measure', 'barrier'] + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[9]; +qreg psi[1]; +creg c[9]; +rz(pi/2) q[0]; +sx q[0]; +rz(pi/2) q[0]; +rz(pi/2) q[1]; +sx q[1]; +rz(pi/2) q[1]; +rz(pi/2) q[2]; +sx q[2]; +rz(pi/2) q[2]; +rz(pi/2) q[3]; +sx q[3]; +rz(pi/2) q[3]; +rz(pi/2) q[4]; +sx q[4]; +rz(pi/2) q[4]; +rz(pi/2) q[5]; +sx q[5]; +rz(pi/2) q[5]; +rz(-pi/2) q[6]; +sx q[6]; +rz(2.4881540023736894) q[6]; +rz(pi/2) q[7]; +sx q[7]; +rz(pi/2) q[7]; +rz(pi/2) q[8]; +sx q[8]; +rz(pi/2) q[8]; +x psi[0]; +rz(-1.0536092607691794) psi[0]; +cx psi[0],q[0]; +rz(1.3499030933393643) q[0]; +cx psi[0],q[0]; +rz(-1.3499030933393643) q[0]; +cx q[0],q[8]; +cx q[8],q[0]; +cx q[0],q[8]; +rz(pi/2) q[0]; +sx q[0]; +rz(pi/2) q[0]; +rz(0.006135923151542544) q[8]; +cx psi[0],q[1]; +rz(-0.44178646691106466) q[1]; +cx psi[0],q[1]; +rz(0.44178646691106466) q[1]; +cx q[1],q[7]; +cx q[7],q[1]; +cx q[1],q[7]; +rz(pi/4) q[1]; +cx q[1],q[0]; +rz(pi/4) q[0]; +cx q[1],q[0]; +rz(-pi/4) q[0]; +sx q[1]; +rz(pi/2) q[1]; +rz(pi/256) q[7]; +cx psi[0],q[2]; +rz(-0.8835729338221293) q[2]; +cx psi[0],q[2]; +rz(0.8835729338221293) q[2]; +cx psi[0],q[3]; +rz(7*pi/16) q[3]; +cx psi[0],q[3]; +rz(-7*pi/16) q[3]; +cx psi[0],q[4]; +rz(-pi/8) q[4]; +cx psi[0],q[4]; +rz(0.49087385212340506) q[4]; +cx psi[0],q[5]; +rz(-pi/4) q[5]; +cx psi[0],q[5]; +rz(pi/4) q[5]; +cx q[3],q[5]; +cx q[5],q[3]; +cx q[3],q[5]; +rz(pi/16) q[3]; +rz(pi/64) q[5]; +sx psi[0]; +rz(-pi/2) psi[0]; +cx q[6],psi[0]; +x q[6]; +rz(-2.2242349780110002) q[6]; +cx q[2],q[6]; +cx q[6],q[2]; +cx q[2],q[6]; +rz(pi/8) q[2]; +cx q[2],q[0]; +rz(pi/8) q[0]; +cx q[2],q[0]; +rz(-pi/8) q[0]; +cx q[2],q[1]; +rz(pi/4) q[1]; +cx q[2],q[1]; +rz(-pi/4) q[1]; +sx q[2]; +rz(pi/2) q[2]; +cx q[3],q[0]; +rz(pi/16) q[0]; +cx q[3],q[0]; +rz(-pi/16) q[0]; +cx q[3],q[1]; +rz(pi/8) q[1]; +cx q[3],q[1]; +rz(-pi/8) q[1]; +cx q[3],q[2]; +rz(pi/4) q[2]; +cx q[3],q[2]; +rz(-pi/4) q[2]; +sx q[3]; +rz(pi/2) q[3]; +cx q[4],q[0]; +rz(pi/32) q[0]; +cx q[4],q[0]; +rz(-pi/32) q[0]; +cx q[4],q[1]; +rz(pi/16) q[1]; +cx q[4],q[1]; +rz(-pi/16) q[1]; +cx q[4],q[2]; +rz(pi/8) q[2]; +cx q[4],q[2]; +rz(-pi/8) q[2]; +cx q[4],q[3]; +rz(pi/4) q[3]; +cx q[4],q[3]; +rz(-pi/4) q[3]; +sx q[4]; +rz(pi/2) q[4]; +cx q[5],q[0]; +rz(pi/64) q[0]; +cx q[5],q[0]; +rz(-pi/64) q[0]; +cx q[5],q[1]; +rz(pi/32) q[1]; +cx q[5],q[1]; +rz(-pi/32) q[1]; +cx q[5],q[2]; +rz(pi/16) q[2]; +cx q[5],q[2]; +rz(-pi/16) q[2]; +cx q[5],q[3]; +rz(pi/8) q[3]; +cx q[5],q[3]; +rz(-pi/8) q[3]; +cx q[5],q[4]; +rz(pi/4) q[4]; +cx q[5],q[4]; +rz(-pi/4) q[4]; +sx q[5]; +rz(pi/2) q[5]; +rz(pi/128) q[6]; +cx q[6],q[0]; +rz(pi/128) q[0]; +cx q[6],q[0]; +rz(-pi/128) q[0]; +cx q[6],q[1]; +rz(pi/64) q[1]; +cx q[6],q[1]; +rz(-pi/64) q[1]; +cx q[6],q[2]; +rz(pi/32) q[2]; +cx q[6],q[2]; +rz(-pi/32) q[2]; +cx q[6],q[3]; +rz(pi/16) q[3]; +cx q[6],q[3]; +rz(-pi/16) q[3]; +cx q[6],q[4]; +rz(pi/8) q[4]; +cx q[6],q[4]; +rz(-pi/8) q[4]; +cx q[6],q[5]; +rz(pi/4) q[5]; +cx q[6],q[5]; +rz(-pi/4) q[5]; +sx q[6]; +rz(pi/2) q[6]; +cx q[7],q[0]; +rz(pi/256) q[0]; +cx q[7],q[0]; +rz(-pi/256) q[0]; +cx q[7],q[1]; +rz(pi/128) q[1]; +cx q[7],q[1]; +rz(-pi/128) q[1]; +cx q[7],q[2]; +rz(pi/64) q[2]; +cx q[7],q[2]; +rz(-pi/64) q[2]; +cx q[7],q[3]; +rz(pi/32) q[3]; +cx q[7],q[3]; +rz(-pi/32) q[3]; +cx q[7],q[4]; +rz(pi/16) q[4]; +cx q[7],q[4]; +rz(-pi/16) q[4]; +cx q[7],q[5]; +rz(pi/8) q[5]; +cx q[7],q[5]; +rz(-pi/8) q[5]; +cx q[7],q[6]; +rz(pi/4) q[6]; +cx q[7],q[6]; +rz(-pi/4) q[6]; +sx q[7]; +rz(pi/2) q[7]; +cx q[8],q[0]; +rz(pi/512) q[0]; +cx q[8],q[0]; +rz(-pi/512) q[0]; +cx q[8],q[1]; +rz(pi/256) q[1]; +cx q[8],q[1]; +rz(-pi/256) q[1]; +cx q[8],q[2]; +rz(pi/128) q[2]; +cx q[8],q[2]; +rz(-pi/128) q[2]; +cx q[8],q[3]; +rz(pi/64) q[3]; +cx q[8],q[3]; +rz(-pi/64) q[3]; +cx q[8],q[4]; +rz(pi/32) q[4]; +cx q[8],q[4]; +rz(-pi/32) q[4]; +cx q[8],q[5]; +rz(pi/16) q[5]; +cx q[8],q[5]; +rz(-pi/16) q[5]; +cx q[8],q[6]; +rz(pi/8) q[6]; +cx q[8],q[6]; +rz(-pi/8) q[6]; +cx q[8],q[7]; +rz(pi/4) q[7]; +cx q[8],q[7]; +rz(-pi/4) q[7]; +sx q[8]; +rz(pi/2) q[8]; +rz(-pi/2) psi[0]; +sx psi[0]; +rz(0.832716027313646) psi[0]; diff --git a/test/circuits/approximateEquivalenceTest/check/qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/check/qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm new file mode 100644 index 00000000..ecf55502 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/check/qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm @@ -0,0 +1,258 @@ +// Benchmark was created by MQT Bench on 2024-03-18 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 +// Used Gate Set: ['id', 'rz', 'sx', 'x', 'cx', 'measure', 'barrier'] + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[9]; +qreg psi[1]; +creg c[9]; +rz(pi/2) q[0]; +sx q[0]; +rz(pi/2) q[0]; +rz(pi/2) q[1]; +sx q[1]; +rz(pi/2) q[1]; +rz(pi/2) q[2]; +sx q[2]; +rz(pi/2) q[2]; +rz(pi/2) q[3]; +sx q[3]; +rz(pi/2) q[3]; +rz(pi/2) q[4]; +sx q[4]; +rz(pi/2) q[4]; +rz(pi/2) q[5]; +sx q[5]; +rz(pi/2) q[5]; +rz(pi/2) q[6]; +sx q[6]; +rz(pi/2) q[6]; +rz(pi/2) q[7]; +sx q[7]; +rz(pi/2) q[7]; +rz(pi/2) q[8]; +sx q[8]; +rz(pi/2) q[8]; +x psi[0]; +rz(-0.22396119503130363) psi[0]; +cx psi[0],q[0]; +rz(1.346835131763593) q[0]; +cx psi[0],q[0]; +rz(-1.346835131763593) q[0]; +cx psi[0],q[1]; +rz(-0.4479223900626072) q[1]; +cx psi[0],q[1]; +rz(0.4479223900626072) q[1]; +cx psi[0],q[2]; +rz(-0.8958447801252144) q[2]; +cx psi[0],q[2]; +rz(0.8958447801252144) q[2]; +cx psi[0],q[3]; +rz(1.3499030933393643) q[3]; +cx psi[0],q[3]; +rz(-1.3499030933393643) q[3]; +cx psi[0],q[4]; +rz(-0.44178646691106466) q[4]; +cx psi[0],q[4]; +rz(0.5399612373357454) q[4]; +cx psi[0],q[5]; +rz(-0.8835729338221293) q[5]; +cx psi[0],q[5]; +rz(0.8835729338221293) q[5]; +cx q[3],q[5]; +cx q[5],q[3]; +cx q[3],q[5]; +rz(pi/16) q[3]; +rz(pi/64) q[5]; +cx psi[0],q[6]; +rz(7*pi/16) q[6]; +cx psi[0],q[6]; +rz(-7*pi/16) q[6]; +cx q[2],q[6]; +cx q[6],q[2]; +cx q[2],q[6]; +rz(pi/8) q[2]; +rz(pi/128) q[6]; +cx psi[0],q[7]; +rz(-pi/8) q[7]; +cx psi[0],q[7]; +rz(pi/8) q[7]; +cx q[1],q[7]; +cx q[7],q[1]; +cx q[1],q[7]; +rz(pi/4) q[1]; +rz(pi/256) q[7]; +cx psi[0],q[8]; +rz(-pi/4) q[8]; +cx psi[0],q[8]; +rz(pi/4) q[8]; +cx q[0],q[8]; +cx q[8],q[0]; +cx q[0],q[8]; +rz(pi/2) q[0]; +sx q[0]; +rz(pi/2) q[0]; +cx q[1],q[0]; +rz(pi/4) q[0]; +cx q[1],q[0]; +rz(-pi/4) q[0]; +sx q[1]; +rz(pi/2) q[1]; +cx q[2],q[0]; +rz(pi/8) q[0]; +cx q[2],q[0]; +rz(-pi/8) q[0]; +cx q[2],q[1]; +rz(pi/4) q[1]; +cx q[2],q[1]; +rz(-pi/4) q[1]; +sx q[2]; +rz(pi/2) q[2]; +cx q[3],q[0]; +rz(pi/16) q[0]; +cx q[3],q[0]; +rz(-pi/16) q[0]; +cx q[3],q[1]; +rz(pi/8) q[1]; +cx q[3],q[1]; +rz(-pi/8) q[1]; +cx q[3],q[2]; +rz(pi/4) q[2]; +cx q[3],q[2]; +rz(-pi/4) q[2]; +sx q[3]; +rz(pi/2) q[3]; +cx q[4],q[0]; +rz(pi/32) q[0]; +cx q[4],q[0]; +rz(-pi/32) q[0]; +cx q[4],q[1]; +rz(pi/16) q[1]; +cx q[4],q[1]; +rz(-pi/16) q[1]; +cx q[4],q[2]; +rz(pi/8) q[2]; +cx q[4],q[2]; +rz(-pi/8) q[2]; +cx q[4],q[3]; +rz(pi/4) q[3]; +cx q[4],q[3]; +rz(-pi/4) q[3]; +sx q[4]; +rz(pi/2) q[4]; +cx q[5],q[0]; +rz(pi/64) q[0]; +cx q[5],q[0]; +rz(-pi/64) q[0]; +cx q[5],q[1]; +rz(pi/32) q[1]; +cx q[5],q[1]; +rz(-pi/32) q[1]; +cx q[5],q[2]; +rz(pi/16) q[2]; +cx q[5],q[2]; +rz(-pi/16) q[2]; +cx q[5],q[3]; +rz(pi/8) q[3]; +cx q[5],q[3]; +rz(-pi/8) q[3]; +cx q[5],q[4]; +rz(pi/4) q[4]; +cx q[5],q[4]; +rz(-pi/4) q[4]; +sx q[5]; +rz(pi/2) q[5]; +cx q[6],q[0]; +rz(pi/128) q[0]; +cx q[6],q[0]; +rz(-pi/128) q[0]; +cx q[6],q[1]; +rz(pi/64) q[1]; +cx q[6],q[1]; +rz(-pi/64) q[1]; +cx q[6],q[2]; +rz(pi/32) q[2]; +cx q[6],q[2]; +rz(-pi/32) q[2]; +cx q[6],q[3]; +rz(pi/16) q[3]; +cx q[6],q[3]; +rz(-pi/16) q[3]; +cx q[6],q[4]; +rz(pi/8) q[4]; +cx q[6],q[4]; +rz(-pi/8) q[4]; +cx q[6],q[5]; +rz(pi/4) q[5]; +cx q[6],q[5]; +rz(-pi/4) q[5]; +sx q[6]; +rz(pi/2) q[6]; +cx q[7],q[0]; +rz(pi/256) q[0]; +cx q[7],q[0]; +rz(-pi/256) q[0]; +cx q[7],q[1]; +rz(pi/128) q[1]; +cx q[7],q[1]; +rz(-pi/128) q[1]; +cx q[7],q[2]; +rz(pi/64) q[2]; +cx q[7],q[2]; +rz(-pi/64) q[2]; +cx q[7],q[3]; +rz(pi/32) q[3]; +cx q[7],q[3]; +rz(-pi/32) q[3]; +cx q[7],q[4]; +rz(pi/16) q[4]; +cx q[7],q[4]; +rz(-pi/16) q[4]; +cx q[7],q[5]; +rz(pi/8) q[5]; +cx q[7],q[5]; +rz(-pi/8) q[5]; +cx q[7],q[6]; +rz(pi/4) q[6]; +cx q[7],q[6]; +rz(-pi/4) q[6]; +sx q[7]; +rz(pi/2) q[7]; +rz(0.006135923151542544) q[8]; +cx q[8],q[0]; +rz(pi/512) q[0]; +cx q[8],q[0]; +rz(-pi/512) q[0]; +cx q[8],q[1]; +rz(pi/256) q[1]; +cx q[8],q[1]; +rz(-pi/256) q[1]; +cx q[8],q[2]; +rz(pi/128) q[2]; +cx q[8],q[2]; +rz(-pi/128) q[2]; +cx q[8],q[3]; +rz(pi/64) q[3]; +cx q[8],q[3]; +rz(-pi/64) q[3]; +cx q[8],q[4]; +rz(pi/32) q[4]; +cx q[8],q[4]; +rz(-pi/32) q[4]; +cx q[8],q[5]; +rz(pi/16) q[5]; +cx q[8],q[5]; +rz(-pi/16) q[5]; +cx q[8],q[6]; +rz(pi/8) q[6]; +cx q[8],q[6]; +rz(-pi/8) q[6]; +cx q[8],q[7]; +rz(pi/4) q[7]; +cx q[8],q[7]; +rz(-pi/4) q[7]; +sx q[8]; +rz(pi/2) q[8]; diff --git a/test/circuits/approximateEquivalenceTest/dj_indep_qiskit_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/dj_indep_qiskit_10_no_measure.qasm new file mode 100644 index 00000000..ae21cc45 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/dj_indep_qiskit_10_no_measure.qasm @@ -0,0 +1,37 @@ +// Benchmark was created by MQT Bench on 2024-03-17 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg c[9]; +u2(0,0) q[0]; +u2(0,0) q[1]; +h q[2]; +u2(0,0) q[3]; +h q[4]; +u2(0,0) q[5]; +u2(0,0) q[6]; +h q[7]; +u2(0,0) q[8]; +u2(-pi,-pi) q[9]; +cx q[0],q[9]; +u2(-pi,-pi) q[0]; +cx q[1],q[9]; +u2(-pi,-pi) q[1]; +cx q[2],q[9]; +h q[2]; +cx q[3],q[9]; +u2(-pi,-pi) q[3]; +cx q[4],q[9]; +h q[4]; +cx q[5],q[9]; +u2(-pi,-pi) q[5]; +cx q[6],q[9]; +u2(-pi,-pi) q[6]; +cx q[7],q[9]; +h q[7]; +cx q[8],q[9]; +u2(-pi,-pi) q[8]; diff --git a/test/circuits/approximateEquivalenceTest/dj_nativegates_ibm_qiskit_opt3_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/dj_nativegates_ibm_qiskit_opt3_10_no_measure.qasm new file mode 100644 index 00000000..4eb30e82 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/dj_nativegates_ibm_qiskit_opt3_10_no_measure.qasm @@ -0,0 +1,69 @@ +// Benchmark was created by MQT Bench on 2024-03-17 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 +// Used Gate Set: ['id', 'rz', 'sx', 'x', 'cx', 'measure', 'barrier'] + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg c[9]; +rz(-pi/2) q[0]; +sx q[0]; +rz(pi) q[0]; +rz(-pi/2) q[1]; +sx q[1]; +rz(pi/2) q[2]; +sx q[2]; +rz(-pi/2) q[3]; +sx q[3]; +rz(pi/2) q[4]; +sx q[4]; +rz(-pi/2) q[5]; +sx q[5]; +rz(-pi/2) q[6]; +sx q[6]; +rz(pi/2) q[7]; +sx q[7]; +rz(-pi/2) q[8]; +sx q[8]; +rz(pi/2) q[9]; +sx q[9]; +rz(-pi/2) q[9]; +cx q[0],q[9]; +sx q[0]; +rz(-pi/2) q[0]; +rz(-pi/2) q[9]; +sx q[9]; +rz(-2.308876626276157) q[9]; +sx q[9]; +rz(pi/2) q[9]; +cx q[1],q[9]; +sx q[1]; +rz(-pi/2) q[1]; +cx q[2],q[9]; +sx q[2]; +rz(pi/2) q[2]; +cx q[3],q[9]; +sx q[3]; +rz(-pi/2) q[3]; +cx q[4],q[9]; +sx q[4]; +rz(pi/2) q[4]; +cx q[5],q[9]; +sx q[5]; +rz(-pi/2) q[5]; +cx q[6],q[9]; +sx q[6]; +rz(-pi/2) q[6]; +cx q[7],q[9]; +sx q[7]; +rz(pi/2) q[7]; +cx q[8],q[9]; +sx q[8]; +rz(-pi/2) q[8]; +rz(-pi/2) q[9]; +sx q[9]; +rz(-2.3088766262761578) q[9]; +sx q[9]; +rz(pi/2) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/ghz_indep_qiskit_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/ghz_indep_qiskit_10_no_measure.qasm new file mode 100644 index 00000000..ff59370c --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/ghz_indep_qiskit_10_no_measure.qasm @@ -0,0 +1,19 @@ +// Benchmark was created by MQT Bench on 2024-03-17 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +h q[9]; +cx q[9],q[8]; +cx q[8],q[7]; +cx q[7],q[6]; +cx q[6],q[5]; +cx q[5],q[4]; +cx q[4],q[3]; +cx q[3],q[2]; +cx q[2],q[1]; +cx q[1],q[0]; diff --git a/test/circuits/approximateEquivalenceTest/ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm new file mode 100644 index 00000000..da97a1ed --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm @@ -0,0 +1,22 @@ +// Benchmark was created by MQT Bench on 2024-03-17 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 +// Used Gate Set: ['id', 'rz', 'sx', 'x', 'cx', 'measure', 'barrier'] + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +rz(pi/2) q[9]; +sx q[9]; +rz(pi/2) q[9]; +cx q[9],q[8]; +cx q[8],q[7]; +cx q[7],q[6]; +cx q[6],q[5]; +cx q[5],q[4]; +cx q[4],q[3]; +cx q[3],q[2]; +cx q[2],q[1]; +cx q[1],q[0]; diff --git a/test/circuits/approximateEquivalenceTest/graphstate_indep_qiskit_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/graphstate_indep_qiskit_10_no_measure.qasm new file mode 100644 index 00000000..38886fa0 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/graphstate_indep_qiskit_10_no_measure.qasm @@ -0,0 +1,29 @@ +// Benchmark was created by MQT Bench on 2024-03-17 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +h q[0]; +h q[1]; +cz q[0],q[1]; +h q[2]; +cz q[1],q[2]; +h q[3]; +h q[4]; +cz q[0],q[4]; +cz q[3],q[4]; +h q[5]; +cz q[2],q[5]; +h q[6]; +cz q[3],q[6]; +cz q[5],q[6]; +h q[7]; +h q[8]; +cz q[7],q[8]; +h q[9]; +cz q[7],q[9]; +cz q[8],q[9]; diff --git a/test/circuits/approximateEquivalenceTest/graphstate_nativegates_ibm_qiskit_opt3_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/graphstate_nativegates_ibm_qiskit_opt3_10_no_measure.qasm new file mode 100644 index 00000000..2c1273f3 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/graphstate_nativegates_ibm_qiskit_opt3_10_no_measure.qasm @@ -0,0 +1,50 @@ +// Benchmark was created by MQT Bench on 2024-03-17 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 +// Used Gate Set: ['id', 'rz', 'sx', 'x', 'cx', 'measure', 'barrier'] + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +rz(pi/2) q[0]; +sx q[0]; +rz(pi/2) q[0]; +cx q[0],q[1]; +rz(pi/2) q[1]; +sx q[1]; +rz(pi/2) q[1]; +rz(pi/2) q[2]; +sx q[2]; +rz(pi/2) q[2]; +cx q[2],q[3]; +rz(pi/2) q[3]; +sx q[3]; +rz(pi/2) q[3]; +cx q[1],q[4]; +rz(pi/2) q[4]; +sx q[4]; +rz(pi/2) q[4]; +cx q[4],q[5]; +rz(pi/2) q[5]; +sx q[5]; +rz(pi/2) q[5]; +cx q[5],q[6]; +rz(pi/2) q[6]; +sx q[6]; +rz(pi/2) q[6]; +cx q[6],q[7]; +rz(pi/2) q[7]; +sx q[7]; +rz(pi/2) q[7]; +cx q[3],q[8]; +cx q[7],q[8]; +rz(pi/2) q[8]; +sx q[8]; +rz(pi/2) q[8]; +cx q[0],q[9]; +cx q[2],q[9]; +rz(pi/2) q[9]; +sx q[9]; +rz(pi/2) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/out_dj_indep_qiskit_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_dj_indep_qiskit_10_high_error.qasm new file mode 100644 index 00000000..3818ab68 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_dj_indep_qiskit_10_high_error.qasm @@ -0,0 +1,29 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(6.06881057839052, 5.903628153049844, 3.0820752952692287) q[0]; +u3(3.774395453789126, 1.6709824825990403, 3.33882857475355) q[1]; +u3(3.604030233387013, 4.266213899121946, -1.1674700191224305) q[2]; +u3(4.713248404795393, 7.4791039259414465, 3.1412247596131837) q[3]; +u3(5.021591154847043, 6.323156730574956, 1.2475761402468823) q[4]; +u3(4.296274954505401, 5.483900759354059, 5.532252415758215) q[5]; +u3(4.419387891174763, 5.3075662498442675, 5.368882638058229) q[6]; +u3(1.5710974411468126, -0.021458163063248534, 0.00043099957982519485) q[7]; +u3(6.784915833152506, 1.634342226570327, 1.9940035867092534) q[8]; +u3(6.945900060636145, 4.666872104921736, 2.4346891426054214) q[9]; +u3(1.5576976507933171, 1.7847821116849119, 2.0083604068943974) q[0]; +u3(-1.6864541005637683, 7.230328119859851, 3.2019424679687423) q[1]; +u3(4.290132918908613, 1.7637434129664025, 2.4619306935322216) q[2]; +u3(6.727080321075377, 0.789023577116072, 3.9341430307926575) q[4]; +u3(4.039131641415167, 2.5981778523200796, 2.008974898274495) q[5]; +u3(0.709218017823603, 0.45864336957936336, 2.1883596097690146) q[6]; +u3(4.257859499816279, 4.4905468668280495, 4.1743999094930535) q[8]; +u3(2.0572393653210113, 3.6112303623305793, 5.5842279129491645) q[9]; +cx q[3], q[9]; +u3(4.711457784824099, -0.0003602263844019784, 1.9455853330529376) q[3]; +u3(6.283309547520465, 5.076237356837114, 1.2070912924807158) q[9]; +u3(-0.13031236669726765, 1.0887725661619272, 3.0091337433275984) q[9]; +u3(1.5884896468654224, 1.4403570173959617, 3.753325609696006) q[9]; +cx q[7], q[9]; +u3(4.712590063817558, 0.00045599593374527885, 3.1631252425729355) q[7]; +u3(-0.0005454370046024911, 6.047308379412852, 3.3770182885562674) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/out_dj_nativegates_ibm_qiskit_opt3_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_dj_nativegates_ibm_qiskit_opt3_10_high_error.qasm new file mode 100644 index 00000000..18718f20 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_dj_nativegates_ibm_qiskit_opt3_10_high_error.qasm @@ -0,0 +1,29 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(2.335306671190346, 3.772812277566454, 2.108741442318727) q[0]; +u3(3.054177095786275, 6.521210169501422, 6.522692801382013) q[1]; +u3(4.445664880809077, 0.4644324719678442, 3.16053766876242) q[2]; +u3(1.57158482298804, 0.32124556615883415, 0.0009593828889625011) q[3]; +u3(5.1647481210818915, 1.9277822468147676, 0.9754987052319422) q[4]; +u3(0.47129463944587763, 2.214354530891446, 3.353365312561171) q[5]; +u3(1.4827897573470243, 0.9417618068009833, 4.883192724133633) q[6]; +u3(1.5717470287211532, 1.0167086547925923, 3.1415340377073235) q[7]; +u3(1.0825206639489946, 2.9280854271111387, 1.1710648430062278) q[8]; +u3(0.5989509836144578, 2.9500255284939136, 5.060035635525321) q[9]; +u3(4.044248376888316, 2.061304101973117, 6.363302885400944) q[0]; +u3(7.832734421282508, 1.6559427069124357, 1.571576574040885) q[1]; +u3(1.5525330152405294, 2.8747693099478377, 4.25320021652121) q[2]; +u3(0.7306917441894218, 0.7130792095915414, 2.212449755753419) q[4]; +u3(4.6160471153784055, 2.032971513123998, 5.4507154661344295) q[5]; +u3(2.949378041854789, 3.6230298276558384, 1.1029104388293516) q[6]; +u3(3.7620355295461785, 5.344854569453492, 4.088736678668232) q[8]; +u3(1.1253917784355454, 3.555964933239227, 2.538307206679658) q[9]; +cx q[3], q[9]; +u3(4.713671755883596, 6.282594625947213, -0.32179273662146896) q[3]; +u3(5.896603381333034, 1.5683833990255478, 4.7136291282296945) q[9]; +u3(1.3184907268778128, 5.325243607641265, 5.596125201988893) q[9]; +u3(2.035653819378473, 3.7197439670825867, 3.2019020544302967) q[9]; +cx q[7], q[9]; +u3(4.712405346456387, 3.141417733882747, -1.0166831735504562) q[7]; +u3(1.8666946080156421, 1.5707648288198446, 4.712613099350399) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/out_ghz_indep_qiskit_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_ghz_indep_qiskit_10_high_error.qasm new file mode 100644 index 00000000..ba4a9f9f --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_ghz_indep_qiskit_10_high_error.qasm @@ -0,0 +1,23 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(-0.6143483334225731, 1.4771257802030138, 4.714276007177734) q[0]; +u3(2.7948842906645646, 3.343488390415191, 4.037932886632076) q[1]; +u3(3.2697050896394253, 1.977487880204244, 1.3056428364533377) q[2]; +u3(2.59107044495318, 4.37444909579603, 4.62938494734676) q[3]; +u3(3.2051829241746397, 2.561893454996514, -0.40164581838041613) q[4]; +u3(4.399043818012508, 3.968692556542786, 1.7737197457170457) q[5]; +u3(1.5786792564859715, 6.455268469721191, 0.878122324232283) q[6]; +u3(1.956348923586676, 0.6548072080713027, 1.2007421173597088) q[7]; +u3(2.114476242182641, 1.2706805676028825, -0.4033711772867306) q[8]; +u3(5.1872033357024225, 6.352255117102099, 1.167531747505399) q[9]; +u3(2.1856597587244257, 1.5699777340044532, 4.804285563971735) q[0]; +u3(1.8398758060738734, -0.22207692020895373, 2.2348696290284455) q[1]; +u3(4.588824605317062, -0.03338686201523063, 4.038928794122309) q[2]; +u3(4.1617406479053, 6.232321334090658, 4.952556005909968) q[3]; +u3(1.5954108334862225, 0.059553849640958355, 1.7498206442004949) q[4]; +u3(3.512863675997405, 3.7000151496319607, 2.904494938284918) q[5]; +u3(3.8342365734957755, 1.5832106331352656, 1.4089831368148396) q[6]; +u3(3.669520405598157, 5.554875924077623, 1.6848740101058448) q[7]; +u3(4.36962904292202, 4.1302220839027886, 3.2243152385877636) q[8]; +u3(1.2141452647009583, 2.6324089754912143, 1.6943114768660263) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm new file mode 100644 index 00000000..72567c9b --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm @@ -0,0 +1,23 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(5.047725273307948, 3.8997785650205583, 2.9653095910496408) q[0]; +u3(2.7662143649914155, 0.7760860320782041, 2.5885346725391973) q[1]; +u3(0.9532994313308205, 2.5497840063420103, 5.681138784560119) q[2]; +u3(4.1191491196917385, 4.772961085343913, 1.9019670713296728) q[3]; +u3(7.793867363553461, 3.3802242803407863, 1.367029880859521) q[4]; +u3(2.0651941103360945, 2.56711917204636, 1.8943324485150532) q[5]; +u3(2.493509453943615, 2.7880242937251296, 0.019422390046078486) q[6]; +u3(3.2831530558423676, 1.836557976116568, 3.2533726217462084) q[7]; +u3(2.31613457125066, 4.416467383381407, 2.10220415641265) q[8]; +u3(-1.6858200613731753, 2.934475344451984, 3.269300432973157) q[9]; +u3(1.404592390794163, 2.8013484127241095, 4.013053572044193) q[0]; +u3(1.3780194780009043, 5.960027157016272, 3.4140734461447066) q[1]; +u3(5.191821051498533, 0.858862855932312, 5.682601431803838) q[2]; +u3(5.6133478485960095, -0.44820307398048637, 5.202741182288472) q[3]; +u3(2.9285781360738965, 7.559560811966148, 1.0445926706466884) q[4]; +u3(5.698593781277909, 2.6092061719198334, 4.33152560692951) q[5]; +u3(4.723701529665525, 0.646968408218973, 1.939776323406654) q[6]; +u3(7.868130407571769, 6.142355452901236, 6.128274073444406) q[7]; +u3(4.025217475457678, 0.5012489867565808, 5.721434197772335) q[8]; +u3(2.9699255128667974, 2.4031714938907967, 1.0448040920303607) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/out_graphstate_indep_qiskit_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_graphstate_indep_qiskit_10_high_error.qasm new file mode 100644 index 00000000..05f711fb --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_graphstate_indep_qiskit_10_high_error.qasm @@ -0,0 +1,31 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(1.432594117296715, 6.523517503696879, 0.5307753009182036) q[0]; +u3(-1.563719864741981, 1.6385481762828487, 3.1501519987816677) q[1]; +u3(5.483925120679292, 4.711156244372728, 4.715245581747235) q[2]; +u3(1.2781788813956485, 4.7532819488974996, 5.42441697008978) q[3]; +u3(1.6964362215906845, 3.0078671870139804, -0.11799205682439023) q[4]; +u3(4.987464431507268, -0.8327076872866116, 0.7700929980801302) q[5]; +u3(0.9859716126901675, 1.5704600844018486, -1.5700489886406939) q[6]; +u3(3.5567369106682056, 1.882368621533429, 0.9899827707353679) q[7]; +u3(-1.570770647415144, -0.017951498822503034, 12.566494237899454) q[8]; +u3(7.155188828036308, 5.6203819882398935, 2.0329220364345195) q[9]; +u3(2.595136575126597, 1.8420136600638655, 1.561545713580413) q[0]; +u3(3.1309091894391763, 1.024288984562663, 3.7375026392585267) q[1]; +u3(2.246259998379157, 6.328344876664135, 5.997561262385133) q[3]; +u3(2.9692037765904344, 5.533117379115061, 2.517174437297823) q[4]; +u3(0.8080522118639935, 1.185700101199915, 2.6769405250075584) q[5]; +u3(4.93584042797918, -0.353042450902948, 2.2883462105038834) q[7]; +u3(1.2740591430973232, 1.9346335353727981, 6.524619047639296) q[9]; +cx q[1], q[2]; +cx q[3], q[6]; +cx q[8], q[9]; +u3(6.2829209455465245, 2.931758104031811, 2.9894621804657286) q[1]; +u3(7.852076600509691, 0.771223369207406, -0.00013106892522044152) q[2]; +u3(6.282504070663867, 6.8700130737682885, 5.271847193703128) q[3]; +u3(0.5512530500777284, 1.571186803497867, 4.712688323023295) q[6]; +u3(0.00025723443696661525, 7.770111440165413, -3.0394939501279237) q[8]; +u3(4.712635149491865, 2.64121679513578, 3.1413335394340307) q[9]; +u3(1.2006011499705118, 3.3624913612182477, 4.296737054801426) q[6]; +u3(5.098372970275851, 4.278452206099582, 4.649821004709238) q[6]; diff --git a/test/circuits/approximateEquivalenceTest/out_graphstate_nativegates_ibm_qiskit_opt3_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_graphstate_nativegates_ibm_qiskit_opt3_10_high_error.qasm new file mode 100644 index 00000000..28088d97 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_graphstate_nativegates_ibm_qiskit_opt3_10_high_error.qasm @@ -0,0 +1,25 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(0.0, 0.0, 0.0) q[0]; +u3(1.5708004796822823, 0.0001122150979442349, -3.141686950159258) q[1]; +u3(4.7132469899784475, 10.693282422255491, -6.28339856365495) q[2]; +u3(1.5707796381087182, -3.1404984683866095, 3.1416335793283556) q[3]; +u3(4.644762724723176, 4.039696158282753, 3.2966197717561525) q[4]; +u3(4.752627214253485, 2.453114764693034, 0.6820669534381145) q[5]; +u3(2.7205332796241186, 2.0677343154903234, 3.9467562202461446) q[6]; +u3(2.3327963490034898, 6.365748929050915, 0.7786224790735101) q[7]; +u3(1.5708699366210679, -0.0005118302437518985, 3.142402850856444) q[8]; +u3(0.04837667378412253, 1.8095455087965278, -0.6573485325032415) q[9]; +u3(0.0, 0.0, 0.0) q[0]; +u3(3.3105311106953974, 1.1559008777490294, 3.4058026473017504) q[4]; +u3(-0.6832889689411028, 4.6493914227679705, 2.3093147747270963) q[5]; +u3(1.2828722620108934, 2.8301002008037655, 1.9234190291182376) q[6]; +u3(4.170071744080869, 3.7759623531347035, 4.019447028491128) q[7]; +u3(3.212498803717826, 1.0124702581344829, 3.003857242235134) q[9]; +u3(0.0, 0.0, 0.0) q[0]; +cx q[2], q[9]; +u3(4.570152680042814, 2.6444675785744884, 0.8530782413266593) q[0]; +u3(6.282303408208207, 1.9045396024277235, 7.822459782931171) q[2]; +u3(7.8541017243149, 4.801951116840429, 3.1423127524001635) q[9]; +u3(0.8620836184095643, 4.899796869847033, 5.086088148796226) q[0]; diff --git a/test/circuits/approximateEquivalenceTest/out_qaoa_indep_qiskit_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_qaoa_indep_qiskit_10_high_error.qasm new file mode 100644 index 00000000..3f6f60d9 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_qaoa_indep_qiskit_10_high_error.qasm @@ -0,0 +1,30 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(1.4624019839245497, -0.24343275343142734, -2.1452489713953007) q[0]; +u3(1.933343797495146, -0.6520681965631354, 4.250068817364644) q[1]; +u3(5.466578160237326, 1.944230971396738, 4.694000276279117) q[2]; +u3(3.0620761958611573, 4.086864345257192, 1.2743521026739149) q[3]; +u3(1.814227440579282, 6.4700374794611575, -1.6867419861657262) q[4]; +u3(4.712393037463343, 5.28006828308011, 2.0505642438361504) q[5]; +u3(4.708230526925601, 0.47849617648089443, 5.438678485367332) q[6]; +u3(4.5551263658752, 3.1829729391170622, 4.65781545732097) q[7]; +u3(0.0, 0.0, 0.0) q[8]; +u3(1.5817935106268783, 2.1211716826928546, 1.098055274909864) q[9]; +u3(1.5662372031815006, 5.160156494184899, 1.7902423688041866) q[2]; +u3(4.438117424266678, 5.831723136425203, 5.569735641913855) q[3]; +u3(6.842140987968218, 2.6755978090714283, 3.9292205794307917) q[4]; +u3(3.472383069346754, 2.664570893966137, 5.102757901617316) q[6]; +u3(-0.24410233712965587, 5.862440537147041, 0.8379848392911975) q[7]; +u3(0.0, 0.0, 0.0) q[8]; +u3(0.1866117853157909, 4.800381580385864, 2.4997943923507324) q[9]; +u3(0.460926360143544, 3.1718236513438276, 2.014374531658772) q[2]; +cx q[5], q[9]; +u3(0.6994182158012909, 2.2581150016299154, 2.5241614420498726) q[8]; +u3(3.3429802940889077, 1.7940925532354683, 3.4208036009126928) q[2]; +u3(5.555760620203913, 4.712159805289027, 5.715694172725523) q[5]; +u3(3.921566564697745, 2.6816530853312663, 2.766712067406482) q[8]; +u3(4.356992150852439, 5.594153065657897, 0.7400150582754648) q[9]; +cx q[7], q[9]; +u3(-2.3645529774684886, 1.5723788249805206, 1.128121475529069) q[7]; +u3(0.005103976693752369, 3.162368208343641, 3.1155808409298302) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/out_qaoa_nativegates_ibm_qiskit_opt3_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_qaoa_nativegates_ibm_qiskit_opt3_10_high_error.qasm new file mode 100644 index 00000000..16b6d8f1 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_qaoa_nativegates_ibm_qiskit_opt3_10_high_error.qasm @@ -0,0 +1,27 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(0.42639050700219194, 3.065442237938425, 0.3273103037531484) q[0]; +u3(1.5714752989468632, 0.00013384228797397313, -3.786262634058096) q[1]; +u3(4.7125493058107795, 4.267995140955728, 3.1416909439478977) q[2]; +u3(4.95787004308975, 3.3301349767393065, 2.568642990797727) q[3]; +u3(1.6498631188623636, 3.2646413547174613, 3.1080961937809315) q[4]; +u3(1.571050073437134, 0.0013948596061459373, 2.115164879426297) q[5]; +u3(1.2508474148802897, -0.014722318596002336, 5.022238650701951) q[6]; +u3(1.5717307707882224, 0.0004985873419509623, -4.167724648345697) q[7]; +u3(0.0, 0.0, 0.0) q[8]; +u3(1.5714773446137233, 0.000830720140711616, 2.115309395335114) q[9]; +u3(4.3082701932390615, 0.14047854101600438, 3.563672502202493) q[0]; +u3(3.398038092712026, 2.8629166783160853, 5.80755693293833) q[3]; +u3(3.0561493383774385, 4.468371756214439, 2.6160303848185755) q[4]; +u3(3.720515272314431, 1.0120990253756275, 5.716031808227701) q[6]; +u3(0.0, 0.0, 0.0) q[8]; +cx q[2], q[6]; +u3(7.7938225972912365, 3.4065676035623937, 0.9687741440152317) q[4]; +u3(0.0, 0.0, 0.0) q[8]; +u3(2.4982712626476853, 4.713094583713299, 5.1569658658054625) q[2]; +u3(1.8809195632979894, 2.814496614303875, 3.4837375115185694) q[4]; +u3(4.6102063746540205, 3.2789598268081837, 5.645057063921604) q[6]; +u3(0.0, 0.0, 0.0) q[8]; +u3(8.157453786451542, 6.2866928162052345, 3.735500276889271) q[8]; +u3(6.5909209929256605, 6.441731812206573, 2.9723106256988805) q[8]; diff --git a/test/circuits/approximateEquivalenceTest/out_vqe_indep_qiskit_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_vqe_indep_qiskit_10_high_error.qasm new file mode 100644 index 00000000..329d6a60 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_vqe_indep_qiskit_10_high_error.qasm @@ -0,0 +1,25 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(1.571945970524166, -1.5416729344346136, 3.1142201840147985) q[0]; +u3(0.0, 0.0, 0.0) q[1]; +u3(1.5683933548274716, -3.1425401983771866, -1.574534477402389) q[2]; +u3(0.0011860195119125772, 0.34232340444286746, 0.06005728803354232) q[3]; +u3(2.7368460810919197, 0.0005494822175939884, 1.5725541135389047) q[4]; +u3(2.1606806512298085, 1.74473677117697, -0.4618126915380293) q[5]; +u3(1.4013444508890258, -0.14725421549339446, -4.233717441593754) q[6]; +u3(7.214733523195288, 2.983749318145844, 1.2976996740201097) q[7]; +u3(3.876473512505923, 5.92864932810349, 1.9450233057723907) q[8]; +u3(4.959984317698359, 8.013346910090654, 5.52792724967543) q[9]; +u3(0.0, 0.0, 0.0) q[0]; +u3(1.5712474652374344, 1.5733287074782505, -3.1391919593989543) q[1]; +u3(2.1581282500612264, 0.5943423038396909, 3.175130225628324) q[7]; +u3(6.706600896198001, 0.797203708624387, 1.7495144131546345) q[8]; +u3(0.0, 0.0, 0.0) q[0]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.0) q[0]; +u3(4.712708466056863, 1.5735566771536544, 0.9902983007753604) q[8]; +u3(2.6324383127303697, 2.9859422277667504, 6.150256274647738) q[9]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; diff --git a/test/circuits/approximateEquivalenceTest/out_vqe_nativegates_ibm_qiskit_opt3_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_vqe_nativegates_ibm_qiskit_opt3_10_high_error.qasm new file mode 100644 index 00000000..134d0f81 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_vqe_nativegates_ibm_qiskit_opt3_10_high_error.qasm @@ -0,0 +1,25 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(3.141144995781528, 0.729230580205777, -5.553809272274417) q[0]; +u3(0.0, 0.0, 0.0) q[1]; +u3(1.5709371603453506, 0.0006003266070311319, 5.667998044147341) q[2]; +u3(0.9280326307264981, 9.433415796311628e-05, -1.5693584303407235) q[3]; +u3(1.5703802843994839, -0.0015860331288160001, 1.570193861561292) q[4]; +u3(1.5802339383487496, 0.00013363582176761923, 1.572419766585579) q[5]; +u3(1.5702978068177287, 3.1422127654061307, 1.5710891030344363) q[6]; +u3(4.56452304943476, 6.868521669974106, 5.450410796613644) q[7]; +u3(6.052685819587351, 2.665045009481868, 4.210061453187524) q[8]; +u3(2.313023584442147, 0.9956696247187454, -0.5859299934515115) q[9]; +u3(0.0, 0.0, 0.0) q[0]; +u3(2.2824213000454696, -2.2709816309767326, 3.8007003027944894) q[1]; +u3(4.189367215345096, 1.1999085972927805, 1.4306859648884949) q[7]; +u3(5.169039433755726, 6.205177700176606, 4.162872003624732) q[8]; +u3(0.0, 0.0, 0.0) q[0]; +cx q[8], q[9]; +u3(0.0, 0.0, 0.0) q[0]; +u3(1.5674008723294437, 1.572244164799447, 1.041070546453933) q[8]; +u3(2.6450537836950025, 0.7599254115981949, 0.7302924449778218) q[9]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; +u3(0.0, 0.0, 0.0) q[0]; diff --git a/test/circuits/approximateEquivalenceTest/out_wstate_indep_qiskit_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_wstate_indep_qiskit_10_high_error.qasm new file mode 100644 index 00000000..292e6d50 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_wstate_indep_qiskit_10_high_error.qasm @@ -0,0 +1,42 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(0.08880432894746627, 0.23189520151989743, 4.77518370435655) q[0]; +u3(4.968719305172505, 3.380143352874718, 5.113349871036835) q[1]; +u3(1.409241967610268, 4.984113581729915, 1.7849930153549283) q[2]; +u3(1.7719429180591144, 5.261720069567487, 1.1501426584798664) q[3]; +u3(4.361696837818329, 1.675586172492358, 4.806014700387583) q[4]; +u3(-0.9366710989765981, 5.97976869040335, 1.8590014268957524) q[5]; +u3(1.5715710383793198, 3.727402254136272, 3.2966551291356483) q[6]; +u3(3.8005889857714075, 1.5036083387294208, 5.3171736722443) q[7]; +u3(5.085084400020848, 1.5719055667740385, 6.230141952900043) q[8]; +u3(3.141592653589887, 2.6033475508277157, 7.315736531212332) q[9]; +u3(-0.7946551917789845, 0.12470679383030889, 1.188808075583932) q[0]; +u3(2.9971131207828527, 0.0767695169903223, 5.109690349147795) q[1]; +u3(3.6184830534599506, 5.301589098078638, 2.353602290482522) q[2]; +u3(2.746258745795315, 3.7012748609790314, 4.212350521871979) q[4]; +u3(2.373351060701321, 1.1549603893186093, 5.54724556157436) q[5]; +u3(1.0805244975415562, 5.87655568524475, 4.270208593613963) q[6]; +u3(1.634688915153328, 1.5779305462111157, 0.74569033177784) q[7]; +u3(3.0683881647264797, 2.14998914993376, 5.522140167582976) q[8]; +u3(2.648602842023635, 5.030958794730189, 0.5347168141649181) q[1]; +u3(3.684974509806954, 2.828121645975489, 4.433617387307407) q[2]; +cx q[3], q[4]; +u3(4.392410785267952, 2.216421283665582, 0.660458922515924) q[5]; +u3(1.5766255732596564, 3.8362648105101793, 1.5477551411129582) q[6]; +cx q[8], q[9]; +u3(4.46816909668358, 2.7084361346054546, 3.303891764094752) q[1]; +u3(1.7252050298932085, 1.4260006444360414, 6.33377853281975) q[2]; +u3(6.283124496073446, 6.59774539351529, 4.268139466585652) q[3]; +u3(2.5441383947004796, 1.570761844864247, 4.712315467100208) q[4]; +u3(5.334016041483067, 5.885897274929878, 5.876657337255943) q[5]; +u3(3.165042510671254, 3.3914132215169506, 4.267378998652459) q[6]; +u3(3.1398956388587766, -0.09088192516558817, 4.834789498465474) q[8]; +u3(3.1415926535885683, 0.36270118025369463, 1.936196943153783) q[9]; +u3(1.8026536690025112, 5.812887830004276, 0.5884802958565906) q[3]; +cx q[7], q[8]; +u3(2.141726036255668, 3.4175167637868427, 5.333863636664062) q[3]; +u3(0.0016830466530898163, -0.009491059653115945, 4.185627647750503) q[7]; +u3(3.141710109840958, 5.172322216088836, 3.604401073096564) q[8]; +u3(2.7305848531990606, 6.375945500507991, 1.3913552924492263) q[7]; +u3(5.115785613859014, 4.790587836291266, 5.995018445914517) q[7]; diff --git a/test/circuits/approximateEquivalenceTest/out_wstate_nativegates_ibm_qiskit_opt3_10_high_error.qasm b/test/circuits/approximateEquivalenceTest/out_wstate_nativegates_ibm_qiskit_opt3_10_high_error.qasm new file mode 100644 index 00000000..f8e1d5a8 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/out_wstate_nativegates_ibm_qiskit_opt3_10_high_error.qasm @@ -0,0 +1,42 @@ +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +u3(3.003909754504298, 0.9755289691212459, 1.0509096344814997) q[0]; +u3(4.156718440227518, 2.611643357503636, 2.08567806863232) q[1]; +u3(4.779639710281416, 0.3948887108584252, 4.639866888915957) q[2]; +u3(4.913529737153367, 1.8022278630260664, 1.1500829634420369) q[3]; +u3(7.36959198493212, 1.5870727469619421, 3.705345729525691) q[4]; +u3(4.5213194521292905, 3.8962985426187635, 0.9264043971866853) q[5]; +u3(1.922121831592675, 1.2827202706029506, 4.264037426734242) q[6]; +u3(4.943093791569544, 0.10303076460489785, 0.8188385388339069) q[7]; +u3(4.336041653615549, 1.3324893286344945, 6.343377074933315) q[8]; +u3(-1.7838511809976763e-10, 4.203743296059084, 0.5086456834278801) q[9]; +u3(2.4163853189395956, 6.465387066236423, 0.2090068671218588) q[0]; +u3(0.21607052563769302, 4.224862904871233, 3.633251715427373) q[1]; +u3(3.644050523995374, 6.479050866837511, 1.873099425712036) q[2]; +u3(0.6633601445653122, 0.1950915333412193, 5.890474757097994) q[4]; +u3(5.290832759626098, 2.644757609848364, 3.9110307486611813) q[5]; +u3(-0.48815664772476397, 1.448663406745269, 4.7705392187328) q[6]; +u3(2.3487512761759, 2.8040036725094883, 4.35845578829468) q[7]; +u3(5.583800835000085, 4.696957583744842, 1.8900735246008296) q[8]; +u3(1.2737849195603657, 5.609243524170237, 1.613725465604109) q[1]; +u3(4.808378709201391, 3.8771753180928465, -0.3824185919056889) q[2]; +cx q[3], q[4]; +u3(5.338606814057927, 3.1058094049256875, 2.250621063711204) q[5]; +u3(7.962807285656218, 3.488001019075014, 5.038865511119175) q[6]; +cx q[8], q[9]; +u3(3.4419025763850546, 6.143227142050376, 0.5274818522890575) q[1]; +u3(1.951220248929252, 3.2445591686879554, 0.872719601458409) q[2]; +u3(6.283120951089399, 3.072256825969127, 4.130006565382937) q[3]; +u3(-0.0004781938832750595, 0.7107157064457341, 2.4317932982022046) q[4]; +u3(2.251864506562823, 3.9974892422446393, 2.234968321661341) q[5]; +u3(2.798485571380734, 2.813553652975767, 4.056102186411141) q[6]; +u3(3.1441195882424173, 0.356473456783513, 1.8618018838221935) q[8]; +u3(3.1415926535785372, 1.7946677720108122, 0.22820913361587367) q[9]; +u3(1.8936855133449952, -0.6477761474203892, 2.5895021398664824) q[3]; +cx q[7], q[8]; +u3(7.333270418993937, 3.515795153397013, 5.167535516857539) q[3]; +u3(6.280951615105036, 2.948394915703154, 2.0937973302206854) q[7]; +u3(6.282241702901769, 2.5361182373574205, -0.962542980648663) q[8]; +u3(1.5233405245621463, 0.44332681832304566, 2.641077451127197) q[7]; +u3(2.070412344929058, 3.1947281124932627, 1.1533011486972722) q[7]; diff --git a/test/circuits/approximateEquivalenceTest/qaoa_indep_qiskit_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/qaoa_indep_qiskit_10_no_measure.qasm new file mode 100644 index 00000000..80e4fd3f --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/qaoa_indep_qiskit_10_no_measure.qasm @@ -0,0 +1,59 @@ +// Benchmark was created by MQT Bench on 2024-03-18 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +h q[0]; +h q[1]; +rzz(-5.6274199584027285) q[0],q[1]; +h q[2]; +h q[3]; +rzz(-5.6274199584027285) q[1],q[3]; +rx(1.8987267857024446) q[1]; +h q[4]; +rzz(-5.6274199584027285) q[3],q[4]; +rx(1.8987267857024446) q[3]; +h q[5]; +h q[6]; +rzz(-5.6274199584027285) q[0],q[6]; +rx(1.8987267857024446) q[0]; +rzz(1.2427965226498625) q[0],q[1]; +rzz(1.2427965226498625) q[1],q[3]; +rx(-0.655872435747533) q[1]; +rzz(-5.6274199584027285) q[2],q[6]; +rx(1.8987267857024446) q[6]; +rzz(1.2427965226498625) q[0],q[6]; +rx(-0.655872435747533) q[0]; +h q[7]; +rzz(-5.6274199584027285) q[5],q[7]; +h q[8]; +rzz(-5.6274199584027285) q[2],q[8]; +rx(1.8987267857024446) q[2]; +rzz(1.2427965226498625) q[2],q[6]; +rzz(-5.6274199584027285) q[4],q[8]; +rx(1.8987267857024446) q[4]; +rzz(1.2427965226498625) q[3],q[4]; +rx(-0.655872435747533) q[3]; +rx(-0.655872435747533) q[6]; +rx(1.8987267857024446) q[8]; +rzz(1.2427965226498625) q[2],q[8]; +rx(-0.655872435747533) q[2]; +rzz(1.2427965226498625) q[4],q[8]; +rx(-0.655872435747533) q[4]; +rx(-0.655872435747533) q[8]; +h q[9]; +rzz(-5.6274199584027285) q[5],q[9]; +rx(1.8987267857024446) q[5]; +rzz(-5.6274199584027285) q[7],q[9]; +rx(1.8987267857024446) q[7]; +rzz(1.2427965226498625) q[5],q[7]; +rx(1.8987267857024446) q[9]; +rzz(1.2427965226498625) q[5],q[9]; +rx(-0.655872435747533) q[5]; +rzz(1.2427965226498625) q[7],q[9]; +rx(-0.655872435747533) q[7]; +rx(-0.655872435747533) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/qaoa_nativegates_ibm_qiskit_opt3_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/qaoa_nativegates_ibm_qiskit_opt3_10_no_measure.qasm new file mode 100644 index 00000000..217b99e1 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/qaoa_nativegates_ibm_qiskit_opt3_10_no_measure.qasm @@ -0,0 +1,194 @@ +// Benchmark was created by MQT Bench on 2024-03-18 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 +// Used Gate Set: ['id', 'rz', 'sx', 'x', 'cx', 'measure', 'barrier'] + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +rz(pi/2) q[0]; +sx q[0]; +rz(pi) q[0]; +rz(pi/2) q[1]; +sx q[1]; +rz(pi/2) q[1]; +cx q[0],q[1]; +rz(1.289442989282985) q[1]; +cx q[0],q[1]; +rz(pi/2) q[2]; +sx q[2]; +rz(pi) q[2]; +rz(pi/2) q[3]; +sx q[3]; +rz(pi/2) q[3]; +cx q[1],q[3]; +rz(1.289442989282985) q[3]; +cx q[1],q[3]; +rz(pi/2) q[1]; +sx q[1]; +rz(13.2110965090601) q[1]; +sx q[1]; +rz(5*pi/2) q[1]; +rz(pi/2) q[4]; +sx q[4]; +rz(pi/2) q[4]; +cx q[3],q[4]; +rz(1.289442989282985) q[4]; +cx q[3],q[4]; +rz(pi/2) q[3]; +sx q[3]; +rz(13.2110965090601) q[3]; +sx q[3]; +rz(5*pi/2) q[3]; +rz(pi/2) q[5]; +sx q[5]; +rz(pi) q[5]; +rz(pi/2) q[6]; +sx q[6]; +rz(pi/2) q[6]; +cx q[0],q[6]; +rz(1.289442989282985) q[6]; +cx q[0],q[6]; +sx q[0]; +rz(13.2110965090601) q[0]; +sx q[0]; +rz(3*pi) q[0]; +cx q[0],q[1]; +rz(-0.6447220641786215) q[1]; +cx q[0],q[1]; +cx q[1],q[3]; +cx q[2],q[6]; +rz(-0.6447220641786215) q[3]; +cx q[1],q[3]; +rz(pi/2) q[1]; +sx q[1]; +rz(17.56010762207137) q[1]; +sx q[1]; +rz(5*pi/2) q[1]; +rz(1.289442989282985) q[6]; +cx q[2],q[6]; +rz(pi/2) q[6]; +sx q[6]; +rz(13.2110965090601) q[6]; +sx q[6]; +rz(5*pi/2) q[6]; +cx q[0],q[6]; +rz(-0.6447220641786215) q[6]; +cx q[0],q[6]; +sx q[0]; +rz(17.56010762207137) q[0]; +sx q[0]; +rz(5*pi/2) q[0]; +rz(pi/2) q[7]; +sx q[7]; +rz(pi/2) q[7]; +cx q[5],q[7]; +rz(1.289442989282985) q[7]; +cx q[5],q[7]; +rz(pi/2) q[8]; +sx q[8]; +rz(pi/2) q[8]; +cx q[2],q[8]; +rz(1.289442989282985) q[8]; +cx q[2],q[8]; +sx q[2]; +rz(13.2110965090601) q[2]; +sx q[2]; +rz(3*pi) q[2]; +cx q[2],q[6]; +cx q[4],q[8]; +rz(-0.6447220641786215) q[6]; +cx q[2],q[6]; +rz(pi/2) q[6]; +sx q[6]; +rz(17.56010762207137) q[6]; +sx q[6]; +rz(5*pi/2) q[6]; +rz(1.289442989282985) q[8]; +cx q[4],q[8]; +rz(pi/2) q[4]; +sx q[4]; +rz(13.2110965090601) q[4]; +sx q[4]; +rz(5*pi/2) q[4]; +cx q[3],q[4]; +rz(-0.6447220641786215) q[4]; +cx q[3],q[4]; +rz(pi/2) q[3]; +sx q[3]; +rz(17.56010762207137) q[3]; +sx q[3]; +rz(5*pi/2) q[3]; +rz(pi/2) q[8]; +sx q[8]; +rz(13.2110965090601) q[8]; +sx q[8]; +rz(5*pi/2) q[8]; +cx q[2],q[8]; +rz(-0.6447220641786215) q[8]; +cx q[2],q[8]; +sx q[2]; +rz(17.56010762207137) q[2]; +sx q[2]; +rz(5*pi/2) q[2]; +cx q[4],q[8]; +rz(-0.6447220641786215) q[8]; +cx q[4],q[8]; +rz(pi/2) q[4]; +sx q[4]; +rz(17.56010762207137) q[4]; +sx q[4]; +rz(5*pi/2) q[4]; +rz(pi/2) q[8]; +sx q[8]; +rz(17.56010762207137) q[8]; +sx q[8]; +rz(5*pi/2) q[8]; +rz(pi/2) q[9]; +sx q[9]; +rz(pi/2) q[9]; +cx q[5],q[9]; +rz(1.289442989282985) q[9]; +cx q[5],q[9]; +sx q[5]; +rz(13.2110965090601) q[5]; +sx q[5]; +rz(3*pi) q[5]; +cx q[7],q[9]; +rz(1.289442989282985) q[9]; +cx q[7],q[9]; +rz(pi/2) q[7]; +sx q[7]; +rz(13.2110965090601) q[7]; +sx q[7]; +rz(5*pi/2) q[7]; +cx q[5],q[7]; +rz(-0.6447220641786215) q[7]; +cx q[5],q[7]; +rz(pi/2) q[9]; +sx q[9]; +rz(13.2110965090601) q[9]; +sx q[9]; +rz(5*pi/2) q[9]; +cx q[5],q[9]; +rz(-0.6447220641786215) q[9]; +cx q[5],q[9]; +sx q[5]; +rz(17.56010762207137) q[5]; +sx q[5]; +rz(5*pi/2) q[5]; +cx q[7],q[9]; +rz(-0.6447220641786215) q[9]; +cx q[7],q[9]; +rz(pi/2) q[7]; +sx q[7]; +rz(17.56010762207137) q[7]; +sx q[7]; +rz(5*pi/2) q[7]; +rz(pi/2) q[9]; +sx q[9]; +rz(17.56010762207137) q[9]; +sx q[9]; +rz(5*pi/2) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/vqe_indep_qiskit_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/vqe_indep_qiskit_10_no_measure.qasm new file mode 100644 index 00000000..26c7c029 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/vqe_indep_qiskit_10_no_measure.qasm @@ -0,0 +1,57 @@ +// Benchmark was created by MQT Bench on 2024-03-19 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +ry(-3.141235478528481) q[0]; +ry(1.5706979045022578) q[1]; +ry(-2.362236077972896e-05) q[2]; +ry(-3.1399208277229347) q[3]; +ry(-0.0011147396600802526) q[4]; +ry(-1.1042563024883283) q[5]; +ry(2.9801510328183927) q[6]; +ry(3.0545670522151607) q[7]; +ry(-1.3668142934358305) q[8]; +ry(-2.9083999118928885) q[9]; +cx q[8],q[9]; +cx q[7],q[8]; +cx q[6],q[7]; +cx q[5],q[6]; +cx q[4],q[5]; +cx q[3],q[4]; +cx q[2],q[3]; +cx q[1],q[2]; +cx q[0],q[1]; +ry(1.599653982977371) q[0]; +ry(-0.003280589550612297) q[1]; +ry(0.0034061099135506466) q[2]; +ry(-1.1679350002528048) q[3]; +ry(pi) q[4]; +ry(-2.7302797356431983) q[5]; +ry(-2.6925756675472736) q[6]; +ry(-0.941592140077449) q[7]; +ry(-0.8734936311655543) q[8]; +ry(-2.300413555921887) q[9]; +cx q[8],q[9]; +cx q[7],q[8]; +cx q[6],q[7]; +cx q[5],q[6]; +cx q[4],q[5]; +cx q[3],q[4]; +cx q[2],q[3]; +cx q[1],q[2]; +cx q[0],q[1]; +ry(1.5993512590035681) q[0]; +ry(1.5708506148951475) q[1]; +ry(0.0006026837145775064) q[2]; +ry(-1.5710638349849695) q[3]; +ry(1.1673330914635904) q[4]; +ry(-1.9859733062653429) q[5]; +ry(2.8994628483268934) q[6]; +ry(-1.6023537028276675) q[7]; +ry(-1.493367754442654) q[8]; +ry(0.5041276741646578) q[9]; diff --git a/test/circuits/approximateEquivalenceTest/vqe_nativegates_ibm_qiskit_opt3_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/vqe_nativegates_ibm_qiskit_opt3_10_no_measure.qasm new file mode 100644 index 00000000..48b460d6 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/vqe_nativegates_ibm_qiskit_opt3_10_no_measure.qasm @@ -0,0 +1,140 @@ +// Benchmark was created by MQT Bench on 2024-03-19 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 +// Used Gate Set: ['id', 'rz', 'sx', 'x', 'cx', 'measure', 'barrier'] + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +sx q[0]; +rz(3.1415813049085717) q[0]; +sx q[0]; +rz(-pi) q[0]; +sx q[1]; +rz(1.570786589208974) q[1]; +sx q[1]; +rz(-pi) q[1]; +rz(-pi) q[2]; +sx q[2]; +rz(3.1415799921181318) q[2]; +sx q[2]; +rz(-pi) q[3]; +x q[3]; +sx q[4]; +rz(3.1414744590066235) q[4]; +sx q[4]; +rz(-pi) q[4]; +rz(-pi) q[5]; +x q[5]; +rz(-pi) q[6]; +x q[6]; +sx q[7]; +rz(0.47424615833851735) q[7]; +sx q[7]; +rz(-pi) q[7]; +rz(-pi) q[8]; +sx q[8]; +rz(1.69789688435345) q[8]; +sx q[8]; +rz(-pi) q[9]; +sx q[9]; +rz(1.9415420397245624) q[9]; +sx q[9]; +cx q[8],q[9]; +cx q[7],q[8]; +cx q[6],q[7]; +cx q[5],q[6]; +cx q[4],q[5]; +cx q[3],q[4]; +cx q[2],q[3]; +cx q[1],q[2]; +cx q[0],q[1]; +sx q[0]; +rz(3.141523748482429) q[0]; +sx q[0]; +rz(-pi) q[1]; +sx q[1]; +rz(0.9545951268105295) q[1]; +sx q[1]; +rz(-pi) q[2]; +sx q[2]; +rz(2.1871374559262557) q[2]; +sx q[2]; +rz(-pi) q[3]; +x q[3]; +rz(-pi) q[4]; +sx q[4]; +rz(2.292662039948823e-05) q[4]; +sx q[4]; +rz(0) q[5]; +sx q[5]; +rz(3.141574454779419) q[5]; +sx q[5]; +rz(3*pi) q[5]; +sx q[6]; +rz(0.0002655815817722562) q[6]; +sx q[6]; +rz(-pi) q[6]; +sx q[7]; +rz(0.490262872023405) q[7]; +sx q[7]; +rz(-pi) q[7]; +sx q[8]; +rz(1.3153030676962363) q[8]; +sx q[8]; +rz(-pi) q[8]; +sx q[9]; +rz(2.0164192929845965) q[9]; +sx q[9]; +rz(-pi) q[9]; +cx q[8],q[9]; +cx q[7],q[8]; +cx q[6],q[7]; +cx q[5],q[6]; +cx q[4],q[5]; +cx q[3],q[4]; +cx q[2],q[3]; +cx q[1],q[2]; +cx q[0],q[1]; +sx q[0]; +rz(9.846008903835468e-05) q[0]; +sx q[0]; +rz(-pi) q[1]; +sx q[1]; +rz(2.498619853451748) q[1]; +sx q[1]; +sx q[2]; +rz(3.1415403906446215) q[2]; +sx q[2]; +rz(-pi) q[2]; +sx q[3]; +rz(2.498776476853159) q[3]; +sx q[3]; +rz(-pi) q[3]; +rz(0) q[4]; +sx q[4]; +rz(6.283166696845613) q[4]; +sx q[4]; +rz(3*pi) q[4]; +sx q[5]; +rz(0.008876342139857218) q[5]; +sx q[5]; +rz(-pi) q[5]; +rz(-pi) q[6]; +sx q[6]; +rz(3.141505956672047) q[6]; +sx q[6]; +sx q[7]; +rz(2.8752078813145037) q[7]; +sx q[7]; +rz(-pi) q[7]; +rz(-pi) q[8]; +sx q[8]; +rz(0.35300094805126037) q[8]; +sx q[8]; +rz(-pi) q[9]; +sx q[9]; +rz(0.3635786676337345) q[9]; +sx q[9]; diff --git a/test/circuits/approximateEquivalenceTest/wstate_indep_qiskit_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/wstate_indep_qiskit_10_no_measure.qasm new file mode 100644 index 00000000..09e46da9 --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/wstate_indep_qiskit_10_no_measure.qasm @@ -0,0 +1,46 @@ +// Benchmark was created by MQT Bench on 2024-03-19 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +ry(-pi/4) q[0]; +ry(-0.9553166181245093) q[1]; +ry(-pi/3) q[2]; +ry(-1.1071487177940904) q[3]; +ry(-1.1502619915109316) q[4]; +ry(-1.183199640139716) q[5]; +ry(-1.2094292028881888) q[6]; +ry(-1.2309594173407747) q[7]; +ry(-1.2490457723982544) q[8]; +x q[9]; +cz q[9],q[8]; +ry(1.2490457723982544) q[8]; +cz q[8],q[7]; +ry(1.2309594173407747) q[7]; +cz q[7],q[6]; +ry(1.2094292028881888) q[6]; +cz q[6],q[5]; +ry(1.183199640139716) q[5]; +cz q[5],q[4]; +ry(1.1502619915109316) q[4]; +cz q[4],q[3]; +ry(1.1071487177940904) q[3]; +cz q[3],q[2]; +ry(pi/3) q[2]; +cz q[2],q[1]; +ry(0.9553166181245093) q[1]; +cz q[1],q[0]; +ry(pi/4) q[0]; +cx q[8],q[9]; +cx q[7],q[8]; +cx q[6],q[7]; +cx q[5],q[6]; +cx q[4],q[5]; +cx q[3],q[4]; +cx q[2],q[3]; +cx q[1],q[2]; +cx q[0],q[1]; diff --git a/test/circuits/approximateEquivalenceTest/wstate_nativegates_ibm_qiskit_opt3_10_no_measure.qasm b/test/circuits/approximateEquivalenceTest/wstate_nativegates_ibm_qiskit_opt3_10_no_measure.qasm new file mode 100644 index 00000000..f9c028bf --- /dev/null +++ b/test/circuits/approximateEquivalenceTest/wstate_nativegates_ibm_qiskit_opt3_10_no_measure.qasm @@ -0,0 +1,83 @@ +// Benchmark was created by MQT Bench on 2024-03-19 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: 1.1.0 +// Qiskit version: 1.0.2 +// Used Gate Set: ['id', 'rz', 'sx', 'x', 'cx', 'measure', 'barrier'] + +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[10]; +creg meas[10]; +sx q[0]; +rz(pi/4) q[0]; +sx q[0]; +sx q[1]; +rz(0.6154797086703874) q[1]; +sx q[1]; +sx q[2]; +rz(pi/6) q[2]; +sx q[2]; +sx q[3]; +rz(0.46364760900080615) q[3]; +sx q[3]; +sx q[4]; +rz(0.42053433528396456) q[4]; +sx q[4]; +sx q[5]; +rz(0.38759668665518054) q[5]; +sx q[5]; +sx q[6]; +rz(0.361367123906708) q[6]; +sx q[6]; +sx q[7]; +rz(0.33983690945412137) q[7]; +sx q[7]; +sx q[8]; +rz(0.32175055439664213) q[8]; +sx q[8]; +x q[9]; +cx q[9],q[8]; +sx q[8]; +rz(0.32175055439664213) q[8]; +sx q[8]; +cx q[8],q[7]; +sx q[7]; +rz(0.3398369094541218) q[7]; +sx q[7]; +cx q[7],q[6]; +sx q[6]; +rz(0.36136712390670755) q[6]; +sx q[6]; +cx q[6],q[5]; +sx q[5]; +rz(0.387596686655181) q[5]; +sx q[5]; +cx q[5],q[4]; +sx q[4]; +rz(0.420534335283965) q[4]; +sx q[4]; +cx q[4],q[3]; +sx q[3]; +rz(0.46364760900080615) q[3]; +sx q[3]; +cx q[3],q[2]; +sx q[2]; +rz(pi/6) q[2]; +sx q[2]; +cx q[2],q[1]; +sx q[1]; +rz(0.6154797086703869) q[1]; +sx q[1]; +cx q[1],q[0]; +sx q[0]; +rz(pi/4) q[0]; +sx q[0]; +cx q[8],q[9]; +cx q[7],q[8]; +cx q[6],q[7]; +cx q[5],q[6]; +cx q[4],q[5]; +cx q[3],q[4]; +cx q[2],q[3]; +cx q[1],q[2]; +cx q[0],q[1]; diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp new file mode 100644 index 00000000..79b15d8a --- /dev/null +++ b/test/test_hsf.cpp @@ -0,0 +1,84 @@ +#include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" + +#include +#include + +TEST(HSFTest, dj10) { + qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" + "dj_indep_qiskit_10_no_measure.qasm"}; + qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "out_dj_indep_qiskit_10_high_error.qasm"}; + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); + auto resultDD = hsf.check(); +} + +TEST(HSFTest, ghz10) { + qc::QuantumComputation c1{ + "./circuits/approximateEquivalenceTest/" + "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + qc::QuantumComputation c2{ + "./circuits/approximateEquivalenceTest/" + "out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); + auto resultDD = hsf.check(); +} + +TEST(HSFTest, wstate10) { + qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" + "wstate_indep_qiskit_10_no_measure.qasm"}; + qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "out_wstate_indep_qiskit_10_high_error.qasm"}; + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); + auto resultDD = hsf.check(); +} + +TEST(HSFTest, graphstate10) { + qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" + "graphstate_indep_qiskit_10_no_measure.qasm"}; + qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "out_graphstate_indep_qiskit_10_high_error.qasm"}; + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); + auto resultDD = hsf.check(); +} + +TEST(HSFTest, vqe10) { + qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" + "vqe_indep_qiskit_10_no_measure.qasm"}; + qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "out_vqe_indep_qiskit_10_high_error.qasm"}; + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); + auto resultDD = hsf.check(); +} + +TEST(HSFTest, qftNativegates10) { + qc::QuantumComputation c2{ + "./circuits/approximateEquivalenceTest/check/" + "qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + qc::QuantumComputation c1{ + "./circuits/approximateEquivalenceTest/check/" + "out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); + auto resultDD = hsf.check(); +} + +TEST(HSFTest, qpeExact10) { + qc::QuantumComputation c1{ + "./circuits/approximateEquivalenceTest/check/" + "qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + qc::QuantumComputation c2{ + "./circuits/approximateEquivalenceTest/check/" + "out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); + auto resultDD = hsf.check(); +} + +TEST(HSFTest, qpeInexact10) { + qc::QuantumComputation c1{ + "./circuits/approximateEquivalenceTest/check/" + "qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + qc::QuantumComputation c2{ + "./circuits/approximateEquivalenceTest/check/" + "out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); + auto resultDD = hsf.check(); +} From 7ea9ff5b7ad5fa6b64fb7a770c4b8ddd03abaa89 Mon Sep 17 00:00:00 2001 From: Theresa Date: Fri, 4 Oct 2024 19:06:49 +0200 Subject: [PATCH 13/38] :rotating_light: Fix linking issues --- include/checker/dd/HybridSchrodingerFeynmanChecker.hpp | 7 +------ src/checker/dd/HybridSchrodingerFeynmanChecker.cpp | 7 ++++--- test/test_equality.cpp | 3 +-- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index be77466c..64c092ec 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -1,15 +1,13 @@ #pragma once -#include "CircuitOptimizer.hpp" #include "Definitions.hpp" -#include "QuantumComputation.hpp" #include "dd/ComplexValue.hpp" #include "dd/Package.hpp" #include "dd/Package_fwd.hpp" +#include "ir/QuantumComputation.hpp" #include #include -#include #include namespace ec { @@ -24,9 +22,6 @@ template class HybridSchrodingerFeynmanChecker final { throw std::invalid_argument( "The two circuits have a different number of qubits."); } - qc::CircuitOptimizer::removeFinalMeasurements(*qc1); - qc::CircuitOptimizer::removeFinalMeasurements(*qc2); - qc2->invert(); } std::map check(); diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index 15ce973e..8f95c1de 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -1,6 +1,7 @@ #include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" #include "Definitions.hpp" +#include "circuit_optimizer/CircuitOptimizer.hpp" #include "dd/ComplexValue.hpp" #include "dd/DDpackageConfig.hpp" #include "dd/Operations.hpp" @@ -11,11 +12,8 @@ #include #include #include -#include -#include #include #include -#include #include #include @@ -171,6 +169,9 @@ bool ec::HybridSchrodingerFeynmanChecker::Slice::apply( template std::map ec::HybridSchrodingerFeynmanChecker::check() { + qc::CircuitOptimizer::removeFinalMeasurements(*qc1); + qc::CircuitOptimizer::removeFinalMeasurements(*qc2); + this->qc2->invert(); auto nqubits = this->qc1->getNqubits(); auto splitQubit = static_cast(nqubits / 2); approximateVerification(splitQubit); diff --git a/test/test_equality.cpp b/test/test_equality.cpp index cc947c0b..8b8d15eb 100644 --- a/test/test_equality.cpp +++ b/test/test_equality.cpp @@ -5,15 +5,14 @@ #include "EquivalenceCheckingManager.hpp" #include "EquivalenceCriterion.hpp" -#include "QuantumComputation.hpp" #include "checker/dd/applicationscheme/ApplicationScheme.hpp" #include "dd/DDDefinitions.hpp" +#include "ir/QuantumComputation.hpp" #include "ir/operations/Control.hpp" #include #include #include -#include #include class EqualityTest : public testing::Test { From e1ca1e2dfb3d23d875e56988c6c5af96f98d6d96 Mon Sep 17 00:00:00 2001 From: Theresa Date: Fri, 4 Oct 2024 19:25:30 +0200 Subject: [PATCH 14/38] :rotating_light: Fix warnings --- extern/mqt-core | 1 - include/checker/dd/HybridSchrodingerFeynmanChecker.hpp | 1 + src/checker/dd/HybridSchrodingerFeynmanChecker.cpp | 3 +++ test/test_equality.cpp | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) delete mode 160000 extern/mqt-core diff --git a/extern/mqt-core b/extern/mqt-core deleted file mode 160000 index 2a7a9295..00000000 --- a/extern/mqt-core +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2a7a92951fb67d0c4e795afbd17449063aa42d20 diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 64c092ec..c7794455 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -5,6 +5,7 @@ #include "dd/Package.hpp" #include "dd/Package_fwd.hpp" #include "ir/QuantumComputation.hpp" +#include "memory" #include #include diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index 8f95c1de..a5499be5 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -12,8 +12,11 @@ #include #include #include +#include +#include #include #include +#include #include #include diff --git a/test/test_equality.cpp b/test/test_equality.cpp index 8b8d15eb..9362a2c7 100644 --- a/test/test_equality.cpp +++ b/test/test_equality.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include class EqualityTest : public testing::Test { From 30b4756dba842ceb109a854eeffdc062ee214aae Mon Sep 17 00:00:00 2001 From: Theresa Date: Sat, 5 Oct 2024 14:06:41 +0200 Subject: [PATCH 15/38] :rotating_light: Fix linter warnings: Include header directly --- include/checker/dd/HybridSchrodingerFeynmanChecker.hpp | 1 + src/checker/dd/HybridSchrodingerFeynmanChecker.cpp | 7 ++++++- test/test_hsf.cpp | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index c7794455..999a02d2 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -9,6 +9,7 @@ #include #include +#include #include namespace ec { diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index a5499be5..9e4da7c6 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -4,8 +4,13 @@ #include "circuit_optimizer/CircuitOptimizer.hpp" #include "dd/ComplexValue.hpp" #include "dd/DDpackageConfig.hpp" +#include "dd/GateMatrixDefinitions.hpp" #include "dd/Operations.hpp" #include "dd/Package.hpp" +#include "ir/QuantumComputation.hpp" +#include "ir/operations/Control.hpp" +#include "ir/operations/OpType.hpp" +#include "ir/operations/StandardOperation.hpp" #include #include @@ -212,7 +217,7 @@ void ec::HybridSchrodingerFeynmanChecker::approximateVerification( splitQubit); auto result = simulateSlicing(sliceDD1, sliceDD2, splitQubit, totalControl); - std::lock_guard guard(traceMutex); + const std::lock_guard guard(traceMutex); trace += result; } }); diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 79b15d8a..698b4178 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -1,4 +1,6 @@ #include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" +#include "dd/DDpackageConfig.hpp" +#include "ir/QuantumComputation.hpp" #include #include From aa7fd5b2eb4d379f71a85c899f128941718c2a0d Mon Sep 17 00:00:00 2001 From: Theresa Date: Sat, 5 Oct 2024 16:59:59 +0200 Subject: [PATCH 16/38] :art: Make input circuits const, keep measurements as they are skipped in simulateSlicing, reverse iterate through second circuit in simulateSlicing --- .../dd/HybridSchrodingerFeynmanChecker.hpp | 26 ++++++++-- .../dd/HybridSchrodingerFeynmanChecker.cpp | 25 ++------- test/test_hsf.cpp | 51 ++++++++++--------- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 999a02d2..c35c7902 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -15,8 +15,8 @@ namespace ec { template class HybridSchrodingerFeynmanChecker final { public: - HybridSchrodingerFeynmanChecker(qc::QuantumComputation& circ1, - qc::QuantumComputation& circ2, + HybridSchrodingerFeynmanChecker(const qc::QuantumComputation& circ1, + const qc::QuantumComputation& circ2, const std::size_t nThreads) : qc1(&circ1), qc2(&circ2), nthreads(nThreads) { // remove final measurements @@ -29,12 +29,13 @@ template class HybridSchrodingerFeynmanChecker final { // Get # of decisions for given split_qubit, so that lower slice: q0 < i < // qubit; upper slice: qubit <= i < nqubits - std::size_t getNDecisions(qc::Qubit splitQubit, qc::QuantumComputation& qc); + std::size_t getNDecisions(qc::Qubit splitQubit, + const qc::QuantumComputation& qc); protected: using DDPackage = typename dd::Package; - qc::QuantumComputation* qc1; - qc::QuantumComputation* qc2; + qc::QuantumComputation const* qc1; + qc::QuantumComputation const* qc2; private: std::size_t nthreads = 2; @@ -45,6 +46,21 @@ template class HybridSchrodingerFeynmanChecker final { std::unique_ptr& sliceDD2, qc::Qubit splitQubit, std::size_t controls); + class Slice; + + inline void applyLowerUpper(std::unique_ptr& sliceDD1, + std::unique_ptr& sliceDD2, + const std::unique_ptr& op, + Slice& lower, Slice& upper) { + if (op->isUnitary()) { + [[maybe_unused]] auto l = lower.apply(sliceDD1, op); + [[maybe_unused]] auto u = upper.apply(sliceDD2, op); + assert(l == u); + } + sliceDD1->garbageCollect(); + sliceDD2->garbageCollect(); + } + class Slice { protected: qc::Qubit nextControlIdx = 0; diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index 9e4da7c6..a1f02724 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -1,7 +1,6 @@ #include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" #include "Definitions.hpp" -#include "circuit_optimizer/CircuitOptimizer.hpp" #include "dd/ComplexValue.hpp" #include "dd/DDpackageConfig.hpp" #include "dd/GateMatrixDefinitions.hpp" @@ -27,7 +26,7 @@ template std::size_t ec::HybridSchrodingerFeynmanChecker::getNDecisions( - qc::Qubit splitQubit, qc::QuantumComputation& qc) { + qc::Qubit splitQubit, const qc::QuantumComputation& qc) { std::size_t ndecisions = 0; // calculate number of decisions for (const auto& op : qc) { @@ -69,22 +68,11 @@ dd::ComplexValue ec::HybridSchrodingerFeynmanChecker::simulateSlicing( Slice upper(sliceDD2, splitQubit, static_cast(this->qc1->getNqubits() - 1), controls); for (const auto& op : *this->qc1) { - if (op->isUnitary()) { - [[maybe_unused]] auto l = lower.apply(sliceDD1, op); - [[maybe_unused]] auto u = upper.apply(sliceDD2, op); - assert(l == u); - } - sliceDD1->garbageCollect(); - sliceDD2->garbageCollect(); + applyLowerUpper(sliceDD1, sliceDD2, op, lower, upper); } - for (const auto& op : *this->qc2) { - if (op->isUnitary()) { - [[maybe_unused]] auto l = lower.apply(sliceDD1, op); - [[maybe_unused]] auto u = upper.apply(sliceDD2, op); - assert(l == u); - } - sliceDD1->garbageCollect(); - sliceDD2->garbageCollect(); + for (auto it = this->qc2->rbegin(); it != this->qc2->rend(); ++it) { + auto opInv = it->get()->getInverted(); + applyLowerUpper(sliceDD1, sliceDD2, opInv, lower, upper); } auto traceLower = sliceDD1->trace(lower.matrix, lower.nqubits); auto traceUpper = sliceDD2->trace(upper.matrix, upper.nqubits); @@ -177,9 +165,6 @@ bool ec::HybridSchrodingerFeynmanChecker::Slice::apply( template std::map ec::HybridSchrodingerFeynmanChecker::check() { - qc::CircuitOptimizer::removeFinalMeasurements(*qc1); - qc::CircuitOptimizer::removeFinalMeasurements(*qc2); - this->qc2->invert(); auto nqubits = this->qc1->getNqubits(); auto splitQubit = static_cast(nqubits / 2); approximateVerification(splitQubit); diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 698b4178..1b4b80c5 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -6,57 +6,58 @@ #include TEST(HSFTest, dj10) { - qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" - "dj_indep_qiskit_10_no_measure.qasm"}; - qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" - "out_dj_indep_qiskit_10_high_error.qasm"}; + const qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" + "dj_indep_qiskit_10_no_measure.qasm"}; + const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "out_dj_indep_qiskit_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); auto resultDD = hsf.check(); } TEST(HSFTest, ghz10) { - qc::QuantumComputation c1{ + const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/" "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; - qc::QuantumComputation c2{ - "./circuits/approximateEquivalenceTest/" + const qc::QuantumComputation c2{ + "./approximateEquivalenceTest/" "out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); auto resultDD = hsf.check(); } TEST(HSFTest, wstate10) { - qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" - "wstate_indep_qiskit_10_no_measure.qasm"}; - qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" - "out_wstate_indep_qiskit_10_high_error.qasm"}; + const qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" + "wstate_indep_qiskit_10_no_measure.qasm"}; + const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "out_wstate_indep_qiskit_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); auto resultDD = hsf.check(); } TEST(HSFTest, graphstate10) { - qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" - "graphstate_indep_qiskit_10_no_measure.qasm"}; - qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" - "out_graphstate_indep_qiskit_10_high_error.qasm"}; + const qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" + "graphstate_indep_qiskit_10_no_measure.qasm"}; + const qc::QuantumComputation c2{ + "./circuits/approximateEquivalenceTest/" + "out_graphstate_indep_qiskit_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); auto resultDD = hsf.check(); } TEST(HSFTest, vqe10) { - qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" - "vqe_indep_qiskit_10_no_measure.qasm"}; - qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" - "out_vqe_indep_qiskit_10_high_error.qasm"}; + const qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" + "vqe_indep_qiskit_10_no_measure.qasm"}; + const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + "out_vqe_indep_qiskit_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); auto resultDD = hsf.check(); } TEST(HSFTest, qftNativegates10) { - qc::QuantumComputation c2{ + const qc::QuantumComputation c2{ "./circuits/approximateEquivalenceTest/check/" "qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; - qc::QuantumComputation c1{ + const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/check/" "out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); @@ -64,10 +65,10 @@ TEST(HSFTest, qftNativegates10) { } TEST(HSFTest, qpeExact10) { - qc::QuantumComputation c1{ + const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/check/" "qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; - qc::QuantumComputation c2{ + const qc::QuantumComputation c2{ "./circuits/approximateEquivalenceTest/check/" "out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); @@ -75,10 +76,10 @@ TEST(HSFTest, qpeExact10) { } TEST(HSFTest, qpeInexact10) { - qc::QuantumComputation c1{ + const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/check/" "qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; - qc::QuantumComputation c2{ + const qc::QuantumComputation c2{ "./circuits/approximateEquivalenceTest/check/" "out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); From da1674afa728120670a54619efa4ce41d9ab374c Mon Sep 17 00:00:00 2001 From: Theresa Date: Sat, 5 Oct 2024 17:08:52 +0200 Subject: [PATCH 17/38] :white_check_mark: Fix test --- test/test_hsf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 1b4b80c5..862c1475 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -19,7 +19,7 @@ TEST(HSFTest, ghz10) { "./circuits/approximateEquivalenceTest/" "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - "./approximateEquivalenceTest/" + "./circuits/approximateEquivalenceTest/" "out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); auto resultDD = hsf.check(); From 9052e16987122bde3ec8779ba46e78db7292cb3c Mon Sep 17 00:00:00 2001 From: Theresa Date: Sat, 5 Oct 2024 17:13:08 +0200 Subject: [PATCH 18/38] :rotating_light: Remove inline keyword and move header --- include/checker/dd/HybridSchrodingerFeynmanChecker.hpp | 9 +++++---- src/checker/dd/HybridSchrodingerFeynmanChecker.cpp | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index c35c7902..3a713023 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -7,6 +7,7 @@ #include "ir/QuantumComputation.hpp" #include "memory" +#include #include #include #include @@ -48,10 +49,10 @@ template class HybridSchrodingerFeynmanChecker final { class Slice; - inline void applyLowerUpper(std::unique_ptr& sliceDD1, - std::unique_ptr& sliceDD2, - const std::unique_ptr& op, - Slice& lower, Slice& upper) { + void applyLowerUpper(std::unique_ptr& sliceDD1, + std::unique_ptr& sliceDD2, + const std::unique_ptr& op, Slice& lower, + Slice& upper) { if (op->isUnitary()) { [[maybe_unused]] auto l = lower.apply(sliceDD1, op); [[maybe_unused]] auto u = upper.apply(sliceDD2, op); diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index a1f02724..4ae83155 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -12,7 +12,6 @@ #include "ir/operations/StandardOperation.hpp" #include -#include #include #include #include From 4596e86eaef8d49724be4b6ddcd48bb469c793a0 Mon Sep 17 00:00:00 2001 From: Theresa Date: Mon, 7 Oct 2024 15:01:03 +0200 Subject: [PATCH 19/38] :art: :test_tube: Add threshold check; make splitQubit class attribute; make getNDecisions const; add failing tests --- .../dd/HybridSchrodingerFeynmanChecker.hpp | 44 +++++++------ .../dd/HybridSchrodingerFeynmanChecker.cpp | 62 ++++++++++--------- test/test_hsf.cpp | 52 ++++++++++------ 3 files changed, 90 insertions(+), 68 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 3a713023..955909cc 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -1,6 +1,7 @@ #pragma once #include "Definitions.hpp" +#include "EquivalenceCriterion.hpp" #include "dd/ComplexValue.hpp" #include "dd/Package.hpp" #include "dd/Package_fwd.hpp" @@ -9,50 +10,53 @@ #include #include -#include #include -#include namespace ec { template class HybridSchrodingerFeynmanChecker final { public: HybridSchrodingerFeynmanChecker(const qc::QuantumComputation& circ1, const qc::QuantumComputation& circ2, + const double threshold, const std::size_t nThreads) - : qc1(&circ1), qc2(&circ2), nthreads(nThreads) { - // remove final measurements - if (qc1->getNqubits() != qc2->getNqubits()) { + : qc1(&circ1), qc2(&circ2), traceThreshold(threshold), + nthreads(nThreads) { + if (this->qc1->getNqubits() != this->qc2->getNqubits()) { throw std::invalid_argument( "The two circuits have a different number of qubits."); } + splitQubit = static_cast(this->qc1->getNqubits() / 2); } - std::map check(); - // Get # of decisions for given split_qubit, so that lower slice: q0 < i < - // qubit; upper slice: qubit <= i < nqubits - std::size_t getNDecisions(qc::Qubit splitQubit, - const qc::QuantumComputation& qc); + EquivalenceCriterion run(); -protected: - using DDPackage = typename dd::Package; +private: qc::QuantumComputation const* qc1; qc::QuantumComputation const* qc2; - -private: + double traceThreshold = 1e-8; std::size_t nthreads = 2; + qc::Qubit splitQubit; + double runtime{}; - void approximateVerification(qc::Qubit splitQubit); + using DDPackage = typename dd::Package; + + EquivalenceCriterion checkEquivalence(); + + // Get # of decisions for given split_qubit, so that lower slice: q0 < i < + // qubit; upper slice: qubit <= i < nqubits + [[nodiscard]] std::size_t + getNDecisions(const qc::QuantumComputation& qc) const; dd::ComplexValue simulateSlicing(std::unique_ptr& sliceDD1, std::unique_ptr& sliceDD2, - qc::Qubit splitQubit, std::size_t controls); + std::size_t controls); class Slice; - void applyLowerUpper(std::unique_ptr& sliceDD1, - std::unique_ptr& sliceDD2, - const std::unique_ptr& op, Slice& lower, - Slice& upper) { + static void applyLowerUpper(std::unique_ptr& sliceDD1, + std::unique_ptr& sliceDD2, + const std::unique_ptr& op, + Slice& lower, Slice& upper) { if (op->isUnitary()) { [[maybe_unused]] auto l = lower.apply(sliceDD1, op); [[maybe_unused]] auto u = upper.apply(sliceDD2, op); diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index 4ae83155..f8097a47 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -15,17 +15,17 @@ #include #include #include -#include +#include #include #include #include -#include #include #include +namespace ec { template -std::size_t ec::HybridSchrodingerFeynmanChecker::getNDecisions( - qc::Qubit splitQubit, const qc::QuantumComputation& qc) { +std::size_t HybridSchrodingerFeynmanChecker::getNDecisions( + const qc::QuantumComputation& qc) const { std::size_t ndecisions = 0; // calculate number of decisions for (const auto& op : qc) { @@ -38,8 +38,8 @@ std::size_t ec::HybridSchrodingerFeynmanChecker::getNDecisions( bool controlInLowerSlice = false; bool controlInUpperSlice = false; for (const auto& target : op->getTargets()) { - targetInLowerSlice = targetInLowerSlice || target < splitQubit; - targetInUpperSlice = targetInUpperSlice || target >= splitQubit; + targetInLowerSlice = targetInLowerSlice || target < this->splitQubit; + targetInUpperSlice = targetInUpperSlice || target >= this->splitQubit; } for (const auto& control : op->getControls()) { controlInLowerSlice = controlInLowerSlice || control.qubit < splitQubit; @@ -59,10 +59,9 @@ std::size_t ec::HybridSchrodingerFeynmanChecker::getNDecisions( } template -dd::ComplexValue ec::HybridSchrodingerFeynmanChecker::simulateSlicing( +dd::ComplexValue HybridSchrodingerFeynmanChecker::simulateSlicing( std::unique_ptr>& sliceDD1, - std::unique_ptr>& sliceDD2, unsigned int splitQubit, - size_t controls) { + std::unique_ptr>& sliceDD2, size_t controls) { Slice lower(sliceDD1, 0, splitQubit - 1, controls); Slice upper(sliceDD2, splitQubit, static_cast(this->qc1->getNqubits() - 1), controls); @@ -80,8 +79,8 @@ dd::ComplexValue ec::HybridSchrodingerFeynmanChecker::simulateSlicing( } template -bool ec::HybridSchrodingerFeynmanChecker::Slice::apply( - std::unique_ptr>& sliceDD, +bool HybridSchrodingerFeynmanChecker::Slice::apply( + std::unique_ptr& sliceDD, const std::unique_ptr& op) { bool isSplitOp = false; if (dynamic_cast(op.get()) != @@ -162,19 +161,18 @@ bool ec::HybridSchrodingerFeynmanChecker::Slice::apply( } template -std::map -ec::HybridSchrodingerFeynmanChecker::check() { - auto nqubits = this->qc1->getNqubits(); - auto splitQubit = static_cast(nqubits / 2); - approximateVerification(splitQubit); - return {}; +EquivalenceCriterion HybridSchrodingerFeynmanChecker::run() { + const auto start = std::chrono::steady_clock::now(); + auto equivalence = checkEquivalence(); + const auto end = std::chrono::steady_clock::now(); + runtime += std::chrono::duration(end - start).count(); + return equivalence; } template -void ec::HybridSchrodingerFeynmanChecker::approximateVerification( - qc::Qubit splitQubit) { - const auto ndecisions = - getNDecisions(splitQubit, *qc1) + getNDecisions(splitQubit, *qc2); +EquivalenceCriterion +HybridSchrodingerFeynmanChecker::checkEquivalence() { + const auto ndecisions = getNDecisions(*qc1) + getNDecisions(*qc2); const auto maxControl = 1ULL << ndecisions; const auto actuallyUsedThreads = std::min(maxControl, nthreads); const auto chunkSize = static_cast( @@ -186,27 +184,31 @@ void ec::HybridSchrodingerFeynmanChecker::approximateVerification( tf::Executor executor(actuallyUsedThreads); for (std::size_t control = 0; control < maxControl; control += nslicesOnOneCpu) { - executor.silent_async([this, &trace, nslicesOnOneCpu, control, splitQubit, - maxControl, &traceMutex]() { + executor.silent_async([this, &trace, nslicesOnOneCpu, control, maxControl, + &traceMutex]() { for (std::size_t localControl = 0; localControl < nslicesOnOneCpu; localControl++) { const std::size_t totalControl = control + localControl; if (totalControl >= maxControl) { break; } - std::unique_ptr> sliceDD1 = - std::make_unique>(splitQubit); - std::unique_ptr> sliceDD2 = - std::make_unique>(this->qc1->getNqubits() - - splitQubit); - auto result = - simulateSlicing(sliceDD1, sliceDD2, splitQubit, totalControl); + std::unique_ptr sliceDD1 = + std::make_unique(splitQubit); + std::unique_ptr sliceDD2 = + std::make_unique(this->qc1->getNqubits() - splitQubit); + auto result = simulateSlicing(sliceDD1, sliceDD2, totalControl); const std::lock_guard guard(traceMutex); trace += result; } }); } executor.wait_for_all(); + + if (std::abs(trace.mag() - 1.) < traceThreshold) { + return EquivalenceCriterion::Equivalent; + } + return EquivalenceCriterion::NotEquivalent; } template class ec::HybridSchrodingerFeynmanChecker; +} // namespace ec diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 862c1475..a43af038 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -10,8 +10,10 @@ TEST(HSFTest, dj10) { "dj_indep_qiskit_10_no_measure.qasm"}; const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" "out_dj_indep_qiskit_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); - auto resultDD = hsf.check(); + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.912, + 6); + auto result = hsf.run(); + EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); } TEST(HSFTest, ghz10) { @@ -21,8 +23,10 @@ TEST(HSFTest, ghz10) { const qc::QuantumComputation c2{ "./circuits/approximateEquivalenceTest/" "out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); - auto resultDD = hsf.check(); + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.956, + 6); + auto result = hsf.run(); + EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); } TEST(HSFTest, wstate10) { @@ -30,8 +34,10 @@ TEST(HSFTest, wstate10) { "wstate_indep_qiskit_10_no_measure.qasm"}; const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" "out_wstate_indep_qiskit_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); - auto resultDD = hsf.check(); + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.991, + 6); + auto result = hsf.run(); + EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); } TEST(HSFTest, graphstate10) { @@ -40,8 +46,10 @@ TEST(HSFTest, graphstate10) { const qc::QuantumComputation c2{ "./circuits/approximateEquivalenceTest/" "out_graphstate_indep_qiskit_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); - auto resultDD = hsf.check(); + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.912, + 6); + auto result = hsf.run(); + EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); } TEST(HSFTest, vqe10) { @@ -49,19 +57,23 @@ TEST(HSFTest, vqe10) { "vqe_indep_qiskit_10_no_measure.qasm"}; const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" "out_vqe_indep_qiskit_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); - auto resultDD = hsf.check(); + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.998, + 6); + auto result = hsf.run(); + EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); } TEST(HSFTest, qftNativegates10) { - const qc::QuantumComputation c2{ + const qc::QuantumComputation c1{ "./circuits/approximateEquivalenceTest/check/" "qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; - const qc::QuantumComputation c1{ + const qc::QuantumComputation c2{ "./circuits/approximateEquivalenceTest/check/" "out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); - auto resultDD = hsf.check(); + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.9981, + 6); + auto result = hsf.run(); + EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); } TEST(HSFTest, qpeExact10) { @@ -71,8 +83,10 @@ TEST(HSFTest, qpeExact10) { const qc::QuantumComputation c2{ "./circuits/approximateEquivalenceTest/check/" "out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); - auto resultDD = hsf.check(); + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.9846, + 6); + auto result = hsf.run(); + EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); } TEST(HSFTest, qpeInexact10) { @@ -82,6 +96,8 @@ TEST(HSFTest, qpeInexact10) { const qc::QuantumComputation c2{ "./circuits/approximateEquivalenceTest/check/" "out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 6); - auto resultDD = hsf.check(); + ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.9893, + 6); + auto result = hsf.run(); + EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); } From 4265cce38d3fa7f3cf95daaf594563a3cf33effc Mon Sep 17 00:00:00 2001 From: Theresa Date: Mon, 7 Oct 2024 15:27:27 +0200 Subject: [PATCH 20/38] :rotating_light: Include header --- src/checker/dd/HybridSchrodingerFeynmanChecker.cpp | 2 ++ test/test_hsf.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index f8097a47..96da7c56 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -1,6 +1,7 @@ #include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" #include "Definitions.hpp" +#include "EquivalenceCriterion.hpp" #include "dd/ComplexValue.hpp" #include "dd/DDpackageConfig.hpp" #include "dd/GateMatrixDefinitions.hpp" @@ -12,6 +13,7 @@ #include "ir/operations/StandardOperation.hpp" #include +#include #include #include #include diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index a43af038..d927ec6b 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -1,3 +1,4 @@ +#include "EquivalenceCriterion.hpp" #include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" #include "dd/DDpackageConfig.hpp" #include "ir/QuantumComputation.hpp" From 2918b60786ca4b22c5b19123d62a4ab515651ff5 Mon Sep 17 00:00:00 2001 From: Theresa Date: Wed, 9 Oct 2024 11:17:52 +0200 Subject: [PATCH 21/38] :children_crossing: Incorporate improved error messaging from ddsim --- .../dd/HybridSchrodingerFeynmanChecker.hpp | 1 + .../dd/HybridSchrodingerFeynmanChecker.cpp | 168 ++++++++++-------- 2 files changed, 92 insertions(+), 77 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 955909cc..dcbe6715 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -91,6 +91,7 @@ template class HybridSchrodingerFeynmanChecker final { dd->incRef(matrix); } + // returns true if this operation was a split operation bool apply(std::unique_ptr& sliceDD, const std::unique_ptr& op); }; diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index 96da7c56..d4083be1 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -34,27 +34,51 @@ std::size_t HybridSchrodingerFeynmanChecker::getNDecisions( if (op->getType() == qc::Barrier) { continue; } - if (op->isStandardOperation()) { - bool targetInLowerSlice = false; - bool targetInUpperSlice = false; - bool controlInLowerSlice = false; - bool controlInUpperSlice = false; - for (const auto& target : op->getTargets()) { - targetInLowerSlice = targetInLowerSlice || target < this->splitQubit; - targetInUpperSlice = targetInUpperSlice || target >= this->splitQubit; + assert(op->isStandardOperation()); + + bool targetInLowerSlice = false; + bool targetInUpperSlice = false; + bool controlInLowerSlice = false; + size_t nControlsInLowerSlice = 0; + bool controlInUpperSlice = false; + size_t nControlsInUpperSlice = 0; + for (const auto& target : op->getTargets()) { + targetInLowerSlice = targetInLowerSlice || target < splitQubit; + targetInUpperSlice = targetInUpperSlice || target >= splitQubit; + } + for (const auto& control : op->getControls()) { + if (control.qubit < splitQubit) { + controlInLowerSlice = true; + nControlsInLowerSlice++; + } else { + controlInUpperSlice = true; + nControlsInUpperSlice++; } - for (const auto& control : op->getControls()) { - controlInLowerSlice = controlInLowerSlice || control.qubit < splitQubit; - controlInUpperSlice = - controlInUpperSlice || control.qubit >= splitQubit; + } + + if (targetInLowerSlice && targetInUpperSlice) { + throw std::invalid_argument( + "Multiple targets spread across the cut through the circuit are not " + "supported at the moment as this would require actually computing " + "the Schmidt decomposition of the gate being cut."); + } + + if (targetInLowerSlice && controlInUpperSlice) { + if (nControlsInUpperSlice > 1) { + throw std::invalid_argument( + "Multiple controls in the control part of the gate being cut are " + "not supported at the moment as this would require actually " + "computing the Schmidt decomposition of the gate being cut."); } - if ((targetInLowerSlice && controlInUpperSlice) || - (targetInUpperSlice && controlInLowerSlice)) { - ndecisions++; + ++ndecisions; + } else if (targetInUpperSlice && controlInLowerSlice) { + if (nControlsInLowerSlice > 1) { + throw std::invalid_argument( + "Multiple controls in the control part of the gate being cut are " + "not supported at the moment as this would require actually " + "computing the Schmidt decomposition of the gate being cut."); } - } else { - throw std::invalid_argument( - "Only StandardOperations are supported for now."); + ++ndecisions; } } return ndecisions; @@ -85,76 +109,67 @@ bool HybridSchrodingerFeynmanChecker::Slice::apply( std::unique_ptr& sliceDD, const std::unique_ptr& op) { bool isSplitOp = false; - if (dynamic_cast(op.get()) != - nullptr) { // TODO change control and target if wrong direction - qc::Targets opTargets{}; - qc::Controls opControls{}; - - // check targets - bool targetInSplit = false; - bool targetInOtherSplit = false; - for (const auto& target : op->getTargets()) { - if (start <= target && target <= end) { - opTargets.push_back(target - start); - targetInSplit = true; - } else { - targetInOtherSplit = true; - } - } + assert(op->isStandardOperation()); + // TODO change control and target if wrong direction + qc::Targets opTargets{}; + qc::Controls opControls{}; - if (targetInSplit && targetInOtherSplit && !op->getControls().empty()) { - throw std::invalid_argument("Multiple Targets that are in different " - "slices are not supported at the moment"); + // check targets + bool targetInSplit = false; + bool targetInOtherSplit = false; + for (const auto& target : op->getTargets()) { + if (start <= target && target <= end) { + opTargets.emplace_back(target - start); + targetInSplit = true; + } else { + targetInOtherSplit = true; } + } - // check controls - for (const auto& control : op->getControls()) { - if (start <= control.qubit && control.qubit <= end) { - opControls.emplace(control.qubit - start, control.type); - } else { // other controls are set to the corresponding value - if (targetInSplit) { - isSplitOp = true; - const bool nextControl = getNextControl(); - if ((control.type == qc::Control::Type::Pos && - !nextControl) || // break if control is not activated - (control.type == qc::Control::Type::Neg && nextControl)) { - nDecisionsExecuted++; - return true; - } + // Ensured in the getNDecisions function + assert(!(targetInSplit && targetInOtherSplit)); + + // check controls + for (const auto& control : op->getControls()) { + if (start <= control.qubit && control.qubit <= end) { + opControls.emplace(control.qubit - start, control.type); + } else { // other controls are set to the corresponding value + if (targetInSplit) { + isSplitOp = true; + const bool nextControl = getNextControl(); + // break if control is not activated + if ((control.type == qc::Control::Type::Pos && !nextControl) || + (control.type == qc::Control::Type::Neg && nextControl)) { + nDecisionsExecuted++; + return true; } } } + } - if (targetInOtherSplit && !opControls.empty()) { // control slice for split - if (opControls.size() > 1) { - throw std::invalid_argument( - "Multiple controls in control slice of operation are not supported " - "at the moment"); - } + if (targetInOtherSplit && !opControls.empty()) { // control slice for split + // Ensured in the getNDecisions function + assert(opControls.size() == 1); - isSplitOp = true; - const bool control = getNextControl(); - for (const auto& c : opControls) { - auto tmp = matrix; - auto project = control != (c.type == qc::Control::Type::Neg) ? 0 : 1; - auto projMatrix = project == 1 - ? sliceDD->makeGateDD(dd::MEAS_ZERO_MAT, c.qubit) - : sliceDD->makeGateDD(dd::MEAS_ONE_MAT, c.qubit); - matrix = sliceDD->multiply(projMatrix, matrix); - sliceDD->incRef(matrix); - sliceDD->decRef(tmp); - } - } else if (targetInSplit) { // target slice for split or operation in split - const auto& param = op->getParameter(); - qc::StandardOperation newOp(opControls, opTargets, op->getType(), param); + isSplitOp = true; + const bool control = getNextControl(); + for (const auto& c : opControls) { auto tmp = matrix; - matrix = sliceDD->multiply(dd::getDD(&newOp, *sliceDD), matrix); + auto project = control != (c.type == qc::Control::Type::Neg) ? 0 : 1; + auto projMatrix = project == 1 + ? sliceDD->makeGateDD(dd::MEAS_ZERO_MAT, c.qubit) + : sliceDD->makeGateDD(dd::MEAS_ONE_MAT, c.qubit); + matrix = sliceDD->multiply(projMatrix, matrix); sliceDD->incRef(matrix); sliceDD->decRef(tmp); } - } else { - throw std::invalid_argument( - "Only StandardOperations are supported for now."); + } else if (targetInSplit) { // target slice for split or operation in split + const auto& param = op->getParameter(); + qc::StandardOperation newOp(opControls, opTargets, op->getType(), param); + auto tmp = matrix; + matrix = sliceDD->multiply(dd::getDD(&newOp, *sliceDD), matrix); + sliceDD->incRef(matrix); + sliceDD->decRef(tmp); } if (isSplitOp) { nDecisionsExecuted++; @@ -205,7 +220,6 @@ HybridSchrodingerFeynmanChecker::checkEquivalence() { }); } executor.wait_for_all(); - if (std::abs(trace.mag() - 1.) < traceThreshold) { return EquivalenceCriterion::Equivalent; } From 4d27272f209d3e157be54ba0d9c1d80f198c7f44 Mon Sep 17 00:00:00 2001 From: Theresa Date: Wed, 9 Oct 2024 15:29:53 +0200 Subject: [PATCH 22/38] :bug: Fix: Throw overflow error when circuit exceeds maximum number of decisions --- include/checker/dd/HybridSchrodingerFeynmanChecker.hpp | 2 +- src/checker/dd/HybridSchrodingerFeynmanChecker.cpp | 5 +++++ test/test_hsf.cpp | 10 ++++------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index dcbe6715..d08bb451 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -68,7 +68,7 @@ template class HybridSchrodingerFeynmanChecker final { class Slice { protected: - qc::Qubit nextControlIdx = 0; + std::uint64_t nextControlIdx = 0; std::size_t getNextControl() { std::size_t idx = 1UL << nextControlIdx; diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index d4083be1..c145b8e9 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -13,6 +13,7 @@ #include "ir/operations/StandardOperation.hpp" #include +#include #include #include #include @@ -190,6 +191,10 @@ template EquivalenceCriterion HybridSchrodingerFeynmanChecker::checkEquivalence() { const auto ndecisions = getNDecisions(*qc1) + getNDecisions(*qc2); + if (ndecisions > 63) { + throw std::overflow_error( + "Number of split operations exceeds the maximum allowed number of 63."); + } const auto maxControl = 1ULL << ndecisions; const auto actuallyUsedThreads = std::min(maxControl, nthreads); const auto chunkSize = static_cast( diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index d927ec6b..3a7455fd 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -4,6 +4,7 @@ #include "ir/QuantumComputation.hpp" #include +#include #include TEST(HSFTest, dj10) { @@ -73,8 +74,7 @@ TEST(HSFTest, qftNativegates10) { "out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.9981, 6); - auto result = hsf.run(); - EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); + EXPECT_THROW(hsf.run(), std::overflow_error); } TEST(HSFTest, qpeExact10) { @@ -86,8 +86,7 @@ TEST(HSFTest, qpeExact10) { "out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.9846, 6); - auto result = hsf.run(); - EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); + EXPECT_THROW(hsf.run(), std::overflow_error); } TEST(HSFTest, qpeInexact10) { @@ -99,6 +98,5 @@ TEST(HSFTest, qpeInexact10) { "out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.9893, 6); - auto result = hsf.run(); - EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); + EXPECT_THROW(hsf.run(), std::overflow_error); } From 7d2386ae9aed8f9a6c0e7bcf4d2f6a93deb6aea5 Mon Sep 17 00:00:00 2001 From: Theresa Date: Wed, 9 Oct 2024 15:37:49 +0200 Subject: [PATCH 23/38] :rotating_light: Fix linter warning --- include/checker/dd/HybridSchrodingerFeynmanChecker.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index d08bb451..6459d038 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -10,6 +10,7 @@ #include #include +#include #include namespace ec { From 1e80d635f1dd3959d67999b63dba7c7dd4cd15da Mon Sep 17 00:00:00 2001 From: Theresa Date: Wed, 9 Oct 2024 21:13:46 +0200 Subject: [PATCH 24/38] :memo: Add comments --- .../dd/HybridSchrodingerFeynmanChecker.hpp | 99 +++++++++++++++++-- .../dd/HybridSchrodingerFeynmanChecker.cpp | 12 +-- test/test_hsf.cpp | 7 ++ 3 files changed, 104 insertions(+), 14 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 6459d038..9b2e72f0 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -14,6 +14,26 @@ #include namespace ec { +/** + * @brief Approximate Equivalence Checking with the + * HybridSchrodingerFeynmanChecker This checker divides a circuit horizontally + * into two halves: a lower part and an upper part. This is achieved by cutting + * controlled gates that cross the middle line according to the Schmidt + * decomposition. By leveraging key trace equalities - specifically, + * + * tr[L ⊗ U] = tr[L] ⋅ tr[U] + * + * and + * + * tr[A + B] = tr[A] + tr[B], + * + * we can treat the lower and upper circuit parts, as well as the summands from + * the Schmidt decomposition, independently. This enables parallel trace + * computation, allowing to check the equivalence of larger, yet shallow + * circuits. + * @note Only suitable for shallow circuits with a maximum number of 63 + * controlled gates crossing the middle line (decisions). + */ template class HybridSchrodingerFeynmanChecker final { public: HybridSchrodingerFeynmanChecker(const qc::QuantumComputation& circ1, @@ -24,7 +44,8 @@ template class HybridSchrodingerFeynmanChecker final { nthreads(nThreads) { if (this->qc1->getNqubits() != this->qc2->getNqubits()) { throw std::invalid_argument( - "The two circuits have a different number of qubits."); + "The two circuits have a different number of qubits and cannot be " + "checked for equivalence."); } splitQubit = static_cast(this->qc1->getNqubits() / 2); } @@ -41,19 +62,63 @@ template class HybridSchrodingerFeynmanChecker final { using DDPackage = typename dd::Package; + /** + * @brief Computing the Frobenius inner product trace(U * V^-1) and comparing + * it to the desired threshold. + * @return EquivalenceCriterion Returns `Equivalent` if the result is below + * the `traceThreshold`, `NotEquivalent´ otherwise. + */ EquivalenceCriterion checkEquivalence(); - // Get # of decisions for given split_qubit, so that lower slice: q0 < i < - // qubit; upper slice: qubit <= i < nqubits + /** + * @brief Get # of decisions for given split_qubit, so that lower slice: q0 < + * i < qubit; upper slice: qubit <= i < nqubits + * @details The number of decisions is determined by the number of controlled + * gates that cross the middle line. + * @param qc + * @return std::size_t + */ [[nodiscard]] std::size_t getNDecisions(const qc::QuantumComputation& qc) const; + /** + * @brief Computes the trace for the i-th summand after applying the Schmidt + * decomposition for all control decisions. + * + * @details The Schmidt decomposition allows decomposing a controlled gate + * into a sum of circuits, each consisting of only single-qubit gates. By + * recursively applying this decomposition to all decisions, we generate a + * total of 2^decisions circuits, which do not contain controlled operations + * crossing the middle line. This enables independent investigation of the + * lower and upper circuit parts. + * + * This function computes the trace for the i-th summand, where the index 'i' + * determines, for each gate, whether the 0 or 1 projection is considered. See + * getNextControl() and apply() for more details on how these projections are + * managed. + * + * @param sliceDD1 Decision diagram for the lower circuit part. + * @param sliceDD2 Decision diagram for the upper circuit part. + * @param i Index of the summand for which the trace is computed. + * @return dd::ComplexValue Returns the trace value for the specified summand. + */ dd::ComplexValue simulateSlicing(std::unique_ptr& sliceDD1, std::unique_ptr& sliceDD2, - std::size_t controls); + std::size_t i); class Slice; + /** + * @brief Applies a single operation to the lower and upper circuit parts + * according to the Schmidt decomposition, for the summand specified by + * `controlIdx` from the class Slice. + * + * @param sliceDD1 Decision diagram for the lower circuit part. + * @param sliceDD2 Decision diagram for the upper circuit part. + * @param op Current operation to be applied + * @param lower + * @param upper + */ static void applyLowerUpper(std::unique_ptr& sliceDD1, std::unique_ptr& sliceDD2, const std::unique_ptr& op, @@ -71,28 +136,46 @@ template class HybridSchrodingerFeynmanChecker final { protected: std::uint64_t nextControlIdx = 0; + /** + * @brief Determines how the current operation is decomposed for the summand + * at index `controlIdx`. + * @details nextControlIdx tracks the number of operations processed so far. + * By comparing the shifted value to the bits of `controlIdx`, we can + * determine how the current operation should be decomposed for the summand + * at index `controlIdx`. + * @return std::size_t + */ std::size_t getNextControl() { std::size_t idx = 1UL << nextControlIdx; nextControlIdx++; - return controls & idx; + return controlIdx & idx; } public: qc::Qubit start; qc::Qubit end; - std::size_t controls; + std::size_t controlIdx; qc::Qubit nqubits; std::size_t nDecisionsExecuted = 0; qc::MatrixDD matrix{}; explicit Slice(std::unique_ptr& dd, const qc::Qubit startQ, const qc::Qubit endQ, const std::size_t controlQ) - : start(startQ), end(endQ), controls(controlQ), + : start(startQ), end(endQ), controlIdx(controlQ), nqubits(end - start + 1), matrix(dd->makeIdent()) { dd->incRef(matrix); } - // returns true if this operation was a split operation + /** + * @brief Applies the decomposition of the current operation, based on the + * summand index `controlIdx`, to the decision diagram of the specified + * circuit slice. + * + * @param sliceDD Decision diagram for the lower or upper circuit part. + * @param op + * @return bool Returns true if the operation is a split operation, false + * otherwise. + */ bool apply(std::unique_ptr& sliceDD, const std::unique_ptr& op); }; diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index c145b8e9..5b1af9a8 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -88,13 +88,15 @@ std::size_t HybridSchrodingerFeynmanChecker::getNDecisions( template dd::ComplexValue HybridSchrodingerFeynmanChecker::simulateSlicing( std::unique_ptr>& sliceDD1, - std::unique_ptr>& sliceDD2, size_t controls) { - Slice lower(sliceDD1, 0, splitQubit - 1, controls); + std::unique_ptr>& sliceDD2, size_t i) { + Slice lower(sliceDD1, 0, splitQubit - 1, i); Slice upper(sliceDD2, splitQubit, - static_cast(this->qc1->getNqubits() - 1), controls); + static_cast(this->qc1->getNqubits() - 1), i); for (const auto& op : *this->qc1) { applyLowerUpper(sliceDD1, sliceDD2, op, lower, upper); } + // Invert the second circuit by iterating through the operations in reverse + // order and inverting each one for (auto it = this->qc2->rbegin(); it != this->qc2->rend(); ++it) { auto opInv = it->get()->getInverted(); applyLowerUpper(sliceDD1, sliceDD2, opInv, lower, upper); @@ -111,7 +113,6 @@ bool HybridSchrodingerFeynmanChecker::Slice::apply( const std::unique_ptr& op) { bool isSplitOp = false; assert(op->isStandardOperation()); - // TODO change control and target if wrong direction qc::Targets opTargets{}; qc::Controls opControls{}; @@ -156,8 +157,7 @@ bool HybridSchrodingerFeynmanChecker::Slice::apply( const bool control = getNextControl(); for (const auto& c : opControls) { auto tmp = matrix; - auto project = control != (c.type == qc::Control::Type::Neg) ? 0 : 1; - auto projMatrix = project == 1 + auto projMatrix = control == (c.type == qc::Control::Type::Neg) ? sliceDD->makeGateDD(dd::MEAS_ZERO_MAT, c.qubit) : sliceDD->makeGateDD(dd::MEAS_ONE_MAT, c.qubit); matrix = sliceDD->multiply(projMatrix, matrix); diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 3a7455fd..17f2faff 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -7,6 +7,13 @@ #include #include +/** + * Approximate equivalence checking of an original circuit 'c1' and its + * approximate version 'c2'. The circuits 'c2' were generated using the BQSKit + * compiler with synthesis_epsilon=0.3 and error_threshold=0.5. + * + */ + TEST(HSFTest, dj10) { const qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" "dj_indep_qiskit_10_no_measure.qasm"}; From 56705599825a61e5a25c7b83d1b8595786dc167b Mon Sep 17 00:00:00 2001 From: Theresa Date: Fri, 11 Oct 2024 10:03:40 +0200 Subject: [PATCH 25/38] :zap: :art: Move inversion of qc2 to constructor and flatten operations - Invert qc2 only once and not in each decision iteration --- .../dd/HybridSchrodingerFeynmanChecker.hpp | 28 +++++++++++++------ .../dd/HybridSchrodingerFeynmanChecker.cpp | 13 ++++----- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 9b2e72f0..28752e98 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -2,6 +2,7 @@ #include "Definitions.hpp" #include "EquivalenceCriterion.hpp" +#include "circuit_optimizer/CircuitOptimizer.hpp" #include "dd/ComplexValue.hpp" #include "dd/Package.hpp" #include "dd/Package_fwd.hpp" @@ -40,21 +41,33 @@ template class HybridSchrodingerFeynmanChecker final { const qc::QuantumComputation& circ2, const double threshold, const std::size_t nThreads) - : qc1(&circ1), qc2(&circ2), traceThreshold(threshold), - nthreads(nThreads) { - if (this->qc1->getNqubits() != this->qc2->getNqubits()) { + : qc1(std::make_unique(circ1)), + qc2Inverted(std::make_unique()), + traceThreshold(threshold), nthreads(nThreads) { + if (circ1.getNqubits() != circ2.getNqubits()) { throw std::invalid_argument( "The two circuits have a different number of qubits and cannot be " "checked for equivalence."); } - splitQubit = static_cast(this->qc1->getNqubits() / 2); + + // Invert the second circuit by iterating through the operations in reverse + // order and inverting each one + for (auto it = circ2.rbegin(); it != circ2.rend(); ++it) { + qc2Inverted->emplace_back(it->get()->getInverted()); + } + + // Flatten the operations of the circuits + qc::CircuitOptimizer::flattenOperations(*qc1); + qc::CircuitOptimizer::flattenOperations(*qc2Inverted); + + splitQubit = static_cast((&circ1)->getNqubits() / 2); } EquivalenceCriterion run(); private: - qc::QuantumComputation const* qc1; - qc::QuantumComputation const* qc2; + std::unique_ptr qc1; + std::unique_ptr qc2Inverted; double traceThreshold = 1e-8; std::size_t nthreads = 2; qc::Qubit splitQubit; @@ -78,8 +91,7 @@ template class HybridSchrodingerFeynmanChecker final { * @param qc * @return std::size_t */ - [[nodiscard]] std::size_t - getNDecisions(const qc::QuantumComputation& qc) const; + [[nodiscard]] std::size_t getNDecisions(qc::QuantumComputation& qc) const; /** * @brief Computes the trace for the i-th summand after applying the Schmidt diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index 5b1af9a8..d55e99f3 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -28,7 +28,7 @@ namespace ec { template std::size_t HybridSchrodingerFeynmanChecker::getNDecisions( - const qc::QuantumComputation& qc) const { + qc::QuantumComputation& qc) const { std::size_t ndecisions = 0; // calculate number of decisions for (const auto& op : qc) { @@ -92,14 +92,11 @@ dd::ComplexValue HybridSchrodingerFeynmanChecker::simulateSlicing( Slice lower(sliceDD1, 0, splitQubit - 1, i); Slice upper(sliceDD2, splitQubit, static_cast(this->qc1->getNqubits() - 1), i); - for (const auto& op : *this->qc1) { + for (const auto& op : *qc1) { applyLowerUpper(sliceDD1, sliceDD2, op, lower, upper); } - // Invert the second circuit by iterating through the operations in reverse - // order and inverting each one - for (auto it = this->qc2->rbegin(); it != this->qc2->rend(); ++it) { - auto opInv = it->get()->getInverted(); - applyLowerUpper(sliceDD1, sliceDD2, opInv, lower, upper); + for (const auto& op : *qc2Inverted) { + applyLowerUpper(sliceDD1, sliceDD2, op, lower, upper); } auto traceLower = sliceDD1->trace(lower.matrix, lower.nqubits); auto traceUpper = sliceDD2->trace(upper.matrix, upper.nqubits); @@ -190,7 +187,7 @@ EquivalenceCriterion HybridSchrodingerFeynmanChecker::run() { template EquivalenceCriterion HybridSchrodingerFeynmanChecker::checkEquivalence() { - const auto ndecisions = getNDecisions(*qc1) + getNDecisions(*qc2); + const auto ndecisions = getNDecisions(*qc1) + getNDecisions(*qc2Inverted); if (ndecisions > 63) { throw std::overflow_error( "Number of split operations exceeds the maximum allowed number of 63."); From 6b9a709760d82b8ec9ca91e88f06d999952a0081 Mon Sep 17 00:00:00 2001 From: Theresa Date: Fri, 11 Oct 2024 10:59:55 +0200 Subject: [PATCH 26/38] :bug: Fix: Skip measure and barrier ops for inversion. --- .../dd/HybridSchrodingerFeynmanChecker.hpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 28752e98..411513da 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -7,6 +7,7 @@ #include "dd/Package.hpp" #include "dd/Package_fwd.hpp" #include "ir/QuantumComputation.hpp" +#include "ir/operations/OpType.hpp" #include "memory" #include @@ -50,16 +51,19 @@ template class HybridSchrodingerFeynmanChecker final { "checked for equivalence."); } - // Invert the second circuit by iterating through the operations in reverse - // order and inverting each one - for (auto it = circ2.rbegin(); it != circ2.rend(); ++it) { - qc2Inverted->emplace_back(it->get()->getInverted()); - } - // Flatten the operations of the circuits qc::CircuitOptimizer::flattenOperations(*qc1); qc::CircuitOptimizer::flattenOperations(*qc2Inverted); + // Invert the second circuit by iterating through the operations in reverse + // order and inverting each one - except for Measure and Barrier operations + for (auto it = circ2.rbegin(); it != circ2.rend(); ++it) { + if (it->get()->getType() != qc::Measure && + it->get()->getType() != qc::Barrier) { + qc2Inverted->emplace_back(it->get()->getInverted()); + } + } + splitQubit = static_cast((&circ1)->getNqubits() / 2); } From afa1cbc66acd7c6a3fdc8509bf598e1397ab5790 Mon Sep 17 00:00:00 2001 From: Theresa Date: Fri, 25 Oct 2024 18:55:34 +0200 Subject: [PATCH 27/38] :sparkles: Expose approximate equivalence checking to Python --- include/EquivalenceCheckingManager.hpp | 8 ++- src/Configuration.cpp | 4 ++ src/mqt/qcec/configuration.py | 2 + src/mqt/qcec/pyqcec.pyi | 4 ++ src/python/bindings.cpp | 42 +++++++++++++++- test/python/test_approximate_equivalence.py | 56 +++++++++++++++++++++ 6 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 test/python/test_approximate_equivalence.py diff --git a/include/EquivalenceCheckingManager.hpp b/include/EquivalenceCheckingManager.hpp index 2ce213df..d57262ab 100644 --- a/include/EquivalenceCheckingManager.hpp +++ b/include/EquivalenceCheckingManager.hpp @@ -219,10 +219,16 @@ class EquivalenceCheckingManager { void setTraceThreshold(double traceThreshold) { configuration.functionality.traceThreshold = traceThreshold; } + void setApproximateCheckingThreshold(double approximateCheckingThreshold) { + configuration.functionality.approximateCheckingThreshold = + approximateCheckingThreshold; + } void setCheckPartialEquivalence(bool checkPE) { configuration.functionality.checkPartialEquivalence = checkPE; } - + void setCheckApproximateEquivalence(bool checkAE) { + configuration.functionality.checkApproximateEquivalence = checkAE; + } // Simulation: These setting may be changed to adjust the kinds of simulations // that are performed void setFidelityThreshold(double fidelityThreshold) { diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 3a1d6dae..8730be4c 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -106,7 +106,11 @@ nlohmann::basic_json<> Configuration::json() const { if (execution.runConstructionChecker || execution.runAlternatingChecker) { auto& fun = config["functionality"]; fun["trace_threshold"] = functionality.traceThreshold; + fun["approximate_checking_threshold"] = + functionality.approximateCheckingThreshold; fun["check_partial_equivalence"] = functionality.checkPartialEquivalence; + fun["check_approximate_equivalence"] = + functionality.checkApproximateEquivalence; } if (execution.runSimulationChecker) { diff --git a/src/mqt/qcec/configuration.py b/src/mqt/qcec/configuration.py index 54884455..9edc48af 100644 --- a/src/mqt/qcec/configuration.py +++ b/src/mqt/qcec/configuration.py @@ -32,7 +32,9 @@ class ConfigurationOptions(TypedDict, total=False): timeout: float # Functionality trace_threshold: float + approximate_checking_threshold: float check_partial_equivalence: bool + check_approximate_equivalence: bool # Optimizations backpropagate_output_permutation: bool elide_permutations: bool diff --git a/src/mqt/qcec/pyqcec.pyi b/src/mqt/qcec/pyqcec.pyi index 46ff207d..cc57ec20 100644 --- a/src/mqt/qcec/pyqcec.pyi +++ b/src/mqt/qcec/pyqcec.pyi @@ -48,7 +48,9 @@ class Configuration: class Functionality: trace_threshold: float + approximate_checking_threshold: float check_partial_equivalence: bool + check_approximate_equivalence: bool def __init__(self) -> None: ... class Optimizations: @@ -144,7 +146,9 @@ class EquivalenceCheckingManager: def set_timeout(self, timeout: float = ...) -> None: ... def set_tolerance(self, tolerance: float = ...) -> None: ... def set_trace_threshold(self, threshold: float = ...) -> None: ... + def set_approximate_checking_threshold(self, threshold: float = ...) -> None: ... def set_check_partial_equivalence(self, enable: bool = ...) -> None: ... + def set_check_approximate_equivalence(self, enable: bool = ...) -> None: ... def set_zx_checker(self, enable: bool = ...) -> None: ... def store_cex_input(self, enable: bool = ...) -> None: ... def store_cex_output(self, enable: bool = ...) -> None: ... diff --git a/src/python/bindings.cpp b/src/python/bindings.cpp index 3ede11df..841fb351 100644 --- a/src/python/bindings.cpp +++ b/src/python/bindings.cpp @@ -322,6 +322,12 @@ PYBIND11_MODULE(pyqcec, m, py::mod_gil_not_used()) { "Set the :attr:`trace threshold " "<.Configuration.Functionality.trace_threshold>` used for comparing " "two unitaries or functionality matrices.") + .def("set_approximate_checking_threshold", + &EquivalenceCheckingManager::setApproximateCheckingThreshold, + "threshold"_a = 1e-8, + "Set the :attr:`approximate checking threshold " + "<.Configuration.Functionality.approximate_checking_threshold>` " + "used for approximate equivalence checking.") .def( "set_check_partial_equivalence", &EquivalenceCheckingManager::setCheckPartialEquivalence, @@ -331,6 +337,16 @@ PYBIND11_MODULE(pyqcec, m, py::mod_gil_not_used()) { "they have the same probability for each measurement outcome. " "If set to false, the checker will output 'not equivalent' for " "circuits that are partially equivalent but not totally equivalent. ") + .def("set_check_approximate_equivalence", + &EquivalenceCheckingManager::setCheckApproximateEquivalence, + "enable"_a = false, + "Set whether to check for approximate equivalence. Two circuits are " + "approximately equivalent if the Hilbert-Schmidt inner product " + "(process distance) of the two circuits is less than the " + "approximate_checking_threshold. " + "If set to false, the checker will output 'not equivalent' for " + "circuits that are approximately equivalent but not totally " + "equivalent. ") // Simulation .def("set_fidelity_threshold", &EquivalenceCheckingManager::setFidelityThreshold, @@ -668,6 +684,15 @@ PYBIND11_MODULE(pyqcec, m, py::mod_gil_not_used()) { "Whenever any decision diagram node differs from this structure by " "more than the configured threshold, the circuits are concluded to " "be non-equivalent. Defaults to :code:`1e-8`.") + .def_readwrite( + "approximate_checking_threshold", + &Configuration::Functionality::approximateCheckingThreshold, + "To determine approximate equivalence, the Hilbert-Schmidt inner " + "product (or process distance) between two circuit representations " + "is calculated and compared against the " + "approximate_checking_threshold. If the process distance falls below " + "this threshold, the circuits are considered approximately " + "equivalent. Defaults to :code:`1e-8`.") .def_readwrite( "check_partial_equivalence", &Configuration::Functionality::checkPartialEquivalence, @@ -679,6 +704,21 @@ PYBIND11_MODULE(pyqcec, m, py::mod_gil_not_used()) { "output 'not equivalent' for circuits that are partially equivalent " "but not totally equivalent. In particular, garbage qubits will be " "treated as if they were measured qubits. Defaults to " + ":code:`False`.") + .def_readwrite( + "check_approximate_equivalence", + &Configuration::Functionality::checkApproximateEquivalence, + "To determine approximate equivalence, the Hilbert-Schmidt inner " + "product (or process distance) between two circuit representations " + "is calculated and compared against the " + "approximate_checking_threshold. If the process distance falls below " + "this threshold, the circuits are considered approximately " + "equivalent. If set to :code:`True`, a check for approximate " + "equivalence " + "will be performed. If set to :code:`False`, the checker will " + "output 'not equivalent' for circuits that are approximately " + "equivalent " + "but not totally equivalent. Defaults to " ":code:`False`."); // simulation options @@ -752,5 +792,5 @@ PYBIND11_MODULE(pyqcec, m, py::mod_gil_not_used()) { "to simpler equivalence checking instances as the random " "instantiation. This option " "changes how many of those additional checks are performed."); -} +}; } // namespace ec diff --git a/test/python/test_approximate_equivalence.py b/test/python/test_approximate_equivalence.py new file mode 100644 index 00000000..c57261b8 --- /dev/null +++ b/test/python/test_approximate_equivalence.py @@ -0,0 +1,56 @@ +"""Tests the partial equivalence checking support of QCEC.""" + +from __future__ import annotations + +import pytest +from qiskit import QuantumCircuit + +from mqt import qcec + + +@pytest.fixture +def original_circuit() -> QuantumCircuit: + """Fixture for a simple circuit.""" + qc = QuantumCircuit(3) + qc.mcx([0, 1], 2) + return qc + + +@pytest.fixture +def alternative_circuit() -> QuantumCircuit: + """Fixture for an approximately equivalent version of the simple circuit.""" + qc = QuantumCircuit(3) + qc.id(0) + qc.id(1) + qc.id(2) + return qc + + +def test_configuration_pec(original_circuit: QuantumCircuit, alternative_circuit: QuantumCircuit) -> None: + """Test if the flag for approximate equivalence checking works.""" + config = qcec.Configuration() + config.execution.run_alternating_checker = True + config.execution.run_construction_checker = False + config.execution.run_simulation_checker = False + config.execution.run_zx_checker = False + config.functionality.check_approximate_equivalence = True + config.functionality.approximate_checking_threshold = 0.3 + result = qcec.verify(original_circuit, alternative_circuit, configuration=config) + assert result.equivalence == qcec.EquivalenceCriterion.equivalent + + +def test_argument_pec(original_circuit: QuantumCircuit, alternative_circuit: QuantumCircuit) -> None: + """Test if the flag for approximate equivalence checking works.""" + config = qcec.Configuration() + config.execution.run_alternating_checker = True + config.execution.run_construction_checker = False + config.execution.run_simulation_checker = False + config.execution.run_zx_checker = False + result = qcec.verify( + original_circuit, + alternative_circuit, + configuration=config, + check_approximate_equivalence=True, + approximate_checking_threshold=0.3, + ) + assert result.equivalence == qcec.EquivalenceCriterion.equivalent From 1cc72492c278d12031bac7c658ee17a945ac68be Mon Sep 17 00:00:00 2001 From: Theresa Date: Sat, 26 Oct 2024 15:12:14 +0200 Subject: [PATCH 28/38] :art: Integrate HSF checker into equivalence checking flow --- include/Configuration.hpp | 1 + include/EquivalenceCheckingManager.hpp | 2 + .../dd/HybridSchrodingerFeynmanChecker.hpp | 46 +++--- src/Configuration.cpp | 20 ++- src/EquivalenceCheckingManager.cpp | 38 +++++ .../dd/HybridSchrodingerFeynmanChecker.cpp | 36 ++-- src/python/bindings.cpp | 7 + test/legacy/test_functionality.cpp | 1 + test/legacy/test_general.cpp | 1 + test/legacy/test_journal.cpp | 3 + test/test_hsf.cpp | 155 +++++++++++------- test/test_partial_equivalence.cpp | 1 + test/test_zx.cpp | 4 + 13 files changed, 206 insertions(+), 109 deletions(-) diff --git a/include/Configuration.hpp b/include/Configuration.hpp index 3f4bb34b..ff7156fb 100644 --- a/include/Configuration.hpp +++ b/include/Configuration.hpp @@ -33,6 +33,7 @@ class Configuration { bool runSimulationChecker = true; bool runAlternatingChecker = true; bool runZXChecker = true; + bool runHSFChecker = false; }; // configuration options for pre-check optimizations diff --git a/include/EquivalenceCheckingManager.hpp b/include/EquivalenceCheckingManager.hpp index d57262ab..ca7bcad9 100644 --- a/include/EquivalenceCheckingManager.hpp +++ b/include/EquivalenceCheckingManager.hpp @@ -139,12 +139,14 @@ class EquivalenceCheckingManager { configuration.execution.runAlternatingChecker = run; } void setZXChecker(bool run) { configuration.execution.runZXChecker = run; } + void setHSFChecker(bool run) { configuration.execution.runHSFChecker = run; } void disableAllCheckers() { configuration.execution.runConstructionChecker = false; configuration.execution.runZXChecker = false; configuration.execution.runSimulationChecker = false; configuration.execution.runAlternatingChecker = false; + configuration.execution.runHSFChecker = false; } // Optimization: Optimizations are applied during initialization. Already diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 411513da..80b684e9 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -1,5 +1,7 @@ #pragma once +#include "Configuration.hpp" +#include "DDEquivalenceChecker.hpp" #include "Definitions.hpp" #include "EquivalenceCriterion.hpp" #include "circuit_optimizer/CircuitOptimizer.hpp" @@ -36,15 +38,15 @@ namespace ec { * @note Only suitable for shallow circuits with a maximum number of 63 * controlled gates crossing the middle line (decisions). */ -template class HybridSchrodingerFeynmanChecker final { +class HybridSchrodingerFeynmanChecker final + : public DDEquivalenceChecker { public: HybridSchrodingerFeynmanChecker(const qc::QuantumComputation& circ1, const qc::QuantumComputation& circ2, - const double threshold, - const std::size_t nThreads) - : qc1(std::make_unique(circ1)), - qc2Inverted(std::make_unique()), - traceThreshold(threshold), nthreads(nThreads) { + ec::Configuration config) + : DDEquivalenceChecker(circ1, circ2, std::move(config)), + qc1(std::make_unique(circ1)), + qc2Inverted(std::make_unique()) { if (circ1.getNqubits() != circ2.getNqubits()) { throw std::invalid_argument( "The two circuits have a different number of qubits and cannot be " @@ -65,19 +67,29 @@ template class HybridSchrodingerFeynmanChecker final { } splitQubit = static_cast((&circ1)->getNqubits() / 2); + initializeApplicationScheme( + this->configuration.application.alternatingScheme); } + EquivalenceCriterion run() override; - EquivalenceCriterion run(); + void json(nlohmann::json& j) const noexcept override; + + /** + * @brief Get # of decisions for given split_qubit, so that lower slice: q0 < + * i < qubit; upper slice: qubit <= i < nqubits + * @details The number of decisions is determined by the number of controlled + * gates that cross the middle line. + * @param qc + * @return std::size_t + */ + [[nodiscard]] std::size_t getNDecisions(qc::QuantumComputation& qc) const; private: std::unique_ptr qc1; std::unique_ptr qc2Inverted; - double traceThreshold = 1e-8; - std::size_t nthreads = 2; qc::Qubit splitQubit; - double runtime{}; - using DDPackage = typename dd::Package; + using DDPackage = typename dd::Package; /** * @brief Computing the Frobenius inner product trace(U * V^-1) and comparing @@ -85,17 +97,7 @@ template class HybridSchrodingerFeynmanChecker final { * @return EquivalenceCriterion Returns `Equivalent` if the result is below * the `traceThreshold`, `NotEquivalent´ otherwise. */ - EquivalenceCriterion checkEquivalence(); - - /** - * @brief Get # of decisions for given split_qubit, so that lower slice: q0 < - * i < qubit; upper slice: qubit <= i < nqubits - * @details The number of decisions is determined by the number of controlled - * gates that cross the middle line. - * @param qc - * @return std::size_t - */ - [[nodiscard]] std::size_t getNDecisions(qc::QuantumComputation& qc) const; + EquivalenceCriterion checkEquivalence() override; /** * @brief Computes the trace for the i-th summand after applying the Schmidt diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 8730be4c..34ab432e 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -15,25 +15,28 @@ namespace ec { bool Configuration::anythingToExecute() const noexcept { return (execution.runSimulationChecker && simulation.maxSims > 0U) || execution.runAlternatingChecker || execution.runConstructionChecker || - execution.runZXChecker; + execution.runZXChecker || + (execution.runHSFChecker && functionality.checkApproximateEquivalence); } bool Configuration::onlySingleTask() const noexcept { // only a single simulation shall be performed if (execution.runSimulationChecker && (simulation.maxSims == 1U) && !execution.runAlternatingChecker && !execution.runConstructionChecker && - !execution.runZXChecker) { + !execution.runZXChecker && !execution.runHSFChecker) { return true; } // no simulations and only one of the other checks shall be performed if (!execution.runSimulationChecker && ((execution.runAlternatingChecker && !execution.runConstructionChecker && - !execution.runZXChecker) || + !execution.runZXChecker && !execution.runHSFChecker) || (!execution.runAlternatingChecker && execution.runConstructionChecker && - !execution.runZXChecker) || + !execution.runZXChecker && !execution.runHSFChecker) || (!execution.runAlternatingChecker && !execution.runConstructionChecker && - execution.runZXChecker))) { + execution.runZXChecker && !execution.runHSFChecker) || + (!execution.runAlternatingChecker && !execution.runConstructionChecker && + !execution.runZXChecker && execution.runHSFChecker))) { return true; } @@ -42,12 +45,14 @@ bool Configuration::onlySingleTask() const noexcept { bool Configuration::onlyZXCheckerConfigured() const noexcept { return !execution.runConstructionChecker && !execution.runSimulationChecker && - !execution.runAlternatingChecker && execution.runZXChecker; + !execution.runAlternatingChecker && execution.runZXChecker && + !execution.runHSFChecker; } bool Configuration::onlySimulationCheckerConfigured() const noexcept { return !execution.runConstructionChecker && execution.runSimulationChecker && - !execution.runAlternatingChecker && !execution.runZXChecker; + !execution.runAlternatingChecker && !execution.runZXChecker && + !execution.runHSFChecker; } nlohmann::basic_json<> Configuration::json() const { @@ -64,6 +69,7 @@ nlohmann::basic_json<> Configuration::json() const { exe["run_simulation_checker"] = execution.runSimulationChecker; exe["run_alternating_checker"] = execution.runAlternatingChecker; exe["run_zx_checker"] = execution.runZXChecker; + exe["run_hsf_checker"] = execution.runHSFChecker; if (execution.timeout > 0.) { exe["timeout"] = execution.timeout; } diff --git a/src/EquivalenceCheckingManager.cpp b/src/EquivalenceCheckingManager.cpp index dd4614c7..4d48a707 100644 --- a/src/EquivalenceCheckingManager.cpp +++ b/src/EquivalenceCheckingManager.cpp @@ -11,6 +11,7 @@ #include "checker/dd/DDAlternatingChecker.hpp" #include "checker/dd/DDConstructionChecker.hpp" #include "checker/dd/DDSimulationChecker.hpp" +#include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" #include "checker/dd/simulation/StateType.hpp" #include "checker/zx/ZXChecker.hpp" #include "circuit_optimizer/CircuitOptimizer.hpp" @@ -380,6 +381,15 @@ EquivalenceCheckingManager::EquivalenceCheckingManager( "inputs! Proceed with caution!\n"; } + if (!configuration.functionality.checkApproximateEquivalence && + configuration.execution.runHSFChecker) { + std::clog + << "[QCEC] Warning: The HSF checker performs approximate, not exact, " + "equivalence checking. The HSF checker has been disabled. Set " + "'checkApproximateEquivalence' to True to enable it.\n"; + this->configuration.execution.runHSFChecker = false; + } + // check whether the alternating checker is configured and can handle the // circuits if (configuration.execution.runAlternatingChecker && @@ -524,6 +534,24 @@ void EquivalenceCheckingManager::checkSequential() { } } + if (configuration.execution.runHSFChecker && !done) { + checkers.emplace_back(std::make_unique( + qc1, qc2, configuration)); + const auto& hsfChecker = checkers.back(); + if (!done) { + const auto result = hsfChecker->run(); + + // if the hsf check produces a result, this is final + if (result != EquivalenceCriterion::NoInformation) { + results.equivalence = result; + + // everything is done + done = true; + doneCond.notify_one(); + } + } + } + if (configuration.execution.runZXChecker && !done) { if (zx::FunctionalityConstruction::transformableToZX(&qc1) && zx::FunctionalityConstruction::transformableToZX(&qc2)) { @@ -609,6 +637,9 @@ void EquivalenceCheckingManager::checkParallel() { if (configuration.execution.runConstructionChecker) { ++tasksToExecute; } + if (configuration.execution.runHSFChecker) { + ++tasksToExecute; + } if (configuration.execution.runSimulationChecker) { if (configuration.simulation.maxSims > 0U) { tasksToExecute += configuration.simulation.maxSims; @@ -657,6 +688,13 @@ void EquivalenceCheckingManager::checkParallel() { ++id; } + if (configuration.execution.runHSFChecker && !done) { + // start a new thread that constructs and runs the HSF check + futures.emplace_back( + asyncRunChecker(id, queue)); + ++id; + } + if (configuration.execution.runZXChecker && !done) { // start a new thread that constructs and runs the ZX checker futures.emplace_back(asyncRunChecker(id, queue)); diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index d55e99f3..b71881a8 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -3,7 +3,6 @@ #include "Definitions.hpp" #include "EquivalenceCriterion.hpp" #include "dd/ComplexValue.hpp" -#include "dd/DDpackageConfig.hpp" #include "dd/GateMatrixDefinitions.hpp" #include "dd/Operations.hpp" #include "dd/Package.hpp" @@ -24,10 +23,10 @@ #include #include #include +#include namespace ec { -template -std::size_t HybridSchrodingerFeynmanChecker::getNDecisions( +std::size_t HybridSchrodingerFeynmanChecker::getNDecisions( qc::QuantumComputation& qc) const { std::size_t ndecisions = 0; // calculate number of decisions @@ -85,10 +84,9 @@ std::size_t HybridSchrodingerFeynmanChecker::getNDecisions( return ndecisions; } -template -dd::ComplexValue HybridSchrodingerFeynmanChecker::simulateSlicing( - std::unique_ptr>& sliceDD1, - std::unique_ptr>& sliceDD2, size_t i) { +dd::ComplexValue HybridSchrodingerFeynmanChecker::simulateSlicing( + std::unique_ptr& sliceDD1, std::unique_ptr& sliceDD2, + size_t i) { Slice lower(sliceDD1, 0, splitQubit - 1, i); Slice upper(sliceDD2, splitQubit, static_cast(this->qc1->getNqubits() - 1), i); @@ -104,8 +102,7 @@ dd::ComplexValue HybridSchrodingerFeynmanChecker::simulateSlicing( return result; } -template -bool HybridSchrodingerFeynmanChecker::Slice::apply( +bool HybridSchrodingerFeynmanChecker::Slice::apply( std::unique_ptr& sliceDD, const std::unique_ptr& op) { bool isSplitOp = false; @@ -175,24 +172,22 @@ bool HybridSchrodingerFeynmanChecker::Slice::apply( return isSplitOp; } -template -EquivalenceCriterion HybridSchrodingerFeynmanChecker::run() { +EquivalenceCriterion HybridSchrodingerFeynmanChecker::run() { const auto start = std::chrono::steady_clock::now(); - auto equivalence = checkEquivalence(); + auto eq = checkEquivalence(); const auto end = std::chrono::steady_clock::now(); runtime += std::chrono::duration(end - start).count(); - return equivalence; + return eq; } -template -EquivalenceCriterion -HybridSchrodingerFeynmanChecker::checkEquivalence() { +EquivalenceCriterion HybridSchrodingerFeynmanChecker::checkEquivalence() { const auto ndecisions = getNDecisions(*qc1) + getNDecisions(*qc2Inverted); if (ndecisions > 63) { throw std::overflow_error( "Number of split operations exceeds the maximum allowed number of 63."); } const auto maxControl = 1ULL << ndecisions; + std::size_t nthreads = std::max(2U, std::thread::hardware_concurrency()); const auto actuallyUsedThreads = std::min(maxControl, nthreads); const auto chunkSize = static_cast( std::ceil(static_cast(maxControl) / @@ -222,11 +217,16 @@ HybridSchrodingerFeynmanChecker::checkEquivalence() { }); } executor.wait_for_all(); - if (std::abs(trace.mag() - 1.) < traceThreshold) { + if (std::abs(trace.mag() - 1.) < + configuration.functionality.approximateCheckingThreshold) { return EquivalenceCriterion::Equivalent; } return EquivalenceCriterion::NotEquivalent; } -template class ec::HybridSchrodingerFeynmanChecker; +void HybridSchrodingerFeynmanChecker::json( + nlohmann::basic_json<>& j) const noexcept { + DDEquivalenceChecker::json(j); + j["checker"] = "decision_diagram_hybridSchrodingerFeynman"; +} } // namespace ec diff --git a/src/python/bindings.cpp b/src/python/bindings.cpp index 841fb351..92fb846d 100644 --- a/src/python/bindings.cpp +++ b/src/python/bindings.cpp @@ -562,6 +562,13 @@ PYBIND11_MODULE(pyqcec, m, py::mod_gil_not_used()) { "` should be " "executed. Defaults to :code:`True` but arbitrary multi-controlled " "operations are only partially supported.") + .def_readwrite( + "run_hsf_checker", &Configuration::Execution::runHSFChecker, + "Set whether the :ref:`hsf checker " + "` should be " + "executed. Defaults to :code:`False`. Arbitrary multi-controlled " + "operations are only partially supported.") .def_readwrite("numerical_tolerance", &Configuration::Execution::numericalTolerance, "Set the numerical tolerance of the underlying decision " diff --git a/test/legacy/test_functionality.cpp b/test/legacy/test_functionality.cpp index 2b61c0ce..7af73ee5 100644 --- a/test/legacy/test_functionality.cpp +++ b/test/legacy/test_functionality.cpp @@ -33,6 +33,7 @@ class FunctionalityTest : public testing::TestWithParam { config.execution.runAlternatingChecker = false; config.execution.runSimulationChecker = false; config.execution.runZXChecker = false; + config.execution.runHSFChecker = false; config.simulation.maxSims = 16; config.application.constructionScheme = ec::ApplicationSchemeType::Sequential; diff --git a/test/legacy/test_general.cpp b/test/legacy/test_general.cpp index 90c0f175..882a772c 100644 --- a/test/legacy/test_general.cpp +++ b/test/legacy/test_general.cpp @@ -69,6 +69,7 @@ TEST_F(GeneralTest, NothingToDo) { config.execution.runSimulationChecker = false; config.execution.runConstructionChecker = false; config.execution.runZXChecker = false; + config.execution.runHSFChecker = false; auto ecm = ec::EquivalenceCheckingManager(qc1, qc2, config); ecm.run(); diff --git a/test/legacy/test_journal.cpp b/test/legacy/test_journal.cpp index 9d772079..20e8d0fc 100644 --- a/test/legacy/test_journal.cpp +++ b/test/legacy/test_journal.cpp @@ -154,6 +154,7 @@ TEST_P(JournalTestNonEQ, PowerOfSimulation) { config.execution.runConstructionChecker = false; config.execution.runSimulationChecker = true; config.execution.runZXChecker = false; + config.execution.runHSFChecker = false; config.execution.parallel = false; config.execution.timeout = 60.; config.simulation.maxSims = 16U; @@ -207,6 +208,7 @@ TEST_P(JournalTestNonEQ, PowerOfSimulationParallel) { config.execution.runAlternatingChecker = false; config.execution.runConstructionChecker = false; config.execution.runZXChecker = false; + config.execution.runHSFChecker = false; config.execution.runSimulationChecker = true; config.execution.parallel = true; config.execution.timeout = 60.; @@ -273,6 +275,7 @@ class JournalTestEQ : public testing::TestWithParam { config.execution.runConstructionChecker = false; config.execution.runAlternatingChecker = false; config.execution.runZXChecker = false; + config.execution.runHSFChecker = false; config.execution.runSimulationChecker = false; config.simulation.maxSims = 16; config.application.simulationScheme = ec::ApplicationSchemeType::OneToOne; diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 17f2faff..cb376754 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -1,3 +1,5 @@ + +#include "EquivalenceCheckingManager.hpp" #include "EquivalenceCriterion.hpp" #include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" #include "dd/DDpackageConfig.hpp" @@ -6,104 +8,133 @@ #include #include #include - /** * Approximate equivalence checking of an original circuit 'c1' and its * approximate version 'c2'. The circuits 'c2' were generated using the BQSKit * compiler with synthesis_epsilon=0.3 and error_threshold=0.5. * */ +class HSFTest : public testing::Test { +protected: + ec::Configuration config{}; + + std::string testOriginal = "./circuits/approximateEquivalenceTest/"; + std::string testApproximateDir = "./circuits/approximateEquivalenceTest/"; + + void SetUp() override { + config.execution.runConstructionChecker = false; + config.execution.runAlternatingChecker = false; + config.execution.runSimulationChecker = false; + config.execution.runZXChecker = false; + config.execution.runHSFChecker = true; + config.functionality.checkApproximateEquivalence = true; + config.optimizations = {false, false, false, false, false, false, false}; + } +}; + +TEST_F(HSFTest, approximateEquivalenceCheckingWithHSF) { + // Check that the approximate equivalence flag has to be enabled to use the + // HSF checker + const qc::QuantumComputation c1{testOriginal + + "dj_indep_qiskit_10_no_measure.qasm"}; + const qc::QuantumComputation c2{testApproximateDir + + "out_dj_indep_qiskit_10_high_error.qasm"}; + config.functionality.checkApproximateEquivalence = false; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NoInformation); +} -TEST(HSFTest, dj10) { - const qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" +TEST_F(HSFTest, dj10) { + const qc::QuantumComputation c1{testOriginal + "dj_indep_qiskit_10_no_measure.qasm"}; - const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + const qc::QuantumComputation c2{testApproximateDir + "out_dj_indep_qiskit_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.912, - 6); - auto result = hsf.run(); - EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); + config.functionality.approximateCheckingThreshold = 0.912; + config.functionality.checkApproximateEquivalence = true; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST(HSFTest, ghz10) { +TEST_F(HSFTest, ghz10) { const qc::QuantumComputation c1{ - "./circuits/approximateEquivalenceTest/" - "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + testOriginal + "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - "./circuits/approximateEquivalenceTest/" + testApproximateDir + "out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.956, - 6); - auto result = hsf.run(); - EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); + config.functionality.approximateCheckingThreshold = 0.956; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST(HSFTest, wstate10) { - const qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" +TEST_F(HSFTest, wstate10) { + const qc::QuantumComputation c1{testOriginal + "wstate_indep_qiskit_10_no_measure.qasm"}; - const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + const qc::QuantumComputation c2{testApproximateDir + "out_wstate_indep_qiskit_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.991, - 6); - auto result = hsf.run(); - EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); + config.functionality.approximateCheckingThreshold = 0.991; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST(HSFTest, graphstate10) { - const qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" +TEST_F(HSFTest, graphstate10) { + const qc::QuantumComputation c1{testOriginal + "graphstate_indep_qiskit_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - "./circuits/approximateEquivalenceTest/" - "out_graphstate_indep_qiskit_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.912, - 6); - auto result = hsf.run(); - EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); + testApproximateDir + "out_graphstate_indep_qiskit_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.912; + config.execution.runAlternatingChecker = false; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST(HSFTest, vqe10) { - const qc::QuantumComputation c1{"./circuits/approximateEquivalenceTest/" +TEST_F(HSFTest, vqe10) { + const qc::QuantumComputation c1{testOriginal + "vqe_indep_qiskit_10_no_measure.qasm"}; - const qc::QuantumComputation c2{"./circuits/approximateEquivalenceTest/" + const qc::QuantumComputation c2{testApproximateDir + "out_vqe_indep_qiskit_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.998, - 6); - auto result = hsf.run(); - EXPECT_EQ(result, ec::EquivalenceCriterion::Equivalent); + config.functionality.approximateCheckingThreshold = 0.998; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST(HSFTest, qftNativegates10) { +TEST_F(HSFTest, qftNativegates10) { const qc::QuantumComputation c1{ - "./circuits/approximateEquivalenceTest/check/" - "qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + testOriginal + + "check/qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - "./circuits/approximateEquivalenceTest/check/" - "out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.9981, - 6); - EXPECT_THROW(hsf.run(), std::overflow_error); + testApproximateDir + + "check/out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.9981; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + EXPECT_THROW(ecm.run(), std::overflow_error); } -TEST(HSFTest, qpeExact10) { +TEST_F(HSFTest, qpeExact10) { const qc::QuantumComputation c1{ - "./circuits/approximateEquivalenceTest/check/" - "qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + testOriginal + + "check/qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - "./circuits/approximateEquivalenceTest/check/" - "out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.9846, - 6); - EXPECT_THROW(hsf.run(), std::overflow_error); + testApproximateDir + + "check/out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.9846; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + EXPECT_THROW(ecm.run(), std::overflow_error); } -TEST(HSFTest, qpeInexact10) { +TEST_F(HSFTest, qpeInexact10) { const qc::QuantumComputation c1{ - "./circuits/approximateEquivalenceTest/check/" - "qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + testOriginal + + "check/qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - "./circuits/approximateEquivalenceTest/check/" - "out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - ec::HybridSchrodingerFeynmanChecker hsf(c1, c2, 0.9893, - 6); - EXPECT_THROW(hsf.run(), std::overflow_error); + testApproximateDir + + "check/out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.9893; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + EXPECT_THROW(ecm.run(), std::overflow_error); } diff --git a/test/test_partial_equivalence.cpp b/test/test_partial_equivalence.cpp index c330e5aa..24751300 100644 --- a/test/test_partial_equivalence.cpp +++ b/test/test_partial_equivalence.cpp @@ -361,6 +361,7 @@ class PartialEquivalenceTest : public testing::Test { config.execution.runAlternatingChecker = false; config.execution.runConstructionChecker = false; config.execution.runZXChecker = false; + config.execution.runHSFChecker = false; config.execution.nthreads = 1; config.functionality.checkPartialEquivalence = true; diff --git a/test/test_zx.cpp b/test/test_zx.cpp index 60937782..77f1f544 100644 --- a/test/test_zx.cpp +++ b/test/test_zx.cpp @@ -35,6 +35,7 @@ class ZXTest : public testing::TestWithParam { config.execution.runConstructionChecker = false; config.execution.runAlternatingChecker = false; config.execution.runSimulationChecker = false; + config.execution.runHSFChecker = false; config.execution.runZXChecker = true; } @@ -268,6 +269,7 @@ class ZXTestCompFlow : public testing::TestWithParam { config.execution.runConstructionChecker = false; config.execution.runAlternatingChecker = false; config.execution.runSimulationChecker = false; + config.execution.runHSFChecker = false; config.execution.runZXChecker = true; qcOriginal.import(testOriginalDir + GetParam() + ".real"); @@ -407,6 +409,7 @@ TEST_F(ZXTest, IdleQubit) { config.execution.runSimulationChecker = false; config.execution.runAlternatingChecker = false; config.execution.runConstructionChecker = false; + config.execution.runHSFChecker = false; ecm = std::make_unique(qc1, qc2, config); ecm->run(); @@ -443,6 +446,7 @@ TEST_F(ZXTest, TwoQubitRotations) { config.execution.runSimulationChecker = false; config.execution.runAlternatingChecker = false; config.execution.runConstructionChecker = false; + config.execution.runHSFChecker = false; ecm = std::make_unique(qc1, qc2, config); ecm->run(); From 1c57b6688147c070ca88cad8c75294d453711115 Mon Sep 17 00:00:00 2001 From: Theresa Date: Sat, 26 Oct 2024 20:58:58 +0200 Subject: [PATCH 29/38] :rotating_light: Fix warnings --- .../checker/dd/HybridSchrodingerFeynmanChecker.hpp | 5 ++++- src/checker/dd/HybridSchrodingerFeynmanChecker.cpp | 11 ++++++----- test/test_hsf.cpp | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 80b684e9..efdcd4ea 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -6,6 +6,7 @@ #include "EquivalenceCriterion.hpp" #include "circuit_optimizer/CircuitOptimizer.hpp" #include "dd/ComplexValue.hpp" +#include "dd/DDpackageConfig.hpp" #include "dd/Package.hpp" #include "dd/Package_fwd.hpp" #include "ir/QuantumComputation.hpp" @@ -15,7 +16,9 @@ #include #include #include +#include #include +#include namespace ec { /** @@ -164,7 +167,7 @@ class HybridSchrodingerFeynmanChecker final * @return std::size_t */ std::size_t getNextControl() { - std::size_t idx = 1UL << nextControlIdx; + const std::size_t idx = 1UL << nextControlIdx; nextControlIdx++; return controlIdx & idx; } diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index b71881a8..91be6e2d 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -20,9 +20,9 @@ #include #include #include +#include #include -#include -#include +#include #include namespace ec { @@ -132,7 +132,7 @@ bool HybridSchrodingerFeynmanChecker::Slice::apply( } else { // other controls are set to the corresponding value if (targetInSplit) { isSplitOp = true; - const bool nextControl = getNextControl(); + const bool nextControl = getNextControl() != 0U; // break if control is not activated if ((control.type == qc::Control::Type::Pos && !nextControl) || (control.type == qc::Control::Type::Neg && nextControl)) { @@ -148,7 +148,7 @@ bool HybridSchrodingerFeynmanChecker::Slice::apply( assert(opControls.size() == 1); isSplitOp = true; - const bool control = getNextControl(); + const bool control = getNextControl() != 0U; for (const auto& c : opControls) { auto tmp = matrix; auto projMatrix = control == (c.type == qc::Control::Type::Neg) @@ -187,7 +187,8 @@ EquivalenceCriterion HybridSchrodingerFeynmanChecker::checkEquivalence() { "Number of split operations exceeds the maximum allowed number of 63."); } const auto maxControl = 1ULL << ndecisions; - std::size_t nthreads = std::max(2U, std::thread::hardware_concurrency()); + const std::size_t nthreads = + std::max(2U, std::thread::hardware_concurrency()); const auto actuallyUsedThreads = std::min(maxControl, nthreads); const auto chunkSize = static_cast( std::ceil(static_cast(maxControl) / diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index cb376754..9a29c1b5 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -1,8 +1,8 @@ +#include "Configuration.hpp" #include "EquivalenceCheckingManager.hpp" #include "EquivalenceCriterion.hpp" -#include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" -#include "dd/DDpackageConfig.hpp" +#include "checker/dd/DDEquivalenceChecker.hpp" #include "ir/QuantumComputation.hpp" #include From bfc2ba61d35de957f8f94ebaf399bd8520a44133 Mon Sep 17 00:00:00 2001 From: Theresa Date: Sat, 26 Oct 2024 23:16:01 +0200 Subject: [PATCH 30/38] :rotating_light: :white_check_mark: Fix warnings & add HSF test in Python --- .../dd/HybridSchrodingerFeynmanChecker.hpp | 2 +- .../dd/HybridSchrodingerFeynmanChecker.cpp | 4 +- src/mqt/qcec/configuration.py | 1 + src/mqt/qcec/pyqcec.pyi | 1 + test/python/test_hsf.py | 60 +++++++++++++++++++ test/test_hsf.cpp | 1 - 6 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 test/python/test_hsf.py diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index efdcd4ea..8c1de765 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -12,11 +12,11 @@ #include "ir/QuantumComputation.hpp" #include "ir/operations/OpType.hpp" #include "memory" +#include "nlohmann/json_fwd.hpp" #include #include #include -#include #include #include diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index 91be6e2d..7413886e 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -2,6 +2,7 @@ #include "Definitions.hpp" #include "EquivalenceCriterion.hpp" +#include "checker/dd/DDEquivalenceChecker.hpp" #include "dd/ComplexValue.hpp" #include "dd/GateMatrixDefinitions.hpp" #include "dd/Operations.hpp" @@ -22,7 +23,8 @@ #include #include #include -#include +#include // IWYU pragma: keep +#include #include namespace ec { diff --git a/src/mqt/qcec/configuration.py b/src/mqt/qcec/configuration.py index 9edc48af..be66a872 100644 --- a/src/mqt/qcec/configuration.py +++ b/src/mqt/qcec/configuration.py @@ -29,6 +29,7 @@ class ConfigurationOptions(TypedDict, total=False): run_construction_checker: bool run_simulation_checker: bool run_zx_checker: bool + run_hsf_checker: bool timeout: float # Functionality trace_threshold: float diff --git a/src/mqt/qcec/pyqcec.pyi b/src/mqt/qcec/pyqcec.pyi index cc57ec20..7c9715a0 100644 --- a/src/mqt/qcec/pyqcec.pyi +++ b/src/mqt/qcec/pyqcec.pyi @@ -43,6 +43,7 @@ class Configuration: run_construction_checker: bool run_simulation_checker: bool run_zx_checker: bool + run_hsf_checker: bool timeout: float def __init__(self) -> None: ... diff --git a/test/python/test_hsf.py b/test/python/test_hsf.py new file mode 100644 index 00000000..2b90b643 --- /dev/null +++ b/test/python/test_hsf.py @@ -0,0 +1,60 @@ +"""Tests the partial equivalence checking support of QCEC.""" + +from __future__ import annotations + +import pytest +from qiskit import QuantumCircuit + +from mqt import qcec + + +@pytest.fixture +def original_circuit() -> QuantumCircuit: + """Fixture for a simple circuit.""" + qc = QuantumCircuit(4) + qc.cx(0, 2) + qc.cx(1, 3) + return qc + + +@pytest.fixture +def alternative_circuit() -> QuantumCircuit: + """Fixture of a second circuit that will be checked for equivalence.""" + qc = QuantumCircuit(4) + qc.id(0) + qc.id(1) + qc.id(2) + qc.id(3) + return qc + + +def test_configuration_pec(original_circuit: QuantumCircuit, alternative_circuit: QuantumCircuit) -> None: + """Test if the flag for hsf equivalence checking works.""" + config = qcec.Configuration() + config.execution.run_alternating_checker = False + config.execution.run_construction_checker = False + config.execution.run_simulation_checker = False + config.execution.run_zx_checker = False + config.execution.run_hsf_checker = True + config.functionality.check_approximate_equivalence = True + config.functionality.approximate_checking_threshold = 0.8 + result = qcec.verify(original_circuit, alternative_circuit, configuration=config) + assert result.equivalence == qcec.EquivalenceCriterion.equivalent + + +def test_argument_pec(original_circuit: QuantumCircuit, alternative_circuit: QuantumCircuit) -> None: + """Test if the flag for hsf equivalence checking works.""" + config = qcec.Configuration() + config.execution.run_alternating_checker = False + config.execution.run_construction_checker = False + config.execution.run_simulation_checker = False + config.execution.run_zx_checker = False + config.execution.run_hsf_checker = True + result = qcec.verify( + original_circuit, + alternative_circuit, + configuration=config, + check_approximate_equivalence=True, + approximate_checking_threshold=0.8, + ) + assert result.equivalence == qcec.EquivalenceCriterion.equivalent diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 9a29c1b5..a4263ad9 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -2,7 +2,6 @@ #include "Configuration.hpp" #include "EquivalenceCheckingManager.hpp" #include "EquivalenceCriterion.hpp" -#include "checker/dd/DDEquivalenceChecker.hpp" #include "ir/QuantumComputation.hpp" #include From 668589e984a9c589b62d5786c79daa59fb310598 Mon Sep 17 00:00:00 2001 From: Theresa Date: Sun, 27 Oct 2024 15:44:39 +0100 Subject: [PATCH 31/38] :bug: :white_check_mark: Fix integration of HSF into equivalence checking flow --- src/EquivalenceCheckingManager.cpp | 8 +- .../dd/HybridSchrodingerFeynmanChecker.cpp | 4 +- test/test_hsf.cpp | 123 +++++++++++------- 3 files changed, 84 insertions(+), 51 deletions(-) diff --git a/src/EquivalenceCheckingManager.cpp b/src/EquivalenceCheckingManager.cpp index 4d48a707..4cd4a396 100644 --- a/src/EquivalenceCheckingManager.cpp +++ b/src/EquivalenceCheckingManager.cpp @@ -781,10 +781,12 @@ void EquivalenceCheckingManager::checkParallel() { break; } - // the alternating and the construction checker provide definitive answers - // once they finish + // the alternating, the construction and the HSF checker provide definitive + // answers once they finish if ((dynamic_cast(checker) != nullptr) || - (dynamic_cast(checker) != nullptr)) { + (dynamic_cast(checker) != nullptr) || + (dynamic_cast(checker) != + nullptr)) { setAndSignalDone(); results.equivalence = result; break; diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp index 7413886e..e44abf0c 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp @@ -176,10 +176,10 @@ bool HybridSchrodingerFeynmanChecker::Slice::apply( EquivalenceCriterion HybridSchrodingerFeynmanChecker::run() { const auto start = std::chrono::steady_clock::now(); - auto eq = checkEquivalence(); + equivalence = checkEquivalence(); const auto end = std::chrono::steady_clock::now(); runtime += std::chrono::duration(end - start).count(); - return eq; + return equivalence; } EquivalenceCriterion HybridSchrodingerFeynmanChecker::checkEquivalence() { diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index a4263ad9..853cb751 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -17,8 +17,7 @@ class HSFTest : public testing::Test { protected: ec::Configuration config{}; - std::string testOriginal = "./circuits/approximateEquivalenceTest/"; - std::string testApproximateDir = "./circuits/approximateEquivalenceTest/"; + std::string testDir = "./circuits/approximateEquivalenceTest/"; void SetUp() override { config.execution.runConstructionChecker = false; @@ -32,108 +31,140 @@ class HSFTest : public testing::Test { }; TEST_F(HSFTest, approximateEquivalenceCheckingWithHSF) { - // Check that the approximate equivalence flag has to be enabled to use the + // Test that enabling the approximate equivalence flag is required to use the // HSF checker - const qc::QuantumComputation c1{testOriginal + + const qc::QuantumComputation c1{testDir + "dj_indep_qiskit_10_no_measure.qasm"}; - const qc::QuantumComputation c2{testApproximateDir + + const qc::QuantumComputation c2{testDir + "out_dj_indep_qiskit_10_high_error.qasm"}; config.functionality.checkApproximateEquivalence = false; ec::EquivalenceCheckingManager ecm(c1, c2, config); ecm.run(); - EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::NoInformation); } -TEST_F(HSFTest, dj10) { - const qc::QuantumComputation c1{testOriginal + +TEST_F(HSFTest, dj10ParallelChecking) { + // Test the parallel equivalence checking flow with only the HSF checker + // enabled + const qc::QuantumComputation c1{testDir + "dj_indep_qiskit_10_no_measure.qasm"}; - const qc::QuantumComputation c2{testApproximateDir + + const qc::QuantumComputation c2{testDir + "out_dj_indep_qiskit_10_high_error.qasm"}; config.functionality.approximateCheckingThreshold = 0.912; - config.functionality.checkApproximateEquivalence = true; + config.execution.parallel = true; ec::EquivalenceCheckingManager ecm(c1, c2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST_F(HSFTest, ghz10) { - const qc::QuantumComputation c1{ - testOriginal + "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; - const qc::QuantumComputation c2{ - testApproximateDir + - "out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - config.functionality.approximateCheckingThreshold = 0.956; +TEST_F(HSFTest, vqe10ParallelChecking) { + // Test the parallel equivalence checking flow with only the HSF checker + // enabled (parallel checking is enabled per default) + const qc::QuantumComputation c1{testDir + + "vqe_indep_qiskit_10_no_measure.qasm"}; + const qc::QuantumComputation c2{testDir + + "out_vqe_indep_qiskit_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.998; ec::EquivalenceCheckingManager ecm(c1, c2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST_F(HSFTest, wstate10) { - const qc::QuantumComputation c1{testOriginal + +TEST_F(HSFTest, wstate10ParallelChecking) { + // Note: This test might be commented out as it takes about 4 minutes to run + // Test the parallel equivalence checking flow where the HSF checker delivers + // results first + const qc::QuantumComputation c1{testDir + "wstate_indep_qiskit_10_no_measure.qasm"}; - const qc::QuantumComputation c2{testApproximateDir + + const qc::QuantumComputation c2{testDir + "out_wstate_indep_qiskit_10_high_error.qasm"}; config.functionality.approximateCheckingThreshold = 0.991; + config.execution.runConstructionChecker = true; + config.execution.runAlternatingChecker = true; + config.execution.parallel = true; ec::EquivalenceCheckingManager ecm(c1, c2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST_F(HSFTest, graphstate10) { - const qc::QuantumComputation c1{testOriginal + - "graphstate_indep_qiskit_10_no_measure.qasm"}; +TEST_F(HSFTest, ghz10ParallelChecking) { + // Test the parallel equivalence checking flow where the alternating or + // construction checker delivers results first + const qc::QuantumComputation c1{ + testDir + "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - testApproximateDir + "out_graphstate_indep_qiskit_10_high_error.qasm"}; - config.functionality.approximateCheckingThreshold = 0.912; - config.execution.runAlternatingChecker = false; + testDir + "out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.956; + config.execution.runConstructionChecker = true; + config.execution.runAlternatingChecker = true; + config.execution.parallel = true; ec::EquivalenceCheckingManager ecm(c1, c2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST_F(HSFTest, vqe10) { - const qc::QuantumComputation c1{testOriginal + - "vqe_indep_qiskit_10_no_measure.qasm"}; - const qc::QuantumComputation c2{testApproximateDir + - "out_vqe_indep_qiskit_10_high_error.qasm"}; - config.functionality.approximateCheckingThreshold = 0.998; +TEST_F(HSFTest, ghz10SequentialChecking) { + // Test the sequential equivalence checking flow where the alternating or + // construction checker delivers results first + const qc::QuantumComputation c1{ + testDir + "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + const qc::QuantumComputation c2{ + testDir + "out_ghz_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.956; + config.execution.runConstructionChecker = true; + config.execution.runAlternatingChecker = true; + config.execution.parallel = false; + ec::EquivalenceCheckingManager ecm(c1, c2, config); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); +} + +TEST_F(HSFTest, graphstate10SequentialChecking) { + // Test the sequential equivalence checking flow with only the HSF checker + // enabled + const qc::QuantumComputation c1{testDir + + "graphstate_indep_qiskit_10_no_measure.qasm"}; + const qc::QuantumComputation c2{ + testDir + "out_graphstate_indep_qiskit_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.912; + config.execution.parallel = false; ec::EquivalenceCheckingManager ecm(c1, c2, config); ecm.run(); EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST_F(HSFTest, qftNativegates10) { +TEST_F(HSFTest, qftNativegates10DecisionOverflow) { + // Test that an overflow_error is thrown if the number of decisions exceeds + // the maximum number of decisions const qc::QuantumComputation c1{ - testOriginal + - "check/qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; + testDir + "check/qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - testApproximateDir + - "check/out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - config.functionality.approximateCheckingThreshold = 0.9981; + testDir + "check/out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; ec::EquivalenceCheckingManager ecm(c1, c2, config); EXPECT_THROW(ecm.run(), std::overflow_error); } -TEST_F(HSFTest, qpeExact10) { +TEST_F(HSFTest, qpeExact10DecisionOverflow) { + // Test that an overflow_error is thrown if the number of decisions exceeds + // the maximum number of decisions const qc::QuantumComputation c1{ - testOriginal + + testDir + "check/qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - testApproximateDir + + testDir + "check/out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - config.functionality.approximateCheckingThreshold = 0.9846; ec::EquivalenceCheckingManager ecm(c1, c2, config); EXPECT_THROW(ecm.run(), std::overflow_error); } -TEST_F(HSFTest, qpeInexact10) { +TEST_F(HSFTest, qpeInexact10DecisionOverflow) { + // Test that an overflow_error is thrown if the number of decisions exceeds + // the maximum number of decisions const qc::QuantumComputation c1{ - testOriginal + + testDir + "check/qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ - testApproximateDir + + testDir + "check/out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - config.functionality.approximateCheckingThreshold = 0.9893; ec::EquivalenceCheckingManager ecm(c1, c2, config); EXPECT_THROW(ecm.run(), std::overflow_error); } From 380d0aab871c2e107d0b01fcd2f0eb7544aa7321 Mon Sep 17 00:00:00 2001 From: Theresa Date: Sun, 27 Oct 2024 16:35:59 +0100 Subject: [PATCH 32/38] :memo: Update documentation --- docs/source/ApproximateEquivalence.ipynb | 248 ++++++++++++++++++ docs/source/index.rst | 1 + .../dd/HybridSchrodingerFeynmanChecker.hpp | 12 +- 3 files changed, 255 insertions(+), 6 deletions(-) create mode 100644 docs/source/ApproximateEquivalence.ipynb diff --git a/docs/source/ApproximateEquivalence.ipynb b/docs/source/ApproximateEquivalence.ipynb new file mode 100644 index 00000000..f8578be4 --- /dev/null +++ b/docs/source/ApproximateEquivalence.ipynb @@ -0,0 +1,248 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "77a131e6", + "metadata": {}, + "source": [ + "# Approximate Equivalence Checking\n", + "\n", + "## Approximate Equivalence vs. Exact Equivalence\n", + "\n", + "Two circuits are considered exactly equivalent if their matrix representations, `U` and `V`, are identical. Thus, the problem of exact equivalence checking reduces to verifying whether $UV^\\dagger = I$, where `I` is the identity matrix.\n", + "\n", + "In practice, however, it is often sufficient to determine whether two circuits are equivalent up to a certain percentage, while permitting an error tolerance. For instance, when optimizing circuits, we may not require exact equivalence, but rather a circuit that is sufficiently close to the original, while being optimal with respect to a specific metric, such as minimizing gate counts.\n", + "\n", + "Here, approximate equivalence is quantified by the process distance between two circuits based on the Hilbert-Schmidt inner product, with n being the number of qubits: $$\\Delta(U, V) = 1 - |\\frac{Tr(U V^\\dagger)}{2^n}|$$ Specifically, we compute the magnitude of the normalized trace of $UV^\\dagger$ and assess its proximity to 1. Two circuits are considered approximately equivalent if their process distance is below a specified error threshold, $\\epsilon$.\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "b9be796e", + "metadata": {}, + "source": [ + "\n", + "## Checking Approximate Equivalence of Quantum Circuits\n", + "\n", + "To enable approximate equivalence checking, set the `check_approximate_equivalence` option to `True` in the configuration parameters. When activated, the equivalence checker will return `equivalent` if the process distance is below a specified threshold. Otherwise, it will return `not-equivalent`. The error threshold is controlled via the `approximate_checking_threshold` parameter, with a default value of `1e-8`. Moreover, it is recommended to disable the simulation checker by setting `run_simulation_checker` to `False`.\n", + "\n", + "The following is a summary of the behaviour of each type of equivalence checker when the `checkApproximateEquivalence` option is set to `True`.\n", + "\n", + "1. **Construction Equivalence Checker:** The construction checker supports approximate equivalence checking by using decision diagrams to compute $UV^\\dagger$. It then calculates the normalized trace and compares the process distance to the defined error threshold. \n", + "\n", + "1. **Alternating Equivalence Checker:** The alternating checker likewise computes the composition of one circuit with the inverse of the other. Again, when checking for approximate equivalence, it suffices to verify that the normalized trace is sufficiently close to 1. \n", + "\n", + "1. **Simulation Equivalence Checker:** Approximate equivalence checking is not directly supported by the Simulation checker. Although numerical instabilities can be mitigated through the configuration parameter `simulation.fidelityThreshold`, this parameter does not serve as an approximate equivalence threshold. For instance, consider $UV^\\dagger$ representing a 10-qubit multi-controlled X-gate with the first 9 qubits as control and the last qubit as the target. In this setup, the process distance would meet an error threshold of $1e^-2$. However, since the Simulation checker evaluates both circuits using random input states, the fidelity drops to zero whenever one of the two computational basis states, $|1111111110\\rangle$ or $|1111111111\\rangle$, is selected. In such cases, regardless of any threshold setting, the checker reports non-equivalence.\n", + "\n", + "1. **ZX-Calculus Equivalence Checker:** Approximate equivalence checking is not yet supported in the ZX-calculus checker, which is not a problem for the equivalence checking workflow, given that the ZX-calculus checker cannot demonstrate non-equivalence of circuits due to its incompleteness. \n", + "Therefore, it will simply output 'No Information' for circuits that are approximately but not totally equivalent.\n", + "\n", + "1. **Hybrid Schrödinger-Feynman (HSF) Equivalence Checker:** By default, the HSF checker is disabled. It can only be used for approximate equivalence checking. To enable it, the `check_approximate_equivalence` option must also be activated. The HSF checker computes the process distance by dividing the circuit corresponding to $UV^\\dagger$ horizontally into two independent halves: a lower part and an upper part. This is achieved by decomposing controlled gates, acting across both halves, according to the Schmidt decomposition.\n", + "By leveraging key trace equalities - specifically,\n", + "\n", + " • $tr[L⊗U]=tr[L]⋅tr[U]$\n", + "\n", + " • $tr[P_1+P_2]=tr[P_1]+tr[P_2]$\n", + "\n", + " we can treat the lower and upper circuit parts, as well as the summands from the Schmidt decomposition, independently. This enables parallel trace computation, allowing to check the equivalence of larger, yet shallow circuits.\n", + " \n", + " Note: The following configurations are not currently supported, as they require the explicit computation of the Schmidt decomposition for the gates being cut (decisions):\n", + "\n", + " • Multiple targets spread across the cut through the circuit\n", + " • Multiple controls in the control part of the gate being cut \n", + " \n", + " Moreover, despite parallelization, the method is best suited for shallow circuits, as the number of paths to be computed grows exponentially with the number of decisions. " + ] + }, + { + "cell_type": "markdown", + "id": "977071d9", + "metadata": {}, + "source": [ + "## Using QCEC to Check for Approximate Equivalence\n", + "\n", + "Consider the following three-qubit circuit representing the Toffoli gate." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "03b73b17", + "metadata": {}, + "outputs": [], + "source": [ + "from qiskit import QuantumCircuit\n", + "\n", + "qc_lhs = QuantumCircuit(3)\n", + "qc_lhs.mcx([0, 1], 2)\n", + "qc_lhs.measure_all()\n", + "qc_lhs.draw(output=\"mpl\", style=\"iqp\")" + ] + }, + { + "cell_type": "markdown", + "id": "10fff8c7-f36c-422e-8deb-796cc7637e45", + "metadata": {}, + "source": [ + "Additionally, consider the following simple circuit, which represents the Identity." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d167869e-e082-4a42-9eab-112931f5c697", + "metadata": {}, + "outputs": [], + "source": [ + "qc_rhs = QuantumCircuit(3)\n", + "qc_rhs.id(0)\n", + "qc_rhs.id(1)\n", + "qc_rhs.id(2)\n", + "qc_rhs.measure_all()\n", + "qc_rhs.draw(output=\"mpl\", style=\"iqp\")" + ] + }, + { + "cell_type": "markdown", + "id": "3b85338e", + "metadata": {}, + "source": [ + "We now aim to compute the process distance between these circuits. Since the second circuit represents the Identity, it follows that $UV^\\dagger$ simplifies to the Toffoli gate matrix. \n", + "\n", + "$$\n", + "\\text{Toffoli} = \\begin{bmatrix}\n", + "1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n", + "0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\\\\n", + "0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\\\\n", + "0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 \\\\\n", + "0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 \\\\\n", + "0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\\\\n", + "0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\\\\n", + "0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\\\\n", + "\\end{bmatrix}\n", + "$$\n", + "\n", + "The normalized trace of this matrix is `0.75`. \n", + "\n", + "Consequently, the process distance $\\Delta(U, V) = 1 - |\\frac{Tr(U V^\\dagger)}{2^n}|$ is equal to `0.25`.\n", + "\n", + "If we set the equivalence tolerance to `0.3`, the checker should output `equivalent`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36df44b7", + "metadata": {}, + "outputs": [], + "source": [ + "from mqt.qcec import Configuration, verify\n", + "\n", + "config = Configuration()\n", + "config.execution.run_simulation_checker = False\n", + "config.functionality.check_approximate_equivalence = True\n", + "config.functionality.approximate_checking_threshold = 0.3\n", + "verify(qc_lhs, qc_rhs, configuration=config)" + ] + }, + { + "cell_type": "markdown", + "id": "f2c4104d", + "metadata": {}, + "source": [ + "However, with an error tolerance below `0.25`, the checker should return `not_equivalent`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da9fa188", + "metadata": {}, + "outputs": [], + "source": [ + "config = Configuration()\n", + "config.execution.run_simulation_checker = False\n", + "config.functionality.check_approximate_equivalence = True\n", + "config.functionality.approximate_checking_threshold = 0.2\n", + "verify(qc_lhs, qc_rhs, configuration=config)" + ] + }, + { + "cell_type": "markdown", + "id": "5d7f9c62", + "metadata": {}, + "source": [ + "To use the HSF checker, it must be explicitly enabled in the configuration. Below, we will explicitly use the HSF checker and disable the other checkers." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "494ef477", + "metadata": {}, + "outputs": [], + "source": [ + "config.execution.run_simulation_checker = False\n", + "config.execution.run_alternating_checker = False\n", + "config.execution.run_construction_checker = False\n", + "config.execution.run_zx_checker = False\n", + "config.execution.run_hsf_checker = True\n", + "config.functionality.check_approximate_equivalence = False\n", + "config.functionality.approximate_checking_threshold = 0.3\n", + "verify(qc_lhs, qc_rhs, configuration=config)" + ] + }, + { + "cell_type": "markdown", + "id": "b327ab4b", + "metadata": {}, + "source": [ + "However, we also need to explicitly enable the `check_approximate_equivalence` option." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "679291b7", + "metadata": {}, + "outputs": [], + "source": [ + "config.functionality.check_approximate_equivalence = True\n", + "config.functionality.approximate_checking_threshold = 0.3\n", + "verify(qc_lhs, qc_rhs, configuration=config)" + ] + }, + { + "cell_type": "markdown", + "id": "6af54b68", + "metadata": {}, + "source": [ + "Source: The concept of approximate equivalence used here is inspired by [Approximate Equivalence Checking of Noisy Quantum Circuits](https://arxiv.org/abs/2103.11595) by Xin Hong, Mingsheng Ying, Yuan Feng, Xiangzhen Zhou, Sanjiang Li, and [QUEST: systematically approximating Quantum circuits for higher output fidelity](https://dl.acm.org/doi/10.1145/3503222.3507739) by Tirthak Patel, Ed Younis, Costin Iancu, Wibe de Jong, and Devesh Tiwari." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/index.rst b/docs/source/index.rst index 5c09ecff..79bf4439 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -27,6 +27,7 @@ We appreciate any feedback and contributions to the project. If you want to cont CompilationFlowVerification ParameterizedCircuits PartialEquivalence + ApproximateEquivalence Publications .. toctree:: diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp index 8c1de765..eb45568d 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp @@ -24,9 +24,9 @@ namespace ec { /** * @brief Approximate Equivalence Checking with the * HybridSchrodingerFeynmanChecker This checker divides a circuit horizontally - * into two halves: a lower part and an upper part. This is achieved by cutting - * controlled gates that cross the middle line according to the Schmidt - * decomposition. By leveraging key trace equalities - specifically, + * into two halves: a lower part and an upper part. This is achieved by + * decomposing controlled gates, acting across both halves, according to the + * Schmidt decomposition. By leveraging key trace equalities - specifically, * * tr[L ⊗ U] = tr[L] ⋅ tr[U] * @@ -39,7 +39,7 @@ namespace ec { * computation, allowing to check the equivalence of larger, yet shallow * circuits. * @note Only suitable for shallow circuits with a maximum number of 63 - * controlled gates crossing the middle line (decisions). + * controlled gates acting on both circuit parts (decisions). */ class HybridSchrodingerFeynmanChecker final : public DDEquivalenceChecker { @@ -81,7 +81,7 @@ class HybridSchrodingerFeynmanChecker final * @brief Get # of decisions for given split_qubit, so that lower slice: q0 < * i < qubit; upper slice: qubit <= i < nqubits * @details The number of decisions is determined by the number of controlled - * gates that cross the middle line. + * gates that operate across both halves. * @param qc * @return std::size_t */ @@ -110,7 +110,7 @@ class HybridSchrodingerFeynmanChecker final * into a sum of circuits, each consisting of only single-qubit gates. By * recursively applying this decomposition to all decisions, we generate a * total of 2^decisions circuits, which do not contain controlled operations - * crossing the middle line. This enables independent investigation of the + * acting on both halves. This enables independent investigation of the * lower and upper circuit parts. * * This function computes the trace for the i-th summand, where the index 'i' From ccd62d806a60110a70f907b14d5034364692deb8 Mon Sep 17 00:00:00 2001 From: Theresa Date: Sun, 27 Oct 2024 17:07:51 +0100 Subject: [PATCH 33/38] :truck: Rename checker --- ...r.hpp => DDHybridSchrodingerFeynmanChecker.hpp} | 10 +++++----- src/EquivalenceCheckingManager.cpp | 8 ++++---- ...r.cpp => DDHybridSchrodingerFeynmanChecker.cpp} | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) rename include/checker/dd/{HybridSchrodingerFeynmanChecker.hpp => DDHybridSchrodingerFeynmanChecker.hpp} (95%) rename src/checker/dd/{HybridSchrodingerFeynmanChecker.cpp => DDHybridSchrodingerFeynmanChecker.cpp} (94%) diff --git a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/DDHybridSchrodingerFeynmanChecker.hpp similarity index 95% rename from include/checker/dd/HybridSchrodingerFeynmanChecker.hpp rename to include/checker/dd/DDHybridSchrodingerFeynmanChecker.hpp index eb45568d..6506f21c 100644 --- a/include/checker/dd/HybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/DDHybridSchrodingerFeynmanChecker.hpp @@ -23,7 +23,7 @@ namespace ec { /** * @brief Approximate Equivalence Checking with the - * HybridSchrodingerFeynmanChecker This checker divides a circuit horizontally + * DDHybridSchrodingerFeynmanChecker This checker divides a circuit horizontally * into two halves: a lower part and an upper part. This is achieved by * decomposing controlled gates, acting across both halves, according to the * Schmidt decomposition. By leveraging key trace equalities - specifically, @@ -41,12 +41,12 @@ namespace ec { * @note Only suitable for shallow circuits with a maximum number of 63 * controlled gates acting on both circuit parts (decisions). */ -class HybridSchrodingerFeynmanChecker final +class DDHybridSchrodingerFeynmanChecker final : public DDEquivalenceChecker { public: - HybridSchrodingerFeynmanChecker(const qc::QuantumComputation& circ1, - const qc::QuantumComputation& circ2, - ec::Configuration config) + DDHybridSchrodingerFeynmanChecker(const qc::QuantumComputation& circ1, + const qc::QuantumComputation& circ2, + ec::Configuration config) : DDEquivalenceChecker(circ1, circ2, std::move(config)), qc1(std::make_unique(circ1)), qc2Inverted(std::make_unique()) { diff --git a/src/EquivalenceCheckingManager.cpp b/src/EquivalenceCheckingManager.cpp index 4cd4a396..9e42f5a1 100644 --- a/src/EquivalenceCheckingManager.cpp +++ b/src/EquivalenceCheckingManager.cpp @@ -10,8 +10,8 @@ #include "ThreadSafeQueue.hpp" #include "checker/dd/DDAlternatingChecker.hpp" #include "checker/dd/DDConstructionChecker.hpp" +#include "checker/dd/DDHybridSchrodingerFeynmanChecker.hpp" #include "checker/dd/DDSimulationChecker.hpp" -#include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" #include "checker/dd/simulation/StateType.hpp" #include "checker/zx/ZXChecker.hpp" #include "circuit_optimizer/CircuitOptimizer.hpp" @@ -535,7 +535,7 @@ void EquivalenceCheckingManager::checkSequential() { } if (configuration.execution.runHSFChecker && !done) { - checkers.emplace_back(std::make_unique( + checkers.emplace_back(std::make_unique( qc1, qc2, configuration)); const auto& hsfChecker = checkers.back(); if (!done) { @@ -691,7 +691,7 @@ void EquivalenceCheckingManager::checkParallel() { if (configuration.execution.runHSFChecker && !done) { // start a new thread that constructs and runs the HSF check futures.emplace_back( - asyncRunChecker(id, queue)); + asyncRunChecker(id, queue)); ++id; } @@ -785,7 +785,7 @@ void EquivalenceCheckingManager::checkParallel() { // answers once they finish if ((dynamic_cast(checker) != nullptr) || (dynamic_cast(checker) != nullptr) || - (dynamic_cast(checker) != + (dynamic_cast(checker) != nullptr)) { setAndSignalDone(); results.equivalence = result; diff --git a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp similarity index 94% rename from src/checker/dd/HybridSchrodingerFeynmanChecker.cpp rename to src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp index e44abf0c..ceb722d3 100644 --- a/src/checker/dd/HybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp @@ -1,4 +1,4 @@ -#include "checker/dd/HybridSchrodingerFeynmanChecker.hpp" +#include "checker/dd/DDHybridSchrodingerFeynmanChecker.hpp" #include "Definitions.hpp" #include "EquivalenceCriterion.hpp" @@ -28,7 +28,7 @@ #include namespace ec { -std::size_t HybridSchrodingerFeynmanChecker::getNDecisions( +std::size_t DDHybridSchrodingerFeynmanChecker::getNDecisions( qc::QuantumComputation& qc) const { std::size_t ndecisions = 0; // calculate number of decisions @@ -86,7 +86,7 @@ std::size_t HybridSchrodingerFeynmanChecker::getNDecisions( return ndecisions; } -dd::ComplexValue HybridSchrodingerFeynmanChecker::simulateSlicing( +dd::ComplexValue DDHybridSchrodingerFeynmanChecker::simulateSlicing( std::unique_ptr& sliceDD1, std::unique_ptr& sliceDD2, size_t i) { Slice lower(sliceDD1, 0, splitQubit - 1, i); @@ -104,7 +104,7 @@ dd::ComplexValue HybridSchrodingerFeynmanChecker::simulateSlicing( return result; } -bool HybridSchrodingerFeynmanChecker::Slice::apply( +bool DDHybridSchrodingerFeynmanChecker::Slice::apply( std::unique_ptr& sliceDD, const std::unique_ptr& op) { bool isSplitOp = false; @@ -174,7 +174,7 @@ bool HybridSchrodingerFeynmanChecker::Slice::apply( return isSplitOp; } -EquivalenceCriterion HybridSchrodingerFeynmanChecker::run() { +EquivalenceCriterion DDHybridSchrodingerFeynmanChecker::run() { const auto start = std::chrono::steady_clock::now(); equivalence = checkEquivalence(); const auto end = std::chrono::steady_clock::now(); @@ -182,7 +182,7 @@ EquivalenceCriterion HybridSchrodingerFeynmanChecker::run() { return equivalence; } -EquivalenceCriterion HybridSchrodingerFeynmanChecker::checkEquivalence() { +EquivalenceCriterion DDHybridSchrodingerFeynmanChecker::checkEquivalence() { const auto ndecisions = getNDecisions(*qc1) + getNDecisions(*qc2Inverted); if (ndecisions > 63) { throw std::overflow_error( @@ -227,7 +227,7 @@ EquivalenceCriterion HybridSchrodingerFeynmanChecker::checkEquivalence() { return EquivalenceCriterion::NotEquivalent; } -void HybridSchrodingerFeynmanChecker::json( +void DDHybridSchrodingerFeynmanChecker::json( nlohmann::basic_json<>& j) const noexcept { DDEquivalenceChecker::json(j); j["checker"] = "decision_diagram_hybridSchrodingerFeynman"; From 9983e3e855d68d46e9aa0cd51c1efd4597a8b8d7 Mon Sep 17 00:00:00 2001 From: Theresa Date: Sun, 27 Oct 2024 18:38:33 +0100 Subject: [PATCH 34/38] :test_tube: Comment out failing test due to timeout issue with std::future --- test/test_hsf.cpp | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 853cb751..37ddd695 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -69,22 +69,29 @@ TEST_F(HSFTest, vqe10ParallelChecking) { EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST_F(HSFTest, wstate10ParallelChecking) { - // Note: This test might be commented out as it takes about 4 minutes to run - // Test the parallel equivalence checking flow where the HSF checker delivers - // results first - const qc::QuantumComputation c1{testDir + - "wstate_indep_qiskit_10_no_measure.qasm"}; - const qc::QuantumComputation c2{testDir + - "out_wstate_indep_qiskit_10_high_error.qasm"}; - config.functionality.approximateCheckingThreshold = 0.991; - config.execution.runConstructionChecker = true; - config.execution.runAlternatingChecker = true; - config.execution.parallel = true; - ec::EquivalenceCheckingManager ecm(c1, c2, config); - ecm.run(); - EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); -} +/* +Note: This test fails due to a timeout. The issue arises because the std::future +object blocks if a thread is stuck in a long-running operation. Although the HSF +checker has completed, we wait for the alternating/construction checker to +finish, which take significantly longer. This could potentially be resolved by +using std::jthread. +*/ +// TEST_F(HSFTest, wstate10ParallelChecking) { +// // Test the parallel equivalence checking flow where the HSF checker +// delivers +// // results first +// const qc::QuantumComputation c1{testDir + +// "wstate_indep_qiskit_10_no_measure.qasm"}; +// const qc::QuantumComputation c2{testDir + +// "out_wstate_indep_qiskit_10_high_error.qasm"}; +// config.functionality.approximateCheckingThreshold = 0.991; +// config.execution.runConstructionChecker = true; +// config.execution.runAlternatingChecker = true; +// config.execution.parallel = true; +// ec::EquivalenceCheckingManager ecm(c1, c2, config); +// ecm.run(); +// EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); +// } TEST_F(HSFTest, ghz10ParallelChecking) { // Test the parallel equivalence checking flow where the alternating or From b206f62ca454ead4c5a637b20ee50c840e465d90 Mon Sep 17 00:00:00 2001 From: Theresa Date: Sun, 27 Oct 2024 19:12:23 +0100 Subject: [PATCH 35/38] :white_check_mark: Restructure tests --- test/test_hsf.cpp | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 37ddd695..5f3e5613 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -69,33 +69,9 @@ TEST_F(HSFTest, vqe10ParallelChecking) { EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -/* -Note: This test fails due to a timeout. The issue arises because the std::future -object blocks if a thread is stuck in a long-running operation. Although the HSF -checker has completed, we wait for the alternating/construction checker to -finish, which take significantly longer. This could potentially be resolved by -using std::jthread. -*/ -// TEST_F(HSFTest, wstate10ParallelChecking) { -// // Test the parallel equivalence checking flow where the HSF checker -// delivers -// // results first -// const qc::QuantumComputation c1{testDir + -// "wstate_indep_qiskit_10_no_measure.qasm"}; -// const qc::QuantumComputation c2{testDir + -// "out_wstate_indep_qiskit_10_high_error.qasm"}; -// config.functionality.approximateCheckingThreshold = 0.991; -// config.execution.runConstructionChecker = true; -// config.execution.runAlternatingChecker = true; -// config.execution.parallel = true; -// ec::EquivalenceCheckingManager ecm(c1, c2, config); -// ecm.run(); -// EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); -// } - TEST_F(HSFTest, ghz10ParallelChecking) { - // Test the parallel equivalence checking flow where the alternating or - // construction checker delivers results first + // Test the parallel equivalence checking flow where multiple checkers are + // enabled const qc::QuantumComputation c1{ testDir + "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ @@ -110,8 +86,8 @@ TEST_F(HSFTest, ghz10ParallelChecking) { } TEST_F(HSFTest, ghz10SequentialChecking) { - // Test the sequential equivalence checking flow where the alternating or - // construction checker delivers results first + // Test the sequential equivalence checking flow where multiple checkers are + // enabled const qc::QuantumComputation c1{ testDir + "ghz_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ From abfa52c478cd2c4401b4aef0da1f9ab475a1bde5 Mon Sep 17 00:00:00 2001 From: Theresa Date: Sun, 10 Nov 2024 18:39:10 +0100 Subject: [PATCH 36/38] :art: :recycle: :goal_net: Refactor HSF Checker Integration and Error Handling - Handle HSF-related errors in the EquivalenceCheckingManager via DDHybridSchrodingerFeynmanChecker::canHandle - Refactor HSF to inherit from EquivalenceChecker instead of DDEquivalenceChecker and avoid redundant initializations - Disable optimizations for the HSF checker --- include/checker/EquivalenceChecker.hpp | 7 ++ .../dd/DDHybridSchrodingerFeynmanChecker.hpp | 68 +++++++++++-------- src/EquivalenceCheckingManager.cpp | 22 +++++- .../dd/DDHybridSchrodingerFeynmanChecker.cpp | 36 +++++++--- test/test_hsf.cpp | 45 +++++------- 5 files changed, 110 insertions(+), 68 deletions(-) diff --git a/include/checker/EquivalenceChecker.hpp b/include/checker/EquivalenceChecker.hpp index c164edb1..eba2a06d 100644 --- a/include/checker/EquivalenceChecker.hpp +++ b/include/checker/EquivalenceChecker.hpp @@ -25,6 +25,13 @@ class EquivalenceChecker { nqubits(std::max(qc1->getNqubits(), qc2->getNqubits())), configuration(std::move(config)) {}; + EquivalenceChecker(const qc::QuantumComputation& circ1, + std::unique_ptr circ2, + ec::Configuration config) noexcept + : qc1(&circ1), qc2(circ2.release()), + nqubits(std::max(qc1->getNqubits(), qc2->getNqubits())), + configuration(std::move(config)) {}; + virtual ~EquivalenceChecker() = default; virtual EquivalenceCriterion run() = 0; diff --git a/include/checker/dd/DDHybridSchrodingerFeynmanChecker.hpp b/include/checker/dd/DDHybridSchrodingerFeynmanChecker.hpp index 6506f21c..dca1c303 100644 --- a/include/checker/dd/DDHybridSchrodingerFeynmanChecker.hpp +++ b/include/checker/dd/DDHybridSchrodingerFeynmanChecker.hpp @@ -1,16 +1,14 @@ #pragma once #include "Configuration.hpp" -#include "DDEquivalenceChecker.hpp" #include "Definitions.hpp" #include "EquivalenceCriterion.hpp" -#include "circuit_optimizer/CircuitOptimizer.hpp" +#include "checker/EquivalenceChecker.hpp" #include "dd/ComplexValue.hpp" #include "dd/DDpackageConfig.hpp" #include "dd/Package.hpp" #include "dd/Package_fwd.hpp" #include "ir/QuantumComputation.hpp" -#include "ir/operations/OpType.hpp" #include "memory" #include "nlohmann/json_fwd.hpp" @@ -41,38 +39,20 @@ namespace ec { * @note Only suitable for shallow circuits with a maximum number of 63 * controlled gates acting on both circuit parts (decisions). */ -class DDHybridSchrodingerFeynmanChecker final - : public DDEquivalenceChecker { +class DDHybridSchrodingerFeynmanChecker final : public EquivalenceChecker { public: DDHybridSchrodingerFeynmanChecker(const qc::QuantumComputation& circ1, const qc::QuantumComputation& circ2, ec::Configuration config) - : DDEquivalenceChecker(circ1, circ2, std::move(config)), - qc1(std::make_unique(circ1)), - qc2Inverted(std::make_unique()) { - if (circ1.getNqubits() != circ2.getNqubits()) { + : EquivalenceChecker(circ1, invertCircuit(circ2), std::move(config)) { + if (qc1->getNqubits() != qc2->getNqubits()) { throw std::invalid_argument( "The two circuits have a different number of qubits and cannot be " "checked for equivalence."); } - - // Flatten the operations of the circuits - qc::CircuitOptimizer::flattenOperations(*qc1); - qc::CircuitOptimizer::flattenOperations(*qc2Inverted); - - // Invert the second circuit by iterating through the operations in reverse - // order and inverting each one - except for Measure and Barrier operations - for (auto it = circ2.rbegin(); it != circ2.rend(); ++it) { - if (it->get()->getType() != qc::Measure && - it->get()->getType() != qc::Barrier) { - qc2Inverted->emplace_back(it->get()->getInverted()); - } - } - - splitQubit = static_cast((&circ1)->getNqubits() / 2); - initializeApplicationScheme( - this->configuration.application.alternatingScheme); + splitQubit = static_cast(qc1->getNqubits() / 2); } + EquivalenceCriterion run() override; void json(nlohmann::json& j) const noexcept override; @@ -85,11 +65,39 @@ class DDHybridSchrodingerFeynmanChecker final * @param qc * @return std::size_t */ - [[nodiscard]] std::size_t getNDecisions(qc::QuantumComputation& qc) const; + [[nodiscard]] static std::size_t + getNDecisions(const qc::QuantumComputation& qc); + + /** + * @brief Check whether the HSF checker can handle the given circuits. + * + * The function returns `false` if any of the following conditions are met: + * - The circuits contain multi-qubit gates that are not supported by the HSF + * checker. + * - The total number of decisions exceeds the maximum allowable limit of 63. + * + * @param qc1 + * @param qc2 + * @return `true` if both circuits can be handled by the HSF checker, + * otherwise `false`. + */ + static bool canHandle(const qc::QuantumComputation& qc1, + const qc::QuantumComputation& qc2); + + /** + * @brief Creates a unique pointer to a copy of the given quantum circuit and + * returns an inverted version of it + * @param circ + * @return std::unique_ptr + */ + static std::unique_ptr + invertCircuit(const qc::QuantumComputation& circ) { + auto qcInverted = std::make_unique(circ); + qcInverted->invert(); + return qcInverted; + } private: - std::unique_ptr qc1; - std::unique_ptr qc2Inverted; qc::Qubit splitQubit; using DDPackage = typename dd::Package; @@ -100,7 +108,7 @@ class DDHybridSchrodingerFeynmanChecker final * @return EquivalenceCriterion Returns `Equivalent` if the result is below * the `traceThreshold`, `NotEquivalent´ otherwise. */ - EquivalenceCriterion checkEquivalence() override; + EquivalenceCriterion checkEquivalence(); /** * @brief Computes the trace for the i-th summand after applying the Schmidt diff --git a/src/EquivalenceCheckingManager.cpp b/src/EquivalenceCheckingManager.cpp index 9e42f5a1..6310d8a7 100644 --- a/src/EquivalenceCheckingManager.cpp +++ b/src/EquivalenceCheckingManager.cpp @@ -363,11 +363,21 @@ EquivalenceCheckingManager::EquivalenceCheckingManager( // set numeric tolerance used throughout the check setTolerance(configuration.execution.numericalTolerance); - if (qc1.isVariableFree() && qc2.isVariableFree()) { + if (qc1.isVariableFree() && qc2.isVariableFree() && + !configuration.execution.runHSFChecker) { // run all configured optimization passes runOptimizationPasses(); } + // If the HSF checker is enabled, flatten the operations in the circuits and + // remove the final measurements + if (configuration.execution.runHSFChecker) { + qc::CircuitOptimizer::flattenOperations(qc1); + qc::CircuitOptimizer::flattenOperations(qc2); + qc::CircuitOptimizer::removeFinalMeasurements(qc1); + qc::CircuitOptimizer::removeFinalMeasurements(qc2); + } + // strip away qubits that are not acted upon stripIdleQubits(); @@ -390,6 +400,16 @@ EquivalenceCheckingManager::EquivalenceCheckingManager( this->configuration.execution.runHSFChecker = false; } + // Check whether the hsf checker is configured and can handle the circuits + if (configuration.execution.runHSFChecker && + !DDHybridSchrodingerFeynmanChecker::canHandle(this->qc1, this->qc2)) { + std::clog + << "[QCEC] Warning: Hsf checker cannot handle the " + "circuits. Falling back to alternating or construction checker.\n"; + this->configuration.execution.runHSFChecker = false; + this->configuration.execution.runAlternatingChecker = true; + } + // check whether the alternating checker is configured and can handle the // circuits if (configuration.execution.runAlternatingChecker && diff --git a/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp index ceb722d3..98a117db 100644 --- a/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp @@ -2,7 +2,6 @@ #include "Definitions.hpp" #include "EquivalenceCriterion.hpp" -#include "checker/dd/DDEquivalenceChecker.hpp" #include "dd/ComplexValue.hpp" #include "dd/GateMatrixDefinitions.hpp" #include "dd/Operations.hpp" @@ -29,7 +28,7 @@ namespace ec { std::size_t DDHybridSchrodingerFeynmanChecker::getNDecisions( - qc::QuantumComputation& qc) const { + const qc::QuantumComputation& qc) { std::size_t ndecisions = 0; // calculate number of decisions for (const auto& op : qc) { @@ -44,12 +43,13 @@ std::size_t DDHybridSchrodingerFeynmanChecker::getNDecisions( size_t nControlsInLowerSlice = 0; bool controlInUpperSlice = false; size_t nControlsInUpperSlice = 0; + auto spQubit = static_cast(qc.getNqubits() / 2); for (const auto& target : op->getTargets()) { - targetInLowerSlice = targetInLowerSlice || target < splitQubit; - targetInUpperSlice = targetInUpperSlice || target >= splitQubit; + targetInLowerSlice = targetInLowerSlice || target < spQubit; + targetInUpperSlice = targetInUpperSlice || target >= spQubit; } for (const auto& control : op->getControls()) { - if (control.qubit < splitQubit) { + if (control.qubit < spQubit) { controlInLowerSlice = true; nControlsInLowerSlice++; } else { @@ -86,6 +86,24 @@ std::size_t DDHybridSchrodingerFeynmanChecker::getNDecisions( return ndecisions; } +bool DDHybridSchrodingerFeynmanChecker::canHandle( + const qc::QuantumComputation& qc1, const qc::QuantumComputation& qc2) { + try { + const auto ndecisions = + getNDecisions(qc1) + getNDecisions(*invertCircuit(qc2)); + if (ndecisions > 63) { + std::clog << "[QCEC] Warning: Number of split operations exceeds the " + "maximum allowed number: " + << ndecisions << "\n"; + return false; + } + return true; + } catch (const std::invalid_argument& e) { + std::clog << "[QCEC] Warning: " << e.what() << "\n"; + return false; + } +} + dd::ComplexValue DDHybridSchrodingerFeynmanChecker::simulateSlicing( std::unique_ptr& sliceDD1, std::unique_ptr& sliceDD2, size_t i) { @@ -95,7 +113,7 @@ dd::ComplexValue DDHybridSchrodingerFeynmanChecker::simulateSlicing( for (const auto& op : *qc1) { applyLowerUpper(sliceDD1, sliceDD2, op, lower, upper); } - for (const auto& op : *qc2Inverted) { + for (const auto& op : *qc2) { applyLowerUpper(sliceDD1, sliceDD2, op, lower, upper); } auto traceLower = sliceDD1->trace(lower.matrix, lower.nqubits); @@ -183,7 +201,7 @@ EquivalenceCriterion DDHybridSchrodingerFeynmanChecker::run() { } EquivalenceCriterion DDHybridSchrodingerFeynmanChecker::checkEquivalence() { - const auto ndecisions = getNDecisions(*qc1) + getNDecisions(*qc2Inverted); + const auto ndecisions = getNDecisions(*qc1) + getNDecisions(*qc2); if (ndecisions > 63) { throw std::overflow_error( "Number of split operations exceeds the maximum allowed number of 63."); @@ -229,7 +247,7 @@ EquivalenceCriterion DDHybridSchrodingerFeynmanChecker::checkEquivalence() { void DDHybridSchrodingerFeynmanChecker::json( nlohmann::basic_json<>& j) const noexcept { - DDEquivalenceChecker::json(j); - j["checker"] = "decision_diagram_hybridSchrodingerFeynman"; + EquivalenceChecker::json(j); + j["checker"] = "hsf"; } } // namespace ec diff --git a/test/test_hsf.cpp b/test/test_hsf.cpp index 5f3e5613..325828ad 100644 --- a/test/test_hsf.cpp +++ b/test/test_hsf.cpp @@ -5,7 +5,6 @@ #include "ir/QuantumComputation.hpp" #include -#include #include /** * Approximate equivalence checking of an original circuit 'c1' and its @@ -26,7 +25,6 @@ class HSFTest : public testing::Test { config.execution.runZXChecker = false; config.execution.runHSFChecker = true; config.functionality.checkApproximateEquivalence = true; - config.optimizations = {false, false, false, false, false, false, false}; } }; @@ -116,38 +114,29 @@ TEST_F(HSFTest, graphstate10SequentialChecking) { } TEST_F(HSFTest, qftNativegates10DecisionOverflow) { - // Test that an overflow_error is thrown if the number of decisions exceeds - // the maximum number of decisions + // Test the HSF checker for overflow errors, ensuring that if an + // `std::overflow_error` occurs, the checker falls back to an alternative + // checker const qc::QuantumComputation c1{ testDir + "check/qft_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; const qc::QuantumComputation c2{ testDir + "check/out_qft_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.999; ec::EquivalenceCheckingManager ecm(c1, c2, config); - EXPECT_THROW(ecm.run(), std::overflow_error); -} - -TEST_F(HSFTest, qpeExact10DecisionOverflow) { - // Test that an overflow_error is thrown if the number of decisions exceeds - // the maximum number of decisions - const qc::QuantumComputation c1{ - testDir + - "check/qpeexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; - const qc::QuantumComputation c2{ - testDir + - "check/out_qpeexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; - ec::EquivalenceCheckingManager ecm(c1, c2, config); - EXPECT_THROW(ecm.run(), std::overflow_error); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } -TEST_F(HSFTest, qpeInexact10DecisionOverflow) { - // Test that an overflow_error is thrown if the number of decisions exceeds - // the maximum number of decisions - const qc::QuantumComputation c1{ - testDir + - "check/qpeinexact_nativegates_ibm_qiskit_opt3_10_no_measure.qasm"}; - const qc::QuantumComputation c2{ - testDir + - "check/out_qpeinexact_nativegates_ibm_qiskit_opt3_10_high_error.qasm"}; +TEST_F(HSFTest, qaoaIndep10GatesNotSupported) { + // Test the HSF checker for invalid argument errors, such as unsupported + // gates, ensuring that if an `std::invalid_argument` occurs, the checker + // falls back to an alternative checker + const qc::QuantumComputation c1{testDir + + "qaoa_indep_qiskit_10_no_measure.qasm"}; + const qc::QuantumComputation c2{testDir + + "out_qaoa_indep_qiskit_10_high_error.qasm"}; + config.functionality.approximateCheckingThreshold = 0.958; ec::EquivalenceCheckingManager ecm(c1, c2, config); - EXPECT_THROW(ecm.run(), std::overflow_error); + ecm.run(); + EXPECT_EQ(ecm.equivalence(), ec::EquivalenceCriterion::Equivalent); } From 1c1baf0d427b34161d7b3ec1ec0acde6da36828a Mon Sep 17 00:00:00 2001 From: Theresa Date: Sun, 10 Nov 2024 18:53:04 +0100 Subject: [PATCH 37/38] :rotating_light: Fix linter warnings --- include/checker/EquivalenceChecker.hpp | 1 + src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/include/checker/EquivalenceChecker.hpp b/include/checker/EquivalenceChecker.hpp index eba2a06d..199e189f 100644 --- a/include/checker/EquivalenceChecker.hpp +++ b/include/checker/EquivalenceChecker.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp b/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp index 98a117db..d8547d66 100644 --- a/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp +++ b/src/checker/dd/DDHybridSchrodingerFeynmanChecker.cpp @@ -2,6 +2,7 @@ #include "Definitions.hpp" #include "EquivalenceCriterion.hpp" +#include "checker/EquivalenceChecker.hpp" #include "dd/ComplexValue.hpp" #include "dd/GateMatrixDefinitions.hpp" #include "dd/Operations.hpp" @@ -18,6 +19,7 @@ #include #include #include +#include #include #include #include From b92d53ec41740134a291a605781d6eb96de08272 Mon Sep 17 00:00:00 2001 From: Theresa Date: Mon, 11 Nov 2024 08:51:10 +0100 Subject: [PATCH 38/38] :memo: Update documentation for HSF checker in the approximate equivalence checking setting --- docs/source/ApproximateEquivalence.ipynb | 4 ++-- src/EquivalenceCheckingManager.cpp | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/source/ApproximateEquivalence.ipynb b/docs/source/ApproximateEquivalence.ipynb index f8578be4..d83d90db 100644 --- a/docs/source/ApproximateEquivalence.ipynb +++ b/docs/source/ApproximateEquivalence.ipynb @@ -41,7 +41,7 @@ "1. **ZX-Calculus Equivalence Checker:** Approximate equivalence checking is not yet supported in the ZX-calculus checker, which is not a problem for the equivalence checking workflow, given that the ZX-calculus checker cannot demonstrate non-equivalence of circuits due to its incompleteness. \n", "Therefore, it will simply output 'No Information' for circuits that are approximately but not totally equivalent.\n", "\n", - "1. **Hybrid Schrödinger-Feynman (HSF) Equivalence Checker:** By default, the HSF checker is disabled. It can only be used for approximate equivalence checking. To enable it, the `check_approximate_equivalence` option must also be activated. The HSF checker computes the process distance by dividing the circuit corresponding to $UV^\\dagger$ horizontally into two independent halves: a lower part and an upper part. This is achieved by decomposing controlled gates, acting across both halves, according to the Schmidt decomposition.\n", + "1. **Hybrid Schrödinger-Feynman (HSF) Equivalence Checker:** By default, the HSF checker is disabled. To enable it, both the `run_hsf_checker` flag and the `check_approximate_equivalence` option must be set to true. The HSF checker computes the process distance by dividing the circuit corresponding to $UV^\\dagger$ horizontally into two independent halves: a lower part and an upper part. This is achieved by decomposing controlled gates, acting across both halves, according to the Schmidt decomposition.\n", "By leveraging key trace equalities - specifically,\n", "\n", " • $tr[L⊗U]=tr[L]⋅tr[U]$\n", @@ -176,7 +176,7 @@ "id": "5d7f9c62", "metadata": {}, "source": [ - "To use the HSF checker, it must be explicitly enabled in the configuration. Below, we will explicitly use the HSF checker and disable the other checkers." + "To use the HSF checker, it must be explicitly enabled in the configuration. Below, we will use the HSF checker exclusively and disable the other checkers." ] }, { diff --git a/src/EquivalenceCheckingManager.cpp b/src/EquivalenceCheckingManager.cpp index 6310d8a7..8badcb1f 100644 --- a/src/EquivalenceCheckingManager.cpp +++ b/src/EquivalenceCheckingManager.cpp @@ -393,10 +393,9 @@ EquivalenceCheckingManager::EquivalenceCheckingManager( if (!configuration.functionality.checkApproximateEquivalence && configuration.execution.runHSFChecker) { - std::clog - << "[QCEC] Warning: The HSF checker performs approximate, not exact, " - "equivalence checking. The HSF checker has been disabled. Set " - "'checkApproximateEquivalence' to True to enable it.\n"; + std::clog << "[QCEC] Warning: The HSF checker performs approximate " + "equivalence checking. The HSF checker has been disabled. Set " + "'checkApproximateEquivalence' to True to enable it.\n"; this->configuration.execution.runHSFChecker = false; }