Skip to main content

bloq_compile/
lib.rs

1//! Compile block graphs into physical circuit programs.
2//!
3//! Pipeline: [`BlockGraph`](bloq_graph::BlockGraph) → [`Bloq`] → backend emission.
4//!
5//! The compiler walks every block in a [`BlockGraph`](bloq_graph::BlockGraph), resolves its signature and
6//! convention, generates per-block circuit templates, composes detectors and
7//! observables from stabilizer flows, and lowers the result into Bloq
8//! nodes suitable for backend emission.
9
10mod block;
11mod cache;
12mod compile;
13mod config;
14mod error;
15mod lower;
16mod padding;
17mod signature;
18mod spatial_port;
19
20pub(crate) type FxMap<K, V> = rustc_hash::FxHashMap<K, V>;
21pub(crate) type FxSet<T> = rustc_hash::FxHashSet<T>;
22
23/// A set usable as a GF(2) parity accumulator — see [`xor_toggle`].
24pub(crate) trait XorToggleSet<T> {
25    /// Insert `item` if absent, remove it if present.
26    fn toggle(&mut self, item: T);
27}
28
29impl<T: Eq + std::hash::Hash, S: std::hash::BuildHasher> XorToggleSet<T>
30    for std::collections::HashSet<T, S>
31{
32    fn toggle(&mut self, item: T) {
33        if !self.remove(&item) {
34            self.insert(item);
35        }
36    }
37}
38
39impl<T: Ord> XorToggleSet<T> for std::collections::BTreeSet<T> {
40    fn toggle(&mut self, item: T) {
41        if !self.remove(&item) {
42            self.insert(item);
43        }
44    }
45}
46
47/// XOR a stream of items into `set`: an item seen an even number of times
48/// cancels out of the parity. The one symmetric-difference kernel shared by
49/// observable, gateway, and output-frame folding.
50pub(crate) fn xor_toggle<T, S: XorToggleSet<T>>(set: &mut S, items: impl IntoIterator<Item = T>) {
51    for item in items {
52        set.toggle(item);
53    }
54}
55
56/// XOR `items` into a parity multiset, returning the survivors sorted for
57/// deterministic downstream ordering.
58///
59/// Sorting first and keeping one element per odd-length run is the same
60/// symmetric difference as [`xor_toggle`] into a set, minus the hashing — and
61/// the result had to be sorted regardless.
62pub(crate) fn xor_toggled_sorted<T: Copy + Ord>(items: impl IntoIterator<Item = T>) -> Vec<T> {
63    let mut all: Vec<T> = items.into_iter().collect();
64    all.sort_unstable();
65    all.chunk_by(|a, b| a == b)
66        .filter(|run| run.len() % 2 == 1)
67        .map(|run| run[0])
68        .collect()
69}
70
71#[doc(no_inline)]
72pub use bloq_ir::{
73    Bloq, BloqEdge, BloqNode, BloqNodeId, NodeProvenance, SourceBlockRef, TemporalPipeRef,
74};
75pub use cache::SharedCompileCache;
76pub(crate) use compile::BlockLayout;
77pub use compile::{
78    CLIFFORD_PROXY_SEED_METADATA_KEY, CODE_DISTANCE_METADATA_KEY, CONVENTION_METADATA_KEY,
79    CompileArtifacts, CompileContext, CompileStage, CompiledObject, compile,
80    compile_clifford_proxy, compile_detslice_proxy, compile_random_clifford_proxy, compile_with,
81    compiled_distance,
82};
83pub use config::{CompileConfig, MAX_CODE_DISTANCE, spatial_hadamard_distance_warning};
84pub use error::{CompileError, InvalidDistance, WalkError};
85pub(crate) use error::{add_resource, check_resource};
86pub use lower::validate_bloq_qubit_layout_for_source;
87pub use signature::Connectivity;