Skip to content
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

Add metadata property for cirq_google devices. #4869

Merged
merged 8 commits into from
Jan 26, 2022
19 changes: 18 additions & 1 deletion cirq-google/cirq_google/devices/known_devices_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down Expand Up @@ -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',
Expand Down
19 changes: 19 additions & 0 deletions cirq-google/cirq_google/devices/serializable_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,25 @@ def __init__(
"""
self.qubits = qubits
self.gate_definitions = gate_definitions
self._metadata = cirq.GridDeviceMetadata(
MichaelBroughton marked this conversation as resolved.
Show resolved Hide resolved
[
(pair[0], pair[1])
MichaelBroughton marked this conversation as resolved.
Show resolved Hide resolved
MichaelBroughton marked this conversation as resolved.
Show resolved Hide resolved
for gate_defs in gate_definitions.values()
for gate_def in gate_defs
if gate_def.number_of_qubits == 2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering: this is just a defensive check right? It should never be false?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, I just copied this from lower down in the module qid_pairs function.

for pair in gate_def.target_set
if len(pair) == 2 and pair[0] < pair[1]
],
cirq.Gateset(
*[g for g in gate_definitions.keys() if isinstance(g, (cirq.Gate, type(cirq.Gate)))]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this (cirq.Gate, type(cirq.Gate))? This seems redundant but I assume there's a good reason for it?

Copy link
Collaborator Author

@MichaelBroughton MichaelBroughton Jan 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full disclosure: Things in this module are in pretty rough shape. In tests, the type contracts are somehow getting violated in this constructor and other "non Type[_Gate]" things are making it into this function. I'm working on deprecating qid_pairs in cirq-core and there are a few hangups in cirq_google that this PR will help unblock.

High level is I want to make sure we keep cirq-core pristine and cirq-google devices limping along in whatever weird state it is in so that we can finish the items here #4744 and then make a more focused effort on cleaning this up knowing that cirq-core now gives a solid foundation.

This weirdness keeps cirq-google behaving, albeit weirdly.

RE: backwards compatibility and changing in the future we should make a more focused effort on SerializableDevice before we cut our next release, I just don't think in this PR as things are bound to keep changing a lot here before that next release.

),
None,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the gate durations exist currently, so I think we could populate this if we wanted to.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, but I think it's best left for when we can turn 100% of our attention to cleaning up things for SerializableDevice this PR is a means to an end for getting cleaner deprecations happening in cirq-core for qid_pairs.

)

@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)
Expand Down
35 changes: 35 additions & 0 deletions cirq-google/cirq_google/devices/serializable_device_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,41 @@ 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)
device_proto = cgdk.create_device_proto_for_qubits(
qubits=qubits,
pairs=[
MichaelBroughton marked this conversation as resolved.
Show resolved Hide resolved
(qubits[0], qubits[1]),
(qubits[0], qubits[3]),
(qubits[1], qubits[4]),
(qubits[4], qubits[5]),
],
gate_sets=[cg.FSIM_GATESET],
)
device = cgdk.SerializableDevice.from_proto(device_proto, gate_sets=[cg.FSIM_GATESET])
assert device.metadata.qubit_pairs == frozenset(
{
(qubits[0], qubits[1]),
(qubits[0], qubits[3]),
(qubits[1], qubits[4]),
(qubits[4], qubits[5]),
}
)
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),
Expand Down
17 changes: 17 additions & 0 deletions cirq-google/cirq_google/devices/xmon_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
MichaelBroughton marked this conversation as resolved.
Show resolved Hide resolved
[(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
Expand Down
29 changes: 29 additions & 0 deletions cirq-google/cirq_google/devices/xmon_device_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)])
Expand Down