qiskit-community / qiskit-dynamics

Tools for building and solving models of quantum systems in Qiskit
https://qiskit-community.github.io/qiskit-dynamics/
Apache License 2.0
106 stars 60 forks source link

Add support for barriers in schedule -> signal converter #202

Closed DanPuzzuoli closed 1 year ago

DanPuzzuoli commented 1 year ago

The following example is courtesy of @zlianghahaha :

from qiskit_dynamics.pulse import InstructionToSignals
from qiskit import pulse
from qiskit.pulse.transforms.canonicalization import block_to_schedule

from qiskit.providers.fake_provider import FakeQuito

backend = FakeQuito()

with pulse.build(backend) as sched_block:
    pulse.play(pulse.Constant(duration=10, amp=0.5), pulse.DriveChannel(0))
    pulse.barrier(0, 1)
    pulse.play(pulse.Constant(duration=10, amp=-0.5), pulse.DriveChannel(1))

converter = InstructionToSignals(dt=1., carriers={'d0': 1., 'd1': 1.})
sched = block_to_schedule(sched_block)

converter.get_signals(sched)

This raises the error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[1], line 18
     15 converter = InstructionToSignals(dt=1., carriers={'d0': 1., 'd1': 1.})
     16 sched = block_to_schedule(sched_block)
---> 18 converter.get_signals(sched)

File ~/Documents/projects/qiskit-dynamics/qiskit_dynamics/pulse/pulse_to_signals.py:166, in InstructionToSignals.get_signals(self, schedule)
    158     signals[chan.name] = DiscreteSignal(
    159         samples=[],
    160         dt=self._dt,
    161         name=chan.name,
    162         carrier_freq=carrier_freq,
    163     )
    165 for start_sample, inst in schedule.instructions:
--> 166     chan = inst.channel.name
    167     phi = phases[chan]
    168     freq = frequency_shifts[chan]

AttributeError: 'RelativeBarrier' object has no attribute 'channel'

The error is being raised as the RelativeBarrier object is in sched, and doesn't have a channel attribute. Interestingly, I'm fairly sure this can be fixed by just doing nothing for barrier instructions. block_to_schedule already puts absolute timing in all of the other instructions (which is what we use), so there is no need to interpret the contents of barrier instructions in the converter.

As the converter already takes action based on the type of instruction (and only handles the types of instructions it needs to know about), I think this can be fixed by just changing the single line chan = inst.channel.name, either by eliminating it and directly using inst.channel.name in the few blocks that follow, or doing chan = inst.channel.name if hasattr(inst, "channel") else None.