Skip to content

Commit 3c34181

Browse files
dstrain115BichengYing
authored andcommitted
Add serialization for Coupler Qids (quantumlib#6682)
* Add serialization for Coupler Qids - Adds serialization for coupler Qids to change them into a qubit string and back.
1 parent cbe1a62 commit 3c34181

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

cirq-google/cirq_google/api/v2/program.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,21 @@ def qubit_to_proto_id(q: cirq.Qid) -> str:
3131
For `cirq.NamedQubit`s this id is the name.
3232
3333
For `cirq.LineQubit`s this is string of the `x` attribute.
34+
35+
For `cirq_google.Coupler`s, this id is `c_{qubit0}_{qubit1}` where
36+
qubit0 and qubit1 are the ids for the two Qid in the Coupler.
3437
"""
38+
# Avoid circular import
39+
from cirq_google.devices.coupler import Coupler
40+
3541
if isinstance(q, cirq.GridQubit):
3642
return f'{q.row}_{q.col}'
3743
elif isinstance(q, cirq.NamedQubit):
3844
return q.name
3945
elif isinstance(q, cirq.LineQubit):
4046
return f'{q.x}'
47+
elif isinstance(q, Coupler):
48+
return f'c_{qubit_to_proto_id(q.qubit0)}_{qubit_to_proto_id(q.qubit1)}'
4149
else:
4250
raise ValueError(f'Qubits of type {type(q)} do not support proto id')
4351

@@ -49,6 +57,15 @@ def qubit_from_proto_id(proto_id: str) -> cirq.Qid:
4957
5058
Proto IDs of the form {int} are parsed as LineQubits.
5159
60+
Proto IDs of the form c_{int}_{int} are parsed as Couplers
61+
between two LineQubits.
62+
63+
Proto IDs of the form c_{int}_{int}_{int}_{int} are parsed as Couplers
64+
between two GridQubit.
65+
66+
Proto IDs of the form c_{name}_{name} are parsed as Couplers
67+
between two NamedQubits.
68+
5269
All other proto IDs are parsed as NamedQubits. Note that this will happily
5370
accept any string; for circuits which explicitly use Grid or LineQubits,
5471
prefer one of the specialized methods below.
@@ -59,8 +76,29 @@ def qubit_from_proto_id(proto_id: str) -> cirq.Qid:
5976
Returns:
6077
A `cirq.Qid` corresponding to the proto id.
6178
"""
62-
num_coords = len(proto_id.split('_'))
63-
if num_coords == 2:
79+
# Avoid circular import
80+
from cirq_google.devices.coupler import Coupler
81+
82+
qubit_field = proto_id.split('_')
83+
num_coords = len(qubit_field)
84+
if proto_id[:2] == 'c_':
85+
if num_coords == 5:
86+
# 2 grid qubits: c_2_1_4_3
87+
grid_qubit0_str = qubit_field[1] + '_' + qubit_field[2]
88+
grid_qubit1_str = qubit_field[3] + '_' + qubit_field[4]
89+
try:
90+
grid_qubit0 = grid_qubit_from_proto_id(grid_qubit0_str)
91+
grid_qubit1 = grid_qubit_from_proto_id(grid_qubit1_str)
92+
return Coupler(grid_qubit0, grid_qubit1)
93+
except ValueError:
94+
pass # Not valid grid qubits.
95+
elif num_coords == 3:
96+
# 2 line qubits: c_2_4
97+
# Or two named qubits: c_qubita_qubitb
98+
line_qubit0 = qubit_from_proto_id(qubit_field[1])
99+
line_qubit1 = qubit_from_proto_id(qubit_field[2])
100+
return Coupler(line_qubit0, line_qubit1)
101+
elif num_coords == 2:
64102
try:
65103
grid_q = grid_qubit_from_proto_id(proto_id)
66104
return grid_q

cirq-google/cirq_google/api/v2/program_test.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import pytest
1616

1717
import cirq
18+
import cirq_google as cg
1819
import cirq_google.api.v2 as v2
1920

2021

@@ -26,6 +27,14 @@ def test_qubit_to_proto_id():
2627
assert v2.qubit_to_proto_id(cirq.LineQubit(10)) == '10'
2728
assert v2.qubit_to_proto_id(cirq.LineQubit(-1)) == '-1'
2829
assert v2.qubit_to_proto_id(cirq.NamedQubit('named')) == 'named'
30+
grid_coupler = cg.Coupler(cirq.GridQubit(2, 1), cirq.GridQubit(4, 3))
31+
assert v2.qubit_to_proto_id(grid_coupler) == 'c_2_1_4_3'
32+
grid_coupler = cg.Coupler(cirq.GridQubit(4, 3), cirq.GridQubit(2, 1))
33+
assert v2.qubit_to_proto_id(grid_coupler) == 'c_2_1_4_3'
34+
line_coupler = cg.Coupler(cirq.LineQubit(4), cirq.LineQubit(5))
35+
assert v2.qubit_to_proto_id(line_coupler) == 'c_4_5'
36+
named_coupler = cg.Coupler(cirq.NamedQubit('named1'), cirq.NamedQubit('named2'))
37+
assert v2.qubit_to_proto_id(named_coupler) == 'c_named1_named2'
2938

3039

3140
def test_to_proto_id_unsupport_qid():
@@ -92,3 +101,12 @@ def test_generic_qubit_from_proto_id():
92101
# All non-int-parseable names are converted to NamedQubits.
93102
assert v2.qubit_from_proto_id('a') == cirq.NamedQubit('a')
94103
assert v2.qubit_from_proto_id('1_b') == cirq.NamedQubit('1_b')
104+
105+
# Test Coupler Qids
106+
grid_coupler = cg.Coupler(cirq.GridQubit(2, 1), cirq.GridQubit(4, 3))
107+
assert v2.qubit_from_proto_id('c_2_1_4_3') == grid_coupler
108+
line_coupler = cg.Coupler(cirq.LineQubit(4), cirq.LineQubit(5))
109+
assert v2.qubit_from_proto_id('c_4_5') == line_coupler
110+
named_coupler = cg.Coupler(cirq.NamedQubit('named1'), cirq.NamedQubit('named2'))
111+
assert v2.qubit_from_proto_id('c_named1_named2') == named_coupler
112+
assert v2.qubit_from_proto_id('c_a_b_c_d') == cirq.NamedQubit('c_a_b_c_d')

0 commit comments

Comments
 (0)