Skip to content

Commit

Permalink
Cpp check nodes (#420)
Browse files Browse the repository at this point in the history
* add logical node property

* remove unused and untested functions

* rename boundary nodes as logical nodes (if associated with a logical)

* fix issues

* linting

* add graph conversion

* rename old file

* Create pymatching_decoder.py (#415)

Creates a matching object which can be used to decode a counts string via the method process.

* linting

* remove old matching code and tests

* remove old matching code and tests

* remove old imports

* fix fault id issue

* standardize stim code circuit

* get rid of measured_logicals

* remove measuremed_logicals

* remove css decoding graph

* remove css decoding graph

* add graph conversions

* make matching work for non-stim

* add matching tests

* convert to edge graph only when needed

* black

* update doc string

* correct logical nodes

* 2 qubit paulis for cx gates

* extend beyond cx

* allow default check nodes to be used

* rename pymatching decoder

* add cpp check_nodes

* lint

* fix building

* correct path

* add is_cluster_neutral

* fix issues

* fix is_cluster_neutral

* remove legacy methods

* add detail to error messages

* fix extra logicals

* fix minimals

* add detail to message"
"

* thing

* initialize frustration

* initialize frustration

* initialize frustration

* limit loop

* limit loop

* limit loop

* limit loop

* limit loop

* fun stuff

* Revert "limit loop"

This reverts commit 8036e3c.

* revert to 8036e3c

* undo reformatting

* add heavy-hex decoder test

* add heavy-hex decoder test

* add heavy-hex decoder test

* add heavy-hex decoder test

* add heavy-hex decoder test

* linting

---------

Co-authored-by: Bence Hetényi <[email protected]>
  • Loading branch information
quantumjim and hetenyib authored Feb 19, 2024
1 parent 9bfe64d commit fb8d9fa
Show file tree
Hide file tree
Showing 38 changed files with 1,207 additions and 3,074 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,9 @@ set(ANALYSIS_BINDINGS_SRC "src/qiskit_qec/analysis/bindings/analysis_bindings.cp
pybind11_add_module(_c_analysis ${ANALYSIS_BINDINGS_SRC})
target_link_libraries(_c_analysis PRIVATE libanalysis)

set(CIRCUITS_BINDINGS_SRC "src/qiskit_qec/circuits/bindings/circuits_bindings.cpp")
pybind11_add_module(_c_circuits ${CIRCUITS_BINDINGS_SRC})
target_link_libraries(_c_circuits PRIVATE libcircuits)



7 changes: 6 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,18 @@ def build_extension(self, ext: CMakeExtension) -> None:
python_requires=">=3.8",
include_package_data=True,
install_requires=(REQUIREMENTS,),
ext_modules=[CMakeExtension("qiskit_qec.analysis._c_analysis")],
ext_modules=[
CMakeExtension("qiskit_qec.circuits._c_circuits"),
CMakeExtension("qiskit_qec.analysis._c_analysis"),
],
packages=find_packages(
where="src",
exclude=[
"test*",
"src/qiskit_qec/analysis/bindings*",
"src/qiskit_qec/analysis/intern*",
"src/qiskit_qec/circuits/bindings*",
"src/qiskit_qec/circuits/intern*",
"src/qiskit_qec/codes/codebase/data*",
],
),
Expand Down
3 changes: 2 additions & 1 deletion src/qiskit_qec/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
add_subdirectory(analysis)
add_subdirectory(analysis)
add_subdirectory(circuits)
28 changes: 28 additions & 0 deletions src/qiskit_qec/circuits/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Code circuit library
cmake_minimum_required(VERSION 3.12)
project(Circuits)

set(CIRCUITS_SRC
intern/arctools.cpp

arctools.h
)

add_library(libcircuits
STATIC
${CIRCUITS_SRC}
)

target_include_directories(libcircuits
PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}"
)

if (NOT (MSVC))
target_compile_options(libcircuits PRIVATE -fno-strict-aliasing -fPIC ${ARCH_OPT})
else ()
target_compile_options(libcircuits PRIVATE -fPIC ${ARCH_OPT})
endif ()

# Set prefix to "" since lib is already in project name
set_target_properties(libcircuits PROPERTIES PREFIX "")
26 changes: 26 additions & 0 deletions src/qiskit_qec/circuits/arctools.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef __ArcTools__
#define __ArcTools__

#include<vector>
#include<tuple>
#include<map>
#include <set>

std::vector<int> check_nodes(
std::vector<std::tuple<int, int, int, bool>> nodes, bool ignore_extra_logicals, bool minimal,
std::map<std::tuple<int, int>, std::set<int>> cycle_dict,
std::vector<std::tuple<int, int>> link_graph,
std::map<int, std::vector<int>> link_neighbors,
std::vector<int> z_logicals
);

bool is_cluster_neutral(
std::vector<std::tuple<int, int, int, bool>> nodes, bool ignore_extra_logicals, bool minimal,
std::map<std::tuple<int, int>, std::set<int>> cycle_dict,
std::vector<std::tuple<int, int>> link_graph,
std::map<int, std::vector<int>> link_neighbors,
std::vector<int> z_logicals,
bool linear
);

#endif
12 changes: 12 additions & 0 deletions src/qiskit_qec/circuits/bindings/circuits_bindings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "arctools.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

namespace py = pybind11;

PYBIND11_MODULE(_c_circuits, module)
{
module.doc() = "qiskit-qec code circuit extensions";
module.def("_c_check_nodes", &check_nodes, "check_nodes in C++");
module.def("_c_is_cluster_neutral", &is_cluster_neutral, "is_cluster_neutral in C++");
}
12 changes: 2 additions & 10 deletions src/qiskit_qec/circuits/code_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,15 @@ def string2nodes(self, string, **kwargs):
pass

@abstractmethod
def measured_logicals(self):
"""
Returns a list of logical operators, each expressed as a list of qubits for which
the parity of the final readouts corresponds to the raw logical readout.
"""
pass

@abstractmethod
def check_nodes(self, nodes, ignore_extra_boundary=False, minimal=False):
def check_nodes(self, nodes, ignore_extra_logical=False, minimal=False):
"""
Determines whether a given set of nodes are neutral. If so, also
determines any additional logical readout qubits that would be
flipped by the errors creating such a cluster and how many errors
would be required to make the cluster.
Args:
nodes (list): List of nodes, of the type produced by `string2nodes`.
ignore_extra_boundary (bool): If `True`, undeeded boundary nodes are
ignore_extra_logical (bool): If `True`, undeeded logical nodes are
ignored.
minimal (bool): Whether output should only reflect the minimal error
case.
Expand Down
12 changes: 1 addition & 11 deletions src/qiskit_qec/circuits/css_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,16 +183,6 @@ def _get_code_properties(self):
self.z_stabilizers = self.code.z_stabilizers
self.logical_x = self.code.logical_x
self.logical_z = self.code.logical_z
# for the unionfind decoder
self.css_x_logical = self.logical_x
self.css_z_logical = self.logical_z

def measured_logicals(self):
if self.basis == "x":
measured_logicals = self.logical_x
else:
measured_logicals = self.logical_z
return measured_logicals

def _prepare_initial_state(self, qc, qregs, state):
if state[0] == "1":
Expand Down Expand Up @@ -289,7 +279,7 @@ def string2raw_logicals(self, string):
log_outs = string2logical_meas(string, self.logicals, self.circuit["0"].clbits)
return log_outs

def check_nodes(self, nodes, ignore_extra_boundary=False, minimal=False):
def check_nodes(self, nodes, ignore_extra_logical=False, minimal=False):
raise NotImplementedError

def is_cluster_neutral(self, atypical_nodes):
Expand Down
42 changes: 42 additions & 0 deletions src/qiskit_qec/circuits/extensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
# pylint: disable=unused-import

"""Code circuit extensions"""

import logging # for logging!

logger = logging.getLogger(__name__)

# Load extensions if available and set appriate indicator flags

try:
from qiskit_qec.analysis._c_circuits import _c_check_nodes

C_CHECK_NODES = True
except ImportError as import_error:
logger.exception( # pylint: disable=logging-fstring-interpolation
f"from qiskit_qec.analysis._c_circuits import _c_check_nodes \
failed, raising {import_error}"
)
C_CHECK_NODES = False

try:
from qiskit_qec.analysis._c_circuits import _c_is_cluster_neutral

C_IS_CLUSTER_NEUTRAL = True
except ImportError as import_error:
logger.exception( # pylint: disable=logging-fstring-interpolation
f"from qiskit_qec.analysis._c_circuits import _c_is_cluster_neutral \
failed, raising {import_error}"
)
C_IS_CLUSTER_NEUTRAL = False
Loading

0 comments on commit fb8d9fa

Please sign in to comment.