Qsurface is a simulation package for the surface code, and is designed to modularize 3 aspects of a surface code simulation.
New types of surface codes, error modules and decoders can be added to Qsurface by using the included templates for each of the three core module categories.
The current included decoders are:
mwpm
) decoder.unionfind
) decoder, which has almost-linear worst-case time complexity.ufns
) decoder, which improves the threshold of the Union-Find decoder to near MWPM performance, while retaining quasi-linear worst-case time complexity.The compatibility of these decoders with the included surface codes are listed below.
| Decoders | toric
code | planar
code |
|-----------|--------------|---------------|
|mwpm
|✅ |✅ |
|unionfind
|✅ |✅ |
|ufns
|✅ |✅ |
All required packages can be installed through:
bash
pip install qsurface
The MWPM decoder utilizes networkx
for finding the minimal weights in a fully connected graph. This implementation is however rather slow compared to Kolmogorov's Blossom V algorithm. Blossom V has its own license and is thus not included with Qsurface. We do provided a single function to download and compile Blossom V, and to setup the integration with Qsurface automatically.
```python
from qsurface.decoders import mwpm mwpm.get_blossomv() ```
To simulate the toric code and simulate with bitflip error for 10 iterations and decode with the MWPM decoder:
```python
from qsurface.main import initialize, run code, decoder = initialize((6,6), "toric", "mwpm", enabled_errors=["pauli"]) run(code, decoder, iterations=10, error_rates = {"p_bitflip": 0.1}) {'no_error': 8} ```
Benchmarking of decoders can be enabled by attaching a benchmarker object to the decoder. See the docs for the syntax and information to setup benchmarking.
```python
from qsurface.main import initialize, run benchmarker = BenchmarkDecoder({"decode":"duration"}) run(code, decoder, iterations=10, error_rates = {"p_bitflip": 0.1}, benchmark=benchmarker) {'no_error': 8, 'benchmark': {'success_rate': [10, 10], 'seed': 12447.413636559, 'durations': {'decode': {'mean': 0.00244155000000319, 'std': 0.002170364089572033}}}} ```
The figures in Qsurface allows for step-by-step visualization of the surface code simulation (and if supported the decoding process). Each figure logs its history such that the user can move backwards in time to view past states of the surface (and decoder). Press h
when the figure is open for more information.
```python
from qsurface.main import initialize, run code, decoder = initialize((6,6), "toric", "mwpm", enabled_errors=["pauli"], plotting=True, initial_states=(0,0)) run(code, decoder, error_rates = {"p_bitflip": 0.1, "p_phaseflip": 0.1}, decode_initial=False) ```
Plotting will be performed on a 3D axis if faulty measurements are enabled.
```python
code, decoder = initialize((3,3), "toric", "mwpm", enabled_errors=["pauli"], faulty_measurements=True, plotting=True, initial_states=(0,0)) run(code, decoder, error_rates = {"p_bitflip": 0.05, "p_bitflip_plaq": 0.05}, decode_initial=False) ```
In IPython, inline images are created for each iteration of the plot, which can be tested in the example notebook.
Simulations can also be initiated from the command line
bash
$ python -m qsurface -e pauli -D mwpm -C toric simulation --p_bitflip 0.1 -n 10
{'no_error': 8}
For more information on command line interface:
bash
$ python -m qsurface -h
usage: qsurface
...
This project is proudly funded by the Unitary Fund.
Hello, I am a new starter and trying to produce the simplest case for the surface code by using qsurface.
I will be appreciate, if you can check the code: I will put no error to the simulation 1)I want to create the surface code for distance 3 2)I want to initialize all the data qubits in 0 state 3)I want to put X and Z stabilizers 4)Then I want to measure all the X stabilizers. In this case they will randomly change and commute with Z stabilizers and Z stabilizers will not change With this scenario, I want to see how mwpm is working
As code: code, decoder = initialize((3,3), "planar", "mwpm", enabled_errors=[], plotting=True, initial_states=(0,0)) run(code, decoder, error_rates = {}, decode_initial=True) #"p_bitflip": 0.1, "p_phaseflip": 0.1
But I could see nothing. Could you help me for my first code?
Hi, could you provide some basic hints on how to produce an animations from a jupyter notebook like the ones you show in the example? Thanks a lot
Running multiprocessed codes on larger lattices (for both union-find and MWPM) results in a recursion depth error for the pickled input arguments, i.e. code and decoder objects. For faulty measurements, this error happens for lattices as small as 4x4. This happens on Windows. While it works perfectly in the Unix environment. Steps to reproduce ``` from qsurface.main import initialize, run_multiprocess
code, decoder = initialize((4, 4), "toric", "unionfind", enabled_errors=["pauli"], faulty_measurements=True) if name == "main": run_multiprocess(code, decoder, iterations=100, error_rates={"p_bitflip": 0.01}) ```
Error
Traceback (most recent call last):
File "c:\Users\*\Desktop\test.py", line 5, in <module>
run_multiprocess(code, decoder, iterations=100, error_rates={"p_bitflip": 0.01})
File "C:\Users\*\AppData\Local\Programs\Python\Python310\lib\site-packages\qsurface\main.py", line 276, in run_multiprocess
worker.start()
File "C:\Users\*\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 121, in start
self._popen = self._Popen(self)
File "C:\Users\*\AppData\Local\Programs\Python\Python310\lib\multiprocessing\context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Users\*\AppData\Local\Programs\Python\Python310\lib\multiprocessing\context.py", line 327, in _Popen
return Popen(process_obj)
File "C:\Users\*\AppData\Local\Programs\Python\Python310\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
reduction.dump(process_obj, to_child)
File "C:\Users\*\AppData\Local\Programs\Python\Python310\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
RecursionError: maximum recursion depth exceeded while calling a Python object
PS C:\Users\*> Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\*\AppData\Local\Programs\Python\Python310\lib\multiprocessing\spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "C:\Users\*\AppData\Local\Programs\Python\Python310\lib\multiprocessing\spawn.py", line 126, in _main
self = reduction.pickle.load(from_parent)
EOFError: Ran out of input
Hi, first or all, thank you for making this amazing repo. I really like the plotting feature that allows me to understand what is happening. I have three issues/questions, and I would really appreciate if you could solve these, especially the first one.
1. Plotting unionfind decoder
I'm running the following in jupyter notebook.
%matplotlib qt from qsurface.main import initialize, run code, decoder = initialize((5,5), "toric", "unionfind", enabled_errors=["pauli"], plotting=True, initial_states=(0,0)) run(code, decoder, error_rates = {"p_bitflip": 0.05, "p_phaseflip": 0.05}, decode_initial=False)
For the first three plots (initialization, error applied, ancilla qubits measured, everything is fine.
But when I hit next, another window pops up, and the grid doesn't show anymore.
It looks like this:
Could you please solve this, so that the grid shows up, just like when I use the mwpm decoder?
I have the following message:
Traceback (most recent call last):
File "C:\Users\lg\anaconda3\lib\site-packages\matplotlib\cbook__init__.py", line 270, in process
func(args, kwargs)
File "C:\Users\lg\anaconda3\lib\site-packages\matplotlib\widgets.py", line 225, in
Again, I really appreciate this repo, and I hope you reply!
Previously, Patch3D objects wouldn't update colors, to which a workaround was made to plot several versions of the same object in the same location and to select one as the visible object. This bug was tracked in https://github.com/matplotlib/matplotlib/issues/3370.
A recent pull request fixes this bug https://github.com/matplotlib/matplotlib/pull/18189. The workaround can thus be removed.
The run_oopsc.py
file has been refactored. It should be updated in the Readme file.
If possible, I'd suggest having also one basic example that produces a plot without any additional command line appended command. I.e., typing
bash
python simple_example.py
generates a plot / intended outcome. I wonder whether a configuration / settings file could help to store command line configurations that one is re-using (e.g., 8 -l planar -px 0.03 -pmx 0.03 -i 1000
).
This release includes a fix for a breaking error as pointed out by @evanphilip in #35, in which ini files are not packaged due to a naming error of the manifest file.
This release has no new features and is simply a (re)release. OpenSurfaceSim has been rebranded to Qsurface.
If you have already installed the package through pip, make sure to uninstall the previous release pip uninstall opensurfacesim
and install the new release pip install qsurface
, which is the version that will be kept updated.
Another update with fixes following the v.0.1.1 PyPI release.
For IPython, the GUI of the Tkinter backend is not available. The included examples.ipynb
, for example, does not produce any figures, but raises an import error. This PR adds support for IPython, and outputs each iteration of the interactive figure as a separate image.
Additional fixes for the Pauli error legend and missing figures.
quantum-error-correction surface-code