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

docs/hardware/pasqal/getting_started.ipynb fails to execute in Google Colab #6655

Open
pavoljuhas opened this issue Jun 28, 2024 · 3 comments
Assignees
Labels
good first issue This issue can be resolved by someone who is not familiar with the codebase. A good starting issue. kind/bug-report Something doesn't seem to work. triage/accepted there is consensus amongst maintainers that this is a real bug or a reasonable feature to add

Comments

@pavoljuhas
Copy link
Collaborator

Description of the issue

The cirq-pasqal getting_started.ipynb notebook calls cirq.optimize_for_target_gateset which should produce a circuit that validates w/r to pasqal device, but this fails when run on https://colab.research.google.com/ notebook.

The same notebook passes if run on a local Debian Linux OS. This seems to be cause by different round-off errors of the CPUs, which lead to differing optimized circuits.

The root cause appears to be that cirq.optimize_for_target_gateset does not ensure that for PasqalGateset the new
circuit has single-operation moments, they just happen to be so for getting_started.ipynb with a favorable round-off errors.
The optimization may also produce a moment with 2 operations, which fails validation as follows:

How to reproduce the issue

Create and run fresh colab at https://colab.research.google.com

# cell 1
!pip install "cirq_pasqal==1.4.1"

# cell 2
import cirq
import cirq_pasqal
from cirq_pasqal import TwoDQubit, PasqalVirtualDevice

p_qubits = TwoDQubit.square(6)  # 6x6 square array of TwoDQubits

# Initialize and create a circuit
initial_circuit = cirq.Circuit()
initial_circuit.append(cirq.CZ(p_qubits[0], p_qubits[1]))
initial_circuit.append(cirq.Z(p_qubits[0]))
initial_circuit.append(cirq.CX(p_qubits[0], p_qubits[2]))

# Create a Pasqal device with a control radius of 2.1 (in units of the lattice spacing)
p_device = PasqalVirtualDevice(control_radius=2.1, qubits=p_qubits)
pasqal_gateset = cirq_pasqal.PasqalGateset(include_additional_controlled_ops=False)

print("INITIAL\n")
print(initial_circuit)
print()

pasqal_circuit = cirq.optimize_for_target_gateset(
    initial_circuit, gateset=pasqal_gateset
)
print("OPTIMIZED\n")
print(pasqal_circuit)

print("\nVALIDATION\n")
p_device.validate_circuit(pasqal_circuit)
INITIAL

(0, 0): ───@───Z───@───
│ │
(1, 0): ───@───────┼───

(2, 0): ───────────X───

OPTIMIZED

(0, 0): ───@───Z──────────────────@───Z─────────────────────
│ │
(1, 0): ───@──────────────────────┼─────────────────────────

(2, 0): ───────────PhX(0.5)^0.5───@───PhX(-0.5)^0.5───Z^0───

VALIDATION


ValueError Traceback (most recent call last)
in <cell line: 28>()
26
27 print("\nVALIDATION\n")
---> 28 p_device.validate_circuit(pasqal_circuit)

2 frames
/usr/local/lib/python3.10/dist-packages/cirq_pasqal/pasqal_device.py in validate_circuit(self, circuit)
137 ValueError: If the given circuit can't be run on this device
138 """
--> 139 super().validate_circuit(circuit)
140
141 # Measurements must be in the last non-empty moment

/usr/local/lib/python3.10/dist-packages/cirq/devices/device.py in validate_circuit(self, circuit)
84 """
85 for moment in circuit:
---> 86 self.validate_moment(moment)
87
88 def validate_moment(self, moment: 'cirq.Moment') -> None:

/usr/local/lib/python3.10/dist-packages/cirq_pasqal/pasqal_device.py in validate_moment(self, moment)
233 for operation in moment:
234 if not isinstance(operation.gate, cirq.MeasurementGate):
--> 235 raise ValueError("Cannot do simultaneous gates. Use cirq.InsertStrategy.NEW.")
236
237 def minimal_distance(self) -> float:

ValueError: Cannot do simultaneous gates. Use cirq.InsertStrategy.NEW.

Cirq version

1.4.1

@pavoljuhas pavoljuhas added the kind/bug-report Something doesn't seem to work. label Jun 28, 2024
@pavoljuhas pavoljuhas self-assigned this Jun 28, 2024
pavoljuhas added a commit to pavoljuhas/Cirq that referenced this issue Jun 28, 2024
This is a workaround to allow execution of getting_started.ipynb
notebook as a part of documentation build.

Related to quantumlib#6655
pavoljuhas added a commit that referenced this issue Jun 28, 2024
…nt (#6656)

This is a workaround to allow execution of getting_started.ipynb
notebook as a part of documentation build.

Here we manually convert optimized circuit to have 1 operation per moment
so it passes validation w/r to the PasqalVirtualDevice.

Related to #6655
@NoureldinYosri NoureldinYosri added the triage/discuss Needs decision / discussion, bring these up during Cirq Cynque label Jul 17, 2024
@dstrain115 dstrain115 added good first issue This issue can be resolved by someone who is not familiar with the codebase. A good starting issue. triage/accepted there is consensus amongst maintainers that this is a real bug or a reasonable feature to add and removed triage/discuss Needs decision / discussion, bring these up during Cirq Cynque labels Jul 17, 2024
@dstrain115
Copy link
Collaborator

Circq cync: Goal is to enable this notebook again and make sure it works.

@rogerzmukiibi
Copy link

I am trying to understand what happened here:

This code in the main was added in pull request #6656:

# TODO(https://github.com/quantumlib/Cirq/issues/6655) - remove after fixup
pasqal_circuit = cirq.Circuit(pasqal_circuit.all_operations(),
                              strategy=cirq.InsertStrategy.NEW)

It was added as a workaround for the original circuit:

pasqal_circuit = cirq.optimize_for_target_gateset(initial_circuit,
                                                  gateset=pasqal_gateset)

So this issue is still open to address the bug in cirq.optimize_for_target_gateset!

I will be trying to look into cirq.optimize_for_target_gateset and see.
"@pavoljuhas please correct me if there is something I am getting wrong."

@pavoljuhas
Copy link
Collaborator Author

The workaround in #6656 transforms pasqal_circuit so that each moment has exactly one operation.
This is ensured by cirq.InsertStrategy.NEW which tells cirq to create new moment for each operation in the phase_circuit.all_operations() sequence. Before that the moment 4 in the initial example would be

In: pasqal_circuit[4]
Out: cirq.Moment(
    cirq.PhasedXPowGate(phase_exponent=-0.5, exponent=0.5).on(pasqal.TwoDQubit(2, 0)),
    (cirq.Z**-1.0).on(pasqal.TwoDQubit(0, 0)),
)

which fails validation for PasqalVirtualDevice, because it requires one operations per moment (excluding measurements) -

if len(moment) > 1:
for operation in moment:
if not isinstance(operation.gate, cirq.MeasurementGate):
raise ValueError("Cannot do simultaneous gates. Use cirq.InsertStrategy.NEW.")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue This issue can be resolved by someone who is not familiar with the codebase. A good starting issue. kind/bug-report Something doesn't seem to work. triage/accepted there is consensus amongst maintainers that this is a real bug or a reasonable feature to add
Projects
None yet
Development

No branches or pull requests

4 participants