Skip to content

Commit

Permalink
Make pass hashable, fix conversion bug (#11961)
Browse files Browse the repository at this point in the history
  • Loading branch information
nkanazawa1989 committed Mar 7, 2024
1 parent af12e64 commit 646e7ef
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
20 changes: 20 additions & 0 deletions qiskit/pulse/compiler/basepasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ def run(
) -> IrBlock:
pass

def __hash__(self) -> int:
warnings.warn(
f"{self.__class__} does not explicitly define a protocol to calculate hash. "
"This pass created the hash only by considering the class name. "
"Qiskit flow controller assumes passes with the identical hash are idempotent, "
"and it may skip execution of the other passes in the pipeline.",
RuntimeWarning,
)
return hash((self.__class__.__name__,))

def __eq__(self, other):
warnings.warn(
f"{self.__class__} does not explicitly define a protocol to evaluate equality. "
Expand Down Expand Up @@ -83,6 +93,16 @@ def run(
) -> None:
pass

def __hash__(self) -> int:
warnings.warn(
f"{self.__class__} does not explicitly define a protocol to calculate hash. "
"This pass created the hash only by considering the class name. "
"Qiskit flow controller assumes passes with the identical hash are idempotent, "
"and it may skip execution of the other passes in the pipeline.",
RuntimeWarning,
)
return hash((self.__class__.__name__,))

def __eq__(self, other):
warnings.warn(
f"{self.__class__} does not explicitly define a protocol to evaluate equality. "
Expand Down
14 changes: 8 additions & 6 deletions qiskit/pulse/compiler/passmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ def _passmanager_frontend(
) -> IrBlock:

def _wrap_recursive(_prog):
_ret = IrBlock(alignment=input_program.alignment_context)
_ret = IrBlock(alignment=_prog.alignment_context)
for _elm in _prog.blocks:
if isinstance(_elm, ScheduleBlock):
return _wrap_recursive(_elm)
_ret.add_element(IrInstruction(instruction=_elm))
_ret.add_element(_wrap_recursive(_elm))
else:
_ret.add_element(IrInstruction(instruction=_elm))
return _ret

return _wrap_recursive(input_program)
Expand Down Expand Up @@ -148,11 +149,12 @@ def _passmanager_backend(
) -> ScheduleBlock:

def _unwrap_recursive(_prog):
_ret = ScheduleBlock(alignment_context=passmanager_ir.alignment)
_ret = ScheduleBlock(alignment_context=_prog.alignment)
for _elm in _prog.elements:
if isinstance(_elm, IrBlock):
return _unwrap_recursive(_elm)
_ret.append(_elm.instruction, inplace=True)
_ret.append(_unwrap_recursive(_elm), inplace=True)
else:
_ret.append(_elm.instruction, inplace=True)
return _ret

out_block = _unwrap_recursive(passmanager_ir)
Expand Down
22 changes: 20 additions & 2 deletions test/python/pulse/test_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,35 @@
"""A test cases for pulse compilation."""

from qiskit.pulse.compiler import BlockTranspiler
from qiskit.pulse.compiler.basepasses import TransformationPass
from qiskit.pulse.ir.ir import IrBlock
from qiskit.providers.fake_provider import GenericBackendV2

from test import QiskitTestCase # pylint: disable=wrong-import-order
from . import _dummy_programs as schedule_lib


class _DummyPass(TransformationPass):
"""A test pass that doesn't perform any transformation."""

def run(self, passmanager_ir: IrBlock) -> IrBlock:
return passmanager_ir

def __hash__(self) -> int:
return hash((self.__class__.__name__,))

def __eq__(self, other):
return self.__class__.__name == other.__class__.name__


class TestCompiler(QiskitTestCase):
"""Test case for pulse compiler."""

def test_roundtrip_simple(self):
"""Test just returns the input program."""
# Just convert an input to PulseIR and convert it back to ScheduleBlock.
pm = BlockTranspiler()
backend = GenericBackendV2(2)
pm = BlockTranspiler([_DummyPass(backend.target)])

in_prog = schedule_lib.play_gaussian()
out_prog = pm.run(pulse_programs=in_prog)
Expand All @@ -33,7 +50,8 @@ def test_roundtrip_simple(self):
def test_roundtrip_nested(self):
"""Test just returns the input program."""
# Just convert an input to PulseIR and convert it back to ScheduleBlock.
pm = BlockTranspiler()
backend = GenericBackendV2(2)
pm = BlockTranspiler([_DummyPass(backend.target)])

in_prog = schedule_lib.play_and_inner_block_sequential()
out_prog = pm.run(pulse_programs=in_prog)
Expand Down

0 comments on commit 646e7ef

Please sign in to comment.