Skip to content

Commit

Permalink
Remove cirq.google references from circuit_test and circuit_dag_test (#…
Browse files Browse the repository at this point in the history
…3738)

Remove cirq.google references from circuit_test and circuit_dag_test.

Related to #3737.
  • Loading branch information
balopat authored Feb 10, 2021
1 parent 2c904da commit 2e5c45b
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 45 deletions.
11 changes: 8 additions & 3 deletions cirq/circuits/circuit_dag_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def test_from_circuit():

def test_from_circuit_with_device():
q0 = cirq.GridQubit(5, 5)
circuit = cirq.Circuit(cirq.X(q0), cirq.Y(q0), device=cirq.google.Bristlecone)
circuit = cirq.Circuit(cirq.X(q0), cirq.Y(q0), device=cirq.UNCONSTRAINED_DEVICE)
dag = cirq.CircuitDag.from_circuit(circuit)
assert networkx.dag.is_directed_acyclic_graph(dag)
assert dag.device == circuit.device
Expand Down Expand Up @@ -193,7 +193,12 @@ def test_equality():


def test_larger_circuit():
q0, q1, q2, q3 = cirq.google.Bristlecone.col(5)[:4]
q0, q1, q2, q3 = [
cirq.GridQubit(0, 5),
cirq.GridQubit(1, 5),
cirq.GridQubit(2, 5),
cirq.GridQubit(3, 5),
]
# This circuit does not have CZ gates on adjacent qubits because the order
# dag.to_circuit() would append them is non-deterministic.
circuit = cirq.Circuit(
Expand All @@ -208,7 +213,7 @@ def test_larger_circuit():
cirq.CZ(q0, q1),
cirq.T(q3),
strategy=cirq.InsertStrategy.EARLIEST,
device=cirq.google.Bristlecone,
device=cirq.UNCONSTRAINED_DEVICE,
)

dag = cirq.CircuitDag.from_circuit(circuit)
Expand Down
156 changes: 114 additions & 42 deletions cirq/circuits/circuit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,16 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Tuple

import os
from collections import defaultdict
from random import randint, random, sample, randrange
import os
from typing import Tuple, cast, AbstractSet, Iterable

import numpy as np
import pytest
import sympy

import cirq
import cirq.google as cg
import cirq.testing
from cirq import ops

Expand Down Expand Up @@ -93,7 +91,7 @@ def test_equality(circuit_cls):
circuit_cls(()),
)
eq.add_equality_group(circuit_cls([cirq.Moment()]), circuit_cls((cirq.Moment(),)))
eq.add_equality_group(circuit_cls(device=cg.Foxtail))
eq.add_equality_group(circuit_cls(device=FOXY))

# Equality depends on structure and contents.
eq.add_equality_group(circuit_cls([cirq.Moment([cirq.X(a)])]))
Expand Down Expand Up @@ -282,13 +280,13 @@ def test_radd_op_tree(circuit_cls):
)

# Preserves device.
c = circuit_cls(device=cirq.google.Bristlecone)
c = circuit_cls(device=FOXY)
c2 = [] + c
assert c2.device is cirq.google.Bristlecone
assert c2.device is FOXY
assert c2 == c

# Validates versus device.
c = circuit_cls(device=cirq.google.Bristlecone)
c = circuit_cls(device=FOXY)
with pytest.raises(ValueError, match='Unsupported qubit'):
_ = [cirq.X(cirq.NamedQubit('a'))] + c

Expand Down Expand Up @@ -336,19 +334,19 @@ def test_repr(circuit_cls):
])"""
)

c = circuit_cls(device=cg.Foxtail)
c = circuit_cls(device=FOXY)
cirq.testing.assert_equivalent_repr(c)
assert repr(c) == f'cirq.{circuit_cls.__name__}(device=cirq.google.Foxtail)'
assert repr(c) == f'cirq.{circuit_cls.__name__}(device=cirq.circuits.circuit_test.FOXY)'

c = circuit_cls(cirq.Z(cirq.GridQubit(0, 0)), device=cg.Foxtail)
c = circuit_cls(cirq.Z(cirq.GridQubit(0, 0)), device=FOXY)
cirq.testing.assert_equivalent_repr(c)
assert (
repr(c)
== f"""cirq.{circuit_cls.__name__}([
cirq.Moment(
cirq.Z(cirq.GridQubit(0, 0)),
),
], device=cirq.google.Foxtail)"""
], device=cirq.circuits.circuit_test.FOXY)"""
)


Expand Down Expand Up @@ -562,8 +560,8 @@ def test_concatenate():


def test_concatenate_with_device():
fox = cirq.Circuit(device=cg.Foxtail)
cone = cirq.Circuit(device=cg.Bristlecone)
fox = cirq.Circuit(device=FOXY)
cone = cirq.Circuit(device=BCONE)
unr = cirq.Circuit()

_ = cone + cone
Expand All @@ -581,44 +579,120 @@ def test_concatenate_with_device():
assert len(cone) == 0


class ValidatingTestDevice(cirq.Device):
"""A fake device that was created to ensure certain Device validation features are
leveraged in Circuit functions. It contains the minimum set of features that tests
require. Feel free to extend the features here as needed."""

def __init__(
self,
allowed_qubit_types: Tuple[type, ...],
allowed_gates: Tuple[type, ...],
qubits: AbstractSet[cirq.Qid],
name: str,
):
self.allowed_qubit_types = allowed_qubit_types
self.allowed_gates = allowed_gates
self.qubits = qubits
self._repr = name

def validate_operation(self, operation: cirq.Operation) -> None:
# This is pretty close to what the cirq.google.XmonDevice has for validation
for q in operation.qubits:
if not isinstance(q, self.allowed_qubit_types):
raise ValueError("Unsupported qubit type: {!r}".format(type(q)))
if q not in self.qubits:
raise ValueError('Qubit not on device: {!r}'.format(q))
if not isinstance(operation.gate, self.allowed_gates):
raise ValueError("Unsupported gate type: {!r}".format(operation.gate))
if len(operation.qubits) == 2 and not isinstance(operation.gate, ops.MeasurementGate):
p, q = operation.qubits
if not cast(cirq.GridQubit, p).is_adjacent(q):
raise ValueError('Non-local interaction: {!r}.'.format(operation))

def decompose_operation(self, operation: 'cirq.Operation') -> 'cirq.OP_TREE':
# a fake decomposer for only TOFFOLI gates
if isinstance(operation.gate, cirq.CCXPowGate):
return cirq.decompose(operation)
return operation

def can_add_operation_into_moment(
self, operation: 'cirq.Operation', moment: 'cirq.Moment'
) -> bool:
if not super().can_add_operation_into_moment(operation, moment):
return False
# a fake rule for ensuring that no two CZs are executed at the same moment.
# this will ensure that CZs are always in separate moments in this device11
return not (
isinstance(operation.gate, cirq.CZPowGate)
and any(isinstance(op.gate, cirq.CZPowGate) for op in moment.operations)
)

def __repr__(self):
return self._repr


FOXY = ValidatingTestDevice(
allowed_qubit_types=(cirq.GridQubit,),
allowed_gates=(
ops.CZPowGate,
ops.XPowGate,
ops.YPowGate,
ops.ZPowGate,
),
qubits=set(cirq.GridQubit.rect(2, 7)),
name='cirq.circuits.circuit_test.FOXY',
)

BCONE = ValidatingTestDevice(
allowed_qubit_types=(cirq.GridQubit,),
allowed_gates=(cirq.XPowGate,),
qubits={
cirq.GridQubit(0, 6),
},
name='cirq.circuits.circuit_test.BCONE',
)


@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit])
def test_with_device(circuit_cls):

c = circuit_cls(cirq.X(cirq.LineQubit(0)))
c2 = c.with_device(cg.Foxtail, lambda e: cirq.GridQubit(e.x, 0))
assert c2 == circuit_cls(cirq.X(cirq.GridQubit(0, 0)), device=cg.Foxtail)
c2 = c.with_device(FOXY, lambda e: cirq.GridQubit(e.x, 0))
assert c2 == circuit_cls(cirq.X(cirq.GridQubit(0, 0)), device=FOXY)

# Qubit type must be correct.
c = circuit_cls(cirq.X(cirq.LineQubit(0)))
with pytest.raises(ValueError, match='Unsupported qubit type'):
_ = c.with_device(cg.Foxtail)
_ = c.with_device(FOXY)

# Operations must be compatible from the start
c = circuit_cls(cirq.X(cirq.GridQubit(0, 0)))
_ = c.with_device(cg.Foxtail)
_ = c.with_device(FOXY)
c = circuit_cls(cirq.H(cirq.GridQubit(0, 0)))
with pytest.raises(ValueError, match='Unsupported gate type'):
_ = c.with_device(cg.Foxtail)
_ = c.with_device(FOXY)

# Some qubits exist on multiple devices.
c = circuit_cls(cirq.X(cirq.GridQubit(0, 0)), device=cg.Foxtail)
c = circuit_cls(cirq.X(cirq.GridQubit(0, 0)), device=FOXY)
with pytest.raises(ValueError):
_ = c.with_device(cg.Bristlecone)
c = circuit_cls(cirq.X(cirq.GridQubit(0, 6)), device=cg.Foxtail)
_ = c.with_device(cg.Bristlecone)
_ = c.with_device(BCONE)
c = circuit_cls(cirq.X(cirq.GridQubit(0, 6)), device=FOXY)
_ = c.with_device(BCONE)


def test_set_device():
c = cirq.Circuit(cirq.X(cirq.LineQubit(0)))
assert c.device is cirq.UNCONSTRAINED_DEVICE

with pytest.raises(ValueError):
c.device = cg.Foxtail
c.device = FOXY
assert c.device is cirq.UNCONSTRAINED_DEVICE

c[:] = []
c.append(cirq.X(cirq.GridQubit(0, 0)))
c.device = cg.Foxtail
assert c.device == cg.Foxtail
c.device = FOXY
assert c.device == FOXY


@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit])
Expand Down Expand Up @@ -841,7 +915,7 @@ def test_insert_moment():

def test_insert_validates_all_operations_before_inserting():
a, b = cirq.GridQubit(0, 0), cirq.GridQubit(1, 1)
c = cirq.Circuit(device=cg.Foxtail)
c = cirq.Circuit(device=FOXY)
operations = [cirq.Z(a), cirq.CZ(a, b)]

with pytest.raises(ValueError, match='Non-local interaction'):
Expand Down Expand Up @@ -3375,7 +3449,7 @@ def test_insert_operations_errors():


def test_validates_while_editing():
c = cirq.Circuit(device=cg.Foxtail)
c = cirq.Circuit(device=FOXY)

with pytest.raises(ValueError, match='Unsupported qubit type'):
# Wrong type of qubit.
Expand All @@ -3387,13 +3461,13 @@ def test_validates_while_editing():

with pytest.raises(ValueError, match='Non-local interaction'):
# Non-adjacent CZ.
c[0] = cirq.Moment([cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(1, 2))])
c[0] = cirq.Moment([cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(1, 1))])

c.insert(0, cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)))


def test_respects_additional_adjacency_constraints():
c = cirq.Circuit(device=cg.Foxtail)
c = cirq.Circuit(device=FOXY)
c.append(cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)))
c.append(
cirq.CZ(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)), strategy=cirq.InsertStrategy.EARLIEST
Expand All @@ -3405,7 +3479,7 @@ def test_respects_additional_adjacency_constraints():
cirq.Moment([cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))]),
cirq.Moment([cirq.CZ(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1))]),
],
device=cg.Foxtail,
device=FOXY,
),
)

Expand All @@ -3417,7 +3491,7 @@ def test_commutes_past_adjacency_constraints():
cirq.Moment(),
cirq.Moment([cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))]),
],
device=cg.Foxtail,
device=FOXY,
)
c.append(
cirq.CZ(cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)), strategy=cirq.InsertStrategy.EARLIEST
Expand All @@ -3430,21 +3504,21 @@ def test_commutes_past_adjacency_constraints():
cirq.Moment(),
cirq.Moment([cirq.CZ(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1))]),
],
device=cg.Foxtail,
device=FOXY,
),
)


def test_decomposes_while_appending():
c = cirq.Circuit(device=cg.Foxtail)
c.append(cirq.TOFFOLI(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(0, 2)))
c = cirq.Circuit(device=FOXY)
c.append(cirq.TOFFOLI(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(1, 0)))
cirq.testing.assert_allclose_up_to_global_phase(
c.unitary(), cirq.unitary(cirq.TOFFOLI), atol=1e-8
)

# But you still have to respect adjacency constraints!
with pytest.raises(ValueError):
c.append(cirq.TOFFOLI(cirq.GridQubit(0, 0), cirq.GridQubit(0, 2), cirq.GridQubit(0, 4)))
c.append(cirq.TOFFOLI(cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(0, 6)))


@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit])
Expand Down Expand Up @@ -4091,11 +4165,9 @@ def test_transform_qubits():
assert original.transform_qubits(func=lambda q: cirq.GridQubit(10 + q.x, 20)) == desired

# Device
original = cirq.Circuit(device=cg.Foxtail)
assert original.transform_qubits(lambda q: q).device is cg.Foxtail
assert (
original.transform_qubits(lambda q: q, new_device=cg.Bristlecone).device is cg.Bristlecone
)
original = cirq.Circuit(device=FOXY)
assert original.transform_qubits(lambda q: q).device is FOXY
assert original.transform_qubits(lambda q: q, new_device=BCONE).device is BCONE


@pytest.mark.parametrize('circuit_cls', [cirq.Circuit, cirq.FrozenCircuit])
Expand Down

0 comments on commit 2e5c45b

Please sign in to comment.