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.
* clean unroller * docstring * moving conditianl handeling in side substitute_circuit_one * rename the method to make it more descriptive * initial commit * linting
- Loading branch information
Showing
7 changed files
with
174 additions
and
59 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
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 |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# -*- 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. | ||
|
||
"""Pass for decompose a gate in a circuit.""" | ||
|
||
from qiskit.transpiler._basepasses import TransformationPass | ||
|
||
|
||
class Decompose(TransformationPass): | ||
""" | ||
Expand a gate in a circle using its decomposition rules. | ||
""" | ||
|
||
def __init__(self, gate=None): | ||
""" | ||
Args: | ||
gate (Gate): Gate to decompose. | ||
""" | ||
super().__init__() | ||
self.gate = gate | ||
|
||
def run(self, dag): | ||
"""Expand a given gate into its decomposition. | ||
Args: | ||
dag(DAGCircuit): input dag | ||
Returns: | ||
DAGCircuit: output dag where gate was expanded. | ||
""" | ||
# Walk through the DAG and expand each non-basis node | ||
for node in dag.get_op_nodes(self.gate): | ||
current_node = dag.multi_graph.node[node] | ||
|
||
decomposition_rules = current_node["op"].decompositions() | ||
|
||
# TODO: allow choosing other possible decompositions | ||
decomposition_dag = decomposition_rules[0] | ||
|
||
dag.substitute_node_with_dag(node, decomposition_dag) | ||
return dag |
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
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,85 @@ | ||
# -*- 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 decompose pass""" | ||
|
||
from sympy import pi | ||
|
||
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit | ||
from qiskit.transpiler.passes import Decompose | ||
from qiskit.converters import circuit_to_dag | ||
from qiskit.extensions.standard import HGate | ||
from qiskit.extensions.standard import ToffoliGate | ||
from ..common import QiskitTestCase | ||
|
||
|
||
class TestDecompose(QiskitTestCase): | ||
"""Tests the decompose pass.""" | ||
|
||
def test_basic(self): | ||
"""Test decompose a single H into u2. | ||
""" | ||
qr = QuantumRegister(1, 'qr') | ||
circuit = QuantumCircuit(qr) | ||
circuit.h(qr[0]) | ||
dag = circuit_to_dag(circuit) | ||
pass_ = Decompose(HGate(qr[0])) | ||
after_dag = pass_.run(dag) | ||
op_nodes = after_dag.get_op_nodes(data=True) | ||
self.assertEqual(len(op_nodes), 1) | ||
self.assertEqual(op_nodes[0][1]["op"].name, 'u2') | ||
|
||
def test_decompose_only_h(self): | ||
"""Test to decompose a single H, without the rest | ||
""" | ||
qr = QuantumRegister(2, 'qr') | ||
circuit = QuantumCircuit(qr) | ||
circuit.h(qr[0]) | ||
circuit.cx(qr[0], qr[1]) | ||
dag = circuit_to_dag(circuit) | ||
pass_ = Decompose(HGate(qr[0])) | ||
after_dag = pass_.run(dag) | ||
op_nodes = after_dag.get_op_nodes(data=True) | ||
self.assertEqual(len(op_nodes), 2) | ||
for node in op_nodes: | ||
op = node[1]["op"] | ||
self.assertIn(op.name, ['cx', 'u2']) | ||
|
||
def test_decompose_toffoli(self): | ||
"""Test decompose CCX. | ||
""" | ||
qr1 = QuantumRegister(2, 'qr1') | ||
qr2 = QuantumRegister(1, 'qr2') | ||
circuit = QuantumCircuit(qr1, qr2) | ||
circuit.ccx(qr1[0], qr1[1], qr2[0]) | ||
dag = circuit_to_dag(circuit) | ||
pass_ = Decompose(ToffoliGate(qr1[0], qr1[1], qr2[0])) | ||
after_dag = pass_.run(dag) | ||
op_nodes = after_dag.get_op_nodes(data=True) | ||
self.assertEqual(len(op_nodes), 15) | ||
for node in op_nodes: | ||
op = node[1]["op"] | ||
self.assertIn(op.name, ['h', 't', 'tdg', 'cx']) | ||
|
||
def test_decompose_conditional(self): | ||
"""Test decompose a 1-qubit gates with a conditional. | ||
""" | ||
qr = QuantumRegister(1, 'qr') | ||
cr = ClassicalRegister(1, 'cr') | ||
circuit = QuantumCircuit(qr, cr) | ||
circuit.h(qr).c_if(cr, 1) | ||
circuit.x(qr).c_if(cr, 1) | ||
dag = circuit_to_dag(circuit) | ||
pass_ = Decompose(HGate(qr[0])) | ||
after_dag = pass_.run(dag) | ||
|
||
ref_circuit = QuantumCircuit(qr, cr) | ||
ref_circuit.u2(0, pi, qr[0]).c_if(cr, 1) | ||
ref_circuit.x(qr).c_if(cr, 1) | ||
ref_dag = circuit_to_dag(ref_circuit) | ||
|
||
self.assertEqual(after_dag, ref_dag) |