From 15d0074b59189e1cc53c594f0a2079e2136b8831 Mon Sep 17 00:00:00 2001 From: Craig Gidney Date: Wed, 13 Dec 2023 20:53:02 -0800 Subject: [PATCH] split 3 --- file_lists/source_files_no_main | 4 + .../graph/collect_composite_errors.cc | 157 ------------------ .../graph/collect_composite_errors_5.cc | 83 +++++++++ .../graph/collect_composite_errors_6.cc | 20 +++ .../graph/collect_composite_errors_7.cc | 50 ++++++ .../graph/collect_composite_errors_8.cc | 48 ++++++ 6 files changed, 205 insertions(+), 157 deletions(-) create mode 100644 src/chromobius/graph/collect_composite_errors_5.cc create mode 100644 src/chromobius/graph/collect_composite_errors_6.cc create mode 100644 src/chromobius/graph/collect_composite_errors_7.cc create mode 100644 src/chromobius/graph/collect_composite_errors_8.cc diff --git a/file_lists/source_files_no_main b/file_lists/source_files_no_main index b315d44..59ac4ed 100644 --- a/file_lists/source_files_no_main +++ b/file_lists/source_files_no_main @@ -30,6 +30,10 @@ src/chromobius/graph/collect_composite_errors.h src/chromobius/graph/collect_composite_errors_2.cc src/chromobius/graph/collect_composite_errors_3.cc src/chromobius/graph/collect_composite_errors_4.cc +src/chromobius/graph/collect_composite_errors_5.cc +src/chromobius/graph/collect_composite_errors_6.cc +src/chromobius/graph/collect_composite_errors_7.cc +src/chromobius/graph/collect_composite_errors_8.cc src/chromobius/graph/collect_nodes.cc src/chromobius/graph/collect_nodes.h src/chromobius/graph/drag_graph.cc diff --git a/src/chromobius/graph/collect_composite_errors.cc b/src/chromobius/graph/collect_composite_errors.cc index ff2fb10..e2ae2c0 100644 --- a/src/chromobius/graph/collect_composite_errors.cc +++ b/src/chromobius/graph/collect_composite_errors.cc @@ -61,160 +61,3 @@ bool chromobius::decompose_single_basis_dets_into_atoms_helper_n4( return try_finish_decomposition(best_score, obs_flip, atomic_errors, out_atoms, out_remnants); } - -bool chromobius::decompose_single_basis_dets_into_atoms_helper_n5( - std::span dets, - obsmask_int obs_flip, - std::span node_colors, - const std::map &atomic_errors, - std::vector *out_atoms, - std::map *out_remnants) { - int best_score = 0; - - // 2:3 decomposition. - for (size_t k1 = 0; k1 < dets.size() && best_score < 2; k1++) { - for (size_t k2 = k1 + 1; k2 < dets.size(); k2++) { - try_grow_decomposition( - AtomicErrorKey{dets[k1], dets[k2], BOUNDARY_NODE}, - AtomicErrorKey{ - dets[0 + (k1 <= 0) + (k2 <= 0)], - dets[1 + (k1 <= 1) + (k2 <= 1)], - dets[2 + (k1 <= 2) + (k2 <= 2)], - }, - node_colors, - atomic_errors, - out_atoms, - best_score); - } - } - - return try_finish_decomposition(best_score, obs_flip, atomic_errors, out_atoms, out_remnants); -} - -bool chromobius::decompose_single_basis_dets_into_atoms_helper_n6( - std::span dets, - obsmask_int obs_flip, - std::span node_colors, - const std::map &atomic_errors, - std::vector *out_atoms, - std::map *out_remnants) { - int best_score = 0; - - // 3:3 decomposition. - for (size_t k1 = 0; k1 < dets.size() && best_score < 2; k1++) { - for (size_t k2 = k1 + 1; k2 < dets.size(); k2++) { - for (size_t k3 = k2 + 1; k3 < dets.size(); k3++) { - try_grow_decomposition( - AtomicErrorKey{dets[k1], dets[k2], dets[k3]}, - AtomicErrorKey{ - dets[0 + (k1 <= 0) + (k2 <= 0) + (k3 <= 0)], - dets[1 + (k1 <= 1) + (k2 <= 1) + (k3 <= 1)], - dets[2 + (k1 <= 2) + (k2 <= 2) + (k3 <= 2)], - }, - node_colors, - atomic_errors, - out_atoms, - best_score); - } - } - } - - return try_finish_decomposition(best_score, obs_flip, atomic_errors, out_atoms, out_remnants); -} - -bool chromobius::decompose_single_basis_dets_into_atoms( - std::span dets, - obsmask_int obs_flip, - std::span node_colors, - const std::map &atomic_errors, - std::vector *out_atoms, - std::map *out_remnants) { - switch (dets.size()) { - case 0: - return true; - case 1: - out_atoms->push_back(AtomicErrorKey{dets[0], BOUNDARY_NODE, BOUNDARY_NODE}); - return atomic_errors.contains(out_atoms->back()); - case 2: - return decompose_single_basis_dets_into_atoms_helper_n2( - dets, obs_flip, node_colors, atomic_errors, out_atoms, out_remnants); - case 3: - return decompose_single_basis_dets_into_atoms_helper_n3( - dets, obs_flip, node_colors, atomic_errors, out_atoms, out_remnants); - case 4: - return decompose_single_basis_dets_into_atoms_helper_n4( - dets, obs_flip, node_colors, atomic_errors, out_atoms, out_remnants); - case 5: - return decompose_single_basis_dets_into_atoms_helper_n5( - dets, obs_flip, node_colors, atomic_errors, out_atoms, out_remnants); - case 6: - return decompose_single_basis_dets_into_atoms_helper_n6( - dets, obs_flip, node_colors, atomic_errors, out_atoms, out_remnants); - default: - return false; - } -} - -void chromobius::collect_composite_errors_and_remnants_into_mobius_dem( - const stim::DetectorErrorModel &dem, - std::span node_colors, - const std::map &atomic_errors, - bool drop_mobius_errors_involving_remnant_errors, - bool ignore_decomposition_failures, - stim::DetectorErrorModel *out_mobius_dem, - std::map *out_remnants) { - - stim::SparseXorVec dets; - std::vector x_buf; - std::vector z_buf; - std::vector atoms_buf; - std::vector composite_error_buffer; - - dem.iter_flatten_error_instructions([&](stim::DemInstruction instruction) { - obsmask_int obs_flip; - extract_obs_and_dets_from_error_instruction(instruction, &dets, &obs_flip); - - decompose_dets_into_atoms( - dets.sorted_items, - obs_flip, - node_colors, - atomic_errors, - ignore_decomposition_failures, - &x_buf, - &z_buf, - instruction, - &dem, - &atoms_buf, - out_remnants); - - if (drop_mobius_errors_involving_remnant_errors && !out_remnants->empty()) { - atoms_buf.clear(); - out_remnants->clear(); - } - - // Convert atomic errors into mobius detection events with decomposition suggestions. - composite_error_buffer.clear(); - bool has_corner_node = false; - for (const auto &atom : atoms_buf) { - has_corner_node |= atom.dets[1] == BOUNDARY_NODE; - atom.iter_mobius_edges(node_colors, [&](node_offset_int d1, node_offset_int d2) { - composite_error_buffer.push_back(stim::DemTarget::relative_detector_id(d1)); - composite_error_buffer.push_back(stim::DemTarget::relative_detector_id(d2)); - composite_error_buffer.push_back(stim::DemTarget::separator()); - }); - } - - // Put the composite error into the mobius dem as an error instruction. - if (!composite_error_buffer.empty()) { - composite_error_buffer.pop_back(); - double p = instruction.arg_data[0]; - if (has_corner_node) { - // Corner nodes have edges to themselves that correspond to reaching the boundary in one subgraph - // and then bouncing back in another subgraph. Accounting for this correctly requires doubling the - // weight of the edge, which corresponds to squaring the probability. - p *= p; - } - out_mobius_dem->append_error_instruction(p, composite_error_buffer); - } - }); -} diff --git a/src/chromobius/graph/collect_composite_errors_5.cc b/src/chromobius/graph/collect_composite_errors_5.cc new file mode 100644 index 0000000..773b5d3 --- /dev/null +++ b/src/chromobius/graph/collect_composite_errors_5.cc @@ -0,0 +1,83 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "chromobius/graph/collect_composite_errors.h" + +#include "chromobius/graph/collect_atomic_errors.h" + +using namespace chromobius; + +void chromobius::collect_composite_errors_and_remnants_into_mobius_dem( + const stim::DetectorErrorModel &dem, + std::span node_colors, + const std::map &atomic_errors, + bool drop_mobius_errors_involving_remnant_errors, + bool ignore_decomposition_failures, + stim::DetectorErrorModel *out_mobius_dem, + std::map *out_remnants) { + + stim::SparseXorVec dets; + std::vector x_buf; + std::vector z_buf; + std::vector atoms_buf; + std::vector composite_error_buffer; + + dem.iter_flatten_error_instructions([&](stim::DemInstruction instruction) { + obsmask_int obs_flip; + extract_obs_and_dets_from_error_instruction(instruction, &dets, &obs_flip); + + decompose_dets_into_atoms( + dets.sorted_items, + obs_flip, + node_colors, + atomic_errors, + ignore_decomposition_failures, + &x_buf, + &z_buf, + instruction, + &dem, + &atoms_buf, + out_remnants); + + if (drop_mobius_errors_involving_remnant_errors && !out_remnants->empty()) { + atoms_buf.clear(); + out_remnants->clear(); + } + + // Convert atomic errors into mobius detection events with decomposition suggestions. + composite_error_buffer.clear(); + bool has_corner_node = false; + for (const auto &atom : atoms_buf) { + has_corner_node |= atom.dets[1] == BOUNDARY_NODE; + atom.iter_mobius_edges(node_colors, [&](node_offset_int d1, node_offset_int d2) { + composite_error_buffer.push_back(stim::DemTarget::relative_detector_id(d1)); + composite_error_buffer.push_back(stim::DemTarget::relative_detector_id(d2)); + composite_error_buffer.push_back(stim::DemTarget::separator()); + }); + } + + // Put the composite error into the mobius dem as an error instruction. + if (!composite_error_buffer.empty()) { + composite_error_buffer.pop_back(); + double p = instruction.arg_data[0]; + if (has_corner_node) { + // Corner nodes have edges to themselves that correspond to reaching the boundary in one subgraph + // and then bouncing back in another subgraph. Accounting for this correctly requires doubling the + // weight of the edge, which corresponds to squaring the probability. + p *= p; + } + out_mobius_dem->append_error_instruction(p, composite_error_buffer); + } + }); +} diff --git a/src/chromobius/graph/collect_composite_errors_6.cc b/src/chromobius/graph/collect_composite_errors_6.cc new file mode 100644 index 0000000..10abc99 --- /dev/null +++ b/src/chromobius/graph/collect_composite_errors_6.cc @@ -0,0 +1,20 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "chromobius/graph/collect_composite_errors.h" + +#include "chromobius/graph/collect_atomic_errors.h" + +using namespace chromobius; + diff --git a/src/chromobius/graph/collect_composite_errors_7.cc b/src/chromobius/graph/collect_composite_errors_7.cc new file mode 100644 index 0000000..d720555 --- /dev/null +++ b/src/chromobius/graph/collect_composite_errors_7.cc @@ -0,0 +1,50 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "chromobius/graph/collect_composite_errors.h" + +#include "chromobius/graph/collect_atomic_errors.h" + +using namespace chromobius; + +bool chromobius::decompose_single_basis_dets_into_atoms_helper_n6( + std::span dets, + obsmask_int obs_flip, + std::span node_colors, + const std::map &atomic_errors, + std::vector *out_atoms, + std::map *out_remnants) { + int best_score = 0; + + // 3:3 decomposition. + for (size_t k1 = 0; k1 < dets.size() && best_score < 2; k1++) { + for (size_t k2 = k1 + 1; k2 < dets.size(); k2++) { + for (size_t k3 = k2 + 1; k3 < dets.size(); k3++) { + try_grow_decomposition( + AtomicErrorKey{dets[k1], dets[k2], dets[k3]}, + AtomicErrorKey{ + dets[0 + (k1 <= 0) + (k2 <= 0) + (k3 <= 0)], + dets[1 + (k1 <= 1) + (k2 <= 1) + (k3 <= 1)], + dets[2 + (k1 <= 2) + (k2 <= 2) + (k3 <= 2)], + }, + node_colors, + atomic_errors, + out_atoms, + best_score); + } + } + } + + return try_finish_decomposition(best_score, obs_flip, atomic_errors, out_atoms, out_remnants); +} diff --git a/src/chromobius/graph/collect_composite_errors_8.cc b/src/chromobius/graph/collect_composite_errors_8.cc new file mode 100644 index 0000000..3170eba --- /dev/null +++ b/src/chromobius/graph/collect_composite_errors_8.cc @@ -0,0 +1,48 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "chromobius/graph/collect_composite_errors.h" + +#include "chromobius/graph/collect_atomic_errors.h" + +using namespace chromobius; + +bool chromobius::decompose_single_basis_dets_into_atoms_helper_n5( + std::span dets, + obsmask_int obs_flip, + std::span node_colors, + const std::map &atomic_errors, + std::vector *out_atoms, + std::map *out_remnants) { + int best_score = 0; + + // 2:3 decomposition. + for (size_t k1 = 0; k1 < dets.size() && best_score < 2; k1++) { + for (size_t k2 = k1 + 1; k2 < dets.size(); k2++) { + try_grow_decomposition( + AtomicErrorKey{dets[k1], dets[k2], BOUNDARY_NODE}, + AtomicErrorKey{ + dets[0 + (k1 <= 0) + (k2 <= 0)], + dets[1 + (k1 <= 1) + (k2 <= 1)], + dets[2 + (k1 <= 2) + (k2 <= 2)], + }, + node_colors, + atomic_errors, + out_atoms, + best_score); + } + } + + return try_finish_decomposition(best_score, obs_flip, atomic_errors, out_atoms, out_remnants); +}