Skip to content

remove 2 deprecated create_device_proto_* methods for v0.16 release #5704

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

Merged
merged 11 commits into from
Jul 12, 2022
88 changes: 1 addition & 87 deletions cirq-google/cirq_google/devices/grid_device_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import cirq
import cirq_google
from cirq_google.api import v2
from cirq_google.devices import grid_device, known_devices
from cirq_google.devices import grid_device


GRID_HEIGHT = 5
Expand Down Expand Up @@ -417,92 +417,6 @@ def test_to_proto_invalid_input(error_match, qubits, qubit_pairs, gateset, gate_
)


def test_to_proto_backward_compatibility():
# Deprecations: cirq_google.SerializableGateSet and
# cirq_google.device.known_devices.create_device_proto_for_qubits()
with cirq.testing.assert_deprecated(
'SerializableGateSet',
'create_device_specification_proto()` can be used',
deadline='v0.16',
count=None,
):
device_info, _ = _create_device_spec_with_horizontal_couplings()

# The set of gates in gate_durations are consistent with what's generated in
# _create_device_spec_with_horizontal_couplings()
base_duration = cirq.Duration(picos=1_000)
gate_durations = {
cirq.GateFamily(cirq_google.SYC): base_duration * 0,
cirq.GateFamily(cirq.SQRT_ISWAP): base_duration * 1,
cirq.GateFamily(cirq.SQRT_ISWAP_INV): base_duration * 2,
cirq.GateFamily(cirq.CZ): base_duration * 3,
cirq.GateFamily(cirq.ops.phased_x_z_gate.PhasedXZGate): base_duration * 4,
cirq.GateFamily(
cirq.ops.common_gates.ZPowGate, tags_to_ignore=[cirq_google.PhysicalZTag()]
): base_duration
* 5,
cirq.GateFamily(
cirq.ops.common_gates.ZPowGate, tags_to_accept=[cirq_google.PhysicalZTag()]
): base_duration
* 6,
cirq.GateFamily(cirq_google.experimental.ops.coupler_pulse.CouplerPulse): base_duration
* 7,
cirq.GateFamily(cirq.ops.measurement_gate.MeasurementGate): base_duration * 8,
cirq.GateFamily(cirq.ops.wait_gate.WaitGate): base_duration * 9,
}

# Serialize the old way
spec = known_devices.create_device_proto_for_qubits(
device_info.grid_qubits,
device_info.qubit_pairs,
[cirq_google.FSIM_GATESET],
known_devices._SYCAMORE_DURATIONS_PICOS,
)

# Serialize the new way
grid_device.create_device_specification_proto(
qubits=device_info.grid_qubits,
pairs=device_info.qubit_pairs,
gateset=cirq.Gateset(*gate_durations.keys()),
gate_durations=gate_durations,
out=spec,
)

with cirq.testing.assert_deprecated(
'Use cirq_google.GridDevice', deadline='v0.16', count=None
):
# Deserialize both ways
serializable_dev = cirq_google.SerializableDevice.from_proto(
spec, [cirq_google.FSIM_GATESET]
)
grid_dev = cirq_google.GridDevice.from_proto(spec)

assert serializable_dev.metadata.qubit_set == grid_dev.metadata.qubit_set
assert serializable_dev.metadata.qubit_pairs == grid_dev.metadata.qubit_pairs

assert serializable_dev.metadata.gateset == cirq.Gateset(
cirq.FSimGate,
cirq.ISwapPowGate,
cirq.CZPowGate,
cirq.PhasedXPowGate,
cirq.XPowGate,
cirq.YPowGate,
cirq.ZPowGate,
cirq.PhasedXZGate,
cirq.MeasurementGate,
cirq.WaitGate,
cirq.GlobalPhaseGate,
)

assert grid_dev.metadata.gateset == device_info.expected_gateset
assert (
tuple(grid_dev.metadata.compilation_target_gatesets)
== device_info.expected_target_gatesets
)

assert grid_dev.metadata.gate_durations == device_info.expected_gate_durations


def test_to_proto_empty():
spec = grid_device.create_device_specification_proto(
# Qubits are always expected to be set
Expand Down
142 changes: 1 addition & 141 deletions cirq-google/cirq_google/devices/known_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import Collection, Dict, Optional, Iterable, List, Set, Tuple, cast
from typing import Collection, Dict, Optional, List, Set, Tuple, cast

import cirq
from cirq import _compat
from cirq_google.api import v2
from cirq_google.api.v2 import device_pb2
from cirq_google.devices import grid_device
from cirq_google.experimental.ops import coupler_pulse
from cirq_google.ops import physical_z_tag, sycamore_gate
from cirq_google.serialization import op_serializer, serializable_gate_set

_2_QUBIT_TARGET_SET = "2_qubit_targets"
_MEAS_TARGET_SET = "meas_targets"
Expand Down Expand Up @@ -55,42 +53,6 @@ def _parse_device(s: str) -> Tuple[List[cirq.GridQubit], Dict[str, Set[cirq.Grid
return qubits, measurement_lines


@_compat.deprecated(
deadline='v0.16',
fix='This function will no longer be available.'
' `cirq_google.grid_device.create_device_specification_proto()` can be used'
' to generate a DeviceSpecification proto which matches the format expected'
' by GridDevice.',
)
def create_device_proto_from_diagram(
ascii_grid: str,
gate_sets: Optional[Iterable[serializable_gate_set.SerializableGateSet]] = None,
durations_picos: Optional[Dict[str, int]] = None,
out: Optional[device_pb2.DeviceSpecification] = None,
) -> device_pb2.DeviceSpecification:
"""Parse ASCIIart device layout into DeviceSpecification proto.
This function assumes that all pairs of adjacent qubits are valid targets
for two-qubit gates.
Args:
ascii_grid: ASCII version of the grid (see _parse_device for details).
gate_sets: Gate sets that define the translation between gate ids and
cirq Gate objects.
durations_picos: A map from gate ids to gate durations in picoseconds.
out: If given, populate this proto, otherwise create a new proto.
"""
qubits, _ = _parse_device(ascii_grid)

# Create a list of all adjacent pairs on the grid for two-qubit gates.
qubit_set = frozenset(qubits)
pairs: List[Tuple[cirq.Qid, cirq.Qid]] = []
for qubit in qubits:
for neighbor in sorted(qubit.neighbors()):
if neighbor > qubit and neighbor in qubit_set:
pairs.append((qubit, neighbor))

return create_device_proto_for_qubits(qubits, pairs, gate_sets, durations_picos, out)


def _create_grid_device_from_diagram(
ascii_grid: str,
gateset: cirq.Gateset,
Expand Down Expand Up @@ -124,108 +86,6 @@ def _create_grid_device_from_diagram(
return grid_device.GridDevice.from_proto(device_specification)


@_compat.deprecated(
deadline='v0.16',
fix='This function will no longer be available.'
' `cirq_google.grid_device.create_device_specification_proto()` can be used'
' to generate a DeviceSpecification proto which matches the format expected'
' by GridDevice.',
)
def create_device_proto_for_qubits(
qubits: Collection[cirq.Qid],
pairs: Collection[Tuple[cirq.Qid, cirq.Qid]],
gate_sets: Optional[Iterable[serializable_gate_set.SerializableGateSet]] = None,
durations_picos: Optional[Dict[str, int]] = None,
out: Optional[device_pb2.DeviceSpecification] = None,
) -> device_pb2.DeviceSpecification:
"""Create device spec for the given qubits and coupled pairs.

Args:
qubits: Qubits that can perform single-qubit gates.
pairs: Pairs of coupled qubits that can perform two-qubit gates.
gate_sets: Gate sets that define the translation between gate ids and
cirq Gate objects.
durations_picos: A map from gate ids to gate durations in picoseconds.
out: If given, populate this proto, otherwise create a new proto.
"""
if out is None:
out = device_pb2.DeviceSpecification()

# Create valid qubit list
populate_qubits_in_device_proto(qubits, out)

# Single qubit gates in this gateset
single_qubit_gates = (cirq.PhasedXPowGate, cirq.PhasedXZGate, cirq.ZPowGate)

# Set up a target set for measurement (any qubit permutation)
meas_targets = out.valid_targets.add()
meas_targets.name = _MEAS_TARGET_SET
meas_targets.target_ordering = device_pb2.TargetSet.SUBSET_PERMUTATION

# Set up a target set for 2 qubit gates (specified qubit pairs)
populate_qubit_pairs_in_device_proto(pairs, out)

# Create gate sets
arg_def = device_pb2.ArgDefinition
for gate_set in gate_sets or []:
gs_proto = out.valid_gate_sets.add()
gs_proto.name = gate_set.name
gate_ids: Set[str] = set()
for internal_type in gate_set.serializers:
for serializer in gate_set.serializers[internal_type]:
gate_id = serializer.serialized_id
if gate_id in gate_ids:
# Only add each type once
continue

gate_ids.add(gate_id)
gate = gs_proto.valid_gates.add()
gate.id = gate_id

if not isinstance(serializer, op_serializer._GateOpSerializer):
# This implies that 'serializer' handles non-gate ops,
# such as CircuitOperations. No other properties apply.
continue

# Choose target set and number of qubits based on gate type.
gate_type = internal_type

# Note: if it is not a measurement gate and it's type
# is not in the single_qubit_gates tuple, it's assumed to be a two qubit gate.
if gate_type == cirq.MeasurementGate:
gate.valid_targets.append(_MEAS_TARGET_SET)
elif gate_type == cirq.WaitGate:
# TODO: Refactor gate-sets / device to eliminate the need
# to keep checking type here.
# Github issue:
# https://github.com/quantumlib/Cirq/issues/2537
gate.number_of_qubits = 1
elif gate_type in single_qubit_gates:
gate.number_of_qubits = 1
else:
# This must be a two-qubit gate
gate.valid_targets.append(_2_QUBIT_TARGET_SET)
gate.number_of_qubits = 2

# Add gate duration
if durations_picos is not None and gate.id in durations_picos:
gate.gate_duration_picos = durations_picos[gate.id]

# Add argument names and types for each gate.
for arg in serializer.args:
new_arg = gate.valid_args.add()
if arg.serialized_type == str:
new_arg.type = arg_def.STRING
if arg.serialized_type == float:
new_arg.type = arg_def.FLOAT
if arg.serialized_type == List[bool]:
new_arg.type = arg_def.REPEATED_BOOLEAN
new_arg.name = arg.serialized_name
# Note: this does not yet support adding allowed_ranges

return out


def populate_qubits_in_device_proto(
qubits: Collection[cirq.Qid], out: device_pb2.DeviceSpecification
) -> None:
Expand Down
Loading