Skip to content

Commit 895fe58

Browse files
maffoorht
authored andcommitted
Convert cirq.Result to ABC and add ResultDict implementation (quantumlib#4806)
This converts cirq.Result into an abstract base class which defines the interface provided by measurement result objects. We introduce a new class cirq.ResultDict which is the default implementation of this result type, based on a dict mapping string keys to array data. This will allow us to provide alternate implementations as needed, for example a result type that is based on a DataFrame and only converts to measurement dict on demand (cf quantumlib#4774), or a result type that is based on experimental data (such as raw IQ data) and allows accessing this raw data while also converting to the standard measurements dict on demand (see quantumlib#3868 for other possible Result implementations). Making this separation will also simplify the implementation of repeated measurement keys (quantumlib#4274), since it will allow us to define the new interface for accessing data from repeated keys separately from the implementation of how this data is stored. Review: @95-martin-orion
1 parent b9a60ad commit 895fe58

31 files changed

+502
-148
lines changed

cirq-aqt/cirq_aqt/aqt_sampler.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def run_sweep(
208208
)
209209
results = results.astype(bool)
210210
res_dict = {meas_name: results}
211-
trial_results.append(cirq.Result(params=param_resolver, measurements=res_dict))
211+
trial_results.append(cirq.ResultDict(params=param_resolver, measurements=res_dict))
212212
return trial_results
213213

214214

cirq-core/cirq/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@
470470
flatten,
471471
flatten_with_params,
472472
flatten_with_sweep,
473+
ResultDict,
473474
Linspace,
474475
ListSweep,
475476
ParamDictType,

cirq-core/cirq/contrib/quantum_volume/quantum_volume_test.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def test_sample_heavy_set():
7070

7171
sampler = Mock(spec=cirq.Simulator)
7272
# Construct a result that returns "1", "2", "3", "0"
73-
result = cirq.Result(
73+
result = cirq.ResultDict(
7474
params=cirq.ParamResolver({}),
7575
measurements={'mock': np.array([[0, 1], [1, 0], [1, 1], [0, 0]])},
7676
)
@@ -94,7 +94,7 @@ def test_sample_heavy_set_with_parity():
9494
# bitstring "10" is valid and heavy. The second "01" is valid and not
9595
# heavy. The third and fourth bitstrings "11" and "00" are not valid and
9696
# dropped.
97-
result = cirq.Result(
97+
result = cirq.ResultDict(
9898
params=cirq.ParamResolver({}),
9999
measurements={
100100
'0': np.array([[1], [0]]),

cirq-core/cirq/json_resolver_cache.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ def _parallel_gate_op(gate, qubits):
144144
'TensoredConfusionMatrices': cirq.TensoredConfusionMatrices,
145145
'RepetitionsStoppingCriteria': cirq.work.RepetitionsStoppingCriteria,
146146
'ResetChannel': cirq.ResetChannel,
147-
'Result': cirq.Result,
147+
'Result': cirq.ResultDict, # Keep support for Cirq < 0.14.
148+
'ResultDict': cirq.ResultDict,
148149
'Rx': cirq.Rx,
149150
'Ry': cirq.Ry,
150151
'Rz': cirq.Rz,
@@ -158,7 +159,7 @@ def _parallel_gate_op(gate, qubits):
158159
'SympyCondition': cirq.SympyCondition,
159160
'TaggedOperation': cirq.TaggedOperation,
160161
'TiltedSquareLattice': cirq.TiltedSquareLattice,
161-
'TrialResult': cirq.Result, # keep support for Cirq < 0.11.
162+
'TrialResult': cirq.ResultDict, # keep support for Cirq < 0.11.
162163
'TwoQubitGateTabulation': cirq.TwoQubitGateTabulation,
163164
'_UnconstrainedDevice': cirq.devices.unconstrained_device._UnconstrainedDevice,
164165
'VarianceStoppingCriteria': cirq.work.VarianceStoppingCriteria,

cirq-core/cirq/protocols/json_test_data/Result.repr

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[True, True, False, True, False], [False, True, True, False, False], [True, False, True, False, True]], dtype=bool)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[1, 1, 0, 1, 0], [0, 1, 1, 0, 0], [1, 0, 1, 0, 1]], dtype=np.uint8)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int8)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int16)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int32)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int64)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint8)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint16)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint32)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint64)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[1, 1, 0, 1, 0], [0, 1, 1, 0, 0], [1, 0, 1, 0, 1]], dtype=np.uint8), 'n': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int64)})]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
[
2+
{
3+
"cirq_type": "ResultDict",
4+
"params": {
5+
"cirq_type": "ParamResolver",
6+
"param_dict": [
7+
[
8+
{
9+
"cirq_type": "sympy.Symbol",
10+
"name": "a"
11+
},
12+
0.5
13+
]
14+
]
15+
},
16+
"measurements": {
17+
"m": {
18+
"packed_digits": "d32a",
19+
"binary": true,
20+
"dtype": "bool",
21+
"shape": [
22+
3,
23+
5
24+
]
25+
}
26+
}
27+
},
28+
{
29+
"cirq_type": "ResultDict",
30+
"params": {
31+
"cirq_type": "ParamResolver",
32+
"param_dict": [
33+
[
34+
{
35+
"cirq_type": "sympy.Symbol",
36+
"name": "a"
37+
},
38+
0.5
39+
]
40+
]
41+
},
42+
"measurements": {
43+
"m": {
44+
"packed_digits": "d32a",
45+
"binary": true,
46+
"dtype": "uint8",
47+
"shape": [
48+
3,
49+
5
50+
]
51+
}
52+
}
53+
},
54+
{
55+
"cirq_type": "ResultDict",
56+
"params": {
57+
"cirq_type": "ParamResolver",
58+
"param_dict": [
59+
[
60+
{
61+
"cirq_type": "sympy.Symbol",
62+
"name": "a"
63+
},
64+
0.5
65+
]
66+
]
67+
},
68+
"measurements": {
69+
"m": {
70+
"packed_digits": "934e554d5059010076007b276465736372273a20277c6931272c2027666f727472616e5f6f72646572273a2046616c73652c20277368617065273a2028332c2033292c207d202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200a000102030405060708",
71+
"binary": false,
72+
"dtype": "int8",
73+
"shape": [
74+
3,
75+
3
76+
]
77+
}
78+
}
79+
},
80+
{
81+
"cirq_type": "ResultDict",
82+
"params": {
83+
"cirq_type": "ParamResolver",
84+
"param_dict": [
85+
[
86+
{
87+
"cirq_type": "sympy.Symbol",
88+
"name": "a"
89+
},
90+
0.5
91+
]
92+
]
93+
},
94+
"measurements": {
95+
"m": {
96+
"packed_digits": "934e554d5059010076007b276465736372273a20273c6932272c2027666f727472616e5f6f72646572273a2046616c73652c20277368617065273a2028332c2033292c207d202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200a000001000200030004000500060007000800",
97+
"binary": false,
98+
"dtype": "int16",
99+
"shape": [
100+
3,
101+
3
102+
]
103+
}
104+
}
105+
},
106+
{
107+
"cirq_type": "ResultDict",
108+
"params": {
109+
"cirq_type": "ParamResolver",
110+
"param_dict": [
111+
[
112+
{
113+
"cirq_type": "sympy.Symbol",
114+
"name": "a"
115+
},
116+
0.5
117+
]
118+
]
119+
},
120+
"measurements": {
121+
"m": {
122+
"packed_digits": "934e554d5059010076007b276465736372273a20273c6934272c2027666f727472616e5f6f72646572273a2046616c73652c20277368617065273a2028332c2033292c207d202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200a000000000100000002000000030000000400000005000000060000000700000008000000",
123+
"binary": false,
124+
"dtype": "int32",
125+
"shape": [
126+
3,
127+
3
128+
]
129+
}
130+
}
131+
},
132+
{
133+
"cirq_type": "ResultDict",
134+
"params": {
135+
"cirq_type": "ParamResolver",
136+
"param_dict": [
137+
[
138+
{
139+
"cirq_type": "sympy.Symbol",
140+
"name": "a"
141+
},
142+
0.5
143+
]
144+
]
145+
},
146+
"measurements": {
147+
"m": {
148+
"packed_digits": "934e554d5059010076007b276465736372273a20273c6938272c2027666f727472616e5f6f72646572273a2046616c73652c20277368617065273a2028332c2033292c207d202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200a000000000000000001000000000000000200000000000000030000000000000004000000000000000500000000000000060000000000000007000000000000000800000000000000",
149+
"binary": false,
150+
"dtype": "int64",
151+
"shape": [
152+
3,
153+
3
154+
]
155+
}
156+
}
157+
},
158+
{
159+
"cirq_type": "ResultDict",
160+
"params": {
161+
"cirq_type": "ParamResolver",
162+
"param_dict": [
163+
[
164+
{
165+
"cirq_type": "sympy.Symbol",
166+
"name": "a"
167+
},
168+
0.5
169+
]
170+
]
171+
},
172+
"measurements": {
173+
"m": {
174+
"packed_digits": "934e554d5059010076007b276465736372273a20277c7531272c2027666f727472616e5f6f72646572273a2046616c73652c20277368617065273a2028332c2033292c207d202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200a000102030405060708",
175+
"binary": false,
176+
"dtype": "uint8",
177+
"shape": [
178+
3,
179+
3
180+
]
181+
}
182+
}
183+
},
184+
{
185+
"cirq_type": "ResultDict",
186+
"params": {
187+
"cirq_type": "ParamResolver",
188+
"param_dict": [
189+
[
190+
{
191+
"cirq_type": "sympy.Symbol",
192+
"name": "a"
193+
},
194+
0.5
195+
]
196+
]
197+
},
198+
"measurements": {
199+
"m": {
200+
"packed_digits": "934e554d5059010076007b276465736372273a20273c7532272c2027666f727472616e5f6f72646572273a2046616c73652c20277368617065273a2028332c2033292c207d202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200a000001000200030004000500060007000800",
201+
"binary": false,
202+
"dtype": "uint16",
203+
"shape": [
204+
3,
205+
3
206+
]
207+
}
208+
}
209+
},
210+
{
211+
"cirq_type": "ResultDict",
212+
"params": {
213+
"cirq_type": "ParamResolver",
214+
"param_dict": [
215+
[
216+
{
217+
"cirq_type": "sympy.Symbol",
218+
"name": "a"
219+
},
220+
0.5
221+
]
222+
]
223+
},
224+
"measurements": {
225+
"m": {
226+
"packed_digits": "934e554d5059010076007b276465736372273a20273c7534272c2027666f727472616e5f6f72646572273a2046616c73652c20277368617065273a2028332c2033292c207d202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200a000000000100000002000000030000000400000005000000060000000700000008000000",
227+
"binary": false,
228+
"dtype": "uint32",
229+
"shape": [
230+
3,
231+
3
232+
]
233+
}
234+
}
235+
},
236+
{
237+
"cirq_type": "ResultDict",
238+
"params": {
239+
"cirq_type": "ParamResolver",
240+
"param_dict": [
241+
[
242+
{
243+
"cirq_type": "sympy.Symbol",
244+
"name": "a"
245+
},
246+
0.5
247+
]
248+
]
249+
},
250+
"measurements": {
251+
"m": {
252+
"packed_digits": "934e554d5059010076007b276465736372273a20273c7538272c2027666f727472616e5f6f72646572273a2046616c73652c20277368617065273a2028332c2033292c207d202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200a000000000000000001000000000000000200000000000000030000000000000004000000000000000500000000000000060000000000000007000000000000000800000000000000",
253+
"binary": false,
254+
"dtype": "uint64",
255+
"shape": [
256+
3,
257+
3
258+
]
259+
}
260+
}
261+
},
262+
{
263+
"cirq_type": "ResultDict",
264+
"params": {
265+
"cirq_type": "ParamResolver",
266+
"param_dict": [
267+
[
268+
{
269+
"cirq_type": "sympy.Symbol",
270+
"name": "a"
271+
},
272+
0.5
273+
]
274+
]
275+
},
276+
"measurements": {
277+
"m": {
278+
"packed_digits": "d32a",
279+
"binary": true,
280+
"dtype": "uint8",
281+
"shape": [
282+
3,
283+
5
284+
]
285+
},
286+
"n": {
287+
"packed_digits": "934e554d5059010076007b276465736372273a20273c6938272c2027666f727472616e5f6f72646572273a2046616c73652c20277368617065273a2028332c2033292c207d202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200a000000000000000001000000000000000200000000000000030000000000000004000000000000000500000000000000060000000000000007000000000000000800000000000000",
288+
"binary": false,
289+
"dtype": "int64",
290+
"shape": [
291+
3,
292+
3
293+
]
294+
}
295+
}
296+
}
297+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[True, True, False, True, False], [False, True, True, False, False], [True, False, True, False, True]], dtype=bool)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[1, 1, 0, 1, 0], [0, 1, 1, 0, 0], [1, 0, 1, 0, 1]], dtype=np.uint8)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int8)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int16)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int32)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int64)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint8)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint16)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint32)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint64)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[1, 1, 0, 1, 0], [0, 1, 1, 0, 0], [1, 0, 1, 0, 1]], dtype=np.uint8), 'n': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int64)})]
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[True, True, False, True, False], [False, True, True, False, False], [True, False, True, False, True]], dtype=np.bool)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[1, 1, 0, 1, 0], [0, 1, 1, 0, 0], [1, 0, 1, 0, 1]], dtype=np.uint8)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int8)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int16)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int32)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int64)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint8)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint16)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint32)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint64)}), cirq.Result(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[1, 1, 0, 1, 0], [0, 1, 1, 0, 0], [1, 0, 1, 0, 1]], dtype=np.uint8), 'n': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int64)})]
1+
[cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[True, True, False, True, False], [False, True, True, False, False], [True, False, True, False, True]], dtype=np.bool)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[1, 1, 0, 1, 0], [0, 1, 1, 0, 0], [1, 0, 1, 0, 1]], dtype=np.uint8)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int8)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int16)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int32)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int64)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint8)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint16)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint32)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.uint64)}), cirq.ResultDict(params=cirq.ParamResolver({sympy.Symbol('a'): 0.5}), measurements={'m': np.array([[1, 1, 0, 1, 0], [0, 1, 1, 0, 0], [1, 0, 1, 0, 1]], dtype=np.uint8), 'n': np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=np.int64)})]

cirq-core/cirq/sim/clifford/stabilizer_sampler.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def run_sweep(
4848
resolved_circuit,
4949
repetitions=repetitions,
5050
)
51-
results.append(cirq.Result(params=param_resolver, measurements=measurements))
51+
results.append(cirq.ResultDict(params=param_resolver, measurements=measurements))
5252
return results
5353

5454
def _run(self, circuit: 'cirq.AbstractCircuit', repetitions: int) -> Dict[str, np.ndarray]:

0 commit comments

Comments
 (0)