diff --git a/crates/lib/src/compiler/isa/edge.rs b/crates/lib/src/compiler/isa/edge.rs index fc6e6b82..ab6add9c 100644 --- a/crates/lib/src/compiler/isa/edge.rs +++ b/crates/lib/src/compiler/isa/edge.rs @@ -62,6 +62,10 @@ impl Edge { pub(crate) fn has_valid_operations(&self) -> bool { !self.dead } + + pub(crate) fn qubits(&self) -> impl Iterator + '_ { + self.id.0.iter() + } } /// All the error which can occur from within this module. diff --git a/crates/lib/src/compiler/isa/mod.rs b/crates/lib/src/compiler/isa/mod.rs index bb0032ae..18e3f223 100644 --- a/crates/lib/src/compiler/isa/mod.rs +++ b/crates/lib/src/compiler/isa/mod.rs @@ -1,6 +1,7 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::convert::TryFrom; +use itertools::{Either, Itertools}; use serde::{Deserialize, Serialize}; use edge::{convert_edges, Edge, Id}; @@ -61,15 +62,19 @@ impl TryFrom for Compiler { } } - let qubits = qubits + let (qubits, dead_qubits): (_, HashSet<_>) = qubits .into_iter() - .map(|(k, v)| (k.to_string(), v)) - .filter(|(_, q)| q.has_valid_operations()) - .collect(); + .partition_map(|(id, q)| { + if q.has_valid_operations() { + Either::Left((id.to_string(), q)) + } else { + Either::Right(id) + } + }); let edges = edges .into_iter() + .filter(|(_, e)| e.has_valid_operations() && !e.qubits().any(|q| dead_qubits.contains(q))) .map(|(k, v)| (k.to_string(), v)) - .filter(|(_, e)| e.has_valid_operations()) .collect(); Ok(Self { qubits, edges }) } @@ -180,19 +185,28 @@ mod describe_compiler_isa { let compiler_isa = Compiler::try_from(qcs_isa).expect("Could not convert ISA to CompilerIsa"); + + assert!( + !compiler_isa.edges.contains_key("31-32"), + "edge with Qubit 31 is excluded from the CompilerIsa" + ); + assert!( + !compiler_isa.qubits.contains_key("31"), + "Qubit 31 is excluded from the CompilerIsa" + ); + let serialized = serde_json::to_value(compiler_isa).expect("Unable to serialize CompilerIsa"); - let result = json_is_equivalent(&serialized, &expected); result.expect("JSON was not equivalent"); } #[test] fn compiler_excludes_qubits_with_no_operations() { - let input = read_to_string("tests/qcs-isa-with-dead-qubits.json") - .expect("Could not read ISA with dead qubits"); + let input = read_to_string("tests/qcs-isa-edges-without-gates.json") + .expect("Could not read ISA with edges without gates"); let qcs_isa: InstructionSetArchitecture = - serde_json::from_str(&input).expect("Could not deserialize ISA with dead qubits"); + serde_json::from_str(&input).expect("Could not deserialize ISA with edges without gates"); assert!( qcs_isa.architecture.nodes.contains(&Node::new(31)), @@ -204,7 +218,7 @@ mod describe_compiler_isa { ); let compiler_isa = Compiler::try_from(qcs_isa) - .expect("Could not convert ISA with dead qubits to CompilerIsa"); + .expect("Could not convert ISA with edges without gates to CompilerIsa"); assert!( !compiler_isa.qubits.contains_key("31"), @@ -215,13 +229,13 @@ mod describe_compiler_isa { "edge with Qubit 31 should not be in the CompilerIsa" ); - let input_without_dead = read_to_string("tests/qcs-isa-excluding-dead-qubits.json") - .expect("Could not read ISA that excludes dead qubits"); + let input_without_dead = read_to_string("tests/qcs-isa-excluding-dead-edges.json") + .expect("Could not read ISA that excludes dead edges"); let isa_without_dead: InstructionSetArchitecture = serde_json::from_str(&input_without_dead) - .expect("Could not read ISA that excludes dead qubits"); + .expect("Could not read ISA that excludes dead edges"); let compiler_isa_excluding_dead = Compiler::try_from(isa_without_dead) - .expect("Could not convert ISA with manually excluded dead qubits to CompilerIsa"); + .expect("Could not convert ISA with manually excluded dead edges to CompilerIsa"); let serialized = serde_json::to_value(compiler_isa).expect("Unable to serialize CompilerIsa"); diff --git a/crates/lib/tests/qcs-isa-with-dead-qubits.json b/crates/lib/tests/qcs-isa-edges-without-gates.json similarity index 100% rename from crates/lib/tests/qcs-isa-with-dead-qubits.json rename to crates/lib/tests/qcs-isa-edges-without-gates.json diff --git a/crates/lib/tests/qcs-isa-excluding-dead-qubits.json b/crates/lib/tests/qcs-isa-excluding-dead-edges.json similarity index 100% rename from crates/lib/tests/qcs-isa-excluding-dead-qubits.json rename to crates/lib/tests/qcs-isa-excluding-dead-edges.json diff --git a/crates/lib/tests/random_9Q.quil b/crates/lib/tests/random_9Q.quil new file mode 100644 index 00000000..ac965b81 --- /dev/null +++ b/crates/lib/tests/random_9Q.quil @@ -0,0 +1,65 @@ +DECLARE x REAL[9] +RX(x[0]) 0 +RX(x[1]) 1 +RX(x[2]) 2 +RX(x[3]) 3 +RX(x[4]) 4 +RX(x[5]) 5 +RX(x[6]) 6 +RX(x[7]) 7 +RX(x[8]) 8 +CNOT 1 3 +RZ(4.091531092109592) 0 +CNOT 0 2 +CNOT 5 7 +RY(1.7617455482463211) 2 +RX(4.341787227340024) 1 +RY(6.03481174851813) 3 +CNOT 2 7 +CNOT 1 3 +RX(3.882403181997303) 8 +CNOT 0 3 +RY(4.5577145626046) 5 +CNOT 3 6 +CNOT 3 6 +CNOT 5 7 +CNOT 2 4 +RX(4.10899233195489) 2 +RZ(1.8339690381798408) 6 +RY(5.89415287392258) 3 +RZ(4.380310025182133) 2 +CNOT 1 6 +RZ(4.5068641836677985) 0 +RZ(1.1369350017910809) 7 +RX(5.299221523914757) 7 +CNOT 5 6 +RY(1.7759903888578796) 2 +RZ(1.6723803444036598) 4 +CNOT 5 8 +RZ(4.81533948533556) 1 +CNOT 0 8 +RX(0.8216674789281084) 8 +RX(0.65172058886683) 3 +RY(1.07527544400171) 1 +RY(1.6371802208324866) 7 +RX(4.061457815390998) 6 +CNOT 4 5 +CNOT 0 7 +RY(5.856936061895889) 3 +CNOT 3 6 +RZ(0.03892836224248009) 2 +RZ(2.7440510725697096) 1 +RX(2.4129374309702927) 6 +RZ(5.323996026775554) 3 +RX(4.649098117376168) 5 +CNOT 2 4 +RZ(6.231156859049788) 3 +RZ(3.8525342980154273) 6 +RZ(5.007144332831469) 1 +RY(3.3425348136846824) 1 +RY(3.1516871757253817) 4 +CNOT 4 6 +RZ(0.7437929070965517) 6 +RY(2.3967746511191987) 8 +RZ(4.137478777058711) 5 +RZ(5.273560283938733) 3