From bb17112b9d1aa32fdca34ebf53b34faf74455a4f Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Tue, 13 Aug 2024 16:03:53 +0200 Subject: [PATCH 1/3] Fix misalignment msg --- .../scheduling/padding/dynamical_decoupling.py | 16 +++++++++++++--- ...ix-dd-misalignment-msg-76fe16e5eb4ae670.yaml | 7 +++++++ .../transpiler/test_dynamical_decoupling.py | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/fix-dd-misalignment-msg-76fe16e5eb4ae670.yaml diff --git a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py index 8c3ea87c8578..c32dad04ff44 100644 --- a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +++ b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py @@ -20,7 +20,7 @@ from qiskit.circuit.delay import Delay from qiskit.circuit.library.standard_gates import IGate, UGate, U3Gate from qiskit.circuit.reset import Reset -from qiskit.dagcircuit import DAGCircuit, DAGNode, DAGInNode, DAGOpNode +from qiskit.dagcircuit import DAGCircuit, DAGNode, DAGInNode, DAGOpNode, DAGOutNode from qiskit.quantum_info.operators.predicates import matrix_equal from qiskit.synthesis.one_qubit import OneQubitEulerDecomposer from qiskit.transpiler.exceptions import TranspilerError @@ -329,10 +329,11 @@ def _pad( # As you can see, constraints on t0 are all satisfied without explicit scheduling. time_interval = t_end - t_start if time_interval % self._alignment != 0: + prev_name, prev_qargs = _format_node(prev_node) + next_name, next_qargs = _format_node(next_node) raise TranspilerError( f"Time interval {time_interval} is not divisible by alignment {self._alignment} " - f"between DAGNode {prev_node.name} on qargs {prev_node.qargs} and {next_node.name} " - f"on qargs {next_node.qargs}." + f"between {prev_name} on qargs {prev_qargs} and {next_name} on qargs {next_qargs}." ) if not self.__is_dd_qubit(dag.qubits.index(qubit)): @@ -430,3 +431,12 @@ def _resolve_params(gate: Gate) -> tuple: else: params.append(p) return tuple(params) + + +def _format_node(node: DAGNode) -> tuple[str, str]: + """Util to format the DAGNode and DAGInNode.""" + if isinstance(node, DAGInNode): + return "the DAGInNode", node.wire + if isinstance(node, DAGOutNode): + return "the DAGOutNode", node.wire + return f"DAGNode {node.name}", node.qargs diff --git a/releasenotes/notes/fix-dd-misalignment-msg-76fe16e5eb4ae670.yaml b/releasenotes/notes/fix-dd-misalignment-msg-76fe16e5eb4ae670.yaml new file mode 100644 index 000000000000..4f57d3b079e1 --- /dev/null +++ b/releasenotes/notes/fix-dd-misalignment-msg-76fe16e5eb4ae670.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixed a bug in :class:`.PadDynamicalDecoupling`, which previously + did not correctly display the error message that a delay is not + pulse-aligned, if the previous or following node was a input/output + node. Now, the error message is correctly displayed. diff --git a/test/python/transpiler/test_dynamical_decoupling.py b/test/python/transpiler/test_dynamical_decoupling.py index 5f11ede3a3e8..38c5c3c2d4ab 100644 --- a/test/python/transpiler/test_dynamical_decoupling.py +++ b/test/python/transpiler/test_dynamical_decoupling.py @@ -1051,6 +1051,23 @@ def test_paramaterized_global_phase(self): self.assertEqual(qc.global_phase + np.pi, pm.run(qc).global_phase) + def test_misalignment_at_boundaries(self): + """Test the correct error message is raised for misalignments at In/Out nodes.""" + # a circuit where the previous node is DAGInNode, and the next DAGOutNode + circuit = QuantumCircuit(1) + circuit.delay(101) + + dd_sequence = [XGate(), XGate()] + pm = PassManager( + [ + ALAPScheduleAnalysis(self.durations), + PadDynamicalDecoupling(self.durations, dd_sequence, pulse_alignment=2), + ] + ) + + with self.assertRaises(TranspilerError): + _ = pm.run(circuit) + if __name__ == "__main__": unittest.main() From 1706dcdea73534f31a576f3fbf7509c7010a7b5e Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Wed, 14 Aug 2024 09:58:49 +0200 Subject: [PATCH 2/3] slightly better formatting --- .../scheduling/padding/dynamical_decoupling.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py index c32dad04ff44..0e351161f7df 100644 --- a/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +++ b/qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py @@ -329,11 +329,9 @@ def _pad( # As you can see, constraints on t0 are all satisfied without explicit scheduling. time_interval = t_end - t_start if time_interval % self._alignment != 0: - prev_name, prev_qargs = _format_node(prev_node) - next_name, next_qargs = _format_node(next_node) raise TranspilerError( f"Time interval {time_interval} is not divisible by alignment {self._alignment} " - f"between {prev_name} on qargs {prev_qargs} and {next_name} on qargs {next_qargs}." + f"between {_format_node(prev_node)} and {_format_node(next_node)}." ) if not self.__is_dd_qubit(dag.qubits.index(qubit)): @@ -433,10 +431,8 @@ def _resolve_params(gate: Gate) -> tuple: return tuple(params) -def _format_node(node: DAGNode) -> tuple[str, str]: - """Util to format the DAGNode and DAGInNode.""" - if isinstance(node, DAGInNode): - return "the DAGInNode", node.wire - if isinstance(node, DAGOutNode): - return "the DAGOutNode", node.wire - return f"DAGNode {node.name}", node.qargs +def _format_node(node: DAGNode) -> str: + """Util to format the DAGNode, DAGInNode, and DAGOutNode.""" + if isinstance(node, (DAGInNode, DAGOutNode)): + return f"{node.__class__.__name__} on qarg {node.wire}" + return f"DAGNode {node.name} on qargs {node.qargs}" From 65402c59893e1adf2dd39de1087d87066c078746 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Wed, 14 Aug 2024 10:40:45 +0200 Subject: [PATCH 3/3] typo --- .../notes/fix-dd-misalignment-msg-76fe16e5eb4ae670.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/notes/fix-dd-misalignment-msg-76fe16e5eb4ae670.yaml b/releasenotes/notes/fix-dd-misalignment-msg-76fe16e5eb4ae670.yaml index 4f57d3b079e1..4634fe48ae9b 100644 --- a/releasenotes/notes/fix-dd-misalignment-msg-76fe16e5eb4ae670.yaml +++ b/releasenotes/notes/fix-dd-misalignment-msg-76fe16e5eb4ae670.yaml @@ -3,5 +3,5 @@ fixes: - | Fixed a bug in :class:`.PadDynamicalDecoupling`, which previously did not correctly display the error message that a delay is not - pulse-aligned, if the previous or following node was a input/output + pulse-aligned, if the previous or following node was an input/output node. Now, the error message is correctly displayed.