diff --git a/cirq-google/cirq_google/devices/known_devices_test.py b/cirq-google/cirq_google/devices/known_devices_test.py index b4b2d3f5ef1..9c932c46ea2 100644 --- a/cirq-google/cirq_google/devices/known_devices_test.py +++ b/cirq-google/cirq_google/devices/known_devices_test.py @@ -21,13 +21,14 @@ def test_foxtail_qubits(): - with cirq.testing.assert_deprecated('Foxtail', deadline='v0.15'): + with cirq.testing.assert_deprecated('Foxtail', deadline='v0.15', count=2): expected_qubits = [] for i in range(0, 2): for j in range(0, 11): expected_qubits.append(cirq.GridQubit(i, j)) assert set(expected_qubits) == cirq_google.Foxtail.qubits + assert len(cirq_google.Foxtail.metadata.qubit_pairs) == 31 def test_foxtail_device_proto(): @@ -490,6 +491,22 @@ def test_sycamore_devices(device): assert device.duration_of(sqrt_iswap) == cirq.Duration(nanos=32) +def test_sycamore_metadata(): + assert len(cirq_google.Sycamore.metadata.qubit_pairs) == 88 + assert len(cirq_google.Sycamore23.metadata.qubit_pairs) == 32 + assert cirq_google.Sycamore.metadata.gateset == cirq.Gateset( + cirq.FSimGate, + cirq.ISwapPowGate, + cirq.PhasedXPowGate, + cirq.XPowGate, + cirq.YPowGate, + cirq.ZPowGate, + cirq.PhasedXZGate, + cirq.MeasurementGate, + cirq.WaitGate, + ) + + def test_sycamore_circuitop_device(): circuitop_gateset = cirq_google.SerializableGateSet( gate_set_name='circuitop_gateset', diff --git a/cirq-google/cirq_google/devices/serializable_device.py b/cirq-google/cirq_google/devices/serializable_device.py index b37792e9501..8b92b3b3136 100644 --- a/cirq-google/cirq_google/devices/serializable_device.py +++ b/cirq-google/cirq_google/devices/serializable_device.py @@ -108,6 +108,25 @@ def __init__( """ self.qubits = qubits self.gate_definitions = gate_definitions + self._metadata = cirq.GridDeviceMetadata( + qubit_pairs=[ + (pair[0], pair[1]) + for gate_defs in gate_definitions.values() + for gate_def in gate_defs + if gate_def.number_of_qubits == 2 + for pair in gate_def.target_set + if len(pair) == 2 and pair[0] < pair[1] + ], + supported_gates=cirq.Gateset( + *[g for g in gate_definitions.keys() if isinstance(g, (cirq.Gate, type(cirq.Gate)))] + ), + gate_durations=None, + ) + + @property + def metadata(self) -> cirq.GridDeviceMetadata: + """Get metadata information for device.""" + return self._metadata def qubit_set(self) -> FrozenSet[cirq.Qid]: return frozenset(self.qubits) diff --git a/cirq-google/cirq_google/devices/serializable_device_test.py b/cirq-google/cirq_google/devices/serializable_device_test.py index 59125d5b35b..230f6d3f446 100644 --- a/cirq-google/cirq_google/devices/serializable_device_test.py +++ b/cirq-google/cirq_google/devices/serializable_device_test.py @@ -77,6 +77,35 @@ def test_repr_pretty(cycle, func): printer.text.assert_called_once_with(func(device)) +def test_metadata_correct(): + qubits = cirq.GridQubit.rect(2, 3, left=1, top=1) + pairs = [ + (qubits[0], qubits[1]), + (qubits[0], qubits[3]), + (qubits[1], qubits[4]), + (qubits[4], qubits[5]), + ] + device_proto = cgdk.create_device_proto_for_qubits( + qubits=qubits, + pairs=pairs, + gate_sets=[cg.FSIM_GATESET], + ) + device = cgdk.SerializableDevice.from_proto(device_proto, gate_sets=[cg.FSIM_GATESET]) + assert device.metadata.qubit_pairs == frozenset(pairs) + assert device.metadata.gateset == cirq.Gateset( + cirq.FSimGate, + cirq.ISwapPowGate, + cirq.CZPowGate, + cirq.PhasedXPowGate, + cirq.XPowGate, + cirq.YPowGate, + cirq.ZPowGate, + cirq.PhasedXZGate, + cirq.MeasurementGate, + cirq.WaitGate, + ) + + def test_gate_definition_equality(): def1 = cg.devices.serializable_device._GateDefinition( duration=cirq.Duration(picos=4), diff --git a/cirq-google/cirq_google/devices/xmon_device.py b/cirq-google/cirq_google/devices/xmon_device.py index 9802a5429c5..fb2866bb229 100644 --- a/cirq-google/cirq_google/devices/xmon_device.py +++ b/cirq-google/cirq_google/devices/xmon_device.py @@ -45,6 +45,23 @@ def __init__( self._exp_w_duration = cirq.Duration(exp_w_duration) self._exp_z_duration = cirq.Duration(exp_11_duration) self.qubits = frozenset(qubits) + self._metadata = cirq.GridDeviceMetadata( + [(q0, q1) for q0 in self.qubits for q1 in self.qubits if q0.is_adjacent(q1)], + cirq.Gateset( + cirq.CZPowGate, + cirq.XPowGate, + cirq.YPowGate, + cirq.PhasedXPowGate, + cirq.MeasurementGate, + cirq.ZPowGate, + ), + None, + ) + + @property + def metadata(self) -> cirq.GridDeviceMetadata: + """Return the metadata for this device""" + return self._metadata def qubit_set(self) -> FrozenSet[cirq.GridQubit]: return self.qubits diff --git a/cirq-google/cirq_google/devices/xmon_device_test.py b/cirq-google/cirq_google/devices/xmon_device_test.py index 5ee00b9d551..08ad26c0e50 100644 --- a/cirq-google/cirq_google/devices/xmon_device_test.py +++ b/cirq-google/cirq_google/devices/xmon_device_test.py @@ -44,6 +44,35 @@ def qubits(self): raise NotImplementedError() +@mock.patch.dict(os.environ, clear='CIRQ_TESTING') +def test_device_metadata(): + d = square_device(3, 3) + assert d.metadata.gateset == cirq.Gateset( + cirq.CZPowGate, + cirq.XPowGate, + cirq.YPowGate, + cirq.PhasedXPowGate, + cirq.MeasurementGate, + cirq.ZPowGate, + ) + assert d.metadata.qubit_pairs == frozenset( + { + (cirq.GridQubit(0, 0), cirq.GridQubit(0, 1)), + (cirq.GridQubit(0, 1), cirq.GridQubit(1, 1)), + (cirq.GridQubit(2, 0), cirq.GridQubit(2, 1)), + (cirq.GridQubit(0, 0), cirq.GridQubit(1, 0)), + (cirq.GridQubit(0, 2), cirq.GridQubit(1, 2)), + (cirq.GridQubit(1, 0), cirq.GridQubit(2, 0)), + (cirq.GridQubit(1, 0), cirq.GridQubit(1, 1)), + (cirq.GridQubit(1, 1), cirq.GridQubit(2, 1)), + (cirq.GridQubit(1, 1), cirq.GridQubit(1, 2)), + (cirq.GridQubit(0, 1), cirq.GridQubit(0, 2)), + (cirq.GridQubit(2, 1), cirq.GridQubit(2, 2)), + (cirq.GridQubit(1, 2), cirq.GridQubit(2, 2)), + } + ) + + @mock.patch.dict(os.environ, clear='CIRQ_TESTING') def test_init(): d = square_device(2, 2, holes=[cirq.GridQubit(1, 1)]) diff --git a/dev_tools/requirements/deps/pytest.txt b/dev_tools/requirements/deps/pytest.txt index 9c48432afcd..b46b0533c04 100644 --- a/dev_tools/requirements/deps/pytest.txt +++ b/dev_tools/requirements/deps/pytest.txt @@ -3,6 +3,7 @@ pytest pytest-asyncio pytest-cov +coverage<=6.2 # for parallel testing notebooks pytest-xdist~=2.2.0