@@ -19,7 +19,7 @@ void HeuristicMapper::map(const MappingSettings& ms) {
1919
2020 createLayers ();
2121 if (ms.verbose ) {
22- std::clog << " Teleportation qubits: " << ms.teleportation_qubits << " \n " ;
22+ std::clog << " Teleportation qubits: " << ms.teleportationQubits << " \n " ;
2323 printLayering (std::clog);
2424 }
2525
@@ -182,31 +182,31 @@ void HeuristicMapper::initResults() {
182182 Mapper::initResults ();
183183 results.method = Method::Heuristic;
184184
185- results.seed = settings.teleportation_seed ;
186- results.input_teleportation_qubits = settings.teleportation_qubits ;
187- results.output_teleportation_qubits = settings.teleportation_qubits ;
188- results.output_teleportation_fake = settings.teleportation_fake ;
185+ results.seed = settings.teleportationSeed ;
186+ results.input_teleportation_qubits = settings.teleportationQubits ;
187+ results.output_teleportation_qubits = settings.teleportationQubits ;
188+ results.output_teleportation_fake = settings.teleportationFake ;
189189}
190190
191191void HeuristicMapper::createInitialMapping () {
192192 if (layers.empty ())
193193 return ;
194194
195- if (settings.teleportation_qubits > 0 ) {
195+ if (settings.teleportationQubits > 0 ) {
196196 std::mt19937_64 mt;
197- if (settings.teleportation_seed == 0 ) {
197+ if (settings.teleportationSeed == 0 ) {
198198 std::array<std::mt19937_64::result_type, std::mt19937_64::state_size> random_data{};
199199 std::random_device rd;
200200 std::generate (std::begin (random_data), std::end (random_data), [&rd]() { return rd (); });
201201 std::seed_seq seeds (std::begin (random_data), std::end (random_data));
202202 mt.seed (seeds);
203203 } else {
204- mt.seed (settings.teleportation_seed );
204+ mt.seed (settings.teleportationSeed );
205205 }
206206
207207 std::uniform_int_distribution<> dis (0 , architecture.getNqubits () - 1 );
208208
209- for (int i = 0 ; i < settings.teleportation_qubits ; i += 2 ) {
209+ for (int i = 0 ; i < settings.teleportationQubits ; i += 2 ) {
210210 Edge e;
211211 do {
212212 auto it = std::begin (architecture.getCouplingMap ());
@@ -217,12 +217,11 @@ void HeuristicMapper::createInitialMapping() {
217217 locations[qc.getNqubits () + i + 1 ] = e.second ;
218218 qubits[e.first ] = qc.getNqubits () + i;
219219 qubits[e.second ] = qc.getNqubits () + i + 1 ;
220- // std::clog << "initial teleportation pair: " << e.first << ", " << e.second << "\n";
221220 }
222221
223- if (settings.teleportation_fake ) {
224- settings.teleportation_qubits = 0 ;
225- results.output_teleportation_qubits = settings.teleportation_qubits ;
222+ if (settings.teleportationFake ) {
223+ settings.teleportationQubits = 0 ;
224+ results.output_teleportation_qubits = settings.teleportationQubits ;
226225 }
227226 }
228227
@@ -300,21 +299,34 @@ void HeuristicMapper::mapUnmappedGates(long layer, HeuristicMapper::Node& node,
300299 possibleEdges.emplace (edge);
301300 }
302301 }
302+ std::pair<unsigned short , unsigned short > chosenEdge;
303303
304304 if (possibleEdges.empty ()) {
305- throw QMAPException (" Could not map logical qubits to physical qubits. No suitable edge found." );
305+ double bestScore = std::numeric_limits<int >::max ();
306+
307+ for (int i=0 ; i < architecture.getNqubits (); i++) {
308+ for (int j = i + 1 ; j < architecture.getNqubits (); j++) {
309+ if (qubits.at (i) == DEFAULT_POSITION && qubits.at (j) == DEFAULT_POSITION) {
310+ double dist = architecture.distance (i, j);
311+ if (dist < bestScore) {
312+ bestScore = dist;
313+ chosenEdge = std::make_pair (i, j);
314+ }
315+ }
316+ }
317+ }
318+ } else {
319+ chosenEdge = *possibleEdges.begin ();
306320 }
307-
308321 // TODO: Consider fidelity here if available. The best available edge should be chosen
309- auto & chosenEdge = *possibleEdges.begin ();
310- locations.at (gate.control ) = chosenEdge.first ;
311- locations.at (gate.target ) = chosenEdge.second ;
312- qubits.at (chosenEdge.first ) = gate.control ;
313- qubits.at (chosenEdge.second ) = gate.target ;
314- qc::QuantumComputation::findAndSWAP (gate.control , chosenEdge.first , qcMapped.initialLayout );
315- qc::QuantumComputation::findAndSWAP (gate.target , chosenEdge.second , qcMapped.initialLayout );
316- qc::QuantumComputation::findAndSWAP (gate.control , chosenEdge.first , qcMapped.outputPermutation );
317- qc::QuantumComputation::findAndSWAP (gate.target , chosenEdge.second , qcMapped.outputPermutation );
322+ locations.at (gate.control ) = chosenEdge.first ;
323+ locations.at (gate.target ) = chosenEdge.second ;
324+ qubits.at (chosenEdge.first ) = gate.control ;
325+ qubits.at (chosenEdge.second ) = gate.target ;
326+ qc::QuantumComputation::findAndSWAP (gate.control , chosenEdge.first , qcMapped.initialLayout );
327+ qc::QuantumComputation::findAndSWAP (gate.target , chosenEdge.second , qcMapped.initialLayout );
328+ qc::QuantumComputation::findAndSWAP (gate.control , chosenEdge.first , qcMapped.outputPermutation );
329+ qc::QuantumComputation::findAndSWAP (gate.target , chosenEdge.second , qcMapped.outputPermutation );
318330 } else if (controlLocation == DEFAULT_POSITION) {
319331 mapToMinDistance (gate.target , gate.control );
320332 } else if (targetLocation == DEFAULT_POSITION) {
@@ -382,7 +394,9 @@ void HeuristicMapper::expandNode(const std::vector<unsigned short>& consideredQu
382394
383395 std::set<Edge> perms = architecture.getCouplingMap ();
384396 architecture.getCurrentTeleportations ().clear ();
385- for (int i = 0 ; i < settings.teleportation_qubits ; i+=2 ) {
397+ architecture.getTeleportationQubits ().clear ();
398+ for (int i = 0 ; i < settings.teleportationQubits ; i+=2 ) {
399+ architecture.getTeleportationQubits ().emplace_back (node.locations [qc.getNqubits () + i], node.locations [qc.getNqubits () + i + 1 ]);
386400 Edge e;
387401 for (auto const & g : architecture.getCouplingMap ()) {
388402 if (g.first == node.locations [qc.getNqubits () + i] && g.second != node.locations [qc.getNqubits () + i + 1 ]) {
@@ -434,14 +448,22 @@ void HeuristicMapper::expand_node_add_one_swap(const Edge &swap, Node& node, lon
434448
435449 Node new_node = Node (node.qubits , node.locations , node.swaps );
436450 new_node.nswaps ++;
437- if (architecture.bidirectional ()) {
438- new_node.costFixed = node.costFixed + COST_BIDIRECTIONAL_SWAP;
439- } else {
440- new_node.costFixed = node.costFixed + COST_UNIDIRECTIONAL_SWAP;
441- }
442451
443452 new_node.swaps .emplace_back ();
444- new_node.applySWAP (swap, architecture);
453+ if (architecture.getCouplingMap ().find (swap) != architecture.getCouplingMap ().end () ||
454+ architecture.getCouplingMap ().find (Edge {swap.second , swap.first }) != architecture.getCouplingMap ().end ()) {
455+
456+ if (architecture.bidirectional ()) {
457+ new_node.costFixed = node.costFixed + COST_BIDIRECTIONAL_SWAP;
458+ } else {
459+ new_node.costFixed = node.costFixed + COST_UNIDIRECTIONAL_SWAP;
460+ }
461+
462+ new_node.applySWAP (swap, architecture);
463+ } else {
464+ new_node.costFixed = node.costFixed + COST_TELEPORTATION;
465+ new_node.applyTeleportation (swap, architecture);
466+ }
445467 new_node.costTotal = new_node.costFixed ;
446468 new_node.done = true ;
447469
0 commit comments