qiskit/test/python/dagcircuit/test_compose.py

655 lines
29 KiB
Python

# This code is part of Qiskit.
#
# (C) Copyright IBM 2017.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""Test for the DAGCircuit object"""
import unittest
from qiskit.circuit import (
QuantumRegister,
ClassicalRegister,
QuantumCircuit,
IfElseOp,
WhileLoopOp,
SwitchCaseOp,
CASE_DEFAULT,
Store,
)
from qiskit.circuit.classical import expr, types
from qiskit.dagcircuit import DAGCircuit, DAGCircuitError
from qiskit.converters import circuit_to_dag, dag_to_circuit
from qiskit.pulse import Schedule
from qiskit.circuit.gate import Gate
from test import QiskitTestCase # pylint: disable=wrong-import-order
class TestDagCompose(QiskitTestCase):
"""Test composition of two dags"""
def setUp(self):
super().setUp()
qreg1 = QuantumRegister(3, "lqr_1")
qreg2 = QuantumRegister(2, "lqr_2")
creg = ClassicalRegister(2, "lcr")
self.circuit_left = QuantumCircuit(qreg1, qreg2, creg)
self.circuit_left.h(qreg1[0])
self.circuit_left.x(qreg1[1])
self.circuit_left.p(0.1, qreg1[2])
self.circuit_left.cx(qreg2[0], qreg2[1])
self.left_qubit0 = qreg1[0]
self.left_qubit1 = qreg1[1]
self.left_qubit2 = qreg1[2]
self.left_qubit3 = qreg2[0]
self.left_qubit4 = qreg2[1]
self.left_clbit0 = creg[0]
self.left_clbit1 = creg[1]
self.condition1 = (creg, 1)
self.condition2 = (creg, 2)
def test_compose_inorder(self):
"""Composing two dags of the same width, default order.
┌───┐
lqr_1_0: |0>──┤ H ├─── rqr_0: |0>──■───────
├───┤ │ ┌───┐
lqr_1_1: |0>──┤ X ├─── rqr_1: |0>──┼──┤ X ├
┌─┴───┴──┐ │ ├───┤
lqr_1_2: |0>┤ P(0.1) ├ + rqr_2: |0>──┼──┤ Y ├ =
└────────┘ ┌─┴─┐└───┘
lqr_2_0: |0>────■───── rqr_3: |0>┤ X ├─────
┌─┴─┐ └───┘┌───┐
lqr_2_1: |0>──┤ X ├─── rqr_4: |0>─────┤ Z ├
└───┘ └───┘
lcr_0: 0 ═══════════
lcr_1: 0 ═══════════
┌───┐
lqr_1_0: |0>──┤ H ├─────■───────
├───┤ │ ┌───┐
lqr_1_1: |0>──┤ X ├─────┼──┤ X ├
┌─┴───┴──┐ │ ├───┤
lqr_1_2: |0>┤ P(0.1) ├──┼──┤ Y ├
└────────┘┌─┴─┐└───┘
lqr_2_0: |0>────■─────┤ X ├─────
┌─┴─┐ └───┘┌───┐
lqr_2_1: |0>──┤ X ├────────┤ Z ├
└───┘ └───┘
lcr_0: 0 ═══════════════════════
lcr_1: 0 ═══════════════════════
"""
qreg = QuantumRegister(5, "rqr")
circuit_right = QuantumCircuit(qreg)
circuit_right.cx(qreg[0], qreg[3])
circuit_right.x(qreg[1])
circuit_right.y(qreg[2])
circuit_right.z(qreg[4])
dag_left = circuit_to_dag(self.circuit_left)
dag_right = circuit_to_dag(circuit_right)
# default wiring: i <- i
dag_left.compose(dag_right)
circuit_composed = dag_to_circuit(dag_left)
circuit_expected = self.circuit_left.copy()
circuit_expected.cx(self.left_qubit0, self.left_qubit3)
circuit_expected.x(self.left_qubit1)
circuit_expected.y(self.left_qubit2)
circuit_expected.z(self.left_qubit4)
self.assertEqual(circuit_composed, circuit_expected)
def test_compose_inorder_smaller(self):
"""Composing with a smaller RHS dag, default order.
┌───┐ ┌─────┐
lqr_1_0: |0>──┤ H ├─── rqr_0: |0>──■──┤ Tdg ├
├───┤ ┌─┴─┐└─────┘
lqr_1_1: |0>──┤ X ├─── rqr_1: |0>┤ X ├───────
┌─┴───┴──┐ └───┘
lqr_1_2: |0>┤ P(0.1) ├ + =
└────────┘
lqr_2_0: |0>────■─────
┌─┴─┐
lqr_2_1: |0>──┤ X ├───
└───┘
lcr_0: 0 ══════════════
lcr_1: 0 ══════════════
┌───┐ ┌─────┐
lqr_1_0: |0>──┤ H ├─────■──┤ Tdg ├
├───┤ ┌─┴─┐└─────┘
lqr_1_1: |0>──┤ X ├───┤ X ├───────
┌─┴───┴──┐└───┘
lqr_1_2: |0>┤ P(0.1) ├────────────
└────────┘
lqr_2_0: |0>────■─────────────────
┌─┴─┐
lqr_2_1: |0>──┤ X ├───────────────
└───┘
lcr_0: 0 ═════════════════════════
lcr_1: 0 ═════════════════════════
"""
qreg = QuantumRegister(2, "rqr")
circuit_right = QuantumCircuit(qreg)
circuit_right.cx(qreg[0], qreg[1])
circuit_right.tdg(qreg[0])
dag_left = circuit_to_dag(self.circuit_left)
dag_right = circuit_to_dag(circuit_right)
# default wiring: i <- i
dag_left.compose(dag_right)
circuit_composed = dag_to_circuit(dag_left)
circuit_expected = self.circuit_left.copy()
circuit_expected.cx(self.left_qubit0, self.left_qubit1)
circuit_expected.tdg(self.left_qubit0)
self.assertEqual(circuit_composed, circuit_expected)
def test_compose_permuted(self):
"""Composing two dags of the same width, permuted wires.
┌───┐
lqr_1_0: |0>──┤ H ├─── rqr_0: |0>──■───────
├───┤ │ ┌───┐
lqr_1_1: |0>──┤ X ├─── rqr_1: |0>──┼──┤ X ├
┌─┴───┴──┐ │ ├───┤
lqr_1_2: |0>┤ P(0.1) ├ rqr_2: |0>──┼──┤ Y ├
└────────┘ ┌─┴─┐└───┘
lqr_2_0: |0>────■───── + rqr_3: |0>┤ X ├───── =
┌─┴─┐ └───┘┌───┐
lqr_2_1: |0>──┤ X ├─── rqr_4: |0>─────┤ Z ├
└───┘ └───┘
lcr_0: 0 ═════════════
lcr_1: 0 ═════════════
┌───┐ ┌───┐
lqr_1_0: |0>──┤ H ├───┤ Z ├
├───┤ ├───┤
lqr_1_1: |0>──┤ X ├───┤ X ├
┌─┴───┴──┐├───┤
lqr_1_2: |0>┤ P(0.1) ├┤ Y ├
└────────┘└───┘
lqr_2_0: |0>────■───────■──
┌─┴─┐ ┌─┴─┐
lqr_2_1: |0>──┤ X ├───┤ X ├
└───┘ └───┘
lcr_0: 0 ══════════════════
lcr_1: 0 ══════════════════
"""
qreg = QuantumRegister(5, "rqr")
circuit_right = QuantumCircuit(qreg)
circuit_right.cx(qreg[0], qreg[3])
circuit_right.x(qreg[1])
circuit_right.y(qreg[2])
circuit_right.z(qreg[4])
dag_left = circuit_to_dag(self.circuit_left)
dag_right = circuit_to_dag(circuit_right)
# permuted wiring
dag_left.compose(
dag_right,
qubits=[
self.left_qubit3,
self.left_qubit1,
self.left_qubit2,
self.left_qubit4,
self.left_qubit0,
],
)
circuit_composed = dag_to_circuit(dag_left)
circuit_expected = self.circuit_left.copy()
circuit_expected.z(self.left_qubit0)
circuit_expected.x(self.left_qubit1)
circuit_expected.y(self.left_qubit2)
circuit_expected.cx(self.left_qubit3, self.left_qubit4)
self.assertEqual(circuit_composed, circuit_expected)
def test_compose_permuted_smaller(self):
"""Composing with a smaller RHS dag, and permuted wires.
┌───┐ ┌─────┐
lqr_1_0: |0>──┤ H ├─── rqr_0: |0>──■──┤ Tdg ├
├───┤ ┌─┴─┐└─────┘
lqr_1_1: |0>──┤ X ├─── rqr_1: |0>┤ X ├───────
┌─┴───┴──┐ └───┘
lqr_1_2: |0>┤ P(0.1) ├ + =
└────────┘
lqr_2_0: |0>────■─────
┌─┴─┐
lqr_2_1: |0>──┤ X ├───
└───┘
lcr_0: 0 ═════════════
lcr_1: 0 ═════════════
┌───┐
lqr_1_0: |0>──┤ H ├───────────────
├───┤
lqr_1_1: |0>──┤ X ├───────────────
┌─┴───┴──┐┌───┐
lqr_1_2: |0>┤ P(0.1) ├┤ X ├───────
└────────┘└─┬─┘┌─────┐
lqr_2_0: |0>────■───────■──┤ Tdg ├
┌─┴─┐ └─────┘
lqr_2_1: |0>──┤ X ├───────────────
└───┘
lcr_0: 0 ═════════════════════════
lcr_1: 0 ═════════════════════════
"""
qreg = QuantumRegister(2, "rqr")
circuit_right = QuantumCircuit(qreg)
circuit_right.cx(qreg[0], qreg[1])
circuit_right.tdg(qreg[0])
dag_left = circuit_to_dag(self.circuit_left)
dag_right = circuit_to_dag(circuit_right)
# permuted wiring of subset
dag_left.compose(dag_right, qubits=[self.left_qubit3, self.left_qubit2])
circuit_composed = dag_to_circuit(dag_left)
circuit_expected = self.circuit_left.copy()
circuit_expected.cx(self.left_qubit3, self.left_qubit2)
circuit_expected.tdg(self.left_qubit3)
self.assertEqual(circuit_composed, circuit_expected)
def test_compose_conditional(self):
"""Composing on classical bits.
┌───┐ ┌───┐ ┌─┐
lqr_1_0: |0>──┤ H ├─── rqr_0: ────────┤ H ├─┤M├───
├───┤ ┌───┐ └─┬─┘ └╥┘┌─┐
lqr_1_1: |0>──┤ X ├─── rqr_1: ─┤ X ├────┼────╫─┤M├
┌─┴───┴──┐ └─┬─┘ │ ║ └╥┘
lqr_1_2: |0>┤ P(0.1) ├ + ┌──┴──┐┌──┴──┐ ║ ║
└────────┘ rcr_0: ╡ ╞╡ ╞═╩══╬═
lqr_2_0: |0>────■───── │ = 2 ││ = 1 │ ║
┌─┴─┐ rcr_1: ╡ ╞╡ ╞════╩═
lqr_2_1: |0>──┤ X ├─── └─────┘└─────┘
└───┘
lcr_0: 0 ═════════════
lcr_1: 0 ═════════════
┌───┐
lqr_1_0: ──┤ H ├───────────────────────
├───┤ ┌───┐ ┌─┐
lqr_1_1: ──┤ X ├───────────┤ H ├────┤M├
┌─┴───┴──┐ └─┬─┘ └╥┘
lqr_1_2: ┤ P(0.1) ├──────────┼───────╫─
└────────┘ │ ║
lqr_2_0: ────■───────────────┼───────╫─
┌─┴─┐ ┌───┐ │ ┌─┐ ║
lqr_2_1: ──┤ X ├────┤ X ├────┼───┤M├─╫─
└───┘ └─┬─┘ │ └╥┘ ║
┌──┴──┐┌──┴──┐ ║ ║
lcr_0: ════════════╡ ╞╡ ╞═╩══╬═
│ = 1 ││ = 2 │ ║
lcr_1: ════════════╡ ╞╡ ╞════╩═
└─────┘└─────┘
"""
qreg = QuantumRegister(2, "rqr")
creg = ClassicalRegister(2, "rcr")
circuit_right = QuantumCircuit(qreg, creg)
with self.assertWarns(DeprecationWarning):
circuit_right.x(qreg[1]).c_if(creg, 2)
with self.assertWarns(DeprecationWarning):
circuit_right.h(qreg[0]).c_if(creg, 1)
circuit_right.measure(qreg, creg)
# permuted subset of qubits and clbits
dag_left = circuit_to_dag(self.circuit_left)
dag_right = circuit_to_dag(circuit_right)
# permuted subset of qubits and clbits
with self.assertWarns(DeprecationWarning):
dag_left.compose(
dag_right,
qubits=[self.left_qubit1, self.left_qubit4],
clbits=[self.left_clbit1, self.left_clbit0],
)
circuit_composed = dag_to_circuit(dag_left)
circuit_expected = self.circuit_left.copy()
with self.assertWarns(DeprecationWarning):
circuit_expected.x(self.left_qubit4).c_if(*self.condition1)
with self.assertWarns(DeprecationWarning):
circuit_expected.h(self.left_qubit1).c_if(*self.condition2)
circuit_expected.measure(self.left_qubit4, self.left_clbit0)
circuit_expected.measure(self.left_qubit1, self.left_clbit1)
self.assertEqual(circuit_composed, circuit_expected)
def test_compose_classical(self):
"""Composing on classical bits.
┌───┐ ┌─────┐┌─┐
lqr_1_0: |0>──┤ H ├─── rqr_0: |0>──■──┤ Tdg ├┤M├
├───┤ ┌─┴─┐└─┬─┬─┘└╥┘
lqr_1_1: |0>──┤ X ├─── rqr_1: |0>┤ X ├──┤M├───╫─
┌─┴───┴──┐ └───┘ └╥┘ ║
lqr_1_2: |0>┤ P(0.1) ├ + rcr_0: 0 ════════╬════╩═ =
└────────┘ ║
lqr_2_0: |0>────■───── rcr_1: 0 ════════╩══════
┌─┴─┐
lqr_2_1: |0>──┤ X ├───
└───┘
lcr_0: 0 ═════════════
lcr_1: 0 ═════════════
┌───┐
lqr_1_0: |0>──┤ H ├──────────────────
├───┤ ┌─────┐┌─┐
lqr_1_1: |0>──┤ X ├─────■──┤ Tdg ├┤M├
┌─┴───┴──┐ │ └─────┘└╥┘
lqr_1_2: |0>┤ P(0.1) ├──┼──────────╫─
└────────┘ │ ║
lqr_2_0: |0>────■───────┼──────────╫─
┌─┴─┐ ┌─┴─┐ ┌─┐ ║
lqr_2_1: |0>──┤ X ├───┤ X ├──┤M├───╫─
└───┘ └───┘ └╥┘ ║
lcr_0: 0 ══════════════════╩════╬═
lcr_1: 0 ═══════════════════════╩═
"""
qreg = QuantumRegister(2, "rqr")
creg = ClassicalRegister(2, "rcr")
circuit_right = QuantumCircuit(qreg, creg)
circuit_right.cx(qreg[0], qreg[1])
circuit_right.tdg(qreg[0])
circuit_right.measure(qreg, creg)
dag_left = circuit_to_dag(self.circuit_left)
dag_right = circuit_to_dag(circuit_right)
# permuted subset of qubits and clbits
dag_left.compose(
dag_right,
qubits=[self.left_qubit1, self.left_qubit4],
clbits=[self.left_clbit1, self.left_clbit0],
)
circuit_composed = dag_to_circuit(dag_left)
circuit_expected = self.circuit_left.copy()
circuit_expected.cx(self.left_qubit1, self.left_qubit4)
circuit_expected.tdg(self.left_qubit1)
circuit_expected.measure(self.left_qubit4, self.left_clbit0)
circuit_expected.measure(self.left_qubit1, self.left_clbit1)
self.assertEqual(circuit_composed, circuit_expected)
def test_compose_condition_multiple_classical(self):
"""Compose a circuit with more than one creg.
┌───┐ ┌───┐
q5_0: q5_0: ─┤ H ├─ q5_0: ─┤ H ├─
└─┬─┘ └─┬─┘
┌──┴──┐ ┌──┴──┐
c0: + c0: 1/╡ = 1 ╞ = c0: 1/╡ = 1 ╞
└─────┘ └─────┘
c1: c1: 1/═══════ c1: 1/═══════
"""
# ref: https://github.com/Qiskit/qiskit-terra/issues/4964
qreg = QuantumRegister(1)
creg1 = ClassicalRegister(1)
creg2 = ClassicalRegister(1)
circuit_left = QuantumCircuit(qreg, creg1, creg2)
circuit_right = QuantumCircuit(qreg, creg1, creg2)
with self.assertWarns(DeprecationWarning):
circuit_right.h(0).c_if(creg1, 1)
dag_left = circuit_to_dag(circuit_left)
dag_right = circuit_to_dag(circuit_right)
with self.assertWarns(DeprecationWarning):
dag_composed = dag_left.compose(dag_right, qubits=[0], clbits=[0, 1], inplace=False)
dag_expected = circuit_to_dag(circuit_right.copy())
self.assertEqual(dag_composed, dag_expected)
def test_compose_expr_condition(self):
"""Test that compose correctly maps clbits and registers in expression conditions."""
inner = QuantumCircuit(1)
inner.x(0)
qr_src = QuantumRegister(1)
a_src = ClassicalRegister(2, "a_src")
b_src = ClassicalRegister(2, "b_src")
source = DAGCircuit()
source.add_qreg(qr_src)
source.add_creg(a_src)
source.add_creg(b_src)
test_1 = lambda: expr.lift(a_src[0])
test_2 = lambda: expr.logic_not(b_src[1])
test_3 = lambda: expr.cast(expr.bit_and(b_src, 2), types.Bool())
node_1 = source.apply_operation_back(IfElseOp(test_1(), inner.copy(), None), qr_src, [])
node_2 = source.apply_operation_back(
IfElseOp(test_2(), inner.copy(), inner.copy()), qr_src, []
)
node_3 = source.apply_operation_back(WhileLoopOp(test_3(), inner.copy()), qr_src, [])
qr_dest = QuantumRegister(1)
a_dest = ClassicalRegister(2, "a_dest")
b_dest = ClassicalRegister(2, "b_dest")
dest = DAGCircuit()
dest.add_qreg(qr_dest)
dest.add_creg(a_dest)
dest.add_creg(b_dest)
dest.compose(source)
# Check that the input conditions weren't mutated.
for in_condition, node in zip((test_1, test_2, test_3), (node_1, node_2, node_3)):
self.assertEqual(in_condition(), node.op.condition)
expected = QuantumCircuit(qr_dest, a_dest, b_dest)
expected.if_test(expr.lift(a_dest[0]), inner.copy(), [0], [])
expected.if_else(expr.logic_not(b_dest[1]), inner.copy(), inner.copy(), [0], [])
expected.while_loop(expr.cast(expr.bit_and(b_dest, 2), types.Bool()), inner.copy(), [0], [])
self.assertEqual(dest, circuit_to_dag(expected))
def test_compose_expr_target(self):
"""Test that compose correctly maps clbits and registers in expression targets."""
inner1 = QuantumCircuit(1)
inner1.x(0)
inner2 = QuantumCircuit(1)
inner2.z(0)
qr_src = QuantumRegister(1)
a_src = ClassicalRegister(2, "a_src")
b_src = ClassicalRegister(2, "b_src")
source = DAGCircuit()
source.add_qreg(qr_src)
source.add_creg(a_src)
source.add_creg(b_src)
test_1 = lambda: expr.lift(a_src[0])
test_2 = lambda: expr.logic_not(b_src[1])
test_3 = lambda: expr.lift(b_src)
test_4 = lambda: expr.bit_and(b_src, 2)
node_1 = source.apply_operation_back(
SwitchCaseOp(test_1(), [(False, inner1.copy()), (True, inner2.copy())]), qr_src, []
)
node_2 = source.apply_operation_back(
SwitchCaseOp(test_2(), [(False, inner1.copy()), (True, inner2.copy())]), qr_src, []
)
node_3 = source.apply_operation_back(
SwitchCaseOp(test_3(), [(0, inner1.copy()), (CASE_DEFAULT, inner2.copy())]), qr_src, []
)
node_4 = source.apply_operation_back(
SwitchCaseOp(test_4(), [(0, inner1.copy()), (CASE_DEFAULT, inner2.copy())]), qr_src, []
)
qr_dest = QuantumRegister(1)
a_dest = ClassicalRegister(2, "a_dest")
b_dest = ClassicalRegister(2, "b_dest")
dest = DAGCircuit()
dest.add_qreg(qr_dest)
dest.add_creg(a_dest)
dest.add_creg(b_dest)
dest.compose(source)
# Check that the input expressions weren't mutated.
for in_target, node in zip(
(test_1, test_2, test_3, test_4), (node_1, node_2, node_3, node_4)
):
self.assertEqual(in_target(), node.op.target)
expected = QuantumCircuit(qr_dest, a_dest, b_dest)
expected.switch(
expr.lift(a_dest[0]), [(False, inner1.copy()), (True, inner2.copy())], [0], []
)
expected.switch(
expr.logic_not(b_dest[1]), [(False, inner1.copy()), (True, inner2.copy())], [0], []
)
expected.switch(
expr.lift(b_dest), [(0, inner1.copy()), (CASE_DEFAULT, inner2.copy())], [0], []
)
expected.switch(
expr.bit_and(b_dest, 2),
[(0, inner1.copy()), (CASE_DEFAULT, inner2.copy())],
[0],
[],
)
self.assertEqual(dest, circuit_to_dag(expected))
def test_join_unrelated_dags(self):
"""This isn't expected to be common, but should work anyway."""
a = expr.Var.new("a", types.Bool())
b = expr.Var.new("b", types.Bool())
c = expr.Var.new("c", types.Uint(8))
dest = DAGCircuit()
dest.add_input_var(a)
dest.apply_operation_back(Store(a, expr.lift(False)), (), ())
source = DAGCircuit()
source.add_declared_var(b)
source.add_input_var(c)
source.apply_operation_back(Store(b, expr.lift(True)), (), ())
dest.compose(source)
expected = DAGCircuit()
expected.add_input_var(a)
expected.add_declared_var(b)
expected.add_input_var(c)
expected.apply_operation_back(Store(a, expr.lift(False)), (), ())
expected.apply_operation_back(Store(b, expr.lift(True)), (), ())
self.assertEqual(dest, expected)
def test_join_unrelated_dags_captures(self):
"""This isn't expected to be common, but should work anyway."""
a = expr.Var.new("a", types.Bool())
b = expr.Var.new("b", types.Bool())
c = expr.Var.new("c", types.Uint(8))
dest = DAGCircuit()
dest.add_captured_var(a)
dest.apply_operation_back(Store(a, expr.lift(False)), (), ())
source = DAGCircuit()
source.add_declared_var(b)
source.add_captured_var(c)
source.apply_operation_back(Store(b, expr.lift(True)), (), ())
dest.compose(source, inline_captures=False)
expected = DAGCircuit()
expected.add_captured_var(a)
expected.add_declared_var(b)
expected.add_captured_var(c)
expected.apply_operation_back(Store(a, expr.lift(False)), (), ())
expected.apply_operation_back(Store(b, expr.lift(True)), (), ())
self.assertEqual(dest, expected)
def test_inline_capture_var(self):
"""Should be able to append uses onto another DAG."""
a = expr.Var.new("a", types.Bool())
b = expr.Var.new("b", types.Bool())
dest = DAGCircuit()
dest.add_input_var(a)
dest.add_input_var(b)
dest.apply_operation_back(Store(a, expr.lift(False)), (), ())
source = DAGCircuit()
source.add_captured_var(b)
source.apply_operation_back(Store(b, expr.lift(True)), (), ())
dest.compose(source, inline_captures=True)
expected = DAGCircuit()
expected.add_input_var(a)
expected.add_input_var(b)
expected.apply_operation_back(Store(a, expr.lift(False)), (), ())
expected.apply_operation_back(Store(b, expr.lift(True)), (), ())
self.assertEqual(dest, expected)
def test_reject_inline_to_nonexistent_var(self):
"""Should not be able to inline a variable that doesn't exist."""
a = expr.Var.new("a", types.Bool())
b = expr.Var.new("b", types.Bool())
dest = DAGCircuit()
dest.add_input_var(a)
dest.apply_operation_back(Store(a, expr.lift(False)), (), ())
source = DAGCircuit()
source.add_captured_var(b)
with self.assertRaisesRegex(
DAGCircuitError, "Variable '.*' to be inlined is not in the base DAG"
):
dest.compose(source, inline_captures=True)
def test_compose_calibrations(self):
"""Test that compose carries over the calibrations."""
dag_cal = QuantumCircuit(1)
dag_cal.append(Gate("", 1, []), qargs=[0])
with self.assertWarns(DeprecationWarning):
dag_cal.add_calibration(Gate("", 1, []), [0], Schedule())
empty_dag = circuit_to_dag(QuantumCircuit(1))
calibrated_dag = circuit_to_dag(dag_cal)
composed_dag = empty_dag.compose(calibrated_dag, inplace=False)
with self.assertWarns(DeprecationWarning):
cal = {"": {((0,), ()): Schedule(name="sched0")}}
with self.assertWarns(DeprecationWarning):
self.assertEqual(composed_dag.calibrations, cal)
self.assertEqual(calibrated_dag.calibrations, cal)
if __name__ == "__main__":
unittest.main()