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

Fix compiler pushing /measurement/ pulses to later time #1096

Draft
wants to merge 3 commits into
base: 0.1
Choose a base branch
from
Draft
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
10 changes: 3 additions & 7 deletions src/qibolab/compilers/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ def _compile_gate(
platform,
sequence,
virtual_z_phases,
moment_start,
delays,
wire_names,
):
Expand All @@ -120,13 +119,12 @@ def _compile_gate(

# update global pulse sequence
# determine the right start time based on the availability of the qubits involved
all_qubits = {*gate_sequence.qubits, *gate.qubits}
all_qubits = {*gate_sequence.qubits, *gate.qubits, *gate_phases.keys()}
stavros11 marked this conversation as resolved.
Show resolved Hide resolved
start = max(
*[
[
sequence.get_qubit_pulses(qubit).finish + delays[qubit]
for qubit in all_qubits
],
moment_start,
]
)
# shift start time and phase according to the global sequence
for pulse in gate_sequence:
Expand Down Expand Up @@ -159,7 +157,6 @@ def compile(self, circuit, platform):
# process circuit gates
delays = defaultdict(int)
for moment in circuit.queue.moments:
moment_start = sequence.finish
for gate in set(filter(lambda x: x is not None, moment)):
if isinstance(gate, gates.Align):
for qubit in gate.qubits:
Expand All @@ -170,7 +167,6 @@ def compile(self, circuit, platform):
platform,
sequence,
virtual_z_phases,
moment_start,
delays,
circuit.wire_names,
)
Expand Down
64 changes: 64 additions & 0 deletions tests/test_compiler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import numpy as np
import pytest
from qibo import Circuit, gates

from qibolab import create_platform
from qibolab.compilers.compiler import Compiler


@pytest.fixture
def dummy():
return create_platform("dummy")


@pytest.fixture
def dummy_couplers():
return create_platform("dummy_couplers")


@pytest.fixture
def compiler():
return Compiler.default()


def test_measurement_timings(dummy, compiler):
q0, q1 = 0, 1
circ = Circuit(2)
circ.add(gates.GPI2(q0, phi=0.0))
circ.add(gates.GPI2(q1, phi=np.pi / 2))
circ.add(gates.GPI2(q1, phi=np.pi))

# put measurement in different moments
circ.add(gates.M(q0))
circ.add(gates.M(q1))

# make sure they are in different moments before proceeding
assert not any(
[
len([gate for gate in m if isinstance(gate, gates.M)]) == 2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
len([gate for gate in m if isinstance(gate, gates.M)]) == 2
len([gate for gate in m if isinstance(gate, gates.M)]) > 1

Silly remark, it's just slightly more readable for myself (it translates more literally the comment above)

for m in circ.queue.moments
]
)

circ._wire_names = [q0, q1]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you really need to force .wire_names?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this the wire names were strings and they caused problems when getting the qubit from platform. I saw a similar thing is done in the backend (here), so did it here as well. Is there any better way around this?

sequence, _ = compiler.compile(circ, dummy)

MEASUREMENT_DURATION = 2000
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you could read this value from dummy, just to be relatively sure in case anyone will change it later on.

for pulse in sequence.ro_pulses:
# assert that measurements don't happen one after another
assert not pulse.start >= MEASUREMENT_DURATION


def test_coupler_pulse_timing(dummy_couplers, compiler):
q0, q1, q2 = 0, 1, 2
circ = Circuit(3)
circ.add(gates.GPI2(q0, phi=0.0))
circ.add(gates.GPI2(q0, phi=np.pi))
circ.add(gates.GPI2(q1, phi=0.0))
circ.add(gates.CZ(q1, q2))

circ._wire_names = [q0, q1, q2]
sequence, _ = compiler.compile(circ, dummy_couplers)

coupler_pulse = sequence.cf_pulses[0]
assert coupler_pulse.start == 40
Loading