Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added __str__ and __repr__ for MappingManager and pushed name 'MappingMananger' to 'cirq' namespace #5828

Merged
Merged
1 change: 1 addition & 0 deletions cirq-core/cirq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@
eject_z,
expand_composite,
is_negligible_turn,
MappingManager,
map_moments,
map_operations,
map_operations_and_unroll,
Expand Down
2 changes: 2 additions & 0 deletions cirq-core/cirq/protocols/json_test_data/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@
# Transformers
'TransformerLogger',
'TransformerContext',
# Routing classes
'MappingManager',
# global objects
'CONTROL_TAG',
'PAULI_BASIS',
Expand Down
2 changes: 2 additions & 0 deletions cirq-core/cirq/transformers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
two_qubit_gate_product_tabulation,
)

from cirq.transformers.routing import MappingManager

from cirq.transformers.target_gatesets import (
create_transformer_with_kwargs,
CompilationTargetGateset,
Expand Down
12 changes: 12 additions & 0 deletions cirq-core/cirq/transformers/routing/mapping_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
import networkx as nx

from cirq import protocols
from cirq.value import value_equality
ammareltigani marked this conversation as resolved.
Show resolved Hide resolved

if TYPE_CHECKING:
import cirq


@value_equality
class MappingManager:
"""Class that manages the mapping from logical to physical qubits.

Expand All @@ -41,6 +43,7 @@ def __init__(
initial_mapping: the initial mapping of logical (keys) to physical qubits (values).
"""
self.device_graph = device_graph
self.graph_adjacency = dict(self.device_graph.adjacency())
ammareltigani marked this conversation as resolved.
Show resolved Hide resolved
self._map = initial_mapping.copy()
self._inverse_map = {v: k for k, v in self._map.items()}
self._induced_subgraph = nx.induced_subgraph(self.device_graph, self._map.values())
Expand Down Expand Up @@ -133,3 +136,12 @@ def shortest_path(self, lq1: 'cirq.Qid', lq2: 'cirq.Qid') -> Sequence['cirq.Qid'
@cached_method
def _physical_shortest_path(self, pq1: 'cirq.Qid', pq2: 'cirq.Qid') -> Sequence['cirq.Qid']:
return nx.shortest_path(self._induced_subgraph, pq1, pq2)

def _value_equality_values_(self):
return self.graph_adjacency, self._map
ammareltigani marked this conversation as resolved.
Show resolved Hide resolved

def __str__(self) -> str:
return f'Device graph adjacency: {self.graph_adjacency}\nMap: {self._map}'

def __repr__(self) -> str:
return f'cirq.MappingManager(nx.Graph({self.graph_adjacency}), {self._map})'
ammareltigani marked this conversation as resolved.
Show resolved Hide resolved
25 changes: 20 additions & 5 deletions cirq-core/cirq/transformers/routing/mapping_manager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def construct_device_graph_and_mapping():

def test_induced_subgraph():
device_graph, initial_mapping, _ = construct_device_graph_and_mapping()
mm = cirq.transformers.routing.MappingManager(device_graph, initial_mapping)
mm = cirq.MappingManager(device_graph, initial_mapping)

expected_induced_subgraph = nx.Graph(
[
Expand All @@ -55,7 +55,7 @@ def test_induced_subgraph():

def test_mapped_op():
device_graph, initial_mapping, q = construct_device_graph_and_mapping()
mm = cirq.transformers.routing.MappingManager(device_graph, initial_mapping)
mm = cirq.MappingManager(device_graph, initial_mapping)

assert mm.mapped_op(cirq.CNOT(q[1], q[3])).qubits == (
cirq.NamedQubit("a"),
Expand All @@ -82,7 +82,7 @@ def test_mapped_op():

def test_distance_on_device_and_can_execute():
device_graph, initial_mapping, q = construct_device_graph_and_mapping()
mm = cirq.transformers.routing.MappingManager(device_graph, initial_mapping)
mm = cirq.MappingManager(device_graph, initial_mapping)

# adjacent qubits have distance 1 and are thus executable
assert mm.dist_on_device(q[1], q[3]) == 1
Expand All @@ -108,7 +108,7 @@ def test_distance_on_device_and_can_execute():

def test_apply_swap():
device_graph, initial_mapping, q = construct_device_graph_and_mapping()
mm = cirq.transformers.routing.MappingManager(device_graph, initial_mapping)
mm = cirq.MappingManager(device_graph, initial_mapping)

# swapping non-adjacent qubits raises error
with pytest.raises(ValueError):
Expand All @@ -130,7 +130,7 @@ def test_apply_swap():

def test_shortest_path():
device_graph, initial_mapping, q = construct_device_graph_and_mapping()
mm = cirq.transformers.routing.MappingManager(device_graph, initial_mapping)
mm = cirq.MappingManager(device_graph, initial_mapping)

one_to_four = [q[1], q[3], q[2], q[4]]
assert mm.shortest_path(q[1], q[2]) == one_to_four[:3]
Expand All @@ -143,3 +143,18 @@ def test_shortest_path():
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]]


ammareltigani marked this conversation as resolved.
Show resolved Hide resolved
def test_repr():
device_graph, initial_mapping, _ = construct_device_graph_and_mapping()
mm = cirq.MappingManager(device_graph, initial_mapping)
cirq.testing.assert_equivalent_repr(mm, setup_code='import cirq\nimport networkx as nx')
ammareltigani marked this conversation as resolved.
Show resolved Hide resolved


def test_str():
device_graph, initial_mapping, _ = construct_device_graph_and_mapping()
mm = cirq.MappingManager(device_graph, initial_mapping)
assert (
str(mm)
== f'Device graph adjacency: {dict(device_graph.adjacency())}\nMap: {initial_mapping}'
)