diff --git a/extern/qfr b/extern/qfr index b38fe5f48..22528b327 160000 --- a/extern/qfr +++ b/extern/qfr @@ -1 +1 @@ -Subproject commit b38fe5f4880090e650ad84865d4114a9e3c2edf1 +Subproject commit 22528b3275e1eed2a302124aeb34a911fb918980 diff --git a/include/Mapper.hpp b/include/Mapper.hpp index d7a211560..d2c505938 100644 --- a/include/Mapper.hpp +++ b/include/Mapper.hpp @@ -42,8 +42,8 @@ class Mapper { } }; - qc::QuantumComputation& qc; - Architecture& architecture; + qc::QuantumComputation qc; + Architecture& architecture; qc::QuantumComputation qcMapped; std::vector> layers{}; @@ -65,8 +65,16 @@ class Mapper { virtual void placeRemainingArchitectureQubits(); virtual void finalizeMappedCircuit(); + virtual void countGates(const qc::QuantumComputation& circuit, MappingResults::CircuitInfo& info) { + countGates(circuit.cbegin(), circuit.cend(), info); + } + virtual void countGates(decltype(qcMapped.cbegin()) it, const decltype(qcMapped.cend())& end, MappingResults::CircuitInfo& info); + + virtual void preMappingOptimizations(const Configuration& config); + virtual void postMappingOptimizations(const Configuration& config); + public: - Mapper(qc::QuantumComputation& qc, Architecture& architecture); + Mapper(const qc::QuantumComputation& qc, Architecture& architecture); virtual ~Mapper() = default; virtual void map(const Configuration& config) = 0; diff --git a/include/MappingResults.hpp b/include/MappingResults.hpp index 5c34c8ad3..67ad79dd2 100644 --- a/include/MappingResults.hpp +++ b/include/MappingResults.hpp @@ -64,7 +64,6 @@ struct MappingResults { circuit["gates"] = input.gates; circuit["single_qubit_gates"] = input.singleQubitGates; circuit["cnots"] = input.cnots; - circuit["layers"] = input.layers; auto& mapped_circuit = resultJSON["mapped_circuit"]; mapped_circuit["name"] = output.name; @@ -72,23 +71,24 @@ struct MappingResults { mapped_circuit["gates"] = output.gates; mapped_circuit["single_qubit_gates"] = output.singleQubitGates; mapped_circuit["cnots"] = output.cnots; - mapped_circuit["swaps"] = output.swaps; if (!mappedCircuit.empty()) { mapped_circuit["qasm"] = mappedCircuit; } - if (config.method == Method::Exact) { - mapped_circuit["direction_reverse"] = output.directionReverse; - } else if (config.method == Method::Heuristic) { - mapped_circuit["teleportations"] = output.teleportations; - } resultJSON["config"] = config.json(); - auto& stats = resultJSON["statistics"]; - stats["timeout"] = timeout; - stats["mapping_time"] = time; - stats["additional_gates"] = output.gates - input.gates; - stats["arch"] = architecture; + auto& stats = resultJSON["statistics"]; + stats["timeout"] = timeout; + stats["mapping_time"] = time; + stats["arch"] = architecture; + stats["layers"] = input.layers; + stats["swaps"] = output.swaps; + if (config.method == Method::Exact) { + stats["direction_reverse"] = output.directionReverse; + } else if (config.method == Method::Heuristic) { + stats["teleportations"] = output.teleportations; + } + stats["additional_gates"] = static_cast(output.gates) - input.gates; return resultJSON; } diff --git a/include/configuration/Configuration.hpp b/include/configuration/Configuration.hpp index 7983f9a6a..fb54e1e7b 100644 --- a/include/configuration/Configuration.hpp +++ b/include/configuration/Configuration.hpp @@ -22,6 +22,9 @@ struct Configuration { // which method to use Method method = Method::Heuristic; + bool preMappingOptimizations = true; + bool postMappingOptimizations = true; + bool verbose = false; // map to particular subgraph of architecture (in exact mapper) @@ -73,7 +76,9 @@ struct Configuration { if (!subgraph.empty()) { config["subgraph"] = subgraph; } - config["verbose"] = verbose; + config["pre_mapping_optimizations"] = preMappingOptimizations; + config["post_mapping_optimizations"] = postMappingOptimizations; + config["verbose"] = verbose; if (method == Method::Heuristic) { auto& heuristic = config["settings"]; diff --git a/mqt/qmap/bindings.cpp b/mqt/qmap/bindings.cpp index 001cb2be4..62b404a80 100644 --- a/mqt/qmap/bindings.cpp +++ b/mqt/qmap/bindings.cpp @@ -184,6 +184,8 @@ PYBIND11_MODULE(pyqmap, m) { .def_readwrite("swap_limit", &Configuration::swapLimit) .def_readwrite("use_bdd", &Configuration::useBDD) .def_readwrite("subgraph", &Configuration::subgraph) + .def_readwrite("pre_mapping_optimizations", &Configuration::preMappingOptimizations) + .def_readwrite("post_mapping_optimizations", &Configuration::postMappingOptimizations) .def("json", &Configuration::json) .def("__repr__", &Configuration::toString); diff --git a/mqt/qmap/compile.py b/mqt/qmap/compile.py index 6aea1356e..c1751f773 100644 --- a/mqt/qmap/compile.py +++ b/mqt/qmap/compile.py @@ -24,6 +24,8 @@ def compile(circ, arch: Union[str, Arch], include_WCNF: bool = False, use_subsets: bool = True, subgraph: Optional[Set[int]] = None, + pre_mapping_optimizations: bool = True, + post_mapping_optimizations: bool = True, verbose: bool = False ) -> MappingResults: """Interface to the MQT QMAP tool for mapping quantum circuits @@ -57,6 +59,10 @@ def compile(circ, arch: Union[str, Arch], :param use_teleportation: Use teleportation in addition to swaps :param teleportation_fake: Assign qubits as ancillary for teleportation in the initial placement but don't actually use them (used for comparisons) :param teleportation_seed: Fix a seed for the RNG in the initial ancilla placement (0 means the RNG will be seeded from /dev/urandom/ or similar) + :param pre_mapping_optimizations: Run pre-mapping optimizations (default: True) + :type pre_mapping_optimizations: bool + :param post_mapping_optimizations: Run post-mapping optimizations (default: True) + :type post_mapping_optimizations: bool :param verbose: Print more detailed information during the mapping process :type verbose: bool :return: Object containing all the results @@ -84,6 +90,8 @@ def compile(circ, arch: Union[str, Arch], config.use_teleportation = use_teleportation config.teleportation_fake = teleportation_fake config.teleportation_seed = teleportation_seed + config.pre_mapping_optimizations = pre_mapping_optimizations + config.post_mapping_optimizations = post_mapping_optimizations config.verbose = verbose return map(circ, arch, config) diff --git a/src/Mapper.cpp b/src/Mapper.cpp index e7efd89af..778e171e6 100644 --- a/src/Mapper.cpp +++ b/src/Mapper.cpp @@ -5,7 +5,10 @@ #include "Mapper.hpp" +#include "CircuitOptimizer.hpp" + void Mapper::initResults() { + countGates(qc, results.input); results.input.name = qc.getName(); results.input.qubits = qc.getNqubits(); results.architecture = architecture.getArchitectureName(); @@ -15,11 +18,12 @@ void Mapper::initResults() { qcMapped.addQubitRegister(architecture.getNqubits()); } -Mapper::Mapper(qc::QuantumComputation& quantumComputation, Architecture& arch): - qc(quantumComputation), architecture(arch) { +Mapper::Mapper(const qc::QuantumComputation& quantumComputation, Architecture& arch): + qc(quantumComputation.clone()), architecture(arch) { qubits.fill(DEFAULT_POSITION); locations.fill(DEFAULT_POSITION); fidelities.fill(INITIAL_FIDELITY); + qc.stripIdleQubits(true, true); } void Mapper::createLayers() { @@ -29,6 +33,7 @@ void Mapper::createLayers() { auto qubitsInLayer = std::set{}; + bool even = true; for (auto& gate: qc) { // skip over barrier instructions if (gate->getType() == qc::Barrier || gate->getType() == qc::Measure) { @@ -46,9 +51,9 @@ void Mapper::createLayers() { bool singleQubit = gate->getControls().empty(); short control = -1; if (!singleQubit) { - control = static_cast((*gate->getControls().begin()).qubit); + control = static_cast(qc.initialLayout.at((*gate->getControls().begin()).qubit)); } - unsigned short target = gate->getTargets().at(0); + unsigned short target = qc.initialLayout.at(gate->getTargets().at(0)); size_t layer = 0; switch (config.layering) { @@ -72,12 +77,13 @@ void Mapper::createLayers() { layers.at(layer).emplace_back(control, target, gate.get()); break; case Layering::OddGates: - if (results.input.gates % 2 == 0) { + if (even) { layers.emplace_back(); layers.back().emplace_back(control, target, gate.get()); } else { layers.back().emplace_back(control, target, gate.get()); } + even = !even; break; case Layering::QubitTriangle: if (layers.empty()) { @@ -103,13 +109,6 @@ void Mapper::createLayers() { } break; } - - if (singleQubit) { - results.input.singleQubitGates++; - } else { - results.input.cnots++; - } - results.input.gates++; } results.input.layers = layers.size(); } @@ -184,3 +183,56 @@ void Mapper::placeRemainingArchitectureQubits() { } } } + +void Mapper::preMappingOptimizations(const Configuration& config [[maybe_unused]]) { + if (!config.preMappingOptimizations) { + return; + } + + // at the moment there are no pre-mapping optimizations +} + +void Mapper::postMappingOptimizations(const Configuration& config) { + if (!config.postMappingOptimizations) { + return; + } + + // try to cancel adjacent CNOT gates + qc::CircuitOptimizer::cancelCNOTs(qcMapped); +} + +void Mapper::countGates(decltype(qcMapped.cbegin()) it, const decltype(qcMapped.cend())& end, MappingResults::CircuitInfo& info) { + for (; it != end; ++it) { + const auto& g = *it; + if (g->getType() == qc::Teleportation) { + info.gates += GATES_OF_TELEPORTATION; + continue; + } + + if (g->isStandardOperation()) { + if (g->getType() == qc::SWAP) { + if (architecture.bidirectional()) { + info.gates += GATES_OF_BIDIRECTIONAL_SWAP; + info.cnots += GATES_OF_BIDIRECTIONAL_SWAP; + } else { + info.gates += GATES_OF_UNIDIRECTIONAL_SWAP; + info.cnots += GATES_OF_BIDIRECTIONAL_SWAP; + info.singleQubitGates += GATES_OF_DIRECTION_REVERSE; + } + } else if (g->getControls().empty()) { + ++info.singleQubitGates; + ++info.gates; + } else { + assert(g->getType() == qc::X); + ++info.cnots; + ++info.gates; + } + continue; + } + + if (g->isCompoundOperation()) { + const auto& cg = dynamic_cast(g.get()); + countGates(cg->cbegin(), cg->cend(), info); + } + } +} diff --git a/src/exact/ExactMapper.cpp b/src/exact/ExactMapper.cpp index ce4506e85..b462af681 100644 --- a/src/exact/ExactMapper.cpp +++ b/src/exact/ExactMapper.cpp @@ -10,9 +10,11 @@ void ExactMapper::map(const Configuration& settings) { const auto& config = results.config; std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); - qc.stripIdleQubits(true, true); initResults(); + // 0) perform pre-mapping optimizations + preMappingOptimizations(config); + // 1) create layers according to different criteria createLayers(); if (config.verbose) { @@ -35,14 +37,14 @@ void ExactMapper::map(const Configuration& settings) { // quickly terminate if the circuit only contains single-qubit gates if (reducedLayerIndices.empty()) { - results.output.gates = results.input.gates; - results.output.cnots = results.input.cnots; - results.output.singleQubitGates = results.input.singleQubitGates; - results.output.layers = results.input.layers; - results.time = static_cast>(std::chrono::high_resolution_clock::now() - start).count(); - results.timeout = false; - qcMapped = qc.clone(); + qcMapped = qc.clone(); + postMappingOptimizations(config); + countGates(qcMapped, results.output); finalizeMappedCircuit(); + + results.output.layers = results.input.layers; + results.time = static_cast>(std::chrono::high_resolution_clock::now() - start).count(); + results.timeout = false; return; } @@ -215,23 +217,15 @@ void ExactMapper::map(const Configuration& settings) { for (unsigned long i = 0U; i < layers.size(); ++i) { if (i == 0U) { - // invert the initial layout of the original circuit (most certainly the identity) - // in order to determine the correct qubit mapping - qc::Permutation inverseInitialLayout{}; - for (const auto& [physical, logical]: qc.initialLayout) { - inverseInitialLayout.insert({logical, physical}); - } - qcMapped.initialLayout.clear(); qcMapped.outputPermutation.clear(); // no swaps but initial permutation for (const auto& [physical, logical]: *swapsIterator) { - dd::Qubit inverseLogical = inverseInitialLayout.at(static_cast(logical)); - locations.at(inverseLogical) = static_cast(physical); - qubits.at(physical) = static_cast(inverseLogical); - qcMapped.initialLayout[static_cast(physical)] = inverseLogical; - qcMapped.outputPermutation[static_cast(physical)] = inverseLogical; + locations.at(logical) = static_cast(physical); + qubits.at(physical) = static_cast(logical); + qcMapped.initialLayout[static_cast(physical)] = static_cast(logical); + qcMapped.outputPermutation[static_cast(physical)] = static_cast(logical); } // place remaining architecture qubits @@ -311,6 +305,16 @@ void ExactMapper::map(const Configuration& settings) { } } + // 9) apply post mapping optimizations + postMappingOptimizations(config); + + // 10) re-count gates + results.output.singleQubitGates = 0U; + results.output.cnots = 0U; + results.output.gates = 0U; + countGates(qcMapped, results.output); + + // 11) final post-processing finalizeMappedCircuit(); auto end = std::chrono::high_resolution_clock::now(); @@ -508,16 +512,16 @@ void ExactMapper::coreMappingRoutine(const std::set& qubitChoice expr coupling = c.bool_val(false); if (architecture.bidirectional()) { for (const auto& edge: rcm) { - auto indexFC = x[k][physicalQubitIndex[edge.first]][qc.initialLayout.at(gate.control)]; - auto indexST = x[k][physicalQubitIndex[edge.second]][qc.initialLayout.at(gate.target)]; + auto indexFC = x[k][physicalQubitIndex[edge.first]][gate.control]; + auto indexST = x[k][physicalQubitIndex[edge.second]][gate.target]; coupling = coupling || (indexFC && indexST); } } else { for (const auto& edge: rcm) { - auto indexFC = x[k][physicalQubitIndex[edge.first]][qc.initialLayout.at(gate.control)]; - auto indexST = x[k][physicalQubitIndex[edge.second]][qc.initialLayout.at(gate.target)]; - auto indexFT = x[k][physicalQubitIndex[edge.first]][qc.initialLayout.at(gate.target)]; - auto indexSC = x[k][physicalQubitIndex[edge.second]][qc.initialLayout.at(gate.control)]; + auto indexFC = x[k][physicalQubitIndex[edge.first]][gate.control]; + auto indexST = x[k][physicalQubitIndex[edge.second]][gate.target]; + auto indexFT = x[k][physicalQubitIndex[edge.first]][gate.target]; + auto indexSC = x[k][physicalQubitIndex[edge.second]][gate.control]; coupling = coupling || ((indexFC && indexST) || (indexFT && indexSC)); } @@ -630,8 +634,8 @@ void ExactMapper::coreMappingRoutine(const std::set& qubitChoice expr reverse = c.bool_val(true); for (const auto& edge: rcm) { - auto indexFT = x[k][physicalQubitIndex[edge.first]][qc.initialLayout.at(gate.target)]; - auto indexSC = x[k][physicalQubitIndex[edge.second]][qc.initialLayout.at(gate.control)]; + auto indexFT = x[k][physicalQubitIndex[edge.first]][gate.target]; + auto indexSC = x[k][physicalQubitIndex[edge.second]][gate.control]; reverse = reverse && (!indexFT || !indexSC); } opt.add(reverse.simplify(), GATES_OF_DIRECTION_REVERSE); @@ -701,8 +705,8 @@ void ExactMapper::coreMappingRoutine(const std::set& qubitChoice if (gate.singleQubit()) continue; for (const auto& edge: rcm) { - auto indexFT = x[k][physicalQubitIndex[edge.first]][qc.initialLayout.at(gate.target)]; - auto indexSC = x[k][physicalQubitIndex[edge.second]][qc.initialLayout.at(gate.control)]; + auto indexFT = x[k][physicalQubitIndex[edge.first]][gate.target]; + auto indexSC = x[k][physicalQubitIndex[edge.second]][gate.control]; if (eq(m.eval(indexFT && indexSC), c.bool_val(true))) { choiceResults.output.directionReverse++; choiceResults.output.gates += GATES_OF_DIRECTION_REVERSE; diff --git a/src/heuristic/HeuristicMapper.cpp b/src/heuristic/HeuristicMapper.cpp index 381822736..e6adc9ce6 100644 --- a/src/heuristic/HeuristicMapper.cpp +++ b/src/heuristic/HeuristicMapper.cpp @@ -15,9 +15,11 @@ void HeuristicMapper::map(const Configuration& ms) { return; } const auto start = std::chrono::steady_clock::now(); - qc.stripIdleQubits(true, false); initResults(); + // perform pre-mapping optimizations + preMappingOptimizations(config); + createLayers(); if (config.verbose) { std::clog << "Teleportation qubits: " << config.teleportationQubits << "\n"; @@ -50,15 +52,9 @@ void HeuristicMapper::map(const Configuration& ms) { for (const auto& swap: swaps) { if (swap.op == qc::SWAP) { qcMapped.swap(swap.first, swap.second); - if (architecture.bidirectional()) { - results.output.gates += GATES_OF_BIDIRECTIONAL_SWAP; - } else { - results.output.gates += GATES_OF_UNIDIRECTIONAL_SWAP; - } results.output.swaps++; } else if (swap.op == qc::Teleportation) { qcMapped.emplace_back(qcMapped.getNqubits(), qc::Targets{static_cast(swap.first), static_cast(swap.second), static_cast(swap.middle_ancilla)}, qc::Teleportation); - results.output.gates += GATES_OF_TELEPORTATION; results.output.teleportations++; } gateidx++; @@ -82,8 +78,6 @@ void HeuristicMapper::map(const Configuration& ms) { op->getParameter().at(1), op->getParameter().at(2)); gatesToAdjust.push_back(gateidx); - results.output.gates++; - results.output.singleQubitGates++; gateidx++; } else { qcMapped.emplace_back(qcMapped.getNqubits(), @@ -92,8 +86,6 @@ void HeuristicMapper::map(const Configuration& ms) { op->getParameter().at(0), op->getParameter().at(1), op->getParameter().at(2)); - results.output.gates++; - results.output.singleQubitGates++; gateidx++; } } else { @@ -110,13 +102,9 @@ void HeuristicMapper::map(const Configuration& ms) { qcMapped.h(reverse.first); results.output.directionReverse++; - results.output.cnots++; - results.output.gates += 5; gateidx += 5; } else { qcMapped.x(cnot.second, dd::Control{static_cast(cnot.first)}); - results.output.cnots++; - results.output.gates++; gateidx++; } } @@ -176,6 +164,9 @@ void HeuristicMapper::map(const Configuration& ms) { ++count; } } + + postMappingOptimizations(config); + countGates(qcMapped, results.output); finalizeMappedCircuit(); const auto end = std::chrono::steady_clock::now(); diff --git a/test/test_exact.cpp b/test/test_exact.cpp index eaa63f808..bdf2a2f86 100644 --- a/test/test_exact.cpp +++ b/test/test_exact.cpp @@ -14,23 +14,35 @@ class ExactTest: public testing::TestWithParam { std::string test_architecture_dir = "./architectures/"; std::string test_calibration_dir = "./calibration/"; - qc::QuantumComputation qc{}; - Configuration settings{}; - Architecture IBMQ_Yorktown{}; - Architecture IBMQ_London{}; - Architecture IBM_QX4{}; - ExactMapper IBMQ_Yorktown_mapper{qc, IBMQ_Yorktown}; - ExactMapper IBMQ_London_mapper{qc, IBMQ_London}; - ExactMapper IBM_QX4_mapper{qc, IBM_QX4}; + qc::QuantumComputation qc{}; + Configuration settings{}; + Architecture IBMQ_Yorktown{}; + Architecture IBMQ_London{}; + Architecture IBM_QX4{}; + std::unique_ptr IBMQ_Yorktown_mapper; + std::unique_ptr IBMQ_London_mapper; + std::unique_ptr IBM_QX4_mapper; void SetUp() override { + using namespace dd::literals; + if (::testing::UnitTest::GetInstance()->current_test_info()->value_param()) { qc.import(test_example_dir + GetParam() + ".qasm"); + } else { + qc.addQubitRegister(3U); + qc.x(0, 1_pc); + qc.x(1, 2_pc); + qc.x(2, 0_pc); } IBMQ_Yorktown.loadCouplingMap(AvailableArchitecture::IBMQ_Yorktown); IBMQ_London.loadCouplingMap(test_architecture_dir + "ibmq_london.arch"); IBMQ_London.loadCalibrationData(test_calibration_dir + "ibmq_london.csv"); IBM_QX4.loadCouplingMap(AvailableArchitecture::IBM_QX4); + + IBMQ_Yorktown_mapper = std::make_unique(qc, IBMQ_Yorktown); + IBMQ_London_mapper = std::make_unique(qc, IBMQ_London); + IBM_QX4_mapper = std::make_unique(qc, IBM_QX4); + settings.verbose = true; settings.method = Method::Exact; } @@ -52,173 +64,173 @@ INSTANTIATE_TEST_SUITE_P(Exact, ExactTest, TEST_P(ExactTest, IndividualGates) { settings.layering = Layering::IndividualGates; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_individual.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_individual.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); - IBMQ_London_mapper.map(settings); - IBMQ_London_mapper.dumpResult(GetParam() + "_exact_london_individual.qasm"); - IBMQ_London_mapper.printResult(std::cout); + IBMQ_London_mapper->map(settings); + IBMQ_London_mapper->dumpResult(GetParam() + "_exact_london_individual.qasm"); + IBMQ_London_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, DisjointQubits) { settings.layering = Layering::DisjointQubits; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_disjoint.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_disjoint.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); - IBMQ_London_mapper.map(settings); - IBMQ_London_mapper.dumpResult(GetParam() + "_exact_london_disjoint.qasm"); - IBMQ_London_mapper.printResult(std::cout); + IBMQ_London_mapper->map(settings); + IBMQ_London_mapper->dumpResult(GetParam() + "_exact_london_disjoint.qasm"); + IBMQ_London_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, OddGates) { settings.layering = Layering::OddGates; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_odd.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_odd.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, QubitTriangle) { settings.layering = Layering::QubitTriangle; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_triangle.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_triangle.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, CommanderEncodingfixed3) { settings.encoding = Encoding::Commander; settings.commanderGrouping = CommanderGrouping::Fixed3; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_commander_fixed3.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_commander_fixed3.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, CommanderEncodingfixed2) { settings.encoding = Encoding::Commander; settings.commanderGrouping = CommanderGrouping::Fixed2; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_commander_fixed2.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_commander_fixed2.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, CommanderEncodinghalves) { settings.encoding = Encoding::Commander; settings.commanderGrouping = CommanderGrouping::Halves; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_commander_halves.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_commander_halves.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, CommanderEncodinglogarithm) { settings.encoding = Encoding::Commander; settings.commanderGrouping = CommanderGrouping::Logarithm; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_commander_log.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_commander_log.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, CommanderEncodingUnidirectionalfixed3) { settings.encoding = Encoding::Commander; settings.commanderGrouping = CommanderGrouping::Fixed3; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_commander_fixed3.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_commander_fixed3.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, CommanderEncodingUnidirectionalfixed2) { settings.encoding = Encoding::Commander; settings.commanderGrouping = CommanderGrouping::Fixed2; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_commander_fixed2.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_commander_fixed2.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, CommanderEncodingUnidirectionalhalves) { settings.encoding = Encoding::Commander; settings.commanderGrouping = CommanderGrouping::Halves; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_commander_halves.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_commander_halves.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, CommanderEncodingUnidirectionallogarithm) { settings.encoding = Encoding::Commander; settings.commanderGrouping = CommanderGrouping::Logarithm; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_commander_log.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_commander_log.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, BimanderEncodingfixed3) { settings.encoding = Encoding::Bimander; settings.commanderGrouping = CommanderGrouping::Fixed3; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_bimander.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_bimander.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, BimanderEncodingfixed2) { settings.encoding = Encoding::Bimander; settings.commanderGrouping = CommanderGrouping::Fixed2; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_bimander.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_bimander.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, BimanderEncodinghalves) { settings.encoding = Encoding::Bimander; settings.commanderGrouping = CommanderGrouping::Halves; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_bimander.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_bimander.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, BimanderEncodinglogaritm) { settings.encoding = Encoding::Bimander; settings.commanderGrouping = CommanderGrouping::Logarithm; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_bimander.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_bimander.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, BimanderEncodingUnidirectionalfixed3) { settings.encoding = Encoding::Bimander; settings.commanderGrouping = CommanderGrouping::Fixed3; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_bimander.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_bimander.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, BimanderEncodingUnidirectionalfixed2) { settings.encoding = Encoding::Bimander; settings.commanderGrouping = CommanderGrouping::Fixed2; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_bimander.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_bimander.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, BimanderEncodingUnidirectionalhalves) { settings.encoding = Encoding::Bimander; settings.commanderGrouping = CommanderGrouping::Halves; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_bimander.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_bimander.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, BimanderEncodingUnidirectionallogarithm) { settings.encoding = Encoding::Bimander; settings.commanderGrouping = CommanderGrouping::Logarithm; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_bimander.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_bimander.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } @@ -226,27 +238,27 @@ TEST_P(ExactTest, LimitsBidirectional) { settings.enableSwapLimits = true; settings.useSubsets = false; settings.swapReduction = SwapReduction::CouplingLimit; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_swapreduct.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_swapreduct.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, LimitsBidirectionalSubsetSwaps) { settings.enableSwapLimits = true; settings.useSubsets = true; settings.swapReduction = SwapReduction::CouplingLimit; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_swapreduct.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_swapreduct.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, LimitsBidirectionalCustomLimit) { settings.enableSwapLimits = true; settings.swapReduction = SwapReduction::Custom; settings.swapLimit = 10; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_swapreduct.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_swapreduct.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } @@ -254,45 +266,45 @@ TEST_P(ExactTest, LimitsUnidirectional) { settings.enableSwapLimits = true; settings.useSubsets = false; settings.swapReduction = SwapReduction::CouplingLimit; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_swapreduct.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_swapreduct.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, LimitsUnidirectionalSubsetSwaps) { settings.enableSwapLimits = true; settings.useSubsets = true; settings.swapReduction = SwapReduction::CouplingLimit; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_swapreduct.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_swapreduct.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, LimitsUnidirectionalCustomLimit) { settings.enableSwapLimits = true; settings.swapReduction = SwapReduction::Custom; settings.swapLimit = 10; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_swapreduct.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_swapreduct.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, IncreasingCustomLimitUnidirectional) { settings.enableSwapLimits = true; settings.swapReduction = SwapReduction::Increasing; settings.swapLimit = 3; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_swapreduct_inccustom.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_swapreduct_inccustom.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, IncreasingUnidirectional) { settings.enableSwapLimits = true; settings.swapReduction = SwapReduction::Increasing; settings.swapLimit = 0; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_swapreduct_inc.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_swapreduct_inc.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } @@ -301,9 +313,9 @@ TEST_P(ExactTest, LimitsBidirectionalBDD) { settings.useSubsets = false; settings.useBDD = true; settings.swapReduction = SwapReduction::CouplingLimit; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_swapreduct_bdd.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_swapreduct_bdd.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, LimitsBidirectionalSubsetSwapsBDD) { @@ -311,18 +323,18 @@ TEST_P(ExactTest, LimitsBidirectionalSubsetSwapsBDD) { settings.useSubsets = true; settings.useBDD = true; settings.swapReduction = SwapReduction::CouplingLimit; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_exact_yorktown_swapreduct_bdd.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_exact_yorktown_swapreduct_bdd.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(ExactTest, NoSubsets) { settings.useSubsets = false; settings.enableSwapLimits = false; - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(GetParam() + "_exact_QX4_nosubsets.qasm"); - IBM_QX4_mapper.printResult(std::cout); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(GetParam() + "_exact_QX4_nosubsets.qasm"); + IBM_QX4_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } @@ -356,25 +368,19 @@ TEST_P(ExactTest, toStringMethods) { } TEST_F(ExactTest, CircuitWithOnlySingleQubitGates) { - qc.addQubitRegister(2U); + qc.clear(); qc.x(0); qc.x(1); - IBM_QX4_mapper.map(settings); - IBM_QX4_mapper.dumpResult(std::cout, qc::OpenQASM); + IBM_QX4_mapper = std::make_unique(qc, IBM_QX4); + IBM_QX4_mapper->map(settings); + IBM_QX4_mapper->dumpResult(std::cout, qc::OpenQASM); SUCCEED() << "Mapping successful"; } TEST_F(ExactTest, MapToSubsetNotIncludingQ0) { - using namespace dd::literals; - CouplingMap cm{{0, 1}, {1, 0}, {1, 2}, {2, 1}, {2, 3}, {3, 2}, {1, 3}, {3, 1}}; Architecture arch(4U, cm); - qc.addQubitRegister(3U); - qc.x(0, 1_pc); - qc.x(1, 2_pc); - qc.x(2, 0_pc); - auto mapper = ExactMapper(qc, arch); settings.useSubsets = false; mapper.map(settings); @@ -392,65 +398,37 @@ TEST_F(ExactTest, MapToSubsetNotIncludingQ0) { } TEST_F(ExactTest, WCNF) { - using namespace dd::literals; - - qc.addQubitRegister(3U); - qc.x(0, 1_pc); - qc.x(1, 2_pc); - qc.x(2, 0_pc); - settings.verbose = false; settings.includeWCNF = true; - IBMQ_London_mapper.map(settings); - const auto& wcnf = IBMQ_London_mapper.getResults().wcnf; + IBMQ_London_mapper->map(settings); + const auto& wcnf = IBMQ_London_mapper->getResults().wcnf; std::cout << wcnf << std::endl; EXPECT_TRUE(!wcnf.empty()); } TEST_F(ExactTest, MapToSubgraph) { - using namespace dd::literals; - - qc.addQubitRegister(3U); - qc.x(0, 1_pc); - qc.x(1, 2_pc); - qc.x(2, 0_pc); - const auto connectedSubset = std::set{0U, 1U, 2U}; settings.subgraph = connectedSubset; - IBMQ_London_mapper.map(settings); - const auto& results = IBMQ_London_mapper.getResults(); + IBMQ_London_mapper->map(settings); + const auto& results = IBMQ_London_mapper->getResults(); EXPECT_FALSE(results.timeout); } TEST_F(ExactTest, MapToSubgraphTooSmall) { - using namespace dd::literals; - - qc.addQubitRegister(3U); - qc.x(0, 1_pc); - qc.x(1, 2_pc); - qc.x(2, 0_pc); - const auto tooSmallSubset = std::set{0U, 1U}; settings.subgraph = tooSmallSubset; - IBMQ_London_mapper.map(settings); - const auto& results = IBMQ_London_mapper.getResults(); + IBMQ_London_mapper->map(settings); + const auto& results = IBMQ_London_mapper->getResults(); EXPECT_TRUE(results.timeout); } TEST_F(ExactTest, MapToSubgraphNotConnected) { - using namespace dd::literals; - - qc.addQubitRegister(3U); - qc.x(0, 1_pc); - qc.x(1, 2_pc); - qc.x(2, 0_pc); - const auto nonConnectedSubset = std::set{0U, 2U, 3U}; settings.subgraph = nonConnectedSubset; - IBMQ_London_mapper.map(settings); - const auto& results = IBMQ_London_mapper.getResults(); + IBMQ_London_mapper->map(settings); + const auto& results = IBMQ_London_mapper->getResults(); EXPECT_TRUE(results.timeout); } diff --git a/test/test_heuristic.cpp b/test/test_heuristic.cpp index adba8a1b2..180c549dc 100644 --- a/test/test_heuristic.cpp +++ b/test/test_heuristic.cpp @@ -14,17 +14,19 @@ class HeuristicTest5Q: public testing::TestWithParam { std::string test_architecture_dir = "./architectures/"; std::string test_calibration_dir = "./calibration/"; - qc::QuantumComputation qc{}; - Architecture IBMQ_Yorktown{}; - Architecture IBMQ_London{}; - HeuristicMapper IBMQ_Yorktown_mapper{qc, IBMQ_Yorktown}; - HeuristicMapper IBMQ_London_mapper{qc, IBMQ_London}; + qc::QuantumComputation qc{}; + Architecture IBMQ_Yorktown{}; + Architecture IBMQ_London{}; + std::unique_ptr IBMQ_Yorktown_mapper; + std::unique_ptr IBMQ_London_mapper; void SetUp() override { qc.import(test_example_dir + GetParam() + ".qasm"); IBMQ_Yorktown.loadCouplingMap(AvailableArchitecture::IBMQ_Yorktown); IBMQ_London.loadCouplingMap(test_architecture_dir + "ibmq_london.arch"); IBMQ_London.loadCalibrationData(test_calibration_dir + "ibmq_london.csv"); + IBMQ_Yorktown_mapper = std::make_unique(qc, IBMQ_Yorktown); + IBMQ_London_mapper = std::make_unique(qc, IBMQ_London); } }; @@ -59,37 +61,37 @@ INSTANTIATE_TEST_SUITE_P(Heuristic, HeuristicTest5Q, TEST_P(HeuristicTest5Q, Identity) { Configuration settings{}; settings.initialLayout = InitialLayout::Identity; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_heuristic_qx4_identity.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_heuristic_qx4_identity.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); - IBMQ_London_mapper.map(settings); - IBMQ_London_mapper.dumpResult(GetParam() + "_heuristic_london_identity.qasm"); - IBMQ_London_mapper.printResult(std::cout); + IBMQ_London_mapper->map(settings); + IBMQ_London_mapper->dumpResult(GetParam() + "_heuristic_london_identity.qasm"); + IBMQ_London_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(HeuristicTest5Q, Static) { Configuration settings{}; settings.initialLayout = InitialLayout::Static; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_heuristic_qx4_static.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); - IBMQ_London_mapper.map(settings); - IBMQ_London_mapper.dumpResult(GetParam() + "_heuristic_london_static.qasm"); - IBMQ_London_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_heuristic_qx4_static.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); + IBMQ_London_mapper->map(settings); + IBMQ_London_mapper->dumpResult(GetParam() + "_heuristic_london_static.qasm"); + IBMQ_London_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } TEST_P(HeuristicTest5Q, Dynamic) { Configuration settings{}; settings.initialLayout = InitialLayout::Dynamic; - IBMQ_Yorktown_mapper.map(settings); - IBMQ_Yorktown_mapper.dumpResult(GetParam() + "_heuristic_qx4_dynamic.qasm"); - IBMQ_Yorktown_mapper.printResult(std::cout); - IBMQ_London_mapper.map(settings); - IBMQ_London_mapper.dumpResult(GetParam() + "_heuristic_london_dynamic.qasm"); - IBMQ_London_mapper.printResult(std::cout); + IBMQ_Yorktown_mapper->map(settings); + IBMQ_Yorktown_mapper->dumpResult(GetParam() + "_heuristic_qx4_dynamic.qasm"); + IBMQ_Yorktown_mapper->printResult(std::cout); + IBMQ_London_mapper->map(settings); + IBMQ_London_mapper->dumpResult(GetParam() + "_heuristic_london_dynamic.qasm"); + IBMQ_London_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } @@ -98,13 +100,14 @@ class HeuristicTest16Q: public testing::TestWithParam { std::string test_example_dir = "../../examples/"; std::string test_architecture_dir = "../../extern/architectures/"; - qc::QuantumComputation qc{}; - Architecture IBM_QX5{}; - HeuristicMapper IBM_QX5_mapper{qc, IBM_QX5}; + qc::QuantumComputation qc{}; + Architecture IBM_QX5{}; + std::unique_ptr IBM_QX5_mapper; void SetUp() override { qc.import(test_example_dir + GetParam() + ".qasm"); IBM_QX5.loadCouplingMap(AvailableArchitecture::IBM_QX5); + IBM_QX5_mapper = std::make_unique(qc, IBM_QX5); } }; @@ -124,9 +127,9 @@ INSTANTIATE_TEST_SUITE_P(Heuristic, HeuristicTest16Q, TEST_P(HeuristicTest16Q, Dynamic) { Configuration settings{}; settings.initialLayout = InitialLayout::Dynamic; - IBM_QX5_mapper.map(settings); - IBM_QX5_mapper.dumpResult(GetParam() + "_heuristic_qx5_dynamic.qasm"); - IBM_QX5_mapper.printResult(std::cout); + IBM_QX5_mapper->map(settings); + IBM_QX5_mapper->dumpResult(GetParam() + "_heuristic_qx5_dynamic.qasm"); + IBM_QX5_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } @@ -135,13 +138,14 @@ class HeuristicTest20Q: public testing::TestWithParam { std::string test_example_dir = "../../examples/"; std::string test_architecture_dir = "../../extern/architectures/"; - qc::QuantumComputation qc{}; - Architecture arch{}; - HeuristicMapper tokyo_mapper{qc, arch}; + qc::QuantumComputation qc{}; + Architecture arch{}; + std::unique_ptr tokyo_mapper; void SetUp() override { qc.import(test_example_dir + GetParam() + ".qasm"); arch.loadCouplingMap(AvailableArchitecture::IBMQ_Tokyo); + tokyo_mapper = std::make_unique(qc, arch); } }; @@ -162,9 +166,9 @@ INSTANTIATE_TEST_SUITE_P(Heuristic, HeuristicTest20Q, TEST_P(HeuristicTest20Q, Dynamic) { Configuration settings{}; settings.initialLayout = InitialLayout::Dynamic; - tokyo_mapper.map(settings); - tokyo_mapper.dumpResult(GetParam() + "_heuristic_tokyo_dynamic.qasm"); - tokyo_mapper.printResult(std::cout); + tokyo_mapper->map(settings); + tokyo_mapper->dumpResult(GetParam() + "_heuristic_tokyo_dynamic.qasm"); + tokyo_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; } @@ -173,13 +177,14 @@ class HeuristicTest20QTeleport: public testing::TestWithParam tokyo_mapper; void SetUp() override { qc.import(test_example_dir + std::get<1>(GetParam()) + ".qasm"); arch.loadCouplingMap(AvailableArchitecture::IBMQ_Tokyo); + tokyo_mapper = std::make_unique(qc, arch); } }; @@ -199,8 +204,8 @@ TEST_P(HeuristicTest20QTeleport, Teleportation) { settings.initialLayout = InitialLayout::Dynamic; settings.teleportationQubits = std::min((arch.getNqubits() - qc.getNqubits()) & ~1u, 8u); settings.teleportationSeed = std::get<0>(GetParam()); - tokyo_mapper.map(settings); - tokyo_mapper.dumpResult(std::get<1>(GetParam()) + "_heuristic_tokyo_teleport.qasm"); - tokyo_mapper.printResult(std::cout); + tokyo_mapper->map(settings); + tokyo_mapper->dumpResult(std::get<1>(GetParam()) + "_heuristic_tokyo_teleport.qasm"); + tokyo_mapper->printResult(std::cout); SUCCEED() << "Mapping successful"; }