Skip to content

Commit d0a150e

Browse files
authored
Add QVM helper extract_gate_times_ns_from_device (#7350)
* Add QVM helper `extract_gate_times_ns_from_device` Gate times are necessary for noisy quantum virtual machine simulations. Provide adapter to fetch them from GridDeviceMetadata (which are supplied for known QVMs) rather than from user-provided value or hard-coded default. Prerequisite for QVM update, b/395705720 * Fix missing line and fill in coverage * Nit - rename `gtype` --> `gate_type` * Use separate unit test for GridDevice without duration data
1 parent 080ec36 commit d0a150e

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

cirq-google/cirq_google/engine/virtual_engine_factory.py

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,28 @@
1313
# limitations under the License.
1414

1515
"""Functions to instantiate SimulatedLocalEngines to simulate various Google Devices."""
16+
17+
from __future__ import annotations
18+
1619
import json
1720
import pathlib
1821
import time
19-
from typing import cast, List, Optional, Type, Union
22+
from typing import cast, Dict, List, Optional, Type, TYPE_CHECKING, Union
2023

2124
import google.protobuf.text_format as text_format
2225

2326
import cirq
24-
from cirq.sim.simulator import SimulatesSamples
2527
from cirq_google.api import v2
2628
from cirq_google.devices import grid_device
2729
from cirq_google.devices.google_noise_properties import NoiseModelFromGoogleNoiseProperties
2830
from cirq_google.engine import calibration, engine_validator, simulated_local_processor, util
2931
from cirq_google.engine.calibration_to_noise_properties import noise_properties_from_calibration
3032
from cirq_google.engine.simulated_local_engine import SimulatedLocalEngine
3133
from cirq_google.engine.simulated_local_processor import SimulatedLocalProcessor
34+
from cirq_google.ops import fsim_gate_family
35+
36+
if TYPE_CHECKING:
37+
import cirq_google
3238

3339
MOST_RECENT_TEMPLATES = {
3440
'rainbow': 'rainbow_2021_12_10_device_spec_for_grid_device.proto.txt',
@@ -303,8 +309,8 @@ def create_device_spec_from_processor_id(processor_id: str) -> v2.device_pb2.Dev
303309
return _create_device_spec_from_template(template_name)
304310

305311

306-
def create_device_from_processor_id(processor_id: str) -> cirq.Device:
307-
"""Generates a `cirq.Device` for a given processor ID.
312+
def create_device_from_processor_id(processor_id: str) -> grid_device.GridDevice:
313+
"""Generates a `cirq_google.GridDevice` for a given processor ID.
308314
309315
Args:
310316
processor_id: name of the processor to simulate.
@@ -385,7 +391,7 @@ def create_noiseless_virtual_engine_from_latest_templates() -> SimulatedLocalEng
385391

386392

387393
def create_default_noisy_quantum_virtual_machine(
388-
processor_id: str, simulator_class: Optional[Type[SimulatesSamples]] = None, **kwargs
394+
processor_id: str, simulator_class: Optional[Type[cirq.SimulatesSamples]] = None, **kwargs
389395
) -> SimulatedLocalEngine:
390396
"""Creates a virtual engine with a noisy simulator based on a processor id.
391397
@@ -425,3 +431,40 @@ def create_default_noisy_quantum_virtual_machine(
425431
)
426432

427433
return SimulatedLocalEngine([simulated_processor])
434+
435+
436+
def extract_gate_times_ns_from_device(
437+
device: cirq_google.GridDevice,
438+
) -> Dict[Type[cirq.Gate], float]:
439+
"""Extract a dictionary of gate durations in nanoseconds from GridDevice object.
440+
441+
The durations are obtained from `GridDevice.metadata` field which is
442+
provided for devices obtained with `create_device_from_processor_id`.
443+
444+
Args:
445+
device: Object representing Google devices with a grid qubit layout.
446+
447+
Returns:
448+
A dictionary of gate durations versus supported gate types. Returns an
449+
empty dictionary when `device.metadata` do not provide gate durations.
450+
"""
451+
gate_times_ns: Dict[Type[cirq.Gate], float] = {}
452+
if not device.metadata.gate_durations:
453+
return gate_times_ns
454+
gate_type: Type[cirq.Gate] # pragma: no cover
455+
for gate_family, duration in device.metadata.gate_durations.items():
456+
if isinstance(gate_family, fsim_gate_family.FSimGateFamily):
457+
for g in gate_family.gates_to_accept:
458+
gate_type = g if isinstance(g, type) else type(g)
459+
gate_times_ns[gate_type] = duration.total_nanos()
460+
continue
461+
# ordinary GateFamily here
462+
gate_type = (
463+
gate_family.gate if isinstance(gate_family.gate, type) else type(gate_family.gate)
464+
)
465+
gate_times_ns[gate_type] = duration.total_nanos()
466+
# cirq.IdentityGate can leak from FSimGateFamily. Exclude to default to zero duration.
467+
_ = gate_times_ns.pop(cirq.IdentityGate, None)
468+
# cirq.WaitGate has variable duration and should not be included here.
469+
_ = gate_times_ns.pop(cirq.WaitGate, None)
470+
return gate_times_ns

cirq-google/cirq_google/engine/virtual_engine_factory_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,20 @@ def test_create_default_noisy_quantum_virtual_machine():
208208
expected = factory.create_device_spec_from_processor_id(processor_id)
209209
assert device_specification is not None
210210
assert device_specification == expected
211+
212+
213+
def test_extract_gate_times_ns_from_device():
214+
device = factory.create_device_from_processor_id('rainbow')
215+
gate_times_ns = factory.extract_gate_times_ns_from_device(device)
216+
assert gate_times_ns[cirq.MeasurementGate] == 4_000_000
217+
assert gate_times_ns[cg.SycamoreGate] == 12
218+
assert cirq.IdentityGate not in gate_times_ns
219+
assert cirq.WaitGate not in gate_times_ns
220+
221+
222+
def test_extract_gate_times_ns_from_device_without_durations():
223+
metadata_without_durations = cirq.GridDeviceMetadata(
224+
qubit_pairs=[tuple(cirq.GridQubit.rect(2, 1))], gateset=cirq.Gateset(cirq.XPowGate)
225+
)
226+
device_without_durations = cg.GridDevice(metadata_without_durations)
227+
assert factory.extract_gate_times_ns_from_device(device_without_durations) == {}

0 commit comments

Comments
 (0)