Skip to content

Commit

Permalink
Manage edge case of pickling instmap. (#9487) (#9495)
Browse files Browse the repository at this point in the history
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit 8af4045)

Co-authored-by: Naoki Kanazawa <[email protected]>
  • Loading branch information
mergify[bot] and nkanazawa1989 authored Jan 31, 2023
1 parent aaf9975 commit 5871ed5
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
7 changes: 7 additions & 0 deletions qiskit/pulse/calibration_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,14 @@ def __init__(self, arguments: Optional[Sequence[str]] = None):
Args:
arguments: User provided argument names for this entry, if parameterized.
Raises:
PulseError: When `arguments` is not a sequence of string.
"""
if arguments and not all(isinstance(arg, str) for arg in arguments):
raise PulseError(f"Arguments must be name of parameters. Not {arguments}.")
if arguments:
arguments = list(arguments)
self._user_arguments = arguments

self._definition = None
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
fixes:
- |
An edge case of pickle :class:`.InstructionScheduleMap` with
non-picklable iterable ``arguments`` is supported.
When :meth:`InstructionScheduleMap.add` is called with
``arguments``, this method typecasts the user value to a python list
to guarantee the added entry is picklable.
For example, a user may supply a python dict keys as ``arguments``.
This also guarantees parallel transpile works with such a custom
instruction schedule map, where the map object is pickled and
distributed to every parallel threads.
25 changes: 25 additions & 0 deletions test/python/pulse/test_instruction_schedule_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,31 @@ def test_instmap_picklable(self):

self.assertEqual(instmap, deser_instmap)

def test_instmap_picklable_with_arguments(self):
"""Test instmap pickling with an edge case.
This test attempts to pickle instmap with custom entry,
in which arguments are provided by users in the form of
python dict key object that is not picklable.
"""
instmap = FakeAthens().defaults().instruction_schedule_map

param1 = Parameter("P1")
param2 = Parameter("P2")
sched = Schedule()
sched.insert(0, Play(Constant(100, param1), DriveChannel(0)), inplace=True)
sched.insert(0, Play(Constant(100, param2), DriveChannel(1)), inplace=True)
to_assign = {"P1": 0.1, "P2": 0.2}

# Note that dict keys is not picklable
# Instmap should typecast it into list to pickle itself.
instmap.add("custom", (0, 1), sched, arguments=to_assign.keys())

ser_obj = pickle.dumps(instmap)
deser_instmap = pickle.loads(ser_obj)

self.assertEqual(instmap, deser_instmap)

def test_check_backend_provider_cals(self):
"""Test if schedules provided by backend provider is distinguishable."""
instmap = FakeOpenPulse2Q().defaults().instruction_schedule_map
Expand Down

0 comments on commit 5871ed5

Please sign in to comment.