forked from quantumlib/Cirq
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add documentation for Engine (quantumlib#2663)
* Add documentation for Engine - Adds a stub page for Engine documentation. - Includes information about device specification and calibration metrics. - Adding more information on device specification.
- Loading branch information
1 parent
4b91b2c
commit 8a0339b
Showing
4 changed files
with
320 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# Quantum Engine | ||
|
||
The Quantum Engine, via the `cirq.google.Engine` class, executes programs and jobs using the | ||
Quantum Engine API. | ||
|
||
Note that the Quantum Engine API is not yet open for public access. | ||
|
||
## Authenticating to Google Cloud | ||
|
||
Before you begin, you will need to create a Google Cloud project with the API | ||
enabled and billing enabled. You will then to create credentials in order to | ||
access the API. | ||
|
||
You can create application default credentials from the command line using the | ||
gcloud client: | ||
|
||
`gcloud auth application-default login` | ||
|
||
From a colab, you can execute: | ||
|
||
``` | ||
from google.colab import auth | ||
auth.authenticate_user(clear_output=False) | ||
``` | ||
|
||
More information on creating application default credentials can be found on the | ||
[Google cloud](https://cloud.google.com/docs/authentication/production) website. | ||
|
||
## Engine class | ||
|
||
The `Engine` class is the entry point to communicate with the API. | ||
|
||
It can be initialized using your project id (found within your | ||
[Google Cloud Platform Console](https://console.cloud.google.com)). | ||
You can use this instance to run quantum circuits or sweeps (parameterized | ||
variants of a general circuit). | ||
|
||
<!---test_substitution | ||
cg.Engine(.*) | ||
cirq.Simulator() | ||
---> | ||
<!---test_substitution | ||
sampler = .* | ||
sampler = engine | ||
---> | ||
```python | ||
import cirq | ||
import cirq.google as cg | ||
import random | ||
import string | ||
|
||
# A simple sample circuit | ||
qubit = cirq.GridQubit(5, 2) | ||
circuit = cirq.Circuit( | ||
cirq.X(qubit)**0.5, # Square root of NOT. | ||
cirq.measure(qubit, key='result') # Measurement. | ||
) | ||
|
||
# Create an Engine object to use. | ||
# Replace YOUR_PROJECT_ID with the id from your cloud project. | ||
engine = cg.Engine(project_id=YOUR_PROJECT_ID, proto_version=cg.ProtoVersion.V2) | ||
|
||
# Create a sampler from the engine | ||
sampler = engine.sampler(processor_id='PROCESSOR_ID', gate_set=cg.SYC_GATESET) | ||
|
||
# This will run the circuit and return the results in a 'TrialResult' | ||
results = sampler.run(circuit, repetitions=1000) | ||
|
||
# Sampler results can be accessed several ways | ||
|
||
# For instance, to see the histogram of results | ||
print(results.histogram(key='result')) | ||
|
||
# Or the data itself | ||
print(results.data) | ||
``` | ||
|
||
## Device Specification | ||
|
||
Several public devices have been released and can be found in the `cirq.google` | ||
package. These are documented further on the [Google Device](devices.md) page. | ||
|
||
However, you can also retrieve the device using the `get_device_specification` of an | ||
`Engine` object. This is a [protocol buffer](https://developers.google.com/protocol-buffers) | ||
message that contains information about the qubits on the device, the | ||
connectivity, and the supported gates. | ||
|
||
This proto can be queried directly to get information about the device or can be transformed | ||
into a `cirq.Device` by using `cirq.google.SerializableDevice.from_proto()` that will | ||
enforce constraints imposed by the hardware. | ||
|
||
See the [Device Specification](specification.md) page for more information on | ||
device specifications. | ||
|
||
|
||
## Calibration Metrics | ||
|
||
Metrics from the current status of the device can be retrieved using the\ | ||
`get_latest_calibration` method of the `Engine` object. This will return a | ||
Python dictionary where each key is the metric name. The value of the | ||
dictionary will be the value of the metric, which can also be a dictionary. | ||
|
||
For example, the key may refer to a two-qubit gate error, and the value may | ||
be a dictionary from 2-tuples of `cirq.GridQubits` to an error rate represented | ||
as a float value. | ||
|
||
Information about specific metrics will be released at a later date. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,5 @@ of devices that have become public information. | |
:maxdepth: 1 | ||
|
||
devices | ||
engine | ||
specification |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# 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](devices.md) 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_device_specification('processor_id') | ||
# 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 ASSYMMETRIC, 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 specification with that id. | ||
spec = engine.get_device_specification('processor_id') | ||
device = cg.SerializableDevice.from_proto( | ||
proto=spec, | ||
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. |