Skip to content

Commit

Permalink
Merge pull request #756 from qiboteam/simplify-pulse-4
Browse files Browse the repository at this point in the history
PulseSequence to list
  • Loading branch information
alecandido authored Jan 18, 2024
2 parents 92f35df + 6d46ba9 commit 8747b46
Show file tree
Hide file tree
Showing 31 changed files with 378 additions and 641 deletions.
2 changes: 1 addition & 1 deletion doc/source/getting-started/experiment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ We leave to the dedicated tutorial a full explanation of the experiment, but her
# define the pulse sequence
sequence = PulseSequence()
ro_pulse = platform.create_MZ_pulse(qubit=0, start=0)
sequence.add(ro_pulse)
sequence.append(ro_pulse)

# define a sweeper for a frequency scan
sweeper = Sweeper(
Expand Down
42 changes: 24 additions & 18 deletions doc/source/main-documentation/qibolab.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ Now we can create a simple sequence (again, without explicitly giving any qubit
from qibolab.pulses import PulseSequence

ps = PulseSequence()
ps.add(platform.create_RX_pulse(qubit=0, start=0)) # start time is in ns
ps.add(platform.create_RX_pulse(qubit=0, start=100))
ps.add(platform.create_MZ_pulse(qubit=0, start=200))
ps.append(platform.create_RX_pulse(qubit=0, start=0)) # start time is in ns
ps.append(platform.create_RX_pulse(qubit=0, start=100))
ps.append(platform.create_MZ_pulse(qubit=0, start=200))

Now we can execute the sequence on hardware:

Expand Down Expand Up @@ -354,15 +354,15 @@ To organize pulses into sequences, Qibolab provides the :class:`qibolab.pulses.P
channel="channel",
qubit=0,
)
sequence.add(pulse1)
sequence.add(pulse2)
sequence.add(pulse3)
sequence.add(pulse4)
sequence.append(pulse1)
sequence.append(pulse2)
sequence.append(pulse3)
sequence.append(pulse4)

print(f"Total duration: {sequence.duration}")

sequence_ch1 = sequence.get_channel_pulses("channel1") # Selecting pulses on channel 1
print(f"We have {sequence_ch1.count} pulses on channel 1.")
print(f"We have {len(sequence_ch1)} pulses on channel 1.")

.. testoutput:: python
:hide:
Expand Down Expand Up @@ -390,8 +390,8 @@ Typical experiments may include both pre-defined pulses and new ones:
from qibolab.pulses import Rectangular

sequence = PulseSequence()
sequence.add(platform.create_RX_pulse(0))
sequence.add(
sequence.append(platform.create_RX_pulse(0))
sequence.append(
DrivePulse(
start=0,
duration=10,
Expand All @@ -402,7 +402,7 @@ Typical experiments may include both pre-defined pulses and new ones:
channel="0",
)
)
sequence.add(platform.create_MZ_pulse(0, start=0))
sequence.append(platform.create_MZ_pulse(0, start=0))

results = platform.execute_pulse_sequence(sequence, options=options)

Expand Down Expand Up @@ -474,9 +474,15 @@ A tipical resonator spectroscopy experiment could be defined with:
from qibolab.sweeper import Parameter, Sweeper, SweeperType

sequence = PulseSequence()
sequence.add(platform.create_MZ_pulse(0, start=0)) # readout pulse for qubit 0 at 4 GHz
sequence.add(platform.create_MZ_pulse(1, start=0)) # readout pulse for qubit 1 at 5 GHz
sequence.add(platform.create_MZ_pulse(2, start=0)) # readout pulse for qubit 2 at 6 GHz
sequence.append(
platform.create_MZ_pulse(0, start=0)
) # readout pulse for qubit 0 at 4 GHz
sequence.append(
platform.create_MZ_pulse(1, start=0)
) # readout pulse for qubit 1 at 5 GHz
sequence.append(
platform.create_MZ_pulse(2, start=0)
) # readout pulse for qubit 2 at 6 GHz

sweeper = Sweeper(
parameter=Parameter.frequency,
Expand Down Expand Up @@ -511,8 +517,8 @@ For example:

sequence = PulseSequence()

sequence.add(platform.create_RX_pulse(0))
sequence.add(platform.create_MZ_pulse(0, start=sequence[0].finish))
sequence.append(platform.create_RX_pulse(0))
sequence.append(platform.create_MZ_pulse(0, start=sequence[0].finish))

sweeper_freq = Sweeper(
parameter=Parameter.frequency,
Expand Down Expand Up @@ -609,8 +615,8 @@ Let's now delve into a typical use case for result objects within the qibolab fr
measurement_pulse = platform.create_qubit_readout_pulse(0, start=0)

sequence = PulseSequence()
sequence.add(drive_pulse_1)
sequence.add(measurement_pulse)
sequence.append(drive_pulse_1)
sequence.append(measurement_pulse)

options = ExecutionParameters(
nshots=1000,
Expand Down
12 changes: 6 additions & 6 deletions doc/source/tutorials/calibration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ around the pre-defined frequency.
# create pulse sequence and add pulse
sequence = PulseSequence()
readout_pulse = platform.create_MZ_pulse(qubit=0, start=0)
sequence.add(readout_pulse)
sequence.append(readout_pulse)

# allocate frequency sweeper
sweeper = Sweeper(
Expand Down Expand Up @@ -127,8 +127,8 @@ complex pulse sequence. Therefore with start with that:
drive_pulse.duration = 2000
drive_pulse.amplitude = 0.01
readout_pulse = platform.create_MZ_pulse(qubit=0, start=drive_pulse.finish)
sequence.add(drive_pulse)
sequence.add(readout_pulse)
sequence.append(drive_pulse)
sequence.append(readout_pulse)

# allocate frequency sweeper
sweeper = Sweeper(
Expand Down Expand Up @@ -220,13 +220,13 @@ and its impact on qubit states in the IQ plane.
one_sequence = PulseSequence()
drive_pulse = platform.create_RX_pulse(qubit=0, start=0)
readout_pulse1 = platform.create_MZ_pulse(qubit=0, start=drive_pulse.finish)
one_sequence.add(drive_pulse)
one_sequence.add(readout_pulse1)
one_sequence.append(drive_pulse)
one_sequence.append(readout_pulse1)

# create pulse sequence 2 and add pulses
zero_sequence = PulseSequence()
readout_pulse2 = platform.create_MZ_pulse(qubit=0, start=0)
zero_sequence.add(readout_pulse2)
zero_sequence.append(readout_pulse2)

options = ExecutionParameters(
nshots=1000,
Expand Down
6 changes: 3 additions & 3 deletions doc/source/tutorials/pulses.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Pulses execution
First, we create the pulse sequence that will be executed. We can do this by
defining a :class:`qibolab.pulses.PulseSequence` object and adding different
pulses (:class:`qibolab.pulses.Pulse`) through the
:func:`qibolab.pulses.PulseSequence.add()` method:
:func:`qibolab.pulses.PulseSequence.append()` method:

.. testcode:: python

Expand All @@ -20,7 +20,7 @@ pulses (:class:`qibolab.pulses.Pulse`) through the
sequence = PulseSequence()

# Add some pulses to the pulse sequence
sequence.add(
sequence.append(
DrivePulse(
start=0,
frequency=200000000,
Expand All @@ -31,7 +31,7 @@ pulses (:class:`qibolab.pulses.Pulse`) through the
qubit=0,
)
)
sequence.add(
sequence.append(
ReadoutPulse(
start=70,
frequency=20000000.0,
Expand Down
2 changes: 1 addition & 1 deletion doc/source/tutorials/transpiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ The following example shows how to modify the transpiler and compiler in order t
"""X gate applied with a single pi-pulse."""
qubit = gate.target_qubits[0]
sequence = PulseSequence()
sequence.add(platform.create_RX_pulse(qubit, start=0))
sequence.append(platform.create_RX_pulse(qubit, start=0))
return sequence, {}


Expand Down
4 changes: 2 additions & 2 deletions examples/minimum_working_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Define PulseSequence
sequence = PulseSequence()
# Add some pulses to the pulse sequence
sequence.add(
sequence.append(
Pulse(
start=0,
amplitude=0.3,
Expand All @@ -18,7 +18,7 @@
)
)

sequence.add(
sequence.append(
ReadoutPulse(
start=4004,
amplitude=0.9,
Expand Down
4 changes: 2 additions & 2 deletions src/qibolab/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def assign_measurements(self, measurement_map, readout):
containing the readout measurement shots. This is created in ``execute_circuit``.
"""
for gate, sequence in measurement_map.items():
_samples = (readout[pulse.serial].samples for pulse in sequence.pulses)
_samples = (readout[pulse.serial].samples for pulse in sequence)
samples = list(filter(lambda x: x is not None, _samples))
gate.result.backend = self
gate.result.register_samples(np.array(samples).T)
Expand Down Expand Up @@ -157,7 +157,7 @@ def execute_circuits(self, circuits, initial_state=None, nshots=1000):
)
for gate, sequence in measurement_map.items():
samples = [
readout[pulse.serial].popleft().samples for pulse in sequence.pulses
readout[pulse.serial].popleft().samples for pulse in sequence
]
gate.result.backend = self
gate.result.register_samples(np.array(samples).T)
Expand Down
2 changes: 1 addition & 1 deletion src/qibolab/compilers/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def _compile_gate(
pulse.start += start
if not isinstance(pulse, ReadoutPulse):
pulse.relative_phase += virtual_z_phases[pulse.qubit]
sequence.add(pulse)
sequence.append(pulse)

return gate_sequence, gate_phases

Expand Down
8 changes: 4 additions & 4 deletions src/qibolab/compilers/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def gpi2_rule(gate, platform):
theta = gate.parameters[0]
sequence = PulseSequence()
pulse = platform.create_RX90_pulse(qubit, start=0, relative_phase=theta)
sequence.add(pulse)
sequence.append(pulse)
return sequence, {}


Expand All @@ -47,7 +47,7 @@ def u3_rule(gate, platform):
qubit, start=0, relative_phase=virtual_z_phases[qubit]
)
# apply RX(pi/2)
sequence.add(RX90_pulse_1)
sequence.append(RX90_pulse_1)
# apply RZ(theta)
virtual_z_phases[qubit] += theta
# Fetch pi/2 pulse from calibration
Expand All @@ -57,7 +57,7 @@ def u3_rule(gate, platform):
relative_phase=virtual_z_phases[qubit] - math.pi,
)
# apply RX(-pi/2)
sequence.add(RX90_pulse_2)
sequence.append(RX90_pulse_2)
# apply RZ(phi)
virtual_z_phases[qubit] += phi

Expand All @@ -78,5 +78,5 @@ def measurement_rule(gate, platform):
sequence = PulseSequence()
for qubit in gate.target_qubits:
MZ_pulse = platform.create_MZ_pulse(qubit, start=0)
sequence.add(MZ_pulse)
sequence.append(MZ_pulse)
return sequence, {}
2 changes: 1 addition & 1 deletion src/qibolab/instruments/qblox/cluster_qcm_bb.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ def process_pulse_sequence(
sequencer.waveforms_buffer.add_waveforms(
pulse, self._ports[port].hardware_mod_en, sweepers
)
sequencer.pulses.add(pulse)
sequencer.pulses.append(pulse)
pulses_to_be_processed.remove(pulse)

# if there is not enough memory in the current sequencer, use another one
Expand Down
2 changes: 1 addition & 1 deletion src/qibolab/instruments/qblox/cluster_qcm_rf.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def process_pulse_sequence(
sequencer.waveforms_buffer.add_waveforms(
pulse, self._ports[port].hardware_mod_en, sweepers
)
sequencer.pulses.add(pulse)
sequencer.pulses.append(pulse)
pulses_to_be_processed.remove(pulse)

# if there is not enough memory in the current sequencer, use another one
Expand Down
2 changes: 1 addition & 1 deletion src/qibolab/instruments/qblox/cluster_qrm_rf.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ def process_pulse_sequence(
sequencer.waveforms_buffer.add_waveforms(
pulse, self._ports[port].hardware_mod_en, sweepers
)
sequencer.pulses.add(pulse)
sequencer.pulses.append(pulse)
pulses_to_be_processed.remove(pulse)

# if there is not enough memory in the current sequencer, use another one
Expand Down
4 changes: 1 addition & 3 deletions src/qibolab/instruments/qm/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,7 @@ def create(cls, qubits, sequence, sweepers, config, time_of_flight, smearing):
# like we do for readout multiplex
duration_sweep_pulses = find_duration_sweeper_pulses(sweepers)
qmsequence = cls()
for pulse in sorted(
sequence.pulses, key=lambda pulse: (pulse.start, pulse.duration)
):
for pulse in sorted(sequence, key=lambda pulse: (pulse.start, pulse.duration)):
config.register_element(
qubits[pulse.qubit], pulse, time_of_flight, smearing
)
Expand Down
2 changes: 1 addition & 1 deletion src/qibolab/instruments/rfsoc/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def _(
"""Convert PulseSequence to list of rfosc pulses with relative time."""
last_pulse_start = 0
list_sequence = []
for pulse in sorted(sequence.pulses, key=lambda item: item.start):
for pulse in sorted(sequence, key=lambda item: item.start):
start_delay = (pulse.start - last_pulse_start) * NS_TO_US
pulse_dict = asdict(convert(pulse, qubits, start_delay, sampling_rate))
list_sequence.append(pulse_dict)
Expand Down
4 changes: 2 additions & 2 deletions src/qibolab/native.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,12 @@ def sequence(self, start=0):

for pulse in self.pulses:
if isinstance(pulse, NativePulse):
sequence.add(pulse.pulse(start=start))
sequence.append(pulse.pulse(start=start))
else:
virtual_z_phases[pulse.qubit.name] += pulse.phase

for coupler_pulse in self.coupler_pulses:
sequence.add(coupler_pulse.pulse(start=start))
sequence.append(coupler_pulse.pulse(start=start))
# TODO: Maybe ``virtual_z_phases`` should be an attribute of ``PulseSequence``
return sequence, virtual_z_phases

Expand Down
4 changes: 2 additions & 2 deletions src/qibolab/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def unroll_sequences(
for pulse in sequence:
new_pulse = pulse.copy()
new_pulse.start += start
total_sequence.add(new_pulse)
total_sequence.append(new_pulse)
if isinstance(pulse, ReadoutPulse):
readout_map[pulse.serial].append(new_pulse.serial)
start = total_sequence.finish + relaxation_time
Expand Down Expand Up @@ -288,7 +288,7 @@ def sweep(
sequence = PulseSequence()
parameter = Parameter.frequency
pulse = platform.create_qubit_readout_pulse(qubit=0, start=0)
sequence.add(pulse)
sequence.append(pulse)
parameter_range = np.random.randint(10, size=10)
sweeper = Sweeper(parameter, parameter_range, [pulse])
platform.sweep(sequence, ExecutionParameters(), sweeper)
Expand Down
Loading

0 comments on commit 8747b46

Please sign in to comment.