Skip to content

Commit

Permalink
Add deep copy
Browse files Browse the repository at this point in the history
  • Loading branch information
TsafrirA committed Mar 14, 2024
1 parent c20573d commit 00524d5
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
13 changes: 12 additions & 1 deletion qiskit/pulse/ir/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ def flatten(self, inplace: bool = False) -> SequenceIR:
else:
block = self.copy()


def edge_map(_x, _y, _node):
if _y == _node:
return 0
Expand Down Expand Up @@ -314,4 +313,16 @@ def __eq__(self, other: SequenceIR):
# It is reasonable to assume that blocks with the same alignment and the same sequence
# will result in the same time_table, but this decision should be made consciously.

def __deepcopy__(self, memo=None):
if memo is None:
memo = {}
copied = self.__class__(copy.deepcopy(self.alignment, memo=memo))
memo[id(self)] = copied
copied._time_table = copy.copy(self._time_table) # Only int keys and values.
copied._sequence = copy.deepcopy(self._sequence, memo=memo)
# To ensure that copied object will be equal to the original.
copied._sequence[0] = self._InNode
copied._sequence[1] = self._OutNode
return copied

# TODO : __repr__
36 changes: 34 additions & 2 deletions test/python/pulse/test_pulse_ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
# that they have been altered from the originals.

"""Test pulse IR"""
import copy

from test import QiskitTestCase
from rustworkx import is_isomorphic_node_match
from test.python.pulse.compiler_passes.utils import PulseIrTranspiler
from rustworkx import is_isomorphic_node_match

from qiskit.pulse import (
Constant,
Expand Down Expand Up @@ -504,7 +506,7 @@ def test_ir_equating_different_ordering(self):

self.assertTrue(ir1 == ir2)

def test_ir_copy(self):
def test_ir_dedicated_copy(self):
"""Test the dedicated semi-deep copy method"""
inst1 = Play(Constant(100, 0.5), frame=QubitFrame(1), target=Qubit(1))
inst2 = Play(Constant(100, 0.5), frame=QubitFrame(2), target=Qubit(2))
Expand Down Expand Up @@ -534,4 +536,34 @@ def test_ir_copy(self):
self.assertIs(copied.elements()[1], inst2)
self.assertIs(copied.elements()[0].elements()[0], inst1)

def test_ir_deepcopy(self):
"""Test the deep copy method"""
inst1 = Play(Constant(100, 0.5), frame=QubitFrame(1), target=Qubit(1))
inst2 = Play(Constant(100, 0.5), frame=QubitFrame(2), target=Qubit(2))
block = SequenceIR(AlignRight())
block.append(inst1)
ir1 = SequenceIR(AlignLeft())
ir1.append(block)
ir1.append(inst2)
ir1.sequence.add_edge(0, 2, None)
ir1._time_table[3] = 100

copied = copy.deepcopy(ir1)
self.assertEqual(copied, ir1)
self.assertIsNot(copied, ir1)
self.assertEqual(copied.alignment, ir1.alignment)
self.assertEqual(copied._time_table, ir1._time_table)
self.assertIsNot(copied._time_table, ir1._time_table)
# PyDAG has no built-in equality check
self.assertTrue(
is_isomorphic_node_match(copied._sequence, ir1._sequence, lambda x, y: x == y)
)
self.assertIsNot(copied._sequence, ir1._sequence)
self.assertEqual(copied.elements()[0], ir1.elements()[0])
self.assertIsNot(copied.elements()[0], ir1.elements()[0])
self.assertEqual(copied.elements()[1], inst2)
self.assertIsNot(copied.elements()[1], inst2)
self.assertEqual(copied.elements()[0].elements()[0], inst1)
self.assertIsNot(copied.elements()[0].elements()[0], inst1)

# TODO : Test SequenceIR.draw()

0 comments on commit 00524d5

Please sign in to comment.