sinter 1.14.dev1726902167__tar.gz → 1.14.dev1727161109__tar.gz

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.

Potentially problematic release.


This version of sinter might be problematic. Click here for more details.

Files changed (66) hide show
  1. {sinter-1.14.dev1726902167/src/sinter.egg-info → sinter-1.14.dev1727161109}/PKG-INFO +1 -1
  2. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/setup.py +1 -1
  3. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/__init__.py +1 -1
  4. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_decoding_all_built_in_decoders.py +5 -0
  5. sinter-1.14.dev1727161109/src/sinter/_decoding/_decoding_mwpf.py +309 -0
  6. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_decoding_test.py +5 -0
  7. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109/src/sinter.egg-info}/PKG-INFO +1 -1
  8. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter.egg-info/SOURCES.txt +1 -0
  9. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/MANIFEST.in +0 -0
  10. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/README.md +0 -0
  11. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/readme_example_plot.png +0 -0
  12. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/requirements.txt +0 -0
  13. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/setup.cfg +0 -0
  14. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/__init__.py +0 -0
  15. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_collection.py +0 -0
  16. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_collection_manager.py +0 -0
  17. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_collection_manager_test.py +0 -0
  18. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_collection_test.py +0 -0
  19. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_collection_worker_loop.py +0 -0
  20. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_collection_worker_state.py +0 -0
  21. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_collection_worker_test.py +0 -0
  22. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_mux_sampler.py +0 -0
  23. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_printer.py +0 -0
  24. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_collection/_sampler_ramp_throttled.py +0 -0
  25. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/__init__.py +0 -0
  26. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/_main.py +0 -0
  27. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/_main_collect.py +0 -0
  28. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/_main_collect_test.py +0 -0
  29. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/_main_combine.py +0 -0
  30. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/_main_combine_test.py +0 -0
  31. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/_main_plot.py +0 -0
  32. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/_main_plot_test.py +0 -0
  33. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/_main_predict.py +0 -0
  34. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_command/_main_predict_test.py +0 -0
  35. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/__init__.py +0 -0
  36. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_anon_task_stats.py +0 -0
  37. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_anon_task_stats_test.py +0 -0
  38. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_collection_options.py +0 -0
  39. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_collection_options_test.py +0 -0
  40. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_csv_out.py +0 -0
  41. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_existing_data.py +0 -0
  42. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_existing_data_test.py +0 -0
  43. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_task.py +0 -0
  44. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_task_stats.py +0 -0
  45. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_task_stats_test.py +0 -0
  46. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_data/_task_test.py +0 -0
  47. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/__init__.py +0 -0
  48. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_decoding.py +0 -0
  49. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_decoding_decoder_class.py +0 -0
  50. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_decoding_fusion_blossom.py +0 -0
  51. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_decoding_pymatching.py +0 -0
  52. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_decoding_vacuous.py +0 -0
  53. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_perfectionist_sampler.py +0 -0
  54. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_sampler.py +0 -0
  55. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_stim_then_decode_sampler.py +0 -0
  56. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_decoding/_stim_then_decode_sampler_test.py +0 -0
  57. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_plotting.py +0 -0
  58. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_plotting_test.py +0 -0
  59. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_predict.py +0 -0
  60. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_predict_test.py +0 -0
  61. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_probability_util.py +0 -0
  62. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter/_probability_util_test.py +0 -0
  63. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter.egg-info/dependency_links.txt +0 -0
  64. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter.egg-info/entry_points.txt +0 -0
  65. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter.egg-info/requires.txt +0 -0
  66. {sinter-1.14.dev1726902167 → sinter-1.14.dev1727161109}/src/sinter.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sinter
3
- Version: 1.14.dev1726902167
3
+ Version: 1.14.dev1727161109
4
4
  Summary: Samples stim circuits and decodes them using pymatching.
5
5
  Author: Craig Gidney
6
6
  Author-email: craig.gidney@gmail.com
@@ -19,7 +19,7 @@ with open('README.md', encoding='UTF-8') as f:
19
19
  with open('requirements.txt', encoding='UTF-8') as f:
20
20
  requirements = f.read().splitlines()
21
21
 
22
- __version__ = '1.14.dev1726902167'
22
+ __version__ = '1.14.dev1727161109'
23
23
 
24
24
  setup(
25
25
  name='sinter',
@@ -1,4 +1,4 @@
1
- __version__ = '1.14.dev1726902167'
1
+ __version__ = '1.14.dev1727161109'
2
2
 
3
3
  from sinter._collection import (
4
4
  collect,
@@ -7,11 +7,16 @@ from sinter._decoding._decoding_pymatching import PyMatchingDecoder
7
7
  from sinter._decoding._decoding_vacuous import VacuousDecoder
8
8
  from sinter._decoding._perfectionist_sampler import PerfectionistSampler
9
9
  from sinter._decoding._sampler import Sampler
10
+ from sinter._decoding._decoding_mwpf import HyperUFDecoder, MwpfDecoder
10
11
 
11
12
  BUILT_IN_DECODERS: Dict[str, Decoder] = {
12
13
  'vacuous': VacuousDecoder(),
13
14
  'pymatching': PyMatchingDecoder(),
14
15
  'fusion_blossom': FusionBlossomDecoder(),
16
+ # an implementation of (weighted) hypergraph UF decoder (https://arxiv.org/abs/2103.08049)
17
+ 'hypergraph_union_find': HyperUFDecoder(),
18
+ # Minimum-Weight Parity Factor using similar primal-dual method the blossom algorithm (https://pypi.org/project/mwpf/)
19
+ 'mw_parity_factor': MwpfDecoder(),
15
20
  }
16
21
 
17
22
  BUILT_IN_SAMPLERS: Dict[str, Union[Decoder, Sampler]] = {
@@ -0,0 +1,309 @@
1
+ import math
2
+ import pathlib
3
+ from typing import Callable, List, TYPE_CHECKING, Tuple, Any, Optional
4
+
5
+ import numpy as np
6
+ import stim
7
+
8
+ from sinter._decoding._decoding_decoder_class import Decoder, CompiledDecoder
9
+
10
+ if TYPE_CHECKING:
11
+ import mwpf
12
+
13
+
14
+ def mwpf_import_error() -> ImportError:
15
+ return ImportError(
16
+ "The decoder 'MWPF' isn't installed\n"
17
+ "To fix this, install the python package 'MWPF' into your environment.\n"
18
+ "For example, if you are using pip, run `pip install MWPF~=0.1.1`.\n"
19
+ )
20
+
21
+
22
+ class MwpfCompiledDecoder(CompiledDecoder):
23
+ def __init__(
24
+ self,
25
+ solver: "mwpf.SolverSerialJointSingleHair",
26
+ fault_masks: "np.ndarray",
27
+ num_dets: int,
28
+ num_obs: int,
29
+ ):
30
+ self.solver = solver
31
+ self.fault_masks = fault_masks
32
+ self.num_dets = num_dets
33
+ self.num_obs = num_obs
34
+
35
+ def decode_shots_bit_packed(
36
+ self,
37
+ *,
38
+ bit_packed_detection_event_data: "np.ndarray",
39
+ ) -> "np.ndarray":
40
+ num_shots = bit_packed_detection_event_data.shape[0]
41
+ predictions = np.zeros(shape=(num_shots, self.num_obs), dtype=np.uint8)
42
+ import mwpf
43
+
44
+ for shot in range(num_shots):
45
+ dets_sparse = np.flatnonzero(
46
+ np.unpackbits(
47
+ bit_packed_detection_event_data[shot],
48
+ count=self.num_dets,
49
+ bitorder="little",
50
+ )
51
+ )
52
+ syndrome = mwpf.SyndromePattern(defect_vertices=dets_sparse)
53
+ if self.solver is None:
54
+ prediction = 0
55
+ else:
56
+ self.solver.solve(syndrome)
57
+ prediction = int(
58
+ np.bitwise_xor.reduce(self.fault_masks[self.solver.subgraph()])
59
+ )
60
+ self.solver.clear()
61
+ predictions[shot] = np.packbits(prediction, bitorder="little")
62
+ return predictions
63
+
64
+
65
+ class MwpfDecoder(Decoder):
66
+ """Use MWPF to predict observables from detection events."""
67
+
68
+ def compile_decoder_for_dem(
69
+ self,
70
+ *,
71
+ dem: "stim.DetectorErrorModel",
72
+ decoder_cls: Any = None, # decoder class used to construct the MWPF decoder.
73
+ # in the Rust implementation, all of them inherits from the class of `SolverSerialPlugins`
74
+ # but just provide different plugins for optimizing the primal and/or dual solutions.
75
+ # For example, `SolverSerialUnionFind` is the most basic solver without any plugin: it only
76
+ # grows the clusters until the first valid solution appears; some more optimized solvers uses
77
+ # one or more plugins to further optimize the solution, which requires longer decoding time.
78
+ ) -> CompiledDecoder:
79
+ solver, fault_masks = detector_error_model_to_mwpf_solver_and_fault_masks(
80
+ dem, decoder_cls=decoder_cls
81
+ )
82
+ return MwpfCompiledDecoder(
83
+ solver, fault_masks, dem.num_detectors, dem.num_observables
84
+ )
85
+
86
+ def decode_via_files(
87
+ self,
88
+ *,
89
+ num_shots: int,
90
+ num_dets: int,
91
+ num_obs: int,
92
+ dem_path: pathlib.Path,
93
+ dets_b8_in_path: pathlib.Path,
94
+ obs_predictions_b8_out_path: pathlib.Path,
95
+ tmp_dir: pathlib.Path,
96
+ decoder_cls: Any = None,
97
+ ) -> None:
98
+ import mwpf
99
+
100
+ error_model = stim.DetectorErrorModel.from_file(dem_path)
101
+ solver, fault_masks = detector_error_model_to_mwpf_solver_and_fault_masks(
102
+ error_model, decoder_cls=decoder_cls
103
+ )
104
+ num_det_bytes = math.ceil(num_dets / 8)
105
+ with open(dets_b8_in_path, "rb") as dets_in_f:
106
+ with open(obs_predictions_b8_out_path, "wb") as obs_out_f:
107
+ for _ in range(num_shots):
108
+ dets_bit_packed = np.fromfile(
109
+ dets_in_f, dtype=np.uint8, count=num_det_bytes
110
+ )
111
+ if dets_bit_packed.shape != (num_det_bytes,):
112
+ raise IOError("Missing dets data.")
113
+ dets_sparse = np.flatnonzero(
114
+ np.unpackbits(
115
+ dets_bit_packed, count=num_dets, bitorder="little"
116
+ )
117
+ )
118
+ syndrome = mwpf.SyndromePattern(defect_vertices=dets_sparse)
119
+ if solver is None:
120
+ prediction = 0
121
+ else:
122
+ solver.solve(syndrome)
123
+ prediction = int(
124
+ np.bitwise_xor.reduce(fault_masks[solver.subgraph()])
125
+ )
126
+ solver.clear()
127
+ obs_out_f.write(
128
+ prediction.to_bytes((num_obs + 7) // 8, byteorder="little")
129
+ )
130
+
131
+
132
+ class HyperUFDecoder(MwpfDecoder):
133
+ def compile_decoder_for_dem(
134
+ self, *, dem: "stim.DetectorErrorModel"
135
+ ) -> CompiledDecoder:
136
+ try:
137
+ import mwpf
138
+ except ImportError as ex:
139
+ raise mwpf_import_error() from ex
140
+
141
+ return super().compile_decoder_for_dem(
142
+ dem=dem, decoder_cls=mwpf.SolverSerialUnionFind
143
+ )
144
+
145
+ def decode_via_files(
146
+ self,
147
+ *,
148
+ num_shots: int,
149
+ num_dets: int,
150
+ num_obs: int,
151
+ dem_path: pathlib.Path,
152
+ dets_b8_in_path: pathlib.Path,
153
+ obs_predictions_b8_out_path: pathlib.Path,
154
+ tmp_dir: pathlib.Path,
155
+ ) -> None:
156
+ try:
157
+ import mwpf
158
+ except ImportError as ex:
159
+ raise mwpf_import_error() from ex
160
+
161
+ return super().decode_via_files(
162
+ num_shots=num_shots,
163
+ num_dets=num_dets,
164
+ num_obs=num_obs,
165
+ dem_path=dem_path,
166
+ dets_b8_in_path=dets_b8_in_path,
167
+ obs_predictions_b8_out_path=obs_predictions_b8_out_path,
168
+ tmp_dir=tmp_dir,
169
+ decoder_cls=mwpf.SolverSerialUnionFind,
170
+ )
171
+
172
+
173
+ def iter_flatten_model(
174
+ model: stim.DetectorErrorModel,
175
+ handle_error: Callable[[float, List[int], List[int]], None],
176
+ handle_detector_coords: Callable[[int, np.ndarray], None],
177
+ ):
178
+ det_offset = 0
179
+ coords_offset = np.zeros(100, dtype=np.float64)
180
+
181
+ def _helper(m: stim.DetectorErrorModel, reps: int):
182
+ nonlocal det_offset
183
+ nonlocal coords_offset
184
+ for _ in range(reps):
185
+ for instruction in m:
186
+ if isinstance(instruction, stim.DemRepeatBlock):
187
+ _helper(instruction.body_copy(), instruction.repeat_count)
188
+ elif isinstance(instruction, stim.DemInstruction):
189
+ if instruction.type == "error":
190
+ dets: List[int] = []
191
+ frames: List[int] = []
192
+ t: stim.DemTarget
193
+ p = instruction.args_copy()[0]
194
+ for t in instruction.targets_copy():
195
+ if t.is_relative_detector_id():
196
+ dets.append(t.val + det_offset)
197
+ elif t.is_logical_observable_id():
198
+ frames.append(t.val)
199
+ handle_error(p, dets, frames)
200
+ elif instruction.type == "shift_detectors":
201
+ det_offset += instruction.targets_copy()[0]
202
+ a = np.array(instruction.args_copy())
203
+ coords_offset[: len(a)] += a
204
+ elif instruction.type == "detector":
205
+ a = np.array(instruction.args_copy())
206
+ for t in instruction.targets_copy():
207
+ handle_detector_coords(
208
+ t.val + det_offset, a + coords_offset[: len(a)]
209
+ )
210
+ elif instruction.type == "logical_observable":
211
+ pass
212
+ else:
213
+ raise NotImplementedError()
214
+ else:
215
+ raise NotImplementedError()
216
+
217
+ _helper(model, 1)
218
+
219
+
220
+ def deduplicate_hyperedges(
221
+ hyperedges: List[Tuple[List[int], float, int]]
222
+ ) -> List[Tuple[List[int], float, int]]:
223
+ indices: dict[frozenset[int], int] = dict()
224
+ result: List[Tuple[List[int], float, int]] = []
225
+ for dets, weight, mask in hyperedges:
226
+ dets_set = frozenset(dets)
227
+ if dets_set in indices:
228
+ idx = indices[dets_set]
229
+ p1 = 1 / (1 + math.exp(weight))
230
+ p2 = 1 / (1 + math.exp(result[idx][1]))
231
+ p = p1 * (1 - p2) + p2 * (1 - p1)
232
+ # not sure why would this fail? two hyperedges with different masks?
233
+ # assert mask == result[idx][2], (result[idx], (dets, weight, mask))
234
+ result[idx] = (dets, math.log((1 - p) / p), result[idx][2])
235
+ else:
236
+ indices[dets_set] = len(result)
237
+ result.append((dets, weight, mask))
238
+ return result
239
+
240
+
241
+ def detector_error_model_to_mwpf_solver_and_fault_masks(
242
+ model: stim.DetectorErrorModel, decoder_cls: Any = None
243
+ ) -> Tuple[Optional["mwpf.SolverSerialJointSingleHair"], np.ndarray]:
244
+ """Convert a stim error model into a NetworkX graph."""
245
+
246
+ try:
247
+ import mwpf
248
+ except ImportError as ex:
249
+ raise mwpf_import_error() from ex
250
+
251
+ num_detectors = model.num_detectors
252
+ is_detector_connected = np.full(num_detectors, False, dtype=bool)
253
+ hyperedges: List[Tuple[List[int], float, int]] = []
254
+
255
+ def handle_error(p: float, dets: List[int], frame_changes: List[int]):
256
+ if p == 0:
257
+ return
258
+ if len(dets) == 0:
259
+ # No symptoms for this error.
260
+ # Code probably has distance 1.
261
+ # Accept it and keep going, though of course decoding will probably perform terribly.
262
+ return
263
+ if p > 0.5:
264
+ # mwpf doesn't support negative edge weights.
265
+ # approximate them as weight 0.
266
+ p = 0.5
267
+ weight = math.log((1 - p) / p)
268
+ mask = sum(1 << k for k in frame_changes)
269
+ is_detector_connected[dets] = True
270
+ hyperedges.append((dets, weight, mask))
271
+
272
+ def handle_detector_coords(detector: int, coords: np.ndarray):
273
+ pass
274
+
275
+ iter_flatten_model(
276
+ model,
277
+ handle_error=handle_error,
278
+ handle_detector_coords=handle_detector_coords,
279
+ )
280
+ # mwpf package panic on duplicate edges, thus we need to handle them here
281
+ hyperedges = deduplicate_hyperedges(hyperedges)
282
+
283
+ # fix the input by connecting an edge to all isolated vertices
284
+ for idx in range(num_detectors):
285
+ if not is_detector_connected[idx]:
286
+ hyperedges.append(([idx], 0, 0))
287
+
288
+ max_weight = max(1e-4, max((w for _, w, _ in hyperedges), default=1))
289
+ rescaled_edges = [
290
+ mwpf.HyperEdge(v, round(w * 2**10 / max_weight) * 2) for v, w, _ in hyperedges
291
+ ]
292
+ fault_masks = np.array([e[2] for e in hyperedges], dtype=np.uint64)
293
+
294
+ initializer = mwpf.SolverInitializer(
295
+ num_detectors, # Total number of nodes.
296
+ rescaled_edges, # Weighted edges.
297
+ )
298
+
299
+ if decoder_cls is None:
300
+ # default to the solver with highest accuracy
301
+ decoder_cls = mwpf.SolverSerialJointSingleHair
302
+ return (
303
+ (
304
+ decoder_cls(initializer)
305
+ if num_detectors > 0 and len(rescaled_edges) > 0
306
+ else None
307
+ ),
308
+ fault_masks,
309
+ )
@@ -27,6 +27,11 @@ def get_test_decoders() -> Tuple[List[str], Dict[str, sinter.Decoder]]:
27
27
  import fusion_blossom
28
28
  except ImportError:
29
29
  available_decoders.remove('fusion_blossom')
30
+ try:
31
+ import mwpf
32
+ except ImportError:
33
+ available_decoders.remove('hypergraph_union_find')
34
+ available_decoders.remove('mw_parity_factor')
30
35
 
31
36
  e = os.environ.get('SINTER_PYTEST_CUSTOM_DECODERS')
32
37
  if e is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sinter
3
- Version: 1.14.dev1726902167
3
+ Version: 1.14.dev1727161109
4
4
  Summary: Samples stim circuits and decodes them using pymatching.
5
5
  Author: Craig Gidney
6
6
  Author-email: craig.gidney@gmail.com
@@ -54,6 +54,7 @@ src/sinter/_decoding/_decoding.py
54
54
  src/sinter/_decoding/_decoding_all_built_in_decoders.py
55
55
  src/sinter/_decoding/_decoding_decoder_class.py
56
56
  src/sinter/_decoding/_decoding_fusion_blossom.py
57
+ src/sinter/_decoding/_decoding_mwpf.py
57
58
  src/sinter/_decoding/_decoding_pymatching.py
58
59
  src/sinter/_decoding/_decoding_test.py
59
60
  src/sinter/_decoding/_decoding_vacuous.py