Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pulse pass manager bugfix #11961

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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