quantumlib / Cirq

A Python framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
Apache License 2.0
4.22k stars 1.01k forks source link

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

Open pavoljuhas opened 2 months ago

pavoljuhas commented 2 months ago

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) [](https://localhost:8080/#) in () 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](https://localhost:8080/#) 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](https://localhost:8080/#) 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](https://localhost:8080/#) 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

dstrain115 commented 1 month ago

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