Skip to content

Commit

Permalink
Fix Channel.__hash__ in multiprocessing contexts
Browse files Browse the repository at this point in the history
Storing an explicit hash key is fragile in cases that a channel might be
created in a different process to where it might be compared or the hash
used, because the hash seeding can vary depending on how the new
interpreter process was created, especially if it's not done by `fork`.

In this case, transmitting the stored `_hash` over pickle meant that a
`DriveChannel(0)` created in the main process of a macOS runner could
compare equal to a `DriveChannel(0)` created in a separate process
(standard start method `spawn`) and pickled over the wire to the main
process, but have different hashes, violating the Python data model.

Instead, we can just use the standard Python behaviour of creating the
hash on demand when requested; this should typically be preferred unless
absolutely necessary for critical performance reasons, because it will
generally fail safe.
  • Loading branch information
jakelishman committed Nov 15, 2023
1 parent 258fb23 commit 88fcdf9
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 2 deletions.
3 changes: 1 addition & 2 deletions qiskit/pulse/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ def __init__(self, index: int):
"""
self._validate_index(index)
self._index = index
self._hash = hash((self.__class__.__name__, self._index))

@property
def index(self) -> Union[int, ParameterExpression]:
Expand Down Expand Up @@ -156,7 +155,7 @@ def __eq__(self, other: "Channel") -> bool:
return type(self) is type(other) and self._index == other._index

def __hash__(self):
return self._hash
return hash((type(self), self._index))


class PulseChannel(Channel, metaclass=ABCMeta):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fixes:
- |
Fixed the :func:`hash` of Qiskit Pulse ``Channel`` objects (such as :class:`.DriveChannel`) in
cases where the channel was transferred from one Python process to another that used a different
hash seed.

0 comments on commit 88fcdf9

Please sign in to comment.