Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions cirq-core/cirq/transformers/routing/mapping_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

Comment thread
ammareltigani marked this conversation as resolved.
"""Manages the mapping from logical to physical qubits during a routing procedure."""

from typing import Dict, Sequence, TYPE_CHECKING
from cirq._compat import cached_method
import networkx as nx
Expand All @@ -23,7 +25,7 @@


class MappingManager:
"""Class that keeps track of the mapping of logical to physical qubits.
"""Class that manages the mapping from logical to physical qubits.

Convenience methods over distance and mapping queries of the physical qubits are also provided.
All such public methods of this class expect logical qubits.
Expand Down Expand Up @@ -116,8 +118,17 @@ def mapped_op(self, op: 'cirq.Operation') -> 'cirq.Operation':
return op.transform_qubits(self._map)

def shortest_path(self, lq1: 'cirq.Qid', lq2: 'cirq.Qid') -> Sequence['cirq.Qid']:
"""Find the shortest path between two logical qubits on the device given their mapping."""
return self._physical_shortest_path(self._map[lq1], self._map[lq2])
"""Find the shortest path between two logical qubits on the device given their mapping.

Args:
lq1: the first logical qubit.
lq2: the second logical qubit.

Returns:
a sequence of logical qubits on the shortest path from lq1 to lq2.
Comment thread
ammareltigani marked this conversation as resolved.
Outdated
"""
physical_shortest_path = self._physical_shortest_path(self._map[lq1], self._map[lq2])
return [self._inverse_map[pq] for pq in physical_shortest_path]

@cached_method
def _physical_shortest_path(self, pq1: 'cirq.Qid', pq2: 'cirq.Qid') -> Sequence['cirq.Qid']:
Expand Down
25 changes: 8 additions & 17 deletions cirq-core/cirq/transformers/routing/mapping_manager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,23 +132,14 @@ def test_shortest_path():
device_graph, initial_mapping, q = construct_device_graph_and_mapping()
mm = cirq.transformers.routing.MappingManager(device_graph, initial_mapping)

assert mm.shortest_path(q[1], q[2]) == [
cirq.NamedQubit("a"),
cirq.NamedQubit("b"),
cirq.NamedQubit("c"),
]
shortest_one_to_four = [
cirq.NamedQubit("a"),
cirq.NamedQubit("b"),
cirq.NamedQubit("c"),
cirq.NamedQubit("d"),
]
assert mm.shortest_path(q[1], q[4]) == shortest_one_to_four
one_to_four = [q[1], q[3], q[2], q[4]]
assert mm.shortest_path(q[1], q[2]) == one_to_four[:3]
assert mm.shortest_path(q[1], q[4]) == one_to_four
# shortest path on symmetric qubit reverses the list
assert mm.shortest_path(q[4], q[1]) == shortest_one_to_four[::-1]
assert mm.shortest_path(q[4], q[1]) == one_to_four[::-1]

# swapping doesn't change shortest paths involving other qubits
mm.apply_swap(q[3], q[2])
assert mm.shortest_path(q[1], q[4]) == shortest_one_to_four
# swapping changes shortest paths involving the swapped qubits
assert mm.shortest_path(q[1], q[2]) == [cirq.NamedQubit("a"), cirq.NamedQubit("b")]
mm.apply_swap(q[3], q[2])
one_to_four[1], one_to_four[2] = one_to_four[2], one_to_four[1]
assert mm.shortest_path(q[1], q[4]) == one_to_four
assert mm.shortest_path(q[1], q[2]) == [q[1], q[2]]