Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #37

Merged
merged 8 commits into from
May 28, 2024
Merged

Dev #37

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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ fusion_blossom.egg-info/

*-uncompressed.png
micro-blossom-examples
.scala-build
.bsp
42 changes: 42 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,18 @@ pub enum Commands {
#[clap(subcommand)]
command: TestCommands,
},
/// visualize a syndrome graph
VisualizeSyndromes(VisualizeSyndromesParameters),
}

#[derive(Parser, Clone, Debug)]
pub struct VisualizeSyndromesParameters {
/// the syndromes file (generated by qecp using `--fusion-blossom-syndrome-export-filename`)
#[clap(value_parser)]
pub filepath: String,
/// visualizer file at visualize/data/<visualizer_filename.json>
#[clap(long, default_value_t = crate::visualize::static_visualize_data_filename())]
pub visualizer_filename: String,
}

#[derive(Subcommand, Clone, Debug)]
Expand Down Expand Up @@ -374,6 +386,36 @@ impl Cli {
let runnable = RunnableBenchmarkParameters::from(benchmark_parameters);
runnable.run();
}
Commands::VisualizeSyndromes(parameters) => {
let code_config = json!({
"filename": parameters.filepath
});
let reader = ErrorPatternReader::new(code_config.clone());
let code_config_str = serde_json::to_string(&code_config).unwrap();
let total_rounds_str = format!("{}", reader.syndrome_patterns.len());
drop(reader);
let command: Vec<String> = [
"",
"benchmark",
"0",
"0",
"--code-type",
"error-pattern-reader",
"--code-config",
code_config_str.as_str(),
"--verifier",
"none",
"--total-rounds",
total_rounds_str.as_str(),
"--enable-visualizer",
"--visualizer-filename",
parameters.visualizer_filename.as_str(),
]
.into_iter()
.map(|s| s.to_string())
.collect();
execute_in_cli(command.iter(), true);
}
Commands::Test { command } => {
match command {
TestCommands::Serial {
Expand Down
50 changes: 30 additions & 20 deletions src/example_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,8 @@ pub struct QECPlaygroundCodeConfig {
pub qubit_type: Option<qecp::types::QubitType>,
#[serde(default = "qecp::decoder_fusion::fusion_default_configs::max_half_weight")]
pub max_half_weight: usize,
#[serde(default = "qec_playground_default_configs::trim_isolated_vertices")]
pub trim_isolated_vertices: bool,
}

#[cfg(feature = "qecp_integrate")]
Expand All @@ -1234,6 +1236,9 @@ pub mod qec_playground_default_configs {
pub fn use_brief_edge() -> bool {
false
}
pub fn trim_isolated_vertices() -> bool {
true
}
}

#[cfg(feature = "qecp_integrate")]
Expand Down Expand Up @@ -1279,11 +1284,16 @@ impl QECPlaygroundCode {
let positions = &adaptor.positions;
let mut vertex_index_map = HashMap::new();
// filter the specific qubit type and also remove isolated virtual vertices
let mut is_vertex_isolated = vec![true; initializer.vertex_num];
for (left_vertex, right_vertex, _) in initializer.weighted_edges.iter().cloned() {
is_vertex_isolated[left_vertex] = false;
is_vertex_isolated[right_vertex] = false;
}
let is_vertex_isolated = if config.trim_isolated_vertices {
let mut is_vertex_isolated = vec![true; initializer.vertex_num];
for (left_vertex, right_vertex, _) in initializer.weighted_edges.iter().cloned() {
is_vertex_isolated[left_vertex] = false;
is_vertex_isolated[right_vertex] = false;
}
is_vertex_isolated
} else {
vec![false; initializer.vertex_num]
};
for (vertex_index, is_isolated) in is_vertex_isolated.iter().cloned().enumerate() {
let position = &adaptor.vertex_to_position_mapping[vertex_index];
let qubit_type = simulator.get_node(position).as_ref().unwrap().qubit_type;
Expand Down Expand Up @@ -1542,25 +1552,25 @@ pub(crate) fn register(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
Ok(())
}

pub fn visualize_code(code: &mut impl ExampleCode, visualize_filename: String) {
print_visualize_link(visualize_filename.clone());
let mut visualizer = Visualizer::new(
Some(visualize_data_folder() + visualize_filename.as_str()),
code.get_positions(),
true,
)
.unwrap();
visualizer.snapshot("code".to_string(), code).unwrap();
for round in 0..3 {
code.generate_random_errors(round);
visualizer.snapshot(format!("syndrome {}", round + 1), code).unwrap();
}
}

#[cfg(test)]
mod tests {
use super::*;

fn visualize_code(code: &mut impl ExampleCode, visualize_filename: String) {
print_visualize_link(visualize_filename.clone());
let mut visualizer = Visualizer::new(
Some(visualize_data_folder() + visualize_filename.as_str()),
code.get_positions(),
true,
)
.unwrap();
visualizer.snapshot("code".to_string(), code).unwrap();
for round in 0..3 {
code.generate_random_errors(round);
visualizer.snapshot(format!("syndrome {}", round + 1), code).unwrap();
}
}

#[test]
fn example_code_capacity_repetition_code() {
// cargo test example_code_capacity_repetition_code -- --nocapture
Expand Down
19 changes: 19 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,25 @@ impl SolverInitializer {
fn __repr__(&self) -> String {
format!("{:?}", self)
}
#[allow(clippy::unnecessary_cast)]
pub fn syndrome_of(&self, subgraph: &[EdgeIndex]) -> BTreeSet<VertexIndex> {
let mut defects = BTreeSet::new();
for edge_index in subgraph {
let (left, right, _weight) = self.weighted_edges[*edge_index as usize];
for vertex_index in [left, right] {
if defects.contains(&vertex_index) {
defects.remove(&vertex_index);
} else {
defects.insert(vertex_index);
}
}
}
// remove virtual vertices
for vertex_index in self.virtual_vertices.iter() {
defects.remove(vertex_index);
}
defects
}
}

/// timestamp type determines how many fast clear before a hard clear is required, see [`FastClear`]
Expand Down