forked from Qiskit/qiskit
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CheckMap analysis pass (Qiskit#1317)
* layout object * layout object * getitem None * lint * get_physical * set length * idle_wires * docstring in _layout.py * docstrings in test * doc * Update qiskit/mapper/_layout.py Co-Authored-By: 1ucian0 <[email protected]> * swap error * Update qiskit/mapper/_layout.py Co-Authored-By: 1ucian0 <[email protected]> * key error if gettin a None * get_logical -> get_bits. get_physical -> get_wires * length -> set_length * logical is not a good name * physical no more * QuantumRegister instead of strings * add_register * style * get_cnot_nodes * check map analysis pass * style * no-effect stmt * style * lint * docstring * no expand_gates=False * Coupling(couplingdict=...
- Loading branch information
Showing
4 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,4 @@ | |
|
||
from .cx_cancellation import CXCancellation | ||
from .fixed_point import FixedPoint | ||
from .check_map import CheckMap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
# Copyright 2018, IBM. | ||
# | ||
# This source code is licensed under the Apache License, Version 2.0 found in | ||
# the LICENSE.txt file in the root directory of this source tree. | ||
|
||
""" | ||
This pass checks if a DAG is mapped to a coupling map. | ||
""" | ||
|
||
from qiskit.transpiler._basepasses import AnalysisPass | ||
from qiskit.mapper import Layout | ||
|
||
|
||
class CheckMap(AnalysisPass): | ||
""" | ||
Checks if a DAGCircuit is mapped to `coupling_map`. | ||
""" | ||
|
||
def __init__(self, coupling_map, initial_layout=None): | ||
""" | ||
Checks if a DAGCircuit is mapped to `coupling_map`. | ||
Args: | ||
coupling_map (Coupling): Directed graph represented a coupling map. | ||
initial_layout (Layout): The initial layout of the DAG to analyze. | ||
""" | ||
super().__init__() | ||
self.layout = initial_layout | ||
self.coupling_map = coupling_map | ||
|
||
def run(self, dag): | ||
""" | ||
If `dag` is mapped to coupling_map, the property `is_mapped` is | ||
set to True (or to False otherwise). | ||
Args: | ||
dag (DAGCircuit): DAG to map. | ||
""" | ||
if self.layout is None: | ||
self.layout = Layout() | ||
for qreg in dag.qregs.values(): | ||
self.layout.add_register(qreg) | ||
|
||
self.property_set['is_mapped'] = None | ||
for layer in dag.serial_layers(): | ||
subdag = layer['graph'] | ||
|
||
for a_cx in subdag.get_cnot_nodes(): | ||
physical_q0 = ('q', self.layout[a_cx['op'].qargs[0]]) | ||
physical_q1 = ('q', self.layout[a_cx['op'].qargs[1]]) | ||
if self.coupling_map.distance(physical_q0, physical_q1) != 1: | ||
self.property_set['is_mapped'] = False | ||
return | ||
self.property_set['is_mapped'] = True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
# Copyright 2018, IBM. | ||
# | ||
# This source code is licensed under the Apache License, Version 2.0 found in | ||
# the LICENSE.txt file in the root directory of this source tree. | ||
|
||
"""Test the Check Map pass""" | ||
|
||
import unittest | ||
|
||
from qiskit import QuantumRegister, QuantumCircuit | ||
from qiskit.transpiler.passes import CheckMap | ||
from qiskit.mapper import Coupling | ||
from qiskit.dagcircuit import DAGCircuit | ||
from ..common import QiskitTestCase | ||
|
||
|
||
class TestCheckMap(QiskitTestCase): | ||
""" Tests the CheckMap pass.""" | ||
|
||
def test_trivial_map(self): | ||
""" Trivial map in a circuit without entanglement | ||
qr0:---[H]--- | ||
qr1:---[H]--- | ||
qr2:---[H]--- | ||
Coupling map: None | ||
""" | ||
qr = QuantumRegister(3, 'qr') | ||
circuit = QuantumCircuit(qr) | ||
circuit.h(qr) | ||
coupling = Coupling() | ||
dag = DAGCircuit.fromQuantumCircuit(circuit) | ||
pass_ = CheckMap(coupling) | ||
pass_.run(dag) | ||
self.assertTrue(pass_.property_set['is_mapped']) | ||
|
||
def test_true_map(self): | ||
""" Mapped is easy to check | ||
qr0:--(+)-[H]-(+)- | ||
| | | ||
qr1:---.-------|-- | ||
| | ||
qr2:-----------.-- | ||
Coupling map: [1]--[0]--[2] | ||
""" | ||
qr = QuantumRegister(3, 'qr') | ||
circuit = QuantumCircuit(qr) | ||
circuit.cx(qr[0], qr[1]) | ||
circuit.h(qr[0]) | ||
circuit.cx(qr[0], qr[2]) | ||
coupling = Coupling(couplingdict={0: [1, 2]}) | ||
dag = DAGCircuit.fromQuantumCircuit(circuit) | ||
|
||
pass_ = CheckMap(coupling) | ||
pass_.run(dag) | ||
|
||
self.assertTrue(pass_.property_set['is_mapped']) | ||
|
||
def test_true_map_in_same_layer(self): | ||
""" Two CXs distance 1 to each other, in the same layer | ||
qr0:--(+)-- | ||
| | ||
qr1:---.--- | ||
qr2:--(+)-- | ||
| | ||
qr3:---.--- | ||
Coupling map: [0]--[1]--[2]--[3] | ||
""" | ||
qr = QuantumRegister(4, 'qr') | ||
circuit = QuantumCircuit(qr) | ||
circuit.cx(qr[0], qr[1]) | ||
circuit.cx(qr[2], qr[3]) | ||
coupling = Coupling(couplingdict={0: [1], 1: [2], 2: [3]}) | ||
dag = DAGCircuit.fromQuantumCircuit(circuit) | ||
|
||
pass_ = CheckMap(coupling) | ||
pass_.run(dag) | ||
|
||
self.assertTrue(pass_.property_set['is_mapped']) | ||
|
||
def test_false_map(self): | ||
""" Needs [0]-[1] in a [0]--[2]--[1] | ||
qr0:--(+)-- | ||
| | ||
qr1:---.--- | ||
Coupling map: [0]--[2]--[1] | ||
""" | ||
qr = QuantumRegister(2, 'qr') | ||
circuit = QuantumCircuit(qr) | ||
circuit.cx(qr[0], qr[1]) | ||
coupling = Coupling(couplingdict={0: [2], 2: [1]}) | ||
dag = DAGCircuit.fromQuantumCircuit(circuit) | ||
|
||
pass_ = CheckMap(coupling) | ||
pass_.run(dag) | ||
|
||
self.assertFalse(pass_.property_set['is_mapped']) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |