Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ embed_visualizer = [
] # use nodejs to build frontend and embed in Python instead of outputing individual JSON files
loose_sanity_check = [] # do not panic when check fails
fast_ds = ["gxhash"] # use fast data structures to fast iterate
unsafe_pointer = [] # if turned on, use unsafe pointers

[dependencies]
pyo3 = { version = "0.23.4", features = [
Expand Down Expand Up @@ -107,6 +108,7 @@ bp = { path = "src/bp" }
thread-priority = "1.2.0"
lnexp = "0.2.1"
gxhash = { version = "3.5.0", optional = true }
weak-table = "0.3.2"

[dev-dependencies]
test-case = "3.1.0"
Expand Down
53 changes: 27 additions & 26 deletions src/bin/aps2024_demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use mwpf::primal_module::*;
use mwpf::primal_module_serial::*;
use mwpf::util::*;
use mwpf::visualize::*;
use mwpf::pointers::*;
use num_traits::{FromPrimitive, Zero};
#[cfg(feature = "progress_bar")]
use pbr::ProgressBar;
Expand All @@ -23,8 +24,8 @@ fn debug_demo() {
let mut code = CodeCapacityTailoredCode::new(3, 0., 0.01);
let initializer = Arc::new(code.get_initializer());
let model_graph = Arc::new(ModelHyperGraph::new(initializer.clone()));
let mut dual_module = DualModulePQ::new_empty(&initializer);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone());
let mut dual_module = DualModulePQ::new_empty(&initializer, 0);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone(), 0);
code.set_physical_errors(&[4]);
let syndrome_pattern = Arc::new(code.get_syndrome());
let mut visualizer = Visualizer::new(
Expand Down Expand Up @@ -55,12 +56,12 @@ fn debug_demo() {
.snapshot_combined("begin".to_string(), vec![&interface_ptr, &dual_module])
.unwrap();
let decoding_graph = interface_ptr.read_recursive().decoding_graph.clone();
let s0 = Arc::new(InvalidSubgraph::new_complete(
let s0 = Arc::new(InvalidSubgraph::new_complete_from_indices(
fast_iter_set! {3},
fast_iter_set! {},
&decoding_graph,
&mut dual_module,
));
let (_, s0_ptr) = interface_ptr.find_or_create_node(&s0, &mut dual_module);
let (_, s0_ptr) = interface_ptr.find_or_create_node(&s0, &mut dual_module, 0);
dual_module.set_grow_rate(&s0_ptr, Rational::from_usize(1).unwrap());
for _ in 0..3 {
dual_module.grow(Rational::new_raw(1.into(), 3.into()));
Expand All @@ -69,12 +70,12 @@ fn debug_demo() {
.unwrap();
}
// create another node
let s1 = Arc::new(InvalidSubgraph::new_complete(
let s1 = Arc::new(InvalidSubgraph::new_complete_from_indices(
fast_iter_set! {6},
fast_iter_set! {},
&decoding_graph,
&mut dual_module,
));
let (_, s1_ptr) = interface_ptr.find_or_create_node(&s1, &mut dual_module);
let (_, s1_ptr) = interface_ptr.find_or_create_node(&s1, &mut dual_module, 0);
dual_module.set_grow_rate(&s0_ptr, -Rational::from_usize(1).unwrap());
dual_module.set_grow_rate(&s1_ptr, Rational::from_usize(1).unwrap());
for _ in 0..3 {
Expand All @@ -101,8 +102,8 @@ fn simple_demo() {
let mut code = CodeCapacityTailoredCode::new(3, 0., 0.01);
let initializer = Arc::new(code.get_initializer());
let model_graph = Arc::new(ModelHyperGraph::new(initializer.clone()));
let mut dual_module = DualModulePQ::new_empty(&initializer);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone());
let mut dual_module = DualModulePQ::new_empty(&initializer, 0);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone(), 0);
code.set_physical_errors(&[4]);
let syndrome_pattern = Arc::new(code.get_syndrome());
let mut visualizer = Visualizer::new(
Expand Down Expand Up @@ -133,12 +134,12 @@ fn simple_demo() {
.snapshot_combined("begin".to_string(), vec![&interface_ptr, &dual_module])
.unwrap();
let decoding_graph = interface_ptr.read_recursive().decoding_graph.clone();
let s0 = Arc::new(InvalidSubgraph::new_complete(
let s0 = Arc::new(InvalidSubgraph::new_complete_from_indices(
fast_iter_set! {3},
fast_iter_set! {},
&decoding_graph,
&mut dual_module,
));
let (_, s0_ptr) = interface_ptr.find_or_create_node(&s0, &mut dual_module);
let (_, s0_ptr) = interface_ptr.find_or_create_node(&s0, &mut dual_module, 0);
dual_module.set_grow_rate(&s0_ptr, Rational::from_usize(1).unwrap());
visualizer
.snapshot_combined("create s0".to_string(), vec![&interface_ptr, &dual_module])
Expand Down Expand Up @@ -167,8 +168,8 @@ fn challenge_demo() {
let mut code = CodeCapacityTailoredCode::new(5, 0., 0.01);
let initializer = Arc::new(code.get_initializer());
let model_graph = Arc::new(ModelHyperGraph::new(initializer.clone()));
let mut dual_module = DualModulePQ::new_empty(&initializer);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone());
let mut dual_module = DualModulePQ::new_empty(&initializer, 0);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone(), 0);
let syndrome_pattern = Arc::new(SyndromePattern::new_vertices(vec![10, 15, 16]));
code.set_syndrome(&syndrome_pattern);
let mut visualizer = Visualizer::new(
Expand Down Expand Up @@ -236,11 +237,11 @@ fn challenge_demo() {
while index >= s_ptr.len() {
let (vertices, edges) = invalid_subgraphs[s_ptr.len()].clone();
let s = if vertices.is_empty() {
Arc::new(InvalidSubgraph::new(edges, &decoding_graph))
Arc::new(InvalidSubgraph::new_from_indices(edges, dual_module))
} else {
Arc::new(InvalidSubgraph::new_complete(vertices, edges, &decoding_graph))
Arc::new(InvalidSubgraph::new_complete_from_indices(vertices, edges, dual_module))
};
let (_, ptr) = interface_ptr.find_or_create_node(&s, dual_module);
let (_, ptr) = interface_ptr.find_or_create_node(&s, dual_module, 0);
dual_module.set_grow_rate(&ptr, Rational::zero());
s_ptr.push(ptr);
}
Expand Down Expand Up @@ -323,8 +324,8 @@ fn surface_code_example() {
let mut code = CodeCapacityTailoredCode::new(9, p / 3., p / 3.);
let initializer = Arc::new(code.get_initializer());
let model_graph = Arc::new(ModelHyperGraph::new(initializer.clone()));
let mut dual_module = DualModulePQ::new_empty(&initializer);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone());
let mut dual_module = DualModulePQ::new_empty(&initializer, 0);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone(), 0);
let mut visualizer = Visualizer::new(
Some(visualize_data_folder() + visualize_filename.as_str()),
code.get_positions(),
Expand Down Expand Up @@ -372,8 +373,8 @@ fn triangle_color_code_example() {
let mut code = CodeCapacityColorCode::new(9, p);
let initializer = Arc::new(code.get_initializer());
let model_graph = Arc::new(ModelHyperGraph::new(initializer.clone()));
let mut dual_module = DualModulePQ::new_empty(&initializer);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone());
let mut dual_module = DualModulePQ::new_empty(&initializer, 0);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone(), 0);
let mut visualizer = Visualizer::new(
Some(visualize_data_folder() + visualize_filename.as_str()),
code.get_positions(),
Expand Down Expand Up @@ -422,8 +423,8 @@ fn small_color_code_example() {
let mut code = CodeCapacityColorCode::new(7, p);
let initializer = Arc::new(code.get_initializer());
let model_graph = Arc::new(ModelHyperGraph::new(initializer.clone()));
let mut dual_module = DualModulePQ::new_empty(&initializer);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone());
let mut dual_module = DualModulePQ::new_empty(&initializer, 0);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone(), 0);
let mut visualizer = Visualizer::new(
Some(visualize_data_folder() + visualize_filename.as_str()),
code.get_positions(),
Expand Down Expand Up @@ -482,8 +483,8 @@ fn circuit_level_example() {
);
let initializer = Arc::new(code.get_initializer());
let model_graph = Arc::new(ModelHyperGraph::new(initializer.clone()));
let mut dual_module = DualModulePQ::new_empty(&initializer);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone());
let mut dual_module = DualModulePQ::new_empty(&initializer, 0);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone(), 0);
let mut visualizer = Visualizer::new(
Some(visualize_data_folder() + visualize_filename.as_str()),
code.get_positions(),
Expand Down
9 changes: 5 additions & 4 deletions src/bin/paper_figures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use mwpf::invalid_subgraph::*;
use mwpf::model_hypergraph::*;
use mwpf::util::*;
use mwpf::visualize::*;
use mwpf::pointers::*;
use num_traits::FromPrimitive;

use std::sync::Arc;
Expand All @@ -30,8 +31,8 @@ fn hyperedge_example() {
// create dual module
let initializer = Arc::new(code.get_initializer());
let model_graph = Arc::new(ModelHyperGraph::new(initializer.clone()));
let mut dual_module = DualModulePQ::new_empty(&initializer);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone());
let mut dual_module = DualModulePQ::new_empty(&initializer, 0);
let interface_ptr = DualModuleInterfacePtr::new(model_graph.clone(), 0);
// add syndrome
let syndrome_pattern = Arc::new(SyndromePattern::new_vertices(vec![1, 2, 4, 6]));
interface_ptr.write().decoding_graph.set_syndrome(syndrome_pattern.clone());
Expand All @@ -47,8 +48,8 @@ fn hyperedge_example() {
(fast_iter_set! {1}, 0.5),
];
for (vertices, dual_variable) in dual_variables.into_iter() {
let s1 = Arc::new(InvalidSubgraph::new_complete(vertices, fast_iter_set! {}, &decoding_graph));
let (_, s1_ptr) = interface_ptr.find_or_create_node(&s1, &mut dual_module);
let s1 = Arc::new(InvalidSubgraph::new_complete_from_indices(vertices, fast_iter_set! {}, &mut dual_module));
let (_, s1_ptr) = interface_ptr.find_or_create_node(&s1, &mut dual_module, 0);
dual_module.set_grow_rate(&s1_ptr, Rational::from_f64(dual_variable).unwrap());
}
dual_module.grow(Rational::from_f64(1.).unwrap());
Expand Down
84 changes: 72 additions & 12 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use serde::Serialize;
use serde_variant::to_variant_name;
use std::env;
use std::sync::Arc;
use crate::num_traits::Zero;
use crate::dual_module_pq::{EdgePtr, EdgeWeak, VertexPtr, VertexWeak, Edge, Vertex};

const TEST_EACH_ROUNDS: usize = 100;

Expand Down Expand Up @@ -271,42 +273,100 @@ impl TypedValueParser for SerdeJsonParser {

impl MatrixSpeedClass {
pub fn run(&self, parameters: MatrixSpeedParameters, samples: Vec<Vec<(Vec<usize>, bool)>>) {
let (vertices, edges) = Self::initialize_vertex_edges_for_matrix_testing(
(0..parameters.height).collect(),
(0..parameters.width).collect(),
);
let vertices_weak: Vec<_> = vertices.into_iter().map(|v| v.downgrade()).collect();
let edges_weak: Vec<_> = edges.into_iter().map(|e| e.downgrade()).collect();

match *self {
MatrixSpeedClass::EchelonTailTight => {
let mut matrix = Echelon::<Tail<Tight<BasicMatrix>>>::new();
for edge_index in 0..parameters.width {
matrix.add_tight_variable(edge_index);
for edge_weak in edges_weak.iter() {
matrix.add_tight_variable(edge_weak.clone());
}
Self::run_on_matrix_interface(&matrix, samples)
Self::run_on_matrix_interface(&matrix, samples, &vertices_weak, &edges_weak);
}
MatrixSpeedClass::EchelonTight => {
let mut matrix = Echelon::<Tight<BasicMatrix>>::new();
for edge_index in 0..parameters.width {
matrix.add_tight_variable(edge_index);
for edge_weak in edges_weak.iter() {
matrix.add_tight_variable(edge_weak.clone());
}
Self::run_on_matrix_interface(&matrix, samples)
Self::run_on_matrix_interface(&matrix, samples, &vertices_weak, &edges_weak)
}
MatrixSpeedClass::Echelon => {
let mut matrix = Echelon::<BasicMatrix>::new();
for edge_index in 0..parameters.width {
matrix.add_variable(edge_index);
for edge_weak in edges_weak.iter() {
matrix.add_variable(edge_weak.clone());
}
Self::run_on_matrix_interface(&matrix, samples)
Self::run_on_matrix_interface(&matrix, samples, &vertices_weak, &edges_weak)
}
}
}

pub fn run_on_matrix_interface<M: MatrixView + Clone>(matrix: &M, samples: Vec<Vec<(Vec<usize>, bool)>>) {
pub fn run_on_matrix_interface<M: MatrixView + Clone>(
matrix: &M,
samples: Vec<Vec<(Vec<usize>, bool)>>,
vertices: &Vec<VertexWeak>,
edges: &Vec<EdgeWeak>,
) {
for parity_checks in samples.iter() {
let mut matrix = matrix.clone();
for (vertex_index, (incident_edges, parity)) in parity_checks.iter().enumerate() {
matrix.add_constraint(vertex_index, incident_edges, *parity);
let incident_edges_weak: Vec<EdgeWeak> = incident_edges.iter().map(|&i| edges[i].clone()).collect();
matrix.add_constraint(vertices[vertex_index].clone(), &incident_edges_weak, *parity);
}
// for a MatrixView, visiting the columns and rows is sufficient to update its internal state
matrix.columns();
matrix.rows();
}
}

fn initialize_vertex_edges_for_matrix_testing(
vertex_indices: Vec<VertexIndex>,
edge_indices: Vec<EdgeIndex>,
) -> (Vec<VertexPtr>, Vec<EdgePtr>) {
// create edges
let edges: Vec<EdgePtr> = edge_indices
.into_iter()
.map(|edge_index| {
EdgePtr::new_value(
Edge {
edge_index,
weight: Rational::zero(),
dual_nodes: vec![],
vertices: vec![],
last_updated_time: Rational::zero(),
growth_at_last_updated_time: Rational::zero(),
grow_rate: Rational::zero(),
// unit_index: Some(0), // dummy value
// connected_to_boundary_vertex: false, // dummy value
#[cfg(feature = "incr_lp")]
cluster_weights: hashbrown::HashMap::new(),
},
(edge_index, edge_index),
)
})
.collect();

// create vertices
let vertices: Vec<VertexPtr> = vertex_indices
.into_iter()
.map(|vertex_index| {
VertexPtr::new_value(
Vertex {
vertex_index,
is_defect: false,
edges: vec![],
},
(vertex_index, vertex_index),
)
})
.collect();

(vertices, edges)
}
}

impl Cli {
Expand Down Expand Up @@ -930,7 +990,7 @@ impl ResultVerifier for VerifierActualError {
} else {
Rational::from(
self.initializer
.get_subgraph_total_weight(&OutputSubgraph::new(error_pattern.clone(), Default::default())),
.get_subgraph_total_weight(&OutputSubgraph::new(error_pattern.clone(), Default::default(), vec![])),
)
};
let (subgraph, weight_range) = solver.subgraph_range_visualizer(visualizer);
Expand Down
Loading
Loading