Device Specifications

The device specification proto defines basic layout of a device as well as the gate set and serialized ids that can be used. This specification can be used to find out specific characteristics of though.

Though several standard Google devices are defined for your convenience, specific devices may have specialized layouts particular to that processor. For instance, there may be one or more qubit “drop-outs” that are non-functional for whatever reason. There could also be new or experimental features enabled on some devices but not on others.

This specification is defined in the Device proto within cirq.google.api.v2.

Gate Set Specifications

Most devices can only accept a limited set of gates. This is known as the gate set of the device. Any circuits sent to this device must only use gates within this set. The gate set portion of the protocol buffer defines which gate set(s) are valid on the device, and which gates make up that set.

Gate Definitions

Each gate in the gate set will have a definition that defines the id that the gate is serialized as, the number of qubits for the gates, the arguments to the gate, the duration, and which qubits it can be applied to.

This definition uses “target sets” to specify which qubits the operation can be applied to. See the section below for more information.

Gate Durations

The time it takes the device to perform each gate is stored within the device specification. This time is stored as an integer number of picoseconds.

Example code to print out the gate durations for every gate supported by the device is shown below:

import cirq

# Create an Engine object to use.
engine = cirq.google.Engine(project_id='your_project_id',
                            proto_version=cirq.google.ProtoVersion.V2)

# Replace the processor id to get the device specification with that id.
spec = engine.get_processor('processor_id').get_device_specification()

# Iterate through each gate set valid on the device.
for gateset in spec.valid_gate_sets:
    print(gateset.name)
    print('-------')
    # Prints each gate valid in the set with its duration
    for gate in gateset.valid_gates:
      print('%s %d' % (gate.id, gate.gate_duration_picos))

Note that, by convention, measurement gate duration includes both the duration of “read-out” pulses to measure the qubit as well as the “ring-down” time that it takes the measurement resonator to reset to a ground state.

Target Sets

Generally, most gates apply to the same set of qubits. To avoid repeating these qubits (or pairs of qubits) for each gate, each gate instead uses a target set to define the set of qubits that are valid.

Each target set contains a list of valid targets. A target is a list of qubits. For one-qubit gates, a target is simply a single qubit. For two qubit gates, a target is a pair of qubits.

The type of a target set defines how the targets are interpreted. If the target set is set to SYMMETRIC, the order of each target does not matter (e.g. if gate.on(q1, q2) is valid, then so is gate.on(q2, q1)). If the target type is set to ASYMMETRIC, then the order of qubits does matter, and other orderings of the qubits that are not specified in the definition cannot be assumed to be valid.

The last type is PERMUTATION_SET. This type specified that any permutation of the targets is valid. This is typically used for measurement gates. If q0, q1 and q2 are all specified as valid targets for a permutation set of the gate, then gate.on(q0), gate.on(q1), gate.on(q2), gate.on(q0, q1), gate.on(q0, q2), gate.on(q1, q2) and gate.on(q0, q1, q2) are all valid uses of the gate.

Developer Recommendations

This is a free form text field for additional recommendations and soft requirements that should be followed for proper operation of the device that are not captured by the hard requirements above.

For instance, “Do not apply two CZ gates in a row.”

Serializable Devices

The cirq.google.SerializableDevice class allows someone to take this device specification and turn it into a cirq.Device that can be used to verify a circuit.

The cirq.google.SerializableDevice combines a DeviceSpecification protocol buffer (defining the device) with a SerializableGateSet (that defines the translation from serialized id to cirq) to produce a cirq.Device that can be used to validate a circuit.

The following example illustrates retrieving the device specification live from the engine and then using it to validate a circuit.

import cirq
import cirq.google as cg

# Create an Engine object to use.
engine = cg.Engine(project_id='your_project_id',
                   proto_version=cirq.google.ProtoVersion.V2)

# Replace the processor id to get the device with that id.
device = engine.get_processor('processor_id').get_device(
  gate_sets=[cg.gate_sets.SQRT_ISWAP_GATESET])

q0, q1 = cirq.LineQubit.range(2)

# Raises a ValueError, since this is not a supported gate.
cirq.Circuit(cirq.CZ(q0,q1), device=device)

Note that, if network traffic is undesired, the DeviceSpecification can easily be stored in either binary format or TextProto format for later usage.