surface-sim 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ """Main surface-sim module."""
2
+
3
+ __version__ = "0.1.0"
4
+
5
+ from . import experiments, models, util, circuit_blocks
6
+ from .setup import Setup
7
+ from .models import Model
8
+
9
+ __all__ = [
10
+ "models",
11
+ "experiments",
12
+ "util",
13
+ "circuit_blocks",
14
+ "Setup",
15
+ "Model",
16
+ ]
@@ -0,0 +1,13 @@
1
+ from . import (
2
+ surface_code_css,
3
+ surface_code_css_pipelined,
4
+ surface_code_xzzx,
5
+ surface_code_xzzx_google,
6
+ )
7
+
8
+ __all__ = [
9
+ "surface_code_css",
10
+ "surface_code_css_pipelined",
11
+ "surface_code_xzzx",
12
+ "surface_code_xzzx_google",
13
+ ]
@@ -0,0 +1,185 @@
1
+ from itertools import chain
2
+
3
+ from stim import Circuit, target_rec
4
+ from qec_util import Layout
5
+
6
+ from ..models import Model
7
+
8
+ # methods to have in this script
9
+ from .util import qubit_coords, log_meas, log_x, log_z, init_qubits
10
+
11
+ __all__ = ["qubit_coords", "log_meas", "log_x", "log_z", "qec_round", "init_qubits"]
12
+
13
+
14
+ def qec_round(
15
+ model: Model,
16
+ layout: Layout,
17
+ meas_reset: bool = False,
18
+ meas_comparison: bool = True,
19
+ ) -> Circuit:
20
+ """
21
+ Returns stim circuit corresponding to a QEC cycle
22
+ of the given model.
23
+
24
+ This implementation follows:
25
+
26
+ https://doi.org/10.1103/PhysRevApplied.8.034021
27
+
28
+ Params
29
+ -------
30
+ meas_comparison
31
+ If True, the detector is set to the measurement of the ancilla
32
+ instead of to the comparison of consecutive syndromes.
33
+ """
34
+ data_qubits = layout.get_qubits(role="data")
35
+ anc_qubits = layout.get_qubits(role="anc")
36
+ qubits = set(data_qubits + anc_qubits)
37
+
38
+ int_order = layout.interaction_order
39
+ stab_types = list(int_order.keys())
40
+ x_stabs = layout.get_qubits(role="anc", stab_type="x_type")
41
+
42
+ # With reset defect[n] = m[n] XOR m[n-1]
43
+ # Wihtout reset defect[n] = m[n] XOR m[n-2]
44
+ comp_round = 1 if meas_reset else 2
45
+
46
+ circuit = Circuit()
47
+
48
+ # a
49
+ directions = [int_order["x_type"][0], int_order["x_type"][3]]
50
+ rot_qubits = set(anc_qubits)
51
+ rot_qubits.update(layout.get_neighbors(x_stabs, direction=directions[0]))
52
+ rot_qubits.update(layout.get_neighbors(x_stabs, direction=directions[1]))
53
+ for instruction in model.hadamard(rot_qubits):
54
+ circuit.append(instruction)
55
+ idle_qubits = qubits - rot_qubits
56
+ for instruction in model.idle(idle_qubits):
57
+ circuit.append(instruction)
58
+ circuit.append("TICK")
59
+
60
+ # b
61
+ interacted_qubits = set()
62
+ for stab_type in stab_types:
63
+ stab_qubits = layout.get_qubits(role="anc", stab_type=stab_type)
64
+ ord_dir = int_order[stab_type][0]
65
+ int_pairs = layout.get_neighbors(stab_qubits, direction=ord_dir, as_pairs=True)
66
+ int_qubits = list(chain.from_iterable(int_pairs))
67
+ interacted_qubits.update(int_qubits)
68
+
69
+ for instruction in model.cphase(int_qubits):
70
+ circuit.append(instruction)
71
+
72
+ idle_qubits = qubits - set(interacted_qubits)
73
+ for instruction in model.idle(idle_qubits):
74
+ circuit.append(instruction)
75
+ circuit.append("TICK")
76
+
77
+ # c
78
+ for instruction in model.hadamard(data_qubits):
79
+ circuit.append(instruction)
80
+ for instruction in model.idle(anc_qubits):
81
+ circuit.append(instruction)
82
+ circuit.append("TICK")
83
+
84
+ # d
85
+ interacted_qubits = set()
86
+ for stab_type in stab_types:
87
+ stab_qubits = layout.get_qubits(role="anc", stab_type=stab_type)
88
+ ord_dir = int_order[stab_type][1]
89
+ int_pairs = layout.get_neighbors(stab_qubits, direction=ord_dir, as_pairs=True)
90
+ int_qubits = list(chain.from_iterable(int_pairs))
91
+ interacted_qubits.update(int_qubits)
92
+
93
+ for instruction in model.cphase(int_qubits):
94
+ circuit.append(instruction)
95
+
96
+ idle_qubits = qubits - set(interacted_qubits)
97
+ for instruction in model.idle(idle_qubits):
98
+ circuit.append(instruction)
99
+ circuit.append("TICK")
100
+
101
+ # e
102
+ interacted_qubits = set()
103
+ for stab_type in stab_types:
104
+ stab_qubits = layout.get_qubits(role="anc", stab_type=stab_type)
105
+ ord_dir = int_order[stab_type][2]
106
+ int_pairs = layout.get_neighbors(stab_qubits, direction=ord_dir, as_pairs=True)
107
+ int_qubits = list(chain.from_iterable(int_pairs))
108
+ interacted_qubits.update(int_qubits)
109
+
110
+ for instruction in model.cphase(int_qubits):
111
+ circuit.append(instruction)
112
+
113
+ idle_qubits = qubits - set(interacted_qubits)
114
+ for instruction in model.idle(idle_qubits):
115
+ circuit.append(instruction)
116
+ circuit.append("TICK")
117
+
118
+ # f
119
+ for instruction in model.hadamard(data_qubits):
120
+ circuit.append(instruction)
121
+ for instruction in model.idle(anc_qubits):
122
+ circuit.append(instruction)
123
+ circuit.append("TICK")
124
+
125
+ # g
126
+ interacted_qubits = set()
127
+ for stab_type in stab_types:
128
+ stab_qubits = layout.get_qubits(role="anc", stab_type=stab_type)
129
+ ord_dir = int_order[stab_type][3]
130
+ int_pairs = layout.get_neighbors(stab_qubits, direction=ord_dir, as_pairs=True)
131
+ int_qubits = list(chain.from_iterable(int_pairs))
132
+ interacted_qubits.update(int_qubits)
133
+
134
+ for instruction in model.cphase(int_qubits):
135
+ circuit.append(instruction)
136
+
137
+ idle_qubits = qubits - set(interacted_qubits)
138
+ for instruction in model.idle(idle_qubits):
139
+ circuit.append(instruction)
140
+ circuit.append("TICK")
141
+
142
+ # h
143
+ directions = [int_order["x_type"][0], int_order["x_type"][3]]
144
+ rot_qubits = set(anc_qubits)
145
+ rot_qubits.update(layout.get_neighbors(x_stabs, direction=directions[0]))
146
+ rot_qubits.update(layout.get_neighbors(x_stabs, direction=directions[1]))
147
+ for instruction in model.hadamard(rot_qubits):
148
+ circuit.append(instruction)
149
+ idle_qubits = qubits - rot_qubits
150
+ for instruction in model.idle(idle_qubits):
151
+ circuit.append(instruction)
152
+ circuit.append("TICK")
153
+
154
+ # i
155
+ for instruction in model.measure(anc_qubits):
156
+ circuit.append(instruction)
157
+
158
+ for instruction in model.idle(data_qubits):
159
+ circuit.append(instruction)
160
+ circuit.append("TICK")
161
+
162
+ if meas_reset:
163
+ for instruction in model.reset(anc_qubits):
164
+ circuit.append(instruction)
165
+
166
+ for instruction in model.idle(data_qubits):
167
+ circuit.append(instruction)
168
+
169
+ circuit.append("TICK")
170
+
171
+ # detectors ordered as in the measurements
172
+ num_anc = len(anc_qubits)
173
+ if meas_comparison:
174
+ det_targets = []
175
+ for ind in range(num_anc):
176
+ target_inds = [ind - (comp_round + 1) * num_anc, ind - num_anc]
177
+ targets = [target_rec(ind) for ind in target_inds]
178
+ det_targets.append(targets)
179
+ else:
180
+ det_targets = [[target_rec(ind - num_anc)] for ind in range(num_anc)]
181
+
182
+ for targets in det_targets:
183
+ circuit.append("DETECTOR", targets)
184
+
185
+ return circuit
@@ -0,0 +1,117 @@
1
+ from itertools import chain
2
+
3
+ from stim import Circuit, target_rec
4
+
5
+ from qec_util import Layout
6
+
7
+ from ..models import Model
8
+
9
+ # methods to have in this script
10
+ from .util import qubit_coords, log_meas, log_x, log_z, init_qubits
11
+
12
+ __all__ = ["qubit_coords", "log_meas", "log_x", "log_z", "qec_round", "init_qubits"]
13
+
14
+
15
+ def qec_round(
16
+ model: Model,
17
+ layout: Layout,
18
+ meas_reset: bool = False,
19
+ meas_comparison: bool = True,
20
+ ) -> Circuit:
21
+ """
22
+ Returns stim circuit corresponding to a QEC cycle
23
+ of the given model.
24
+
25
+ Params
26
+ -------
27
+ meas_comparison
28
+ If True, the detector is set to the measurement of the ancilla
29
+ instead of to the comparison of consecutive syndromes.
30
+ stab_type_det
31
+ If specified, only adds detectors to the ancillas for the
32
+ specific stabilizator type.
33
+ """
34
+ data_qubits = layout.get_qubits(role="data")
35
+ anc_qubits = layout.get_qubits(role="anc")
36
+
37
+ qubits = set(data_qubits + anc_qubits)
38
+ # With reset defect[n] = m[n] XOR m[n-1]
39
+ # Wihtout reset defect[n] = m[n] XOR m[n-2]
40
+ comp_round = 1 if meas_reset else 2
41
+
42
+ circuit = Circuit()
43
+ int_order = layout.interaction_order
44
+ stab_types = list(int_order.keys())
45
+
46
+ for ind, stab_type in enumerate(stab_types):
47
+ stab_qubits = layout.get_qubits(role="anc", stab_type=stab_type)
48
+ rot_qubits = set(stab_qubits)
49
+ if stab_type == "x_type":
50
+ rot_qubits.update(data_qubits)
51
+
52
+ if not ind:
53
+ for instruction in model.hadamard(rot_qubits):
54
+ circuit.append(instruction)
55
+
56
+ idle_qubits = qubits - rot_qubits
57
+ for instruction in model.idle(idle_qubits):
58
+ circuit.append(instruction)
59
+ circuit.append("TICK")
60
+
61
+ for ord_dir in int_order[stab_type]:
62
+ int_pairs = layout.get_neighbors(
63
+ stab_qubits, direction=ord_dir, as_pairs=True
64
+ )
65
+ int_qubits = list(chain.from_iterable(int_pairs))
66
+
67
+ for instruction in model.cphase(int_qubits):
68
+ circuit.append(instruction)
69
+
70
+ idle_qubits = qubits - set(int_qubits)
71
+ for instruction in model.idle(idle_qubits):
72
+ circuit.append(instruction)
73
+ circuit.append("TICK")
74
+
75
+ if not ind:
76
+ for instruction in model.hadamard(qubits):
77
+ circuit.append(instruction)
78
+ else:
79
+ for instruction in model.hadamard(rot_qubits):
80
+ circuit.append(instruction)
81
+
82
+ idle_qubits = qubits - rot_qubits
83
+ for instruction in model.idle(idle_qubits):
84
+ circuit.append(instruction)
85
+
86
+ circuit.append("TICK")
87
+
88
+ for instruction in model.measure(anc_qubits):
89
+ circuit.append(instruction)
90
+
91
+ for instruction in model.idle(data_qubits):
92
+ circuit.append(instruction)
93
+ circuit.append("TICK")
94
+
95
+ if meas_reset:
96
+ for instruction in model.reset(anc_qubits):
97
+ circuit.append(instruction)
98
+ for instruction in model.idle(data_qubits):
99
+ circuit.append(instruction)
100
+
101
+ circuit.append("TICK")
102
+
103
+ # detectors ordered as in the measurements
104
+ num_anc = len(anc_qubits)
105
+ if meas_comparison:
106
+ det_targets = []
107
+ for ind in range(num_anc):
108
+ target_inds = [ind - (comp_round + 1) * num_anc, ind - num_anc]
109
+ targets = [target_rec(ind) for ind in target_inds]
110
+ det_targets.append(targets)
111
+ else:
112
+ det_targets = [[target_rec(ind - num_anc)] for ind in range(num_anc)]
113
+
114
+ for targets in det_targets:
115
+ circuit.append("DETECTOR", targets)
116
+
117
+ return circuit
@@ -0,0 +1,122 @@
1
+ from itertools import chain
2
+
3
+ from stim import Circuit, target_rec
4
+ from qec_util import Layout
5
+
6
+ from ..models import Model
7
+
8
+
9
+ # methods to have in this script
10
+ from .util import qubit_coords, log_x, log_z
11
+ from .util import log_meas_xzzx as log_meas, init_qubits_xzzx as init_qubits
12
+
13
+ __all__ = ["qubit_coords", "log_meas", "log_x", "log_z", "qec_round", "init_qubits"]
14
+
15
+
16
+ def qec_round(
17
+ model: Model,
18
+ layout: Layout,
19
+ meas_reset: bool = False,
20
+ meas_comparison: bool = True,
21
+ ) -> Circuit:
22
+ """
23
+ Returns stim circuit corresponding to a QEC cycle
24
+ of the given model.
25
+
26
+ Params
27
+ -------
28
+ meas_comparison
29
+ If True, the detector is set to the measurement of the ancilla
30
+ instead of to the comparison of consecutive syndromes.
31
+ stab_type_det
32
+ If specified, only adds detectors to the ancillas for the
33
+ specific stabilizator type.
34
+ """
35
+ data_qubits = layout.get_qubits(role="data")
36
+ anc_qubits = layout.get_qubits(role="anc")
37
+
38
+ qubits = set(data_qubits + anc_qubits)
39
+
40
+ # With reset defect[n] = m[n] XOR m[n-1]
41
+ # Wihtout reset defect[n] = m[n] XOR m[n-2]
42
+ comp_round = 1 if meas_reset else 2
43
+
44
+ circuit = Circuit()
45
+ int_order = layout.interaction_order
46
+ stab_types = list(int_order.keys())
47
+
48
+ for ind, stab_type in enumerate(stab_types):
49
+ stab_qubits = layout.get_qubits(role="anc", stab_type=stab_type)
50
+
51
+ rot_qubits = set(stab_qubits)
52
+ for direction in ("north_west", "south_east"):
53
+ neighbors = layout.get_neighbors(stab_qubits, direction=direction)
54
+ rot_qubits.update(neighbors)
55
+
56
+ if not ind:
57
+ for instruction in model.hadamard(rot_qubits):
58
+ circuit.append(instruction)
59
+
60
+ idle_qubits = qubits - rot_qubits
61
+ for instruction in model.idle(idle_qubits):
62
+ circuit.append(instruction)
63
+ circuit.append("TICK")
64
+
65
+ for ord_dir in int_order[stab_type]:
66
+ int_pairs = layout.get_neighbors(
67
+ stab_qubits, direction=ord_dir, as_pairs=True
68
+ )
69
+ int_qubits = list(chain.from_iterable(int_pairs))
70
+
71
+ for instruction in model.cphase(int_qubits):
72
+ circuit.append(instruction)
73
+
74
+ idle_qubits = qubits - set(int_qubits)
75
+ for instruction in model.idle(idle_qubits):
76
+ circuit.append(instruction)
77
+ circuit.append("TICK")
78
+
79
+ if not ind:
80
+ for instruction in model.hadamard(qubits):
81
+ circuit.append(instruction)
82
+ else:
83
+ for instruction in model.hadamard(rot_qubits):
84
+ circuit.append(instruction)
85
+
86
+ idle_qubits = qubits - rot_qubits
87
+ for instruction in model.idle(idle_qubits):
88
+ circuit.append(instruction)
89
+
90
+ circuit.append("TICK")
91
+
92
+ for instruction in model.measure(anc_qubits):
93
+ circuit.append(instruction)
94
+
95
+ for instruction in model.idle(data_qubits):
96
+ circuit.append(instruction)
97
+ circuit.append("TICK")
98
+
99
+ if meas_reset:
100
+ for instruction in model.reset(anc_qubits):
101
+ circuit.append(instruction)
102
+
103
+ for instruction in model.idle(data_qubits):
104
+ circuit.append(instruction)
105
+
106
+ circuit.append("TICK")
107
+
108
+ # detectors ordered as in the measurements
109
+ num_anc = len(anc_qubits)
110
+ if meas_comparison:
111
+ det_targets = []
112
+ for ind in range(num_anc):
113
+ target_inds = [ind - (comp_round + 1) * num_anc, ind - num_anc]
114
+ targets = [target_rec(ind) for ind in target_inds]
115
+ det_targets.append(targets)
116
+ else:
117
+ det_targets = [[target_rec(ind - num_anc)] for ind in range(num_anc)]
118
+
119
+ for targets in det_targets:
120
+ circuit.append("DETECTOR", targets)
121
+
122
+ return circuit