Skip to content

Commit 7019adc

Browse files
authored
Add benchmarks for transformer primitives and json serialization (#5957)
* Add benchmarks for transformer primitives and json serialization * Track json size upto 3 decimal places
1 parent 30181d4 commit 7019adc

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

benchmarks/serialization.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Copyright 2022 The Cirq Developers
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import cirq
16+
17+
18+
def _human_size(num_bytes: int, mod: int = 0, units=(' bytes', 'KB', 'MB', 'GB', 'TB', 'PB')):
19+
"""Returns a human readable string representation of bytes"""
20+
return (
21+
f'{num_bytes}.{mod}{units[0]}'
22+
if num_bytes < 1024
23+
else _human_size(num_bytes >> 10, num_bytes % 1024, units[1:])
24+
)
25+
26+
27+
class SerializeLargeExpandedCircuits:
28+
param_names = ["num_qubits", "num_moments"]
29+
params = ([100, 500, 1000], [100, 1000, 4000])
30+
timeout = 600 # Change timeout to 2 minutes instead of default 60 seconds.
31+
32+
def setup(self, num_qubits: int, num_moments: int):
33+
qubits = cirq.LineQubit.range(num_qubits)
34+
one_q_x_moment = cirq.Moment(cirq.X(q) for q in qubits[::2])
35+
one_q_y_moment = cirq.Moment(cirq.Y(q) for q in qubits[1::2])
36+
two_q_cx_moment = cirq.Moment(
37+
cirq.CNOT(q1, q2) for q1, q2 in zip(qubits[::4], qubits[1::4])
38+
)
39+
two_q_cz_moment = cirq.Moment(cirq.CZ(q1, q2) for q1, q2 in zip(qubits[::4], qubits[1::4]))
40+
measurement_moment = cirq.Moment(cirq.measure_each(*qubits))
41+
self.circuit = cirq.Circuit(
42+
[one_q_x_moment, two_q_cx_moment, one_q_y_moment, two_q_cz_moment, measurement_moment]
43+
* (num_moments // 5)
44+
)
45+
46+
def time_json_serialization(self, *_):
47+
_ = cirq.to_json(self.circuit)
48+
49+
def time_json_serialization_gzip(self, *_):
50+
_ = cirq.to_json_gzip(self.circuit)
51+
52+
def track_json_serialization_gzip_size(self, *_):
53+
return _human_size(len(cirq.to_json_gzip(self.circuit)))
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Copyright 2022 The Cirq Developers
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import cirq
16+
17+
18+
class MapLargeExpandedCircuit:
19+
param_names = ["num_qubits", "num_moments"]
20+
params = ([100, 500, 1000], [100, 1000, 4000])
21+
timeout = 600 # Change timeout to 2 minutes instead of default 60 seconds.
22+
23+
def setup(self, num_qubits: int, num_moments: int):
24+
qubits = cirq.LineQubit.range(num_qubits)
25+
one_q_x_moment = cirq.Moment(cirq.X(q) for q in qubits[::2])
26+
one_q_y_moment = cirq.Moment(cirq.Y(q) for q in qubits[1::2])
27+
two_q_cx_moment = cirq.Moment(
28+
cirq.CNOT(q1, q2) for q1, q2 in zip(qubits[::4], qubits[1::4])
29+
)
30+
two_q_cz_moment = cirq.Moment(cirq.CZ(q1, q2) for q1, q2 in zip(qubits[::4], qubits[1::4]))
31+
self.circuit = cirq.Circuit(
32+
[one_q_x_moment, two_q_cx_moment, one_q_y_moment, two_q_cz_moment] * (num_moments // 4)
33+
)
34+
35+
def time_map_moments(self, num_qubits: int, _):
36+
all_qubits = cirq.LineQubit.range(num_qubits)
37+
38+
def map_func(m: cirq.Moment, _) -> cirq.Moment:
39+
new_ops = [op.with_tags("old op") for op in m.operations]
40+
new_ops += [
41+
cirq.Z(q).with_tags("new op")
42+
for q in all_qubits
43+
if not m.operates_on_single_qubit(q)
44+
]
45+
return cirq.Moment(new_ops)
46+
47+
_ = cirq.map_moments(circuit=self.circuit, map_func=map_func)
48+
49+
def time_map_operations_apply_tag(self, *_):
50+
def map_func(op: cirq.Operation, _) -> cirq.Operation:
51+
return op.with_tags("old op")
52+
53+
_ = cirq.map_operations(circuit=self.circuit, map_func=map_func)
54+
55+
def time_map_operations_to_optree(self, *_):
56+
def map_func(op: cirq.Operation, _) -> cirq.OP_TREE:
57+
return [op, op]
58+
59+
_ = cirq.map_operations(circuit=self.circuit, map_func=map_func)
60+
61+
def time_map_operations_to_optree_and_unroll(self, *_):
62+
def map_func(op: cirq.Operation, _) -> cirq.OP_TREE:
63+
return [op, op]
64+
65+
_ = cirq.map_operations_and_unroll(circuit=self.circuit, map_func=map_func)

0 commit comments

Comments
 (0)