From 5e64a9ab4d611f3e22fc7b27a96d646b165d0525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Pe=C3=B1a=20Tapia?= Date: Wed, 20 Nov 2024 17:07:45 +0100 Subject: [PATCH 1/2] Update PadDynamicalDecoupling pass to conform to 1.3 data model restrictions. From Qiskit 1.3 DAGNode objects will no longer return references to the same underlying objects, they will be created on the fly. For this reason we need to change the re-parametrization and node id tracking code. Co-authored-by: Raynel Sanchez --- .../passes/scheduling/dynamical_decoupling.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/qiskit_ibm_runtime/transpiler/passes/scheduling/dynamical_decoupling.py b/qiskit_ibm_runtime/transpiler/passes/scheduling/dynamical_decoupling.py index af1958ea51..04405e9e44 100644 --- a/qiskit_ibm_runtime/transpiler/passes/scheduling/dynamical_decoupling.py +++ b/qiskit_ibm_runtime/transpiler/passes/scheduling/dynamical_decoupling.py @@ -493,14 +493,24 @@ def _pad( op = next_node.op theta_r, phi_r, lam_r = op.params op.params = Optimize1qGates.compose_u3(theta_r, phi_r, lam_r, theta, phi, lam) - next_node.op = op + new_next_node = self._block_dag.substitute_node( + next_node, op, propagate_condition=False + ) + start_time = self.property_set["node_start_time"].pop(next_node) + if start_time is not None: + self.property_set["node_start_time"][new_next_node] = start_time sequence_gphase += phase elif isinstance(prev_node, DAGOpNode) and isinstance(prev_node.op, (UGate, U3Gate)): # Absorb the inverse into the predecessor (from right in circuit) op = prev_node.op theta_l, phi_l, lam_l = op.params op.params = Optimize1qGates.compose_u3(theta, phi, lam, theta_l, phi_l, lam_l) - prev_node.op = op + new_prev_node = self._block_dag.substitute_node( + prev_node, op, propagate_condition=False + ) + start_time = self.property_set["node_start_time"].pop(prev_node) + if start_time is not None: + self.property_set["node_start_time"][new_prev_node] = start_time sequence_gphase += phase else: # Don't do anything if there's no single-qubit gate to absorb the inverse From 11ee8bae28903e516f0b92e0db71765bd643a757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elena=20Pe=C3=B1a=20Tapia?= Date: Wed, 20 Nov 2024 17:24:45 +0100 Subject: [PATCH 2/2] Simplify solution. Property set is only accessed for prev_node. --- .../transpiler/passes/scheduling/dynamical_decoupling.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/qiskit_ibm_runtime/transpiler/passes/scheduling/dynamical_decoupling.py b/qiskit_ibm_runtime/transpiler/passes/scheduling/dynamical_decoupling.py index 04405e9e44..9971125ac4 100644 --- a/qiskit_ibm_runtime/transpiler/passes/scheduling/dynamical_decoupling.py +++ b/qiskit_ibm_runtime/transpiler/passes/scheduling/dynamical_decoupling.py @@ -493,12 +493,7 @@ def _pad( op = next_node.op theta_r, phi_r, lam_r = op.params op.params = Optimize1qGates.compose_u3(theta_r, phi_r, lam_r, theta, phi, lam) - new_next_node = self._block_dag.substitute_node( - next_node, op, propagate_condition=False - ) - start_time = self.property_set["node_start_time"].pop(next_node) - if start_time is not None: - self.property_set["node_start_time"][new_next_node] = start_time + self._block_dag.substitute_node(next_node, op, propagate_condition=False) sequence_gphase += phase elif isinstance(prev_node, DAGOpNode) and isinstance(prev_node.op, (UGate, U3Gate)): # Absorb the inverse into the predecessor (from right in circuit)