Skip to content

Commit

Permalink
Bugfix: change API to modularized cirq package. (#308)
Browse files Browse the repository at this point in the history
* Refactor circuit build to `cirq_google` module.
* Add check for `cirq_google`, add test.
* Update ci_backends.yml
  • Loading branch information
dariavh authored Sep 26, 2023
1 parent 0621616 commit 51391a3
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci_backends.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
# myqlm does not work in python3.7
pip install "cirq" "qiskit>=0.30" "qulacs" "qibo==0.1.1"
elif [ $ver -eq 8 ]; then
pip install "cirq" "qiskit>=0.30" "qulacs" "qibo==0.1.1" "myqlm"
pip install "cirq" "qiskit>=0.30" "qulacs" "qibo==0.1.1" "myqlm" "cirq-google"
fi
pip install -e .
- name: Lint with flake8
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ qulacs # default simulator (best integration), remove if the installation gives

#optional quantum backends
#cirq >= 0.9.2 #
#cirq_google
#qiskit>=0.30
#pyquil<3.0 # you also need to install the forest-sdk
#qulacs-gpu # you can't have qulacs and qulacs-gpu at the same time
Expand Down
40 changes: 15 additions & 25 deletions src/tequila/simulators/simulator_cirq.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
import sympy
from tequila.utils import to_float

import importlib
import numpy as np
import typing, numbers

import cirq
import cirq_google

map_1 = lambda x: {'exponent': x}
map_2 = lambda x: {'exponent': x / np.pi, 'global_shift': -0.5}
Expand Down Expand Up @@ -356,35 +358,23 @@ def build_device_circuit(self, ignore_failures=False):
line = None
circuit = None
if isinstance(device, cirq.Device):
if isinstance(device, cirq.google.devices.XmonDevice) or isinstance(device,
cirq.google.devices.serializable_device.SerializableDevice):
options = ['xmon', 'xmon_partial_cz', 'sqrt_iswap', 'sycamore']
if device in [cirq.google.Sycamore, cirq.google.Sycamore23]:
options = ['sycamore', 'sqrt_iswap', 'xmon', 'xmon_partial_cz']
for option in options:
try:
line = cirq.google.line_on_device(device, length=len(self.abstract_circuit.qubits))

circuit = cirq.google.optimized_for_sycamore(circuit=c, new_device=device,
optimizer_type=option,
qubit_map=lambda q: line[q.x])
except:
line = None
pass
if circuit is None:
raise TequilaCirqException('could not optimize for device={}'.format(device))

HAS_GOOGLE = importlib.util.find_spec('cirq_google')
assert HAS_GOOGLE, TequilaCirqException(' cirq_google package is not installed.')

if device in [cirq_google.Sycamore, cirq_google.Sycamore23]:
try:
circuit = cirq.optimize_for_target_gateset(circuit=c, gateset=cirq_google.SycamoreTargetGateset())
except ValueError as E:
original_message = str(E)
raise TequilaCirqException('original message:\n{}\n\ncould not optimize for device={}'.format(original_message,device))
else:
### under construction (potentially on other branches)
raise TequilaException('Only known and Xmon devices currently functional. Sorry!')
raise TequilaException('Only Sycamore and Sycamore23 devices currently functional. Sorry!')

else:
raise TequilaException(
'build_device_circuit demands a cirq.Device object; received {}, of type {}'.format(str(device),
type(device)))

if line is not None:
for k in self.qubit_map.keys():
self.qubit_map[k].instance = line[self.qubit_map[k].instance.x]
return circuit

def build_noisy_circuit(self, noise):
Expand Down Expand Up @@ -447,7 +437,7 @@ def retrieve_device(self, device):
the device on which to execute cirq circuits.
"""
if isinstance(device, str):
return getattr(cirq.google, device)
return getattr(cirq_google, device)
else:
if device is None:
return device
Expand All @@ -474,7 +464,7 @@ def check_device(self, device):
return
else:
assert isinstance(device, str)
if device.lower() in ['foxtail', 'sycamore', 'sycamore23', 'bristlecone']:
if device.lower() in ['sycamore', 'sycamore23']:
pass
else:
raise TequilaException('requested device {} could not be found!'.format(device))
Expand Down
15 changes: 15 additions & 0 deletions tests/test_simulator_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
All Backends need to be installed for full testing
"""

import importlib
import numpy
import pytest
import random
Expand All @@ -16,6 +17,20 @@
import os, glob


HAS_GOOGLE = importlib.util.find_spec('cirq_google')
@pytest.mark.skipif(condition=HAS_GOOGLE, reason="cirq_google not installed")
def test_cirq_google_devices():
import cirq_google

U = tq.paulis.X(0)
U += tq.gates.Givens(0, 1, angle=numpy.pi/4) # Givens rotation with angle = pi/4 gives 1/sqrt(2)|01> + 1/sqrt(2)|10> (up to a phase factor).
wfn = tq.simulate(U, device="Sycamore", backend="cirq")
wfnx0 = tq.simulate(tq.paulis.X(0))
assert numpy.isclose(numpy.abs(wfn.inner(wfnx0))**2, 0.5)
wfnx1 = tq.simulate(tq.paulis.X(1))
assert numpy.isclose(numpy.abs(wfn.inner(wfnx1))**2, 0.5)


def teardown_function(function):
[os.remove(x) for x in glob.glob("*.npy")]
[os.remove(x) for x in glob.glob("qvm.log")]
Expand Down

0 comments on commit 51391a3

Please sign in to comment.