From e5323e1d4f278c11a15c2bfd6c5f22ea51afdb84 Mon Sep 17 00:00:00 2001 From: James Wootton Date: Wed, 14 Feb 2024 18:07:41 +0100 Subject: [PATCH] fix building --- CMakeLists.txt | 6 +- setup.py | 7 +- src/qiskit_qec/circuits/arctools.h | 23 ++++--- ...uit_bindings.cpp => circuits_bindings.cpp} | 0 src/qiskit_qec/circuits/intern/arctools.cpp | 68 +++++++++---------- src/qiskit_qec/circuits/repetition_code.py | 2 + 6 files changed, 58 insertions(+), 48 deletions(-) rename src/qiskit_qec/circuits/bindings/{circuit_bindings.cpp => circuits_bindings.cpp} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38cbae58..b0d295a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,9 +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(CIRCUIT_BINDINGS_SRC "src/qiskit_qec/circuits/bindings/circuit_bindings.cpp") -pybind11_add_module(_c_circuit ${CIRCUIT_BINDINGS_SRC}) -target_link_libraries(_c_circuit PRIVATE libcircuit) +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) diff --git a/setup.py b/setup.py index 044e7b0f..cc450a20 100644 --- a/setup.py +++ b/setup.py @@ -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.analysis._c_analysis"), + CMakeExtension("qiskit_qec.analysis._c_circuits"), + ], 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*", ], ), diff --git a/src/qiskit_qec/circuits/arctools.h b/src/qiskit_qec/circuits/arctools.h index 03da1097..d88f29f7 100644 --- a/src/qiskit_qec/circuits/arctools.h +++ b/src/qiskit_qec/circuits/arctools.h @@ -1,14 +1,17 @@ -#include -#include -#include -#include +#ifndef __CheckNodes__ +#define __CheckNodes__ + +#include +#include +#include #include -#include std::vector check_nodes( - std::vector> nodes, bool ignore_extra_logicals, bool minimal, - map, set> cycle_dict, - std::vector> link_graph, - map> link_neighbors, + std::vector> nodes, bool ignore_extra_logicals, bool minimal, + std::map, std::set> cycle_dict, + std::vector> link_graph, + std::map> link_neighbors, std::vector z_logicals - ) \ No newline at end of file + ); + +#endif \ No newline at end of file diff --git a/src/qiskit_qec/circuits/bindings/circuit_bindings.cpp b/src/qiskit_qec/circuits/bindings/circuits_bindings.cpp similarity index 100% rename from src/qiskit_qec/circuits/bindings/circuit_bindings.cpp rename to src/qiskit_qec/circuits/bindings/circuits_bindings.cpp diff --git a/src/qiskit_qec/circuits/intern/arctools.cpp b/src/qiskit_qec/circuits/intern/arctools.cpp index 4779eae0..f1b47c99 100644 --- a/src/qiskit_qec/circuits/intern/arctools.cpp +++ b/src/qiskit_qec/circuits/intern/arctools.cpp @@ -1,35 +1,35 @@ -#include arctools.h +#include "arctools.h" -vector check_nodes( - vector> nodes, bool ignore_extra_logicals, bool minimal, - map, set> cycle_dict, vector> link_graph, map> link_neighbors, vector z_logicals +std::vector check_nodes( + std::vector> nodes, bool ignore_extra_logicals, bool minimal, + std::map, std::set> cycle_dict, std::vector> link_graph, std::map> link_neighbors, std::vector z_logicals ) { // output[0] is neutral (as int), output[1] is num_errors, rest is list of given logicals - vector output; + std::vector output; - // we convert to flat nodes, which are a tuple with (q0, q1, boundary) + // we convert to flat nodes, which are a std::tuple with (q0, q1, boundary) // if we have an even number of corresponding nodes, they cancel - map, int> node_counts; + std::map, int> node_counts; for (auto & node : nodes) { - node_counts[make_tuple(get<0>(node), get<1>(node), get<3>(node))] = 0; + node_counts[std::make_tuple(std::get<0>(node), std::get<1>(node), std::get<3>(node))] = 0; } for (auto & node : nodes) { - node_counts[make_tuple(get<0>(node), get<1>(node), get<3>(node))] ++; + node_counts[std::make_tuple(std::get<0>(node), std::get<1>(node), std::get<3>(node))] ++; } - // make a vector of the net flat nodes - vector> flat_nodes; + // make a std::vector of the net flat nodes + std::vector> flat_nodes; for (auto & node_count : node_counts) { if (node_count.second % 2 == 1) { flat_nodes.push_back(node_count.first); } } // see what logicals and bulk nodes are given - set given_logicals; - set> bulk_nodes; + std::set given_logicals; + std::set> bulk_nodes; for (auto & node : flat_nodes) { - if (get<2>(node)) { - given_logicals.insert(get<0>(node)); + if (std::get<2>(node)) { + given_logicals.insert(std::get<0>(node)); } else { bulk_nodes.insert(node); } @@ -44,13 +44,13 @@ vector check_nodes( output.push_back(num_errors); // no flipped logicals need to be added } else { - map parities; + std::map parities; // check how many times the bulk nodes turn up in each cycle for (int c = 0; c < cycle_dict.size(); c++){ parities[c] = 0; } for (auto & node: bulk_nodes) { - for (auto & c: cycle_dict[(make_tuple(get<0>(node), get<1>(node)))]){ + for (auto & c: cycle_dict[(std::make_tuple(std::get<0>(node), std::get<1>(node)))]){ parities[c]++; } } @@ -70,12 +70,12 @@ vector check_nodes( // first make a list of the qubits that definitely need to be covered // (those in the bulk nodes) and see how often each comes up in the nodes - set node_qubits; - map nq_nums; + std::set node_qubits; + std::map nq_nums; for (auto & node: bulk_nodes){ - vector qs = { - get<0>(node), - get<1>(node) + std::vector qs = { + std::get<0>(node), + std::get<1>(node) }; for (auto & q: qs) { if (node_qubits.insert(q).second){ @@ -95,28 +95,28 @@ vector check_nodes( } } // start colouring with the most mentioned qubit - map color; + std::map color; color[root] = 0; - vector newly_colored = {root}; - set colored = {root}; + std::vector newly_colored = {root}; + std::set colored = {root}; // stop once all node qubits are coloured and one color has stopped growing bool converged = false; node_qubits.erase(root); - map num_nodes = { + std::map num_nodes = { {0, 1}, {1, 0} }; - map last_num_nodes = num_nodes; + std::map last_num_nodes = num_nodes; while (not converged){ // for each newly coloured qubit - vector very_newly_colored; + std::vector very_newly_colored; for (auto & n: newly_colored){ // loop through all the neighbours for (auto & nn: link_neighbors[n]){ // if they haven't yet been coloured if (colored.find(nn) == colored.end()){ // if this pair don't correspond to a bulk node, the new one is the same colour - if ((bulk_nodes.find(make_tuple(n,nn,false)) == bulk_nodes.end()) and (bulk_nodes.find(make_tuple(nn,n,false)) == bulk_nodes.end())){ + if ((bulk_nodes.find(std::make_tuple(n,nn,false)) == bulk_nodes.end()) and (bulk_nodes.find(std::make_tuple(nn,n,false)) == bulk_nodes.end())){ color[nn] = color[n]; // otherwise, it's the opposite color } else { @@ -143,13 +143,13 @@ vector check_nodes( int min_color = (num_nodes[1] <= num_nodes[0]); // list the colours with the max error one first // (unless we do min only) - vector cs; + std::vector cs; if (not minimal){ cs.push_back((min_color+1)%2); } cs.push_back(min_color); // determine which flipped logicals correspond to which colour - vector> color_logicals = {{}, {}}; + std::vector> color_logicals = {{}, {}}; for (auto & q: z_logicals){ if (color.find(q) == color.end()){ color[q] = (conv_color+1)%2; @@ -158,8 +158,8 @@ vector check_nodes( } // see if we can find a color for which we have no extra logicals // and see what additional logicals are required - vector flipped_logicals; - vector extra_logicals; + std::vector flipped_logicals; + std::vector extra_logicals; bool done = false; int j = 0; while (not done){ @@ -199,4 +199,4 @@ vector check_nodes( } return output; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/qiskit_qec/circuits/repetition_code.py b/src/qiskit_qec/circuits/repetition_code.py index 038f1e8e..05ac99dd 100644 --- a/src/qiskit_qec/circuits/repetition_code.py +++ b/src/qiskit_qec/circuits/repetition_code.py @@ -1143,6 +1143,7 @@ def check_nodes(self, nodes, ignore_extra_logical=False, minimal=False, cpp=Fals ignored. minimal (bool): Whether output should only reflect the minimal error case. + cpp (bool): Whether to use C++ implementation. Returns: neutral (bool): Whether the nodes independently correspond to a valid set of errors. @@ -1364,6 +1365,7 @@ def is_cluster_neutral(self, atypical_nodes: dict, cpp=False): to the method. Args: atypical_nodes: dictionary in the form of the return value of string2nodes + cpp (bool): Whether to use C++ implementation. """ if self._linear: return not bool(len(atypical_nodes) % 2)