Obtain a reduced coupling_map for a subgraph of a device (#2225)

* reduced_coupling_map

* style

* new headers

* make reduce a CouplingMap method

* get rid of 'backend'

* fix test for python version dependent ordering

* fix idx
This commit is contained in:
Paul Nation 2019-05-02 05:35:16 -04:00 committed by Ali Javadi-Abhari
parent 1b4a6976b7
commit 25bed6f9f0
2 changed files with 61 additions and 1 deletions

View File

@ -23,8 +23,9 @@ CNOT gates. The object has a distance function that can be used to map quantum c
onto a device with this coupling.
"""
import numpy as np
import scipy.sparse as sp
import scipy.sparse.csgraph as cs
import networkx as nx
from qiskit.transpiler.exceptions import CouplingError
@ -185,6 +186,45 @@ class CouplingMap:
raise CouplingError(
"Nodes %s and %s are not connected" % (str(physical_qubit1), str(physical_qubit2)))
def reduce(self, mapping):
"""Returns a reduced coupling map that
corresponds to the subgraph of qubits
selected in the mapping.
Args:
mapping (list): A mapping of reduced qubits to device
qubits.
Returns:
CouplingMap: A reduced coupling_map for the selected qubits.
Raises:
CouplingError: Reduced coupling map must be connected.
"""
reduced_qubits = len(mapping)
inv_map = [None]*(max(mapping)+1)
for idx, val in enumerate(mapping):
inv_map[val] = idx
reduced_cmap = []
for edge in self.get_edges():
if edge[0] in mapping and edge[1] in mapping:
reduced_cmap.append([inv_map[edge[0]], inv_map[edge[1]]])
# Verify coupling_map is connected
rows = np.array([edge[0] for edge in reduced_cmap], dtype=int)
cols = np.array([edge[1] for edge in reduced_cmap], dtype=int)
data = np.ones_like(rows)
mat = sp.coo_matrix((data, (rows, cols)),
shape=(reduced_qubits, reduced_qubits)).tocsr()
if cs.connected_components(mat)[0] != 1:
raise CouplingError('coupling_map must be connected.')
return CouplingMap(reduced_cmap)
def __str__(self):
"""Return a string representation of the coupling graph."""
string = ""

View File

@ -16,6 +16,7 @@
from qiskit.transpiler import CouplingMap
from qiskit.transpiler.exceptions import CouplingError
from qiskit.test.mock import FakeRueschlikon
from qiskit.test import QiskitTestCase
@ -78,3 +79,22 @@ class CouplingTest(QiskitTestCase):
self.assertEqual(coupling.physical_qubits, qubits_expected)
self.assertEqual(coupling.get_edges(), edges_expected)
self.assertEqual(2, coupling.distance(0, 2))
def test_successful_reduced_map(self):
"""Generate a reduced map
"""
fake = FakeRueschlikon()
cmap = fake.configuration().coupling_map
coupling_map = CouplingMap(cmap)
out = coupling_map.reduce([12, 11, 10, 9]).get_edges()
ans = [(1, 2), (3, 2), (0, 1)]
self.assertEqual(set(out), set(ans))
def test_failed_reduced_map(self):
"""Generate a bad disconnected reduced map
"""
fake = FakeRueschlikon()
cmap = fake.configuration().coupling_map
coupling_map = CouplingMap(cmap)
with self.assertRaises(CouplingError):
coupling_map.reduce([12, 11, 10, 3])