Skip to content

Commit

Permalink
split 3
Browse files Browse the repository at this point in the history
  • Loading branch information
Strilanc committed Dec 14, 2023
1 parent 9440821 commit 15d0074
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 157 deletions.
4 changes: 4 additions & 0 deletions file_lists/source_files_no_main
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
157 changes: 0 additions & 157 deletions src/chromobius/graph/collect_composite_errors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<const node_offset_int> dets,
obsmask_int obs_flip,
std::span<const ColorBasis> node_colors,
const std::map<AtomicErrorKey, obsmask_int> &atomic_errors,
std::vector<AtomicErrorKey> *out_atoms,
std::map<AtomicErrorKey, obsmask_int> *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<const node_offset_int> dets,
obsmask_int obs_flip,
std::span<const ColorBasis> node_colors,
const std::map<AtomicErrorKey, obsmask_int> &atomic_errors,
std::vector<AtomicErrorKey> *out_atoms,
std::map<AtomicErrorKey, obsmask_int> *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<const node_offset_int> dets,
obsmask_int obs_flip,
std::span<const ColorBasis> node_colors,
const std::map<AtomicErrorKey, obsmask_int> &atomic_errors,
std::vector<AtomicErrorKey> *out_atoms,
std::map<AtomicErrorKey, obsmask_int> *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<const ColorBasis> node_colors,
const std::map<AtomicErrorKey, obsmask_int> &atomic_errors,
bool drop_mobius_errors_involving_remnant_errors,
bool ignore_decomposition_failures,
stim::DetectorErrorModel *out_mobius_dem,
std::map<AtomicErrorKey, obsmask_int> *out_remnants) {

stim::SparseXorVec<node_offset_int> dets;
std::vector<node_offset_int> x_buf;
std::vector<node_offset_int> z_buf;
std::vector<AtomicErrorKey> atoms_buf;
std::vector<stim::DemTarget> 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);
}
});
}
83 changes: 83 additions & 0 deletions src/chromobius/graph/collect_composite_errors_5.cc
Original file line number Diff line number Diff line change
@@ -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<const ColorBasis> node_colors,
const std::map<AtomicErrorKey, obsmask_int> &atomic_errors,
bool drop_mobius_errors_involving_remnant_errors,
bool ignore_decomposition_failures,
stim::DetectorErrorModel *out_mobius_dem,
std::map<AtomicErrorKey, obsmask_int> *out_remnants) {

stim::SparseXorVec<node_offset_int> dets;
std::vector<node_offset_int> x_buf;
std::vector<node_offset_int> z_buf;
std::vector<AtomicErrorKey> atoms_buf;
std::vector<stim::DemTarget> 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);
}
});
}
20 changes: 20 additions & 0 deletions src/chromobius/graph/collect_composite_errors_6.cc
Original file line number Diff line number Diff line change
@@ -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;

50 changes: 50 additions & 0 deletions src/chromobius/graph/collect_composite_errors_7.cc
Original file line number Diff line number Diff line change
@@ -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<const node_offset_int> dets,
obsmask_int obs_flip,
std::span<const ColorBasis> node_colors,
const std::map<AtomicErrorKey, obsmask_int> &atomic_errors,
std::vector<AtomicErrorKey> *out_atoms,
std::map<AtomicErrorKey, obsmask_int> *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);
}
48 changes: 48 additions & 0 deletions src/chromobius/graph/collect_composite_errors_8.cc
Original file line number Diff line number Diff line change
@@ -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<const node_offset_int> dets,
obsmask_int obs_flip,
std::span<const ColorBasis> node_colors,
const std::map<AtomicErrorKey, obsmask_int> &atomic_errors,
std::vector<AtomicErrorKey> *out_atoms,
std::map<AtomicErrorKey, obsmask_int> *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);
}

0 comments on commit 15d0074

Please sign in to comment.