diff --git a/Justfile b/Justfile index 8407463b..267e2873 100644 --- a/Justfile +++ b/Justfile @@ -146,6 +146,10 @@ ci-rust: setup-python set -euo pipefail cargo fmt --all -- --check cargo clippy --workspace {{WORKSPACE_EXCLUDE}} --all-targets -- -D warnings + # Workspace Rustdoc must be warning-free (#406): unresolved intra-doc links, + # private-item references, output collisions, and accidental citation links + # are all denied. --no-deps scopes the check to workspace crates only. + RUSTDOCFLAGS="-D warnings" cargo doc --workspace {{WORKSPACE_EXCLUDE}} --no-deps cargo build --release --workspace {{WORKSPACE_EXCLUDE}} cargo build --examples --workspace {{WORKSPACE_EXCLUDE}} # MLIR-free module-seam feature combinations (issue #407). Runs after @@ -271,6 +275,12 @@ tooling-full: _tooling-build ci-docs-assert: ./scripts/assert-validation-docs.sh +# Workspace Rustdoc with warnings denied (#406): unresolved intra-doc links, +# private-item references, output collisions, and accidental citation links. +# Also run as part of `ci-rust`; this recipe runs it in isolation. +ci-rustdoc: + RUSTDOCFLAGS="-D warnings" cargo doc --workspace {{WORKSPACE_EXCLUDE}} --no-deps + # Local convenience: re-run just the sample corpus catalog lint (schema, # path existence, category coverage, required README sections, and a real # `quonc` typecheck for every `ci: smoke` entry in samples/catalog.yaml; diff --git a/backend/src/descriptor.rs b/backend/src/descriptor.rs index ca058299..50fb14a4 100644 --- a/backend/src/descriptor.rs +++ b/backend/src/descriptor.rs @@ -129,7 +129,7 @@ pub struct NeutralAtomTargetDescriptor { #[serde(default, skip_serializing_if = "Option::is_none")] pub error_model: Option, /// Optional movement-induced heating / atom-loss parameters (issue #310, - /// [Atomique] Eqs. (1)–(2)). Sibling to `error_model`; omitted targets + /// \[Atomique\] Eqs. (1)–(2)). Sibling to `error_model`; omitted targets /// still load and the report simply skips the `atom_loss_budget` section. #[serde(default, skip_serializing_if = "Option::is_none")] pub atom_loss_model: Option, @@ -245,10 +245,10 @@ pub struct NeutralAtomErrorModelDescriptor { #[derive(Debug, Clone, Copy, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct NeutralAtomLossModelDescriptor { - /// Heating per µm of atom travel ([Atomique] Eq. (1)). + /// Heating per µm of atom travel (\[Atomique\] Eq. (1)). pub heating_rate_per_um: f64, /// Dimensionless loss coefficient → `1 − exp(−loss_coeff × H)` - /// ([Atomique] Eq. (2)). + /// (\[Atomique\] Eq. (2)). pub loss_coeff: f64, } diff --git a/backend/src/target.rs b/backend/src/target.rs index 9cc82377..757a33b7 100644 --- a/backend/src/target.rs +++ b/backend/src/target.rs @@ -322,7 +322,7 @@ impl FixedTarget { /// /// Use this for descriptor loading where `num_qubits` arrives from JSON /// independent of the topology built from the same document. Returns - /// [`BackendError::InvalidTargetConfig`] on mismatch. + /// [`crate::error::BackendError::InvalidTargetConfig`] on mismatch. pub fn try_new( num_qubits: usize, topology: ConnectivityGraph, @@ -368,7 +368,7 @@ pub struct NeutralAtomTarget { /// derived from [`Self::fidelity`] (ADR-0017). pub error_model: Option, /// Optional movement-induced heating / atom-loss parameters (issue #310, - /// [Atomique] Wang et al. ISCA 2024, arXiv:2311.15123, Eqs. (1)–(2)). + /// \[Atomique\] Wang et al. ISCA 2024, arXiv:2311.15123, Eqs. (1)–(2)). /// /// Sibling to `error_model`; not derived from fidelity. When present, the /// NA resource report attaches an analytic `atom_loss_budget` section @@ -378,13 +378,13 @@ pub struct NeutralAtomTarget { /// /// **Provenance / placeholder status (architecture_model.md §2 / §8.6):** /// the heating→loss coefficients are *placeholder analytic knobs*, not - /// measured device calibrations. [Atomique] Sec. IV gives the model shape; + /// measured device calibrations. \[Atomique\] Sec. IV gives the model shape; /// its numeric fidelity table is deliberately ×10-optimistic relative to /// the 2022 experiments it scales from (see - /// `docs/neutral_atom/literature_notes.md` [Atomique]) — do not quote its + /// `docs/neutral_atom/literature_notes.md` \[Atomique\]) — do not quote its /// numbers as measured values. The model accumulates heating against the /// *actual per-atom travel distance* through Quon's √-law movement - /// schedule and does **not** import [Atomique]'s fixed 300 µs-per-stage + /// schedule and does **not** import \[Atomique\]'s fixed 300 µs-per-stage /// movement timing (the documented §5 divergence). pub atom_loss_model: Option, pub cost_model: NeutralAtomCostModel, @@ -395,7 +395,7 @@ impl NeutralAtomTarget { self.native_gates.iter().any(|g| g == gate) } - /// Return the physical error model, or [`BackendError::MissingErrorModel`]. + /// Return the physical error model, or [`crate::error::BackendError::MissingErrorModel`]. /// /// Call this when QEC error-budget reporting or `--emit-qec-experiment` is /// requested. Do not convert from `fidelity`. @@ -496,7 +496,7 @@ pub struct AodSpeedModel { /// Jerk limit `J` (m/s³) for the [`AodSpeedModelKind::JerkLimited`] timing /// model. Unused (and serializes as `0.0`) under `Sqrt`. Provenance: /// placeholder pending access to the QMAP eval scripts' calibration (see - /// `docs/neutral_atom/literature_notes.md`'s [RAP] caveats — the QMAP repo's + /// `docs/neutral_atom/literature_notes.md`'s \[RAP\] caveats — the QMAP repo's /// newer eval scripts use a jerk-limited model that differs from the /// paper's √-law except at d = 110 µm); the value is target-specific, not a /// universal constant (architecture_model.md §8.6). @@ -509,7 +509,7 @@ pub struct AodSpeedModel { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum AodSpeedModelKind { - /// √-law `t = √(d/a)` (the reproduced [RAP] Table I timing model; default). + /// √-law `t = √(d/a)` (the reproduced \[RAP\] Table I timing model; default). Sqrt, /// Jerk-limited symmetric S-curve: acceleration ramps at jerk `J` up to /// `acceleration_m_s2`, optionally cruises at `max_velocity_m_s`, then @@ -613,7 +613,7 @@ impl TryFrom for NeutralAtomErrorModel { } } /// Optional movement-induced heating / atom-loss parameters (issue #310; -/// [Atomique] Wang et al. ISCA 2024, arXiv:2311.15123, Eqs. (1)–(2)). +/// \[Atomique\] Wang et al. ISCA 2024, arXiv:2311.15123, Eqs. (1)–(2)). /// /// Sibling to [`NeutralAtomErrorModel`] and [`NeutralAtomFidelity`]; not /// derived from either. Wire JSON lives in @@ -623,9 +623,9 @@ impl TryFrom for NeutralAtomErrorModel { /// # Model /// /// Per-atom heating accumulates with travel: -/// `H_a = heating_rate_per_um × cumulative_distance_um_a` ([Atomique] Eq. (1), +/// `H_a = heating_rate_per_um × cumulative_distance_um_a` (\[Atomique\] Eq. (1), /// distance-only term). Per-atom loss probability follows: -/// `p_a = 1 − exp(−loss_coeff × H_a)` ([Atomique] Eq. (2)). The report's +/// `p_a = 1 − exp(−loss_coeff × H_a)` (\[Atomique\] Eq. (2)). The report's /// `expected_atoms_lost = Σ_a p_a`. /// /// `heating_rate_per_um = 0` zeros every `H_a` (heating still reported as 0); @@ -638,14 +638,14 @@ impl TryFrom for NeutralAtomErrorModel { /// Placeholder analytic knobs (architecture_model.md §2 / §8.6), not measured /// calibrations. The model accumulates heating against actual per-atom travel /// distance through Quon's √-law movement schedule — it does **not** import -/// [Atomique]'s fixed 300 µs-per-stage movement timing (§5 divergence). +/// \[Atomique\]'s fixed 300 µs-per-stage movement timing (§5 divergence). #[derive(Debug, Clone, Copy, PartialEq)] pub struct NeutralAtomLossModel { /// Heating gained per µm of atom travel - /// (`H = heating_rate_per_um × cumulative_distance_um`; [Atomique] Eq. (1)). + /// (`H = heating_rate_per_um × cumulative_distance_um`; \[Atomique\] Eq. (1)). pub heating_rate_per_um: f64, /// Dimensionless loss coefficient mapping accumulated heating `H` to a - /// per-atom loss probability `1 − exp(−loss_coeff × H)` ([Atomique] + /// per-atom loss probability `1 − exp(−loss_coeff × H)` (\[Atomique\] /// Eq. (2)). Non-negative; `0` reports heating with zero loss probability. pub loss_coeff: f64, } diff --git a/docs/agents/validation.md b/docs/agents/validation.md index 6ba6c1a6..587aa4fb 100644 --- a/docs/agents/validation.md +++ b/docs/agents/validation.md @@ -23,6 +23,7 @@ Static analysis and refinement-type checks for the Quon workspace. | `just rap-table-i` | #111 local-only convenience: `cargo test --release -p quonc --test rap_table_i -- --include-ignored --nocapture` (the metrics-dump test; the fast structural preflight already runs in `just ci-rust`). **Not invoked by any CI job** — see the `rust` row below. | | `just na-rap-sweep` | #306 local-only: both `--na-placer` modes over every checked-in RAP Table I row (`ising_n42`, `ising_n98`), one qmap-comparable CSV (`python/na_rap_table_i_sweep.py`). Not CI — see `docs/neutral_atom/rap_table_i_methodology.md`'s "Full sweep harness (#306)". | | `just ci-docs-assert` | `./scripts/assert-validation-docs.sh` | +| `just ci-rustdoc` | Workspace Rustdoc with warnings denied (`RUSTDOCFLAGS="-D warnings" cargo doc --workspace --exclude flux_verify --no-deps`); unresolved intra-doc links, private-item references, output collisions, and accidental citation links all fail (#406). Also run as a step in `just ci-rust`. | | `just ci-website` | Starlight `pnpm build` under `website/` | Inside Devbox: `devbox run -- just ` (or `just` after `devbox shell`). @@ -33,7 +34,7 @@ This table is an adapter of the **Justfile** recipes invoked by `.github/workflo | Workflow | Trigger | What runs | | -------- | ------- | --------- | -| [ci.yml](../../.github/workflows/ci.yml) `rust` | every push and PR | `just ci-rust`: fmt, clippy, release build (+ examples for lit oracles), `cargo test --workspace --exclude flux_verify` with `QUON_REQUIRE_LIT` so [`quonc/tests/lit.rs`](../../quonc/tests/lit.rs) hard-fails without lit/FileCheck/oracles, and [`quonc/tests/samples_catalog.rs`](../../quonc/tests/samples_catalog.rs) lints `samples/catalog.yaml` and typechecks every `ci: smoke` entry with the debug `quonc` this same `cargo test` builds (ADR-0025 / #185) — the RAP Table I preflight test (#111) runs here too, while the full `rap_table_i --include-ignored` metrics dump is **local-only** (`just rap-table-i`, not invoked by this or any other CI job): pre-#297 its routing-aware A* peaked ~17.5 GB RSS and OOM'd GitHub's 16 GB hosted runners; #297's heuristic search dropped that to ~64 MB, but the recipe has not been re-wired into CI since (documented follow-up, not done here or in #306) — see `docs/neutral_atom/rap_table_i_methodology.md`'s "Runtime / CI wiring" correction; then Qiskit Aer: `test/verify/{bell,teleport,bernstein_vazirani,routing,grover,qft,ising,qaoa,shor}.py` with `QUONC=target/release/quonc`, then QEC Python smokes (`test_qec_stim_smoke`, `test_quon_qec_sinter`, `test_quon_qec_benchmarks` / #254). | +| [ci.yml](../../.github/workflows/ci.yml) `rust` | every push and PR | `just ci-rust`: fmt, clippy, workspace Rustdoc with warnings denied (`ci-rustdoc`, #406), release build (+ examples for lit oracles), `cargo test --workspace --exclude flux_verify` with `QUON_REQUIRE_LIT` so [`quonc/tests/lit.rs`](../../quonc/tests/lit.rs) hard-fails without lit/FileCheck/oracles, and [`quonc/tests/samples_catalog.rs`](../../quonc/tests/samples_catalog.rs) lints `samples/catalog.yaml` and typechecks every `ci: smoke` entry with the debug `quonc` this same `cargo test` builds (ADR-0025 / #185) — the RAP Table I preflight test (#111) runs here too, while the full `rap_table_i --include-ignored` metrics dump is **local-only** (`just rap-table-i`, not invoked by this or any other CI job): pre-#297 its routing-aware A* peaked ~17.5 GB RSS and OOM'd GitHub's 16 GB hosted runners; #297's heuristic search dropped that to ~64 MB, but the recipe has not been re-wired into CI since (documented follow-up, not done here or in #306) — see `docs/neutral_atom/rap_table_i_methodology.md`'s "Runtime / CI wiring" correction; then Qiskit Aer: `test/verify/{bell,teleport,bernstein_vazirani,routing,grover,qft,ising,qaoa,shor}.py` with `QUONC=target/release/quonc`, then QEC Python smokes (`test_qec_stim_smoke`, `test_quon_qec_sinter`, `test_quon_qec_benchmarks` / #254). | | [ci.yml](../../.github/workflows/ci.yml) `docs` | every push and PR | `just ci-docs-assert` + `just ci-website` | | [ci.yml](../../.github/workflows/ci.yml) `tooling` | every push and PR | `just ci-tooling`: `quonfmt --check`, `quonlint`, `quon_lsp` smoke on CI corpus | | [release.yml](../../.github/workflows/release.yml) | tags `v*` (+ manual dry-run) | `devbox run release` — static MLIR/LLVM + release-built static libz3; link audit; upload `quon-{version}-{arch}-{os}.tar.gz` to GitHub Releases | diff --git a/frontend/src/ast.rs b/frontend/src/ast.rs index 183f0f08..9a86487b 100644 --- a/frontend/src/ast.rs +++ b/frontend/src/ast.rs @@ -139,7 +139,7 @@ impl CliffordClass { // ── Nat expressions ─────────────────────────────────────────────────────────── -/// Type-level natural number expression (appears in QReg, Circuit). +/// Type-level natural number expression (appears in `QReg`, `Circuit`). #[derive(Debug, Clone, PartialEq)] pub enum NatExpr { Lit(u64), diff --git a/frontend/src/refinement.rs b/frontend/src/refinement.rs index b8b0a80b..d3c0ea47 100644 --- a/frontend/src/refinement.rs +++ b/frontend/src/refinement.rs @@ -72,7 +72,7 @@ impl RefinementCtx { } /// Verify that `inferred` equals `annotated` for all assignments — the no-assumption - /// equality used by branch-join reconciliation. A thin wrapper over [`prove_eq`]. + /// equality used by branch-join reconciliation. A thin wrapper over [`Self::prove_eq`]. pub fn verify_equal( &self, inferred: &DepthExpr, @@ -109,7 +109,7 @@ impl RefinementCtx { /// Prove `lhs ≤ rhs` under `assumptions` — the depth-as-upper-bound check (SPEC §3.3): a /// synthesized depth `lhs` satisfies an annotation `rhs` when it is no larger. `Hole` on the - /// annotation side accepts anything; equal/constant fast paths mirror [`prove_eq`]. + /// annotation side accepts anything; equal/constant fast paths mirror [`Self::prove_eq`]. pub fn prove_le( &self, assumptions: &[Assumption], diff --git a/frontend/src/specialized_circuit.rs b/frontend/src/specialized_circuit.rs index 4899616f..571fb381 100644 --- a/frontend/src/specialized_circuit.rs +++ b/frontend/src/specialized_circuit.rs @@ -1,7 +1,7 @@ //! `SpecializedCircuit` — the Melior-free first-order gate DAG between //! `elaborate` and `lower` (issue #206). //! -//! Parametric specialization ([`elaborate`](crate::elaborate)) already produces +//! Parametric specialization ([`crate::elaborate`]) already produces //! a first-order gate tree — `Compose` / `GateApp` / `Adjoint` over concrete //! qubit indices and literal rotation angles — but the interface stayed surface //! `Expr`, and the inverse / placement / `flatten_app` helpers were duplicated @@ -11,9 +11,8 @@ //! - **Interface** ([`SpecializedCircuit`]): the elaborator's output and lower's //! only input — a gate DAG with resolved in/out widths, depth, and Clifford //! class. No classical parameters remain. -//! - **Implementation** ([`SpecializedCircuit::specialize`], -//! [`SpecializedCircuit::adjoint`], [`collect_gate_placements`], -//! [`reverse_and_invert`]): specialization, adjoint/inverse normalization, and +//! [`SpecializedCircuit::adjoint`], `collect_gate_placements`, +//! `reverse_and_invert`): specialization, adjoint/inverse normalization, and //! placement — all Melior-free, all living once here. //! - **Adapter** (in `lower.rs`): Melior builders that consume a //! `SpecializedCircuit` and emit `quantum.circ`. Nothing in this module @@ -206,7 +205,7 @@ impl SpecializedCircuit { /// The adjoint circuit: reverse gate order and invert each gate, swapping /// the in/out widths (`Circuit† : Circuit`). Depth and Clifford /// class are preserved. This is the typed adjoint normalization; the - /// AST-level kernel is [`reverse_and_invert`]. + /// AST-level kernel is `reverse_and_invert`. pub fn adjoint(&self) -> Result { let body = reverse_and_invert(&self.body)?; Ok(Self { diff --git a/frontend/src/typecheck/mod.rs b/frontend/src/typecheck/mod.rs index a3cc6426..4ae2f92e 100644 --- a/frontend/src/typecheck/mod.rs +++ b/frontend/src/typecheck/mod.rs @@ -1,9 +1,9 @@ //! Bidirectional type checker facade — dispatches into one judgment module per form //! (issue #9, SPEC §3.8; epic #207). The **classical Γ** judgment (synth/check, unify -//! coordination, exhaustiveness, patterns) lives in [`classical`]; the **Circuit** -//! judgment lives in [`circuit`] (#323, ADR-0028); first-order unification in [`unify`] -//! (`Table`); exhaustiveness/reachability in [`exhaust`]; the linear context `Δ` in -//! [`linear`]. The quantum monad (`Q<τ>`, `<-` binds, `run { }`), the borrow block, and +//! coordination, exhaustiveness, patterns) lives in `classical`; the **Circuit** +//! judgment lives in `circuit` (#323, ADR-0028); first-order unification in `unify` +//! (`Table`); exhaustiveness/reachability in `exhaust`; the linear context `Δ` in +//! `linear`. The quantum monad (`Q<τ>`, `<-` binds, `run { }`), the borrow block, and //! the Z3 refinement bridge stay here as slices #325 and #326. //! //! Judgment form: @@ -22,11 +22,11 @@ //! //! * **Bidirectional, not full inference.** User functions are fully annotated, so the //! only polymorphism is the classical prelude (`map`, `fold`, `zip`, …). Those are -//! [`Scheme`]s instantiated with fresh metavariables at each use; everything else flows +//! `Scheme`s instantiated with fresh metavariables at each use; everything else flows //! through synthesis and checking. There is no let-generalization. //! * **One unifier.** Application, branch joining, and subsumption all bottom out in -//! [`Table::unify`]. Metavariables are zonked away before a type is returned to a caller. -//! * **Exhaustiveness** is delegated to the [`exhaust`] usefulness algorithm. +//! `Table::unify`. Metavariables are zonked away before a type is returned to a caller. +//! * **Exhaustiveness** is delegated to the `exhaust` usefulness algorithm. pub(crate) mod builtins; pub(crate) mod circuit; @@ -182,7 +182,7 @@ impl TypeChecker { /// Initialize the LSP annotation/resolution sinks (issue #45). When enabled, the /// checker owns the sinks for the duration of `check_decls` and records into them - /// during synthesis; call [`take_sinks`] to extract the accumulated results. + /// during synthesis; call [`Self::take_sinks`] to extract the accumulated results. pub fn enable_sinks(&mut self) { self.annotations = Some(TypeAnnotations::default()); self.resolutions = Some(ResolutionMap::default()); @@ -350,7 +350,7 @@ impl TypeChecker { } } - /// Resolved top-level function type after [`check_decls`] (issue #16 lowering). + /// Resolved top-level function type after [`Self::check_decls`] (issue #16 lowering). pub fn fn_type_of(&self, name: &str) -> Option<&Ty> { self.globals.get(name) } diff --git a/mlir_bridge/src/circ_extract.rs b/mlir_bridge/src/circ_extract.rs index 6a82d48a..89083c18 100644 --- a/mlir_bridge/src/circ_extract.rs +++ b/mlir_bridge/src/circ_extract.rs @@ -16,7 +16,7 @@ //! //! ## Wire tracking //! -//! Logical qubit indices are recovered from SSA values via [`WireTracker`], +//! Logical qubit indices are recovered from SSA values via `WireTracker`, //! not from operand positions. This makes multi-qubit extraction faithful: //! after a `CNOT` on wires `[0, 1]`, a subsequent gate on wire `1` correctly //! records `qubits: [1]`, whereas the old operand-position encoding always @@ -158,7 +158,7 @@ fn read_bool_attr<'c: 'a, 'a, O: OperationLike<'c, 'a>>(operation: &O, key: &str /// Faithfully extracts a `quantum.circ.func` body into a Melior-free [`CircIr`]. /// /// Walks the func's single block in order, tracking logical wire indices through -/// SSA values via [`WireTracker`]. Each `quantum.circ.gate` op becomes a +/// SSA values via `WireTracker`. Each `quantum.circ.gate` op becomes a /// [`CircGate`] whose `name` is the **canonical registry id** (looked up /// through `quon_core::gates`), whose `qubits` are the faithful logical wire /// indices, and whose `angle`/`depth_contribution`/`clifford` are preserved @@ -336,7 +336,7 @@ pub fn rebuild<'c, 'a>( // --- ZX kernel interop ----------------------------------------------------- -/// Converts a [`CircGate`] to the `zx` crate's [`GateRef`] for ZX translation. +/// Converts a [`CircGate`] to the `zx` crate's [`zx::GateRef`] for ZX translation. /// /// Drops `depth_contribution`/`clifford` (the ZX kernel does not use them). /// Used by the ZX simplification pass to feed the shared seam's [`CircIr`] @@ -349,7 +349,7 @@ pub fn circ_gate_to_gate_ref(gate: &CircGate) -> zx::GateRef { } } -/// Converts a `zx` crate [`GateRef`] back to a [`CircGate`] for rebuilding. +/// Converts a `zx` crate [`zx::GateRef`] back to a [`CircGate`] for rebuilding. /// /// Looks up the registry for the Clifford classification and defaults /// `depth_contribution` to 1 (one gate per step). Used by the ZX diff --git a/mlir_bridge/src/dialect/quantum_circ.rs b/mlir_bridge/src/dialect/quantum_circ.rs index 926d35f0..a730e4e1 100644 --- a/mlir_bridge/src/dialect/quantum_circ.rs +++ b/mlir_bridge/src/dialect/quantum_circ.rs @@ -93,7 +93,7 @@ pub mod attr { pub const IN_QUBITS: &str = "in_qubits"; /// Number of output qubits (`I64Attr`). pub const OUT_QUBITS: &str = "out_qubits"; - /// Symbolic depth bound, a [`DepthExpr`] S-expression (`DepthExprAttr`). + /// Symbolic depth bound, a [`quon_core::DepthExpr`] S-expression (`DepthExprAttr`). pub const DEPTH: &str = "depth"; /// Clifford classification (`BoolAttr`). pub const CLIFFORD: &str = "clifford"; diff --git a/mlir_bridge/src/dynamic_walk.rs b/mlir_bridge/src/dynamic_walk.rs index e3365a09..34ad75d9 100644 --- a/mlir_bridge/src/dynamic_walk.rs +++ b/mlir_bridge/src/dynamic_walk.rs @@ -6,7 +6,7 @@ //! with its own copy of the qubit-wire-identity tracker needed to keep a //! logical qubit's identity continuous across those region boundaries. This //! module is the one walk: it owns the recursion and the -//! [`WireTracker`](crate::passes::qubit_wiring::WireTracker) threading, and +//! `WireTracker` threading, and //! calls back into a [`DynamicVisitor`] for every structural element (gate, //! barrier, measure, reset, unitary_region enter/exit, if-arm enter/exit). //! Consumers implement aggregation, not recursion. @@ -49,7 +49,7 @@ impl IfArm { /// Callbacks for one recursive descent over a `quantum.dynamic` block. /// /// Every method defaults to a no-op, so a visitor implements only the events -/// it needs. `qubit_roots` are [`WireTracker`] root ids: stable identifiers +/// it needs. `qubit_roots` are `WireTracker` root ids: stable identifiers /// for a logical qubit's wire that survive `unitary_region`/`if` boundaries /// (a region's block argument aliases the enclosing op's operand root), not /// raw SSA pointer identity. @@ -128,7 +128,7 @@ fn read_i32_attr<'c: 'a, 'a, O: OperationLike<'c, 'a>>(operation: &O, key: &str) /// Resolves the qubit identity for a gate's operands from the **canonical SSA /// wiring channel** (ADR-0034). /// -/// `qubit_roots` are [`WireTracker`] root ids: stable identifiers for a logical +/// `qubit_roots` are `WireTracker` root ids: stable identifiers for a logical /// qubit's wire that survive `unitary_region`/`if` boundaries (a region's block /// argument aliases the enclosing op's operand root). When roots are available /// — the normal case after SABRE routing, threaded across region boundaries by @@ -155,7 +155,7 @@ pub fn resolve_phys_qubits<'c: 'a, 'a, O: OperationLike<'c, 'a>>( .unwrap_or_default() } -/// Walks `block`, seeding a fresh [`WireTracker`] from its own block +/// Walks `block`, seeding a fresh `WireTracker` from its own block /// arguments. Use this for a module's top-level executed body, or a /// standalone `quantum.circ.func`/module body — each is an independent qubit /// register and gets its own tracker. diff --git a/mlir_bridge/src/passes/dynamic_linearity_verifier.rs b/mlir_bridge/src/passes/dynamic_linearity_verifier.rs index 329f715e..cfb6971f 100644 --- a/mlir_bridge/src/passes/dynamic_linearity_verifier.rs +++ b/mlir_bridge/src/passes/dynamic_linearity_verifier.rs @@ -5,7 +5,7 @@ //! another op is reported as reuse-after-measure when applicable. //! //! `unitary_region` inner blocks reuse the circ linearity rules via -//! [`super::linearity_verifier::check_region_linearity`]; inner ops are not +//! `check_region_linearity`; inner ops are not //! folded into the outer dynamic scope. //! //! Note: this pass does not forbid stray `quantum.circ` ops appearing directly diff --git a/quon_core/src/depth.rs b/quon_core/src/depth.rs index 5cc61565..f2cea281 100644 --- a/quon_core/src/depth.rs +++ b/quon_core/src/depth.rs @@ -366,7 +366,7 @@ impl fmt::Display for DepthExpr { } /// Total ordering of [`DepthExpr`] that mirrors lexicographic comparison of -/// the canonical S-expression string, without allocating. Used by [`norm_ac`] +/// the canonical S-expression string, without allocating. Used by `norm_ac` /// to sort operands with `sort()` instead of `sort_by_key(to_sexpr)`. impl Ord for DepthExpr { fn cmp(&self, other: &Self) -> Ordering { diff --git a/quon_core/src/qasm.rs b/quon_core/src/qasm.rs index 9ea7accc..788ecba1 100644 --- a/quon_core/src/qasm.rs +++ b/quon_core/src/qasm.rs @@ -219,7 +219,7 @@ impl TwoQubitGate { /// intentionally unrefined (Flux's f64 support is weak). /// /// Prefer [`from_gate_info`] for compiler emission: it builds the registry-backed -/// [`QasmGate::Std1`] / [`Std2`] / [`Std3`](QasmGate::Std3) forms so a new OpenQASM +/// [`QasmGate::Std1`] / [`Std2`](QasmGate::Std2) / [`Std3`](QasmGate::Std3) forms so a new OpenQASM /// spelling in [`crate::gates::REGISTRY`] emits without a second keyword match. /// The typed [`One`](QasmGate::One) / [`Two`](QasmGate::Two) / [`Rotation`](QasmGate::Rotation) /// variants remain for hand-built test programs. diff --git a/quon_na/src/compaction.rs b/quon_na/src/compaction.rs index 26e15657..1230f8f4 100644 --- a/quon_na/src/compaction.rs +++ b/quon_na/src/compaction.rs @@ -10,10 +10,10 @@ //! //! Independent layers are serialized (makespan can exceed the critical-path //! lower bound). **True ASAP** (independent work may share a cycle) is what -//! [Enola] Sec. 3 stage-optimality refers to; that notion is **not** the v0 +//! \[Enola\] Sec. 3 stage-optimality refers to; that notion is **not** the v0 //! baseline API. //! -//! Cite [Enola] Sec. 3 only for: (1) critical-path **lower bound** reporting +//! Cite \[Enola\] Sec. 3 only for: (1) critical-path **lower bound** reporting //! (`CriticalPathReport.critical_path_length`), (2) describing true ASAP, and //! (3) the optional note that on **dependency chains** exclusive-cycle and //! true ASAP coincide numerically. Do **not** claim that exclusive-cycle ASAP diff --git a/quon_na/src/entangling_schedule.rs b/quon_na/src/entangling_schedule.rs index c0a2f5f6..2052f7b4 100644 --- a/quon_na/src/entangling_schedule.rs +++ b/quon_na/src/entangling_schedule.rs @@ -17,7 +17,7 @@ //! left unchanged; atom identity is `AtomId(vertex.index())` (same as //! placement #104). //! -//! References: [Enola] Sec. 3 / Theorem 1; Misra & Gries, "A constructive proof +//! References: \[Enola\] Sec. 3 / Theorem 1; Misra & Gries, "A constructive proof //! of Vizing's theorem", IPL 1992. use std::collections::{BTreeMap, BTreeSet}; diff --git a/quon_na/src/geometry.rs b/quon_na/src/geometry.rs index 1457d2d7..d1e20ecf 100644 --- a/quon_na/src/geometry.rs +++ b/quon_na/src/geometry.rs @@ -41,7 +41,7 @@ pub fn movement_duration_us(d_max_um: f64, acceleration_m_s2: f64) -> u64 { #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] #[serde(rename_all = "snake_case")] pub enum SpeedModelKind { - /// √-law `t = √(d/a)` (default; the [RAP] Table I timing model). + /// √-law `t = √(d/a)` (default; the \[RAP\] Table I timing model). #[default] Sqrt, /// Jerk-limited symmetric S-curve (issue #308); see [`movement_duration_us_jerk`]. @@ -117,7 +117,7 @@ impl From<&BackendSpeedModel> for SpeedModel { /// **Provenance:** standard symmetric S-curve derivation. The jerk and /// cruise-velocity values are target-specific placeholders — calibrating to /// the QMAP eval scripts' jerk-limited model (which coincides with the √-law -/// only at d = 110 µm; see `docs/neutral_atom/literature_notes.md`'s [RAP] +/// only at d = 110 µm; see `docs/neutral_atom/literature_notes.md`'s \[RAP\] /// caveats) is out of scope for #308; the default model stays [`SpeedModelKind::Sqrt`]. pub fn movement_duration_us_jerk( d_max_um: f64, @@ -189,7 +189,7 @@ pub fn movement_duration_for_model(d_max_um: f64, model: &SpeedModel) -> u64 { } } -/// `√(d_max / a)` duration contribution for one movement group ([RAP] Eq. (1)). +/// `√(d_max / a)` duration contribution for one movement group (\[RAP\] Eq. (1)). /// /// `d_max_um` is micrometres; `acceleration_m_s2` is m/s². Returns seconds×1e6 /// scaled consistently as a dimensionless `√(µm)` proxy when `a` is fixed — we @@ -204,7 +204,7 @@ pub fn sqrt_d_max(d_max_um: f64) -> f64 { } } -/// Sum of `√(d_max)` over groups — [RAP] Eq. (1) (up to `1/√a`). +/// Sum of `√(d_max)` over groups — \[RAP\] Eq. (1) (up to `1/√a`). pub fn routing_cost_eq1(group_d_max_um: &[f64]) -> f64 { group_d_max_um.iter().map(|&d| sqrt_d_max(d)).sum() } diff --git a/quon_na/src/graph.rs b/quon_na/src/graph.rs index 564a4a2f..a9d146c6 100644 --- a/quon_na/src/graph.rs +++ b/quon_na/src/graph.rs @@ -7,9 +7,9 @@ //! the hybrid QEC schedule feeds atom identities without a //! `LogicalQubitId(atom.0)` numeric cast. Edges are undirected pairwise //! interactions weighted with Atomique's layer-decayed gate-frequency formula -//! `Σ γ^l` ([Atomique] Sec. III-A; default [`DEFAULT_GAMMA`] = 0.8). Segments +//! `Σ γ^l` (\[Atomique\] Sec. III-A; default [`DEFAULT_GAMMA`] = 0.8). Segments //! preserve Enola's distinction between commutation groups and ordered -//! dependency DAGs ([Enola] Sec. 3) so later Misra–Gries edge-coloring (#105) +//! dependency DAGs (\[Enola\] Sec. 3) so later Misra–Gries edge-coloring (#105) //! can apply the right bound. //! //! See `docs/neutral_atom/architecture_model.md` §4 and @@ -235,7 +235,7 @@ impl<'de, V: VertexId> Deserialize<'de> for InteractionGraph { } } -/// Default Atomique layer-decay base ([Atomique] Sec. III-A). +/// Default Atomique layer-decay base (\[Atomique\] Sec. III-A). pub const DEFAULT_GAMMA: f64 = 0.8; /// Structural problems with an [`InteractionGraph`]. diff --git a/quon_na/src/lib.rs b/quon_na/src/lib.rs index d36fcd55..70b23809 100644 --- a/quon_na/src/lib.rs +++ b/quon_na/src/lib.rs @@ -5,12 +5,12 @@ //! code-block expansion, and resource reports without registering dialects or //! requiring an MLIR context. //! -//! Interaction-graph extraction (#103) follows [Enola] (interaction graph / -//! dependency segments) and [Atomique] (layer-decayed `γ^l` edge weights); see +//! Interaction-graph extraction (#103) follows \[Enola\] (interaction graph / +//! dependency segments) and \[Atomique\] (layer-decayed `γ^l` edge weights); see //! `docs/neutral_atom/architecture_model.md` §4. //! //! Placement (#104) maps logical qubits onto SLM sites with row-major, -//! degree-based, and interaction-clustering heuristics inspired by [Atomique] +//! degree-based, and interaction-clustering heuristics inspired by \[Atomique\] //! Sec. III-B; see `docs/neutral_atom/architecture_model.md` §4. //! //! Entangling-layer scheduling (#105) uses Misra–Gries edge coloring on @@ -22,7 +22,7 @@ //! packing (not Enola one-atom duals; not RAP zoned routing). See //! `docs/neutral_atom/architecture_model.md` §5–§6 and [`movement`]. //! -//! Zoned routing-aware placement (#107) follows [RAP] (placement cost = routing +//! Zoned routing-aware placement (#107) follows \[RAP\] (placement cost = routing //! cost, Eqs. (1)–(2)); see `docs/neutral_atom/architecture_model.md` §7. //! //! Schedule compaction (#108) is engineering glue: exclusive-cycle ASAP baseline diff --git a/quon_na/src/matching.rs b/quon_na/src/matching.rs index 65baa53a..e42ec2a0 100644 --- a/quon_na/src/matching.rs +++ b/quon_na/src/matching.rs @@ -21,7 +21,7 @@ //! # Forbidden entries //! //! Occupancy-illegal and repair-forbidden `(gate, pair)` edges are encoded as -//! [`FORBIDDEN_COST`]: a *finite* sentinel larger than any real travel distance +//! `FORBIDDEN_COST`: a *finite* sentinel larger than any real travel distance //! (µm sums are at most a few thousand on the anchored fixtures, so `1e15` //! leaves ~12 orders of headroom). Finiteness is load-bearing — `f64::INFINITY` //! would make the potential updates `∞ − ∞ = NaN` and corrupt the assignment. diff --git a/quon_na/src/movement/mod.rs b/quon_na/src/movement/mod.rs index 47233b57..5bd12258 100644 --- a/quon_na/src/movement/mod.rs +++ b/quon_na/src/movement/mod.rs @@ -8,14 +8,14 @@ //! - B7 second packing pass that serializes dual legs, //! - B8/B13 multi-layer reuse / eviction / partial-overlap reclaim. //! -//! [Enola] Sec. 5 is cited **only** for: (1) three per-axis move conflict types +//! \[Enola\] Sec. 5 is cited **only** for: (1) three per-axis move conflict types //! and (2) the greedy longest-first maximal independent-set *idea* (sortIS //! spirit — not KaMIS). Enola Sec. 5 duals are one-atom "move either endpoint" //! candidates; **this planner does not implement those duals**. //! //! # Not in scope //! -//! - RAP zoned joint placement-routing ([RAP] / issue #107) — use +//! - RAP zoned joint placement-routing (\[RAP\] / issue #107) — use //! [`crate::zoned::schedule_zoned`] instead. //! - Atomique's flat 300 µs stage cost — duration uses shared √-law helpers //! [`crate::geometry::movement_duration_us`] / [`crate::geometry::euclidean_um`]. @@ -48,12 +48,12 @@ //! //! | Submodule | Responsibility | //! | --- | --- | -//! | [`types`] | Params, results, errors, leg/pair/spec payloads | -//! | [`geometry`] | R1–R3 predicates, AOD legality, conflict oracle | -//! | [`bank`] | Interaction-pair bank creation / detection | -//! | [`duals`] | Dual generation, sortIS selection, greedy packing | -//! | [`emit`] | EmitCtx: load→move→store stages, reclaim/evict, layer helpers | -//! | [`plan`] | `plan_aod_movement` orchestrator | +//! | `types` | Params, results, errors, leg/pair/spec payloads | +//! | `geometry` | R1–R3 predicates, AOD legality, conflict oracle | +//! | `bank` | Interaction-pair bank creation / detection | +//! | `duals` | Dual generation, sortIS selection, greedy packing | +//! | `emit` | EmitCtx: load→move→store stages, reclaim/evict, layer helpers | +//! | `plan` | `plan_aod_movement` orchestrator | mod bank; mod duals; diff --git a/quon_na/src/pipeline.rs b/quon_na/src/pipeline.rs index 94fe3783..e97b777d 100644 --- a/quon_na/src/pipeline.rs +++ b/quon_na/src/pipeline.rs @@ -418,7 +418,7 @@ pub fn run_from_graph( /// and splices the results into the entangling-scheduled layers at the /// gate's extraction-time anchor, before zoned/flat-AOD placement (neither /// backend's movement planning needs `LocalGate`/`GlobalRy` site info — see -/// [`interleave_local_gates`]). +/// `interleave_local_gates`). #[cfg(feature = "mlir")] pub fn run_from_graph_with_local_gates( graph: InteractionGraph, @@ -775,7 +775,7 @@ fn finish_pipeline( // production report from this pipeline. let report = report.with_fidelity_estimate(&req.layers, &na.fidelity); // Analytic per-atom movement-heating / atom-loss budget (issue #310, - // [Atomique] Eqs. (1)–(2)). Optional like `error_model`: attached only + // \[Atomique\] Eqs. (1)–(2)). Optional like `error_model`: attached only // when the target carries `atom_loss_model`, else the section is omitted. // Distance is measured against the zoned schedule's layout (the real // √-law travel); `req.layout` is `None` only for non-zoned hand-built diff --git a/quon_na/src/placement.rs b/quon_na/src/placement.rs index 2433ca82..cf635a21 100644 --- a/quon_na/src/placement.rs +++ b/quon_na/src/placement.rs @@ -6,7 +6,7 @@ //! [`crate::layout::AtomSite`]s and fill //! [`crate::schedule_entry::GraphScheduleRequest::layout`]. //! -//! Strategies are **inspired by** [Atomique] Sec. III-B (load-balance / spiral +//! Strategies are **inspired by** \[Atomique\] Sec. III-B (load-balance / spiral //! fill; MAX-k-Cut array mapper Alg. 1), adapted to a single flat grid — not //! reproductions. Enola's simulated-annealing placer is out of scope. //! @@ -39,7 +39,7 @@ pub enum PlacementStrategy { /// (Atomique MAX-k-Cut–inspired, adapted to spatial proximity). InteractionClustering, /// SMT-optimal placement via z3 (issue #302, Deliverable B). Requires the - /// `solver` feature; the exact encoding lives in [`crate::exact::placement`]. + /// `solver` feature; the exact encoding lives in `crate::exact::placement`. /// Falls back to [`PlacementStrategy::InteractionClustering`] with a logged /// optimality gap when the `solver` feature is off or z3 times out. Exact, diff --git a/quon_na/src/plan.rs b/quon_na/src/plan.rs index 9fa25edd..1d5f7d69 100644 --- a/quon_na/src/plan.rs +++ b/quon_na/src/plan.rs @@ -71,7 +71,7 @@ pub struct BackendStageInfo { /// /// **Shared entry point** for the bare-qubit pipeline /// ([`crate::pipeline::run_from_graph`] → `finish_pipeline`) and the hybrid -/// QEC per-round planner ([`crate::qec_schedule::schedule_cnot_phase`]) +/// QEC per-round planner (`crate::qec_schedule::schedule_cnot_phase`) /// — issue #317. Both paths call this function for the place/AOD/zoned step; /// the hybrid round-loop orchestration (per-round expansion, Wait barriers, /// serial Z-then-X, shared layout) stays in `qec_schedule` (ADR-0016). diff --git a/quon_na/src/qec_schedule.rs b/quon_na/src/qec_schedule.rs index d8b196d8..96ce7233 100644 --- a/quon_na/src/qec_schedule.rs +++ b/quon_na/src/qec_schedule.rs @@ -237,7 +237,7 @@ fn schedule_expanded( // mandatory, so this always applies once a target is available. let report = report.with_fidelity_estimate(&req.layers, &na.fidelity); // Analytic per-atom movement-heating / atom-loss budget (issue #310, - // [Atomique] Eqs. (1)–(2)). Optional like `error_model`: attached only + // \[Atomique\] Eqs. (1)–(2)). Optional like `error_model`: attached only // when the target carries `atom_loss_model`; distance measured against // the zoned schedule's layout (real √-law travel), else zeroed/omitted. let report = match na.atom_loss_model.as_ref() { diff --git a/quon_na/src/report.rs b/quon_na/src/report.rs index 1266d05d..19a5ea37 100644 --- a/quon_na/src/report.rs +++ b/quon_na/src/report.rs @@ -404,7 +404,7 @@ pub struct ResourceReport { pub gate_fidelity_product: Option, /// `gate_fidelity_product` times per-atom idle decay: /// `∏_atoms max(0, 1 - t_idle(atom) / fidelity.coherence_time_us)` — - /// architecture_model.md §9/§11's **linear** approximation of [Enola] + /// architecture_model.md §9/§11's **linear** approximation of \[Enola\] /// Eq. (1)'s decoherence factor (not `exp(-t_idle/T)`). `t_idle(atom)` /// is `total_time_us` minus the sum of layer max-durations /// (`simultaneous_layer_time`) over layers in which the atom appears in @@ -427,9 +427,9 @@ pub struct ResourceReport { // `build_resource_report` without that overlay leave it `None`. // // **Analytic, not Monte Carlo** (ADR-0020): a per-atom `heating → loss` - // closed form ([Atomique] Eqs. (1)–(2)), kept visibly separate from the + // closed form (\[Atomique\] Eqs. (1)–(2)), kept visibly separate from the // `error_budget` rate×count sum and the `estimated_fidelity` product. - /// Analytic per-atom movement-heating / atom-loss budget ([Atomique] + /// Analytic per-atom movement-heating / atom-loss budget (\[Atomique\] /// Eqs. (1)–(2)). `None` when the target carries no loss model or the /// overlay was not applied. #[serde(default, skip_serializing_if = "Option::is_none")] @@ -533,31 +533,31 @@ impl ErrorBudgetContributions { } /// Analytic per-atom movement-heating / atom-loss budget (issue #310, -/// [Atomique] Wang et al. ISCA 2024 Eqs. (1)–(2)). Evidence-kind: analytic +/// \[Atomique\] Wang et al. ISCA 2024 Eqs. (1)–(2)). Evidence-kind: analytic /// (ADR-0020) — not Monte Carlo loss simulation and not a threshold claim. /// /// # Model /// /// Per-atom heating accumulates over every `Move` action across all layers: -/// `H_a = heating_rate_per_um × cumulative_movement_um_a` ([Atomique] Eq. (1), +/// `H_a = heating_rate_per_um × cumulative_movement_um_a` (\[Atomique\] Eq. (1), /// distance-only term). Per-atom loss probability follows: -/// `p_a = 1 − exp(−loss_coeff × H_a)` ([Atomique] Eq. (2)). Aggregate +/// `p_a = 1 − exp(−loss_coeff × H_a)` (\[Atomique\] Eq. (2)). Aggregate /// [`expected_atoms_lost`](Self::expected_atoms_lost) `= Σ_a p_a` (a /// fractional expected count, not a survival probability). /// /// `cumulative_movement_um_a` is the Euclidean distance between each move's /// `from`/`to` site positions in the schedule's [`NeutralAtomLayout`], /// summed across layers — the actual travel Quon's √-law movement planner -/// emits, **not** [Atomique]'s fixed 300 µs-per-stage timing (see below). +/// emits, **not** \[Atomique\]'s fixed 300 µs-per-stage timing (see below). /// -/// # Documented divergence from [Atomique] (architecture_model.md §5) +/// # Documented divergence from \[Atomique\] (architecture_model.md §5) /// -/// [Atomique] charges a *fixed* 300 µs per movement stage regardless of +/// \[Atomique\] charges a *fixed* 300 µs per movement stage regardless of /// distance (its Table I) and lets distance enter only its heating model. /// This budget does **not** import that fixed stage timing: movement here is /// the real per-atom travel distance through Quon's `√(d/a)` movement /// schedule (`rearrangement_time_us` in the parent report), never 300 µs. -/// Heating scales with distance (µm), not with [Atomique]'s stage count. +/// Heating scales with distance (µm), not with \[Atomique\]'s stage count. /// /// # Omission /// @@ -1021,12 +1021,12 @@ impl ResourceReport { } /// Overlay the analytic per-atom movement-heating / atom-loss budget - /// (issue #310, [Atomique] Eqs. (1)–(2)). + /// (issue #310, \[Atomique\] Eqs. (1)–(2)). /// /// `layers` must be the same compiled schedule this report's counts came /// from (`from_layers`); per-atom cumulative travel is re-scanned from the /// `Move` actions and measured against `layout`'s site positions (the - /// actual √-law travel, never [Atomique]'s fixed 300 µs stage timing — see + /// actual √-law travel, never \[Atomique\]'s fixed 300 µs stage timing — see /// [`AtomLossBudget`]'s divergence note). `layout: None` (non-zoned / /// hand-built schedules with no site map) yields an empty budget: all /// per-atom distances are zero / unmeasurable, so `expected_atoms_lost` diff --git a/quon_na/src/stats.rs b/quon_na/src/stats.rs index cb456fdd..e9db96d0 100644 --- a/quon_na/src/stats.rs +++ b/quon_na/src/stats.rs @@ -132,15 +132,15 @@ pub struct SearchDiagnostics { /// fraction of budget without hardcoding the constant. #[serde(default, skip_serializing_if = "Option::is_none")] pub aware_search_node_budget: Option, - /// δ used ([`crate::zoned::AwareSearchParams::deepening_factor`], [RAP] + /// δ used ([`crate::zoned::AwareSearchParams::deepening_factor`], \[RAP\] /// Eq. (4)) — issue #297. #[serde(default, skip_serializing_if = "Option::is_none")] pub aware_search_deepening_factor: Option, - /// β used ([`crate::zoned::AwareSearchParams::deepening_value`], [RAP] + /// β used ([`crate::zoned::AwareSearchParams::deepening_value`], \[RAP\] /// Eq. (4)) — issue #297. #[serde(default, skip_serializing_if = "Option::is_none")] pub aware_search_deepening_value: Option, - /// [RAP] Sec. V-D pruning window used + /// \[RAP\] Sec. V-D pruning window used /// ([`crate::zoned::AwareSearchParams::pruning_window`]) — issue #297. #[serde(default, skip_serializing_if = "Option::is_none")] pub aware_search_pruning_window: Option, diff --git a/quon_na/src/zoned.rs b/quon_na/src/zoned.rs index 6a874fd4..a8bf1de6 100644 --- a/quon_na/src/zoned.rs +++ b/quon_na/src/zoned.rs @@ -1,14 +1,14 @@ //! Zoned routing-aware placement (issue #107, heuristic search #297). //! //! Reproduces the **placement cost = routing cost** formulation of -//! [RAP] (Stade, Lin, Cong, Wille, ICCAD 2025, arXiv:2505.22715): +//! \[RAP\] (Stade, Lin, Cong, Wille, ICCAD 2025, arXiv:2505.22715): //! //! - Sec. III-B — routing-aware definition (layer-by-layer; cost is routing) //! - Sec. III-A — reuse analysis (“don’t move atoms already in place”) //! - Sec. IV-A — cost Eq. (1): `cost(p) = Σ_G √(d_max(G))` over greedily //! grouped compatible movements ([`routing_cost_eq1`]) //! - Sec. IV-B — search extends by assigning one gate’s atoms to entanglement -//! pairs (A*-style / best-first): [`assign_aware_legal`] +//! pairs (A*-style / best-first): `assign_aware_legal` //! - Sec. IV-C / V-C, Eqs. (3)-(5) — the guiding heuristic //! ([`AwareSearchParams`], `heuristic_estimate`): an admissible-lower-bound //! term (Eq. 3: worst-case nearest-available distance among unplaced gates @@ -40,9 +40,9 @@ //! hook to look ahead to) — documented scope reduction, not an oversight. //! - Sec. V-A — binary-search-tree movement-group compatibility check: this //! module uses the same per-axis order/coupling test -//! ([`positions_aod_compatible`]) both post-search (`partition_aod_compatible`) +//! (`positions_aod_compatible`) both post-search (`partition_aod_compatible`) //! and, as of #297, *during* the search itself (search-time `groups` on -//! [`AwareNode`]) so a node's cost matches what routing will actually emit. +//! `AwareNode`) so a node's cost matches what routing will actually emit. //! Linear-scan compatibility checking (not a literal BST) — legal at this //! crate's layer sizes (≤ tens of gates), a documented simplification of //! the paper's data structure, not of its legality semantics. @@ -72,12 +72,12 @@ //! from the paper's (unspecified) search-loop mechanics, not from its //! legality semantics. //! -//! Readout-zone measurement constraints come from [AbstractModel] -//! (arXiv:2405.08068) Sec. III-A, **not** from [RAP] (which models only +//! Readout-zone measurement constraints come from \[AbstractModel\] +//! (arXiv:2405.08068) Sec. III-A, **not** from \[RAP\] (which models only //! storage + entanglement). Flat AOD movement (#106) is a distinct Enola / //! OLSQ-DPQA line — do not cite this module as that planner. //! -//! Dual modes ([RAP] Sec. VI-B comparison methodology): +//! Dual modes (\[RAP\] Sec. VI-B comparison methodology): //! - [`PlacerMode::RoutingAgnostic`] — ZAC-style distance-minimizing placement //! - [`PlacerMode::RoutingAware`] — heuristic-guided search minimizing Eq. (1) //! routing cost. With the Eq. (3)-(5) heuristic (#297), this is true A* @@ -108,7 +108,7 @@ use backend::NeutralAtomErrorModel; #[cfg(feature = "flux")] use flux_rs::attrs::*; -/// Zone capability taxonomy ([AbstractModel] Sec. III-A; [RAP] Sec. II-A). +/// Zone capability taxonomy (\[AbstractModel\] Sec. III-A; \[RAP\] Sec. II-A). /// /// Owned by `backend` (issue #212): one `ZoneKind` for the workspace, /// re-exported here so the zoned placer's public API is unchanged. @@ -275,7 +275,7 @@ impl PlacementCostModel { } /// Cost of one AOD-compatible movement group — the unit the routing - /// cost sums over ([RAP] Eq. (1) for `Time`; error-budget per group for + /// cost sums over (\[RAP\] Eq. (1) for `Time`; error-budget per group for /// `ErrorBudget`). Used by the aware search's `groups_cost`. fn group_cost(&self, group: &SearchGroup) -> f64 { match self { @@ -307,7 +307,7 @@ impl PlacementCostModel { /// (upper bound — AOD-compatible moves share a group), 2 transfers per /// non-reuse move (SLM→AOD + AOD→SLM), idle exposure for the move duration /// (`movement_duration_for_model`), one rydberg stage per gate's -/// entanglement. The [`pick_agnostic_assignment`] dispatch compares full +/// entanglement. The pick_agnostic_assignment dispatch compares full /// assignments on the actual group-level cost (not this per-gate /// approximation) to correct the step overcount. fn error_budget_gate_cost( @@ -330,7 +330,7 @@ fn error_budget_gate_cost( + model.rydberg } -/// Placer mode ([RAP] Sec. VI-B agnostic-vs-aware pairs). +/// Placer mode (\[RAP\] Sec. VI-B agnostic-vs-aware pairs). #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum PlacerMode { @@ -339,9 +339,9 @@ pub enum PlacerMode { /// RAP: minimize Eq. (1) routing cost of the transition. RoutingAware, /// SMT-optimal placement (issue #302, Deliverable B). On the **flat - /// AOD** path this dispatches to [`PlacementStrategy::Exact`], which + /// AOD** path this dispatches to [`crate::placement::PlacementStrategy::Exact`], which /// solves the atom→site assignment with z3 (or brute-force for n ≤ 8) - /// and falls back to [`PlacementStrategy::InteractionClustering`] with + /// and falls back to [`crate::placement::PlacementStrategy::InteractionClustering`] with /// a logged optimality gap on timeout or when the `solver` feature is /// off. On the **zoned** path exact initial storage placement is not /// yet implemented, so this runs the routing-agnostic per-layer @@ -353,22 +353,22 @@ pub enum PlacerMode { /// Which routing-agnostic placement mechanism ran for a layer (issue #300). /// /// The agnostic path now has two mechanisms: the new min-weight bipartite -/// matching placer ([`assign_matching_legal`], the Lin et al. 2025 +/// matching placer (assign_matching_legal, the Lin et al. 2025 /// `VertexMatchingPlacer` parity target) and the original greedy nearest-legal -/// placer ([`assign_greedy_legal`]), kept as a fast fallback for very large +/// placer (assign_greedy_legal), kept as a fast fallback for very large /// layers and for when matching's conflict-repair cannot find a spacing-legal /// assignment. This enum records which one produced a given schedule so a /// `routing-agnostic` compile is never silently one or the other. #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum AgnosticPlacerMechanism { - /// [`assign_matching_legal`] produced the layer's assignment (min-weight + /// assign_matching_legal produced the layer's assignment (min-weight /// bipartite matching, the #300 default for normal-size layers). Matching, - /// [`assign_greedy_legal`] produced the layer's assignment — either because + /// assign_greedy_legal produced the layer's assignment — either because /// the layer exceeded the [`MATCHING_FALLBACK_GATE_PAIR_PRODUCT`] threshold /// (very large, where the O(n²·m) matching is skipped for speed) or because - /// the dispatch's group-count comparison ([`pick_agnostic_assignment`]) + /// the dispatch's group-count comparison (pick_agnostic_assignment) /// kept greedy: matching's min-travel optimum can pack gates into *more* /// AOD movement stages than the spread-out greedy choice, so greedy is kept /// whenever it yields ≤ matching's rearrangement-step count. In both cases @@ -393,44 +393,44 @@ impl AgnosticPlacerMechanism { pub struct ZonedScheduleResult { pub request: GraphScheduleRequest, pub mode: PlacerMode, - /// Σ_G √(d_max(G)) over emitted movement groups ([RAP] Eq. (1)). + /// Σ_G √(d_max(G)) over emitted movement groups (\[RAP\] Eq. (1)). pub routing_cost: f64, pub rearrangement_steps: u64, pub trap_transfers: u64, - /// Number of per-layer gate-assignment calls where [`assign_aware_legal`] + /// Number of per-layer gate-assignment calls where assign_aware_legal /// found a full legal assignment within budget. As of #297 this is a /// heuristic-guided A* with an intentionally inadmissible accelerating /// term (Eqs. (3)-(4)), so `Completed` means "the search's best find", - /// not a proven joint optimum for the layer (matching [RAP]'s own + /// not a proven joint optimum for the layer (matching \[RAP\]'s own /// framing — see the module doc). Always `0` under /// [`PlacerMode::RoutingAgnostic`] (the concept doesn't apply). pub aware_search_completed_layers: u64, /// Per-layer calls where the aware search exhausted the expansion budget /// before finding a full assignment and fell back to - /// [`assign_greedy_legal`] (issue #111 review finding: this makes a + /// assign_greedy_legal (issue #111 review finding: this makes a /// budget-exhaustion fallback — which can silently reproduce the greedy /// schedule byte-for-byte — visible instead of indistinguishable from "no /// routing contention"). Always `0` under [`PlacerMode::RoutingAgnostic`]. pub aware_search_budget_exceeded_layers: u64, /// Per-layer calls where the aware search exhausted its entire search /// space (no legal full assignment exists, e.g. spacing/occupancy - /// conflicts) and fell back to [`assign_greedy_legal`]. Always `0` under + /// conflicts) and fell back to assign_greedy_legal. Always `0` under /// [`PlacerMode::RoutingAgnostic`]. pub aware_search_no_legal_assignment_layers: u64, /// Sum of best-first search node expansions across every - /// [`assign_aware_legal`] call this schedule made (issue #307: exposes + /// assign_aware_legal call this schedule made (issue #307: exposes /// search cost, not just its pass/fail outcome). Always `0` under /// [`PlacerMode::RoutingAgnostic`]. pub aware_search_node_expansions: u64, - /// Per-layer routing-agnostic calls where [`assign_matching_legal`] (the + /// Per-layer routing-agnostic calls where assign_matching_legal (the /// #300 min-weight bipartite matching placer) produced the layer's /// assignment. Always `0` under [`PlacerMode::RoutingAware`]. pub agnostic_matching_layers: u64, /// Per-layer routing-agnostic calls where the agnostic path instead used - /// [`assign_greedy_legal`] — either because the layer exceeded the + /// assign_greedy_legal — either because the layer exceeded the /// [`MATCHING_FALLBACK_GATE_PAIR_PRODUCT`] threshold (very large layer, /// where the O(n²·m) matching is skipped for speed) or because the - /// dispatch's group-count comparison ([`pick_agnostic_assignment`]) kept + /// dispatch's group-count comparison (pick_agnostic_assignment) kept /// greedy (matching's min-travel optimum grouped into ≥ as many AOD /// movement stages). Always `0` under [`PlacerMode::RoutingAware`]. See /// [`AgnosticPlacerMechanism`]. @@ -465,7 +465,7 @@ pub enum ZonedScheduleError { Conflict(String), } -/// √(d_max / a) duration contribution for one movement group ([RAP] Eq. (1)). +/// √(d_max / a) duration contribution for one movement group (\[RAP\] Eq. (1)). /// /// `d_max_um` is micrometres; `acceleration_m_s2` is m/s². Returns seconds×1e6 /// scaled consistently as a dimensionless √(µm) proxy when a is fixed — we @@ -495,7 +495,7 @@ pub fn movement_duration_us(d_max_um: f64, acceleration_m_s2: f64) -> u64 { crate::geometry::movement_duration_us(d_max_um, acceleration_m_s2) } -/// Sum of √(d_max) over groups — [RAP] Eq. (1) (up to 1/√a). +/// Sum of √(d_max) over groups — \[RAP\] Eq. (1) (up to 1/√a). pub fn routing_cost_eq1(group_d_max_um: &[f64]) -> f64 { group_d_max_um.iter().map(|&d| sqrt_d_max(d)).sum() } @@ -644,7 +644,7 @@ fn zone_id_for_site(layout: &NeutralAtomLayout, arch: &ZonedArchitecture, site: } /// Schedule a graph request onto a zoned architecture, using the default -/// [`AwareSearchParams`] ([RAP] Sec. VI-A QASMBench set) for +/// [`AwareSearchParams`] (\[RAP\] Sec. VI-A QASMBench set) for /// [`PlacerMode::RoutingAware`]. Use /// [`schedule_zoned_with_aware_params`] to override the A* search's /// tunables (node budget, deepening factor/value, pruning window). @@ -844,7 +844,7 @@ pub fn schedule_zoned_with_aware_params( // AOD row/column coupling makes some move sets unrealizable as one // grab (e.g. storage- and zone-sourced atoms converging on the same // row). Partition into compatible groups — the greedily grouped - // compatible movements [RAP] Eq. (1) sums over — and emit each as + // compatible movements \[RAP\] Eq. (1) sums over — and emit each as // its own load → move → store stage. for group in partition_aod_compatible(&planned_moves, arch.aod_min_separation_um) { let d_max = group.iter().fold(0.0_f64, |d, m| d.max(m.distance_um)); @@ -1064,11 +1064,11 @@ fn moves_aod_compatible(a: &PlannedMove, b: &PlannedMove, min_sep_um: f64) -> bo positions_aod_compatible((a.from, a.to), (b.from, b.to), min_sep_um) } -/// [RAP] Sec. V-A's movement-group compatibility check (non-crossing + +/// \[RAP\] Sec. V-A's movement-group compatibility check (non-crossing + /// preservation), on raw `(from, to)` position pairs rather than /// [`PlannedMove`] — shared by the post-search routing grouper /// ([`moves_aod_compatible`]) and the search-time grouping -/// [`assign_aware_legal`] performs to keep its Eq. (1) cost consistent with +/// assign_aware_legal performs to keep its Eq. (1) cost consistent with /// what routing will actually emit (#297). The paper implements this with a /// binary search tree per group for O(log n) lookups (Sec. V-A); this is a /// linear scan against existing group members instead — legal at this @@ -1226,7 +1226,7 @@ struct AssignInputs<'a> { conflict_um: f64, /// Minimum AOD row/column separation ([`ZonedArchitecture::aod_min_separation_um`], /// here `aod_min_separation_um` field) used only by - /// [`assign_aware_legal`]'s search-time movement grouping (Eq. (1)); `0.0` + /// assign_aware_legal's search-time movement grouping (Eq. (1)); `0.0` /// disables the separation sub-check (see [`positions_aod_compatible`]). aod_min_sep_um: f64, /// Placement cost model (issue #309): `Time` uses the RAP Eq. (1) @@ -1234,13 +1234,13 @@ struct AssignInputs<'a> { cost_model: PlacementCostModel, } -/// Whether [`assign_aware_legal`]'s A* search found a full legal assignment -/// for a layer, or gave up and fell back to [`assign_greedy_legal`] (issue +/// Whether assign_aware_legal's A* search found a full legal assignment +/// for a layer, or gave up and fell back to assign_greedy_legal (issue /// #111 review finding: a silent fallback here is indistinguishable from "no /// routing contention" unless it is surfaced). #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum AwareSearchOutcome { - /// [`assign_greedy_legal`] was called directly (routing-agnostic mode); + /// assign_greedy_legal was called directly (routing-agnostic mode); /// the aware-search-completion concept doesn't apply. NotApplicable, /// The search popped a full-assignment goal node within @@ -1251,12 +1251,12 @@ pub enum AwareSearchOutcome { Completed, /// The search exhausted [`AwareSearchParams::node_budget`] expansions /// before popping a full-assignment goal node and fell back to - /// [`assign_greedy_legal`]. + /// assign_greedy_legal. BudgetExceeded, /// The search exhausted its reachable space (heap emptied) within the /// current [`AwareSearchParams::pruning_window`]/[`AwareSearchParams::beam_width`] /// bounds without popping a full-assignment goal node, and fell back to - /// [`assign_greedy_legal`]. Pre-#297 (unwindowed, unbeamed uniform-cost + /// assign_greedy_legal. Pre-#297 (unwindowed, unbeamed uniform-cost /// search) this proved no full legal assignment existed at all (e.g. /// spacing/occupancy conflicts); as of #297 it does **not** prove that — /// `pruning_window` can exclude the only choice a full assignment @@ -1271,14 +1271,14 @@ pub enum AwareSearchOutcome { struct GateAssignment { placed: Vec<(usize, (Position, Position))>, deferred: Vec, - /// See [`AwareSearchOutcome`]. [`assign_greedy_legal`] always reports + /// See [`AwareSearchOutcome`]. assign_greedy_legal always reports /// [`AwareSearchOutcome::NotApplicable`] unless it was called as a - /// fallback from [`assign_aware_legal`], in which case the caller + /// fallback from assign_aware_legal, in which case the caller /// overwrites this with the specific fallback reason. outcome: AwareSearchOutcome, /// Best-first search node expansions this call performed (issue #307). - /// `0` from [`assign_greedy_legal`] unless it is a fallback from - /// [`assign_aware_legal`], in which case the caller overwrites this with + /// `0` from assign_greedy_legal unless it is a fallback from + /// assign_aware_legal, in which case the caller overwrites this with /// the aware search's expansion count before falling back. node_expansions: usize, } @@ -1381,7 +1381,7 @@ fn assign_greedy_legal(gates: &[(AtomId, AtomId)], inputs: &AssignInputs<'_>) -> /// For one gate, one occupancy-legal entanglement pair: `(pair_index, d_max /// cost, oriented destination positions)`. Built per gate by -/// [`assign_matching_legal`] for the cost matrix and orientation lookup. +/// assign_matching_legal for the cost matrix and orientation lookup. type LegalPairOption = (usize, f64, (Position, Position)); /// Routing-agnostic placement via min-weight bipartite matching (issue #300): @@ -1394,7 +1394,7 @@ type LegalPairOption = (usize, f64, (Position, Position)); /// # Cost model /// /// The per-`(gate, pair)` cost is the √-law per-gate move distance the agnostic -/// path charges ([RAP] Eq. (1)): `d_max = max(euclidean(pa, left), +/// path charges (\[RAP\] Eq. (1)): `d_max = max(euclidean(pa, left), /// euclidean(pb, right))` for the cheaper of the two pair orientations /// (orientation does not affect [`pairs_conflict`], which is between *pair /// sites*, so the cheaper orientation is picked freely per matched pair). @@ -1412,7 +1412,7 @@ type LegalPairOption = (usize, f64, (Position, Position)); /// travel-optimal choices in increasing-cost order, skipping any whose pair is /// already taken or which [`pairs_conflict`]s with an already-accepted pair, /// then greedily re-finds a legal pair (via the same [`pair_legal`] oracle -/// [`assign_greedy_legal`] uses, seeded with the accepted set) for every gate +/// assign_greedy_legal uses, seeded with the accepted set) for every gate /// whose matching choice was rejected. Legality is therefore never violated: /// accepted pairs are conflict-free by construction and repaired pairs are /// checked against the accepted set. @@ -1421,7 +1421,7 @@ type LegalPairOption = (usize, f64, (Position, Position)); /// which on a densely-conflicting entanglement zone (e.g. ising_n42, where the /// 18.75 µm isolation spacing exceeds the 12 µm pair pitch) groups into *more* /// AOD movement stages than the spread-out greedy choice. The dispatch -/// ([`pick_agnostic_assignment`]) therefore compares the two on the actual +/// (pick_agnostic_assignment) therefore compares the two on the actual /// rearrangement-step metric and keeps the better — guaranteeing the agnostic /// path never regresses the step count while still using matching wherever it /// does group better. @@ -1436,7 +1436,7 @@ type LegalPairOption = (usize, f64, (Position, Position)); /// rather than greedily. /// /// Returns the [`GateAssignment`] and a flag: `true` if matching produced it, -/// `false` if it fell back to [`assign_greedy_legal`]. (The current +/// `false` if it fell back to assign_greedy_legal. (The current /// implementation always returns `true`; the flag is retained for the /// dispatch's group-count comparison and any future conflict-repair variant /// that does fall back.) @@ -1463,7 +1463,7 @@ fn assign_matching_legal( continue; } // Cost = the per-gate move cost the agnostic path charges - // ([RAP] Eq. (1) under `Time`: d_max = max of the two atoms' + // (\[RAP\] Eq. (1) under `Time`: d_max = max of the two atoms' // travels for the cheaper orientation; under `ErrorBudget`: // the analytic error-budget contribution — issue #309). // Orientation does not affect [`pairs_conflict`] (between pair @@ -1569,7 +1569,7 @@ fn assign_matching_legal( // 4. Greedily reassign every active gate whose matching choice was rejected // (taken or conflicting) to its nearest legal free pair that does not // conflict with the accepted set — the same legality oracle - // [`assign_greedy_legal`] uses ([`pair_legal`]), seeded with the + // assign_greedy_legal uses ([`pair_legal`]), seeded with the // matching's accepted pairs. Gates with no such pair are deferred // (exactly as greedy would). This keeps matching's gain for the // non-conflicting bulk of the layer and falls back to greedy only for @@ -1634,9 +1634,9 @@ fn assign_matching_legal( } /// Number of AOD-coupled-motion-compatible movement groups an assignment would -/// emit — the actual per-layer rearrangement-step contribution ([RAP] Eq. +/// emit — the actual per-layer rearrangement-step contribution (\[RAP\] Eq. /// (1) sums `√(d_max)` over exactly these groups). Used by -/// [`pick_agnostic_assignment`] to compare the matching and greedy placers on +/// pick_agnostic_assignment to compare the matching and greedy placers on /// the metric that matters (steps), not just travel distance. fn assignment_group_count( assignment: &GateAssignment, @@ -1672,7 +1672,7 @@ fn assignment_group_count( /// Computes the actual group-level cost: `movement × steps + transfer × /// transfers + idle × exposed_wait + rydberg × stages` using the real /// AOD-compatible movement groups the assignment would emit. Used by -/// [`pick_agnostic_assignment`] under [`PlacementCostModel::ErrorBudget`] +/// pick_agnostic_assignment under [`PlacementCostModel::ErrorBudget`] /// to compare the matching and greedy placers on the error-budget metric /// (not just step count). `rate × count` only (ADR-0017/0020) — **not** a /// logical error rate or threshold claim. @@ -1726,8 +1726,8 @@ fn assignment_error_budget_cost( } /// Choose the routing-agnostic layer assignment: compute both the -/// min-weight matching placer ([`assign_matching_legal`]) and the greedy -/// placer ([`assign_greedy_legal`]), keep whichever yields fewer AOD movement +/// min-weight matching placer (assign_matching_legal) and the greedy +/// placer (assign_greedy_legal), keep whichever yields fewer AOD movement /// groups (the rearrangement-step metric) — with greedy winning ties and any /// case where matching defers more gates. This guarantees the agnostic path /// never produces more rearrangement steps than the greedy baseline (issue @@ -1790,7 +1790,7 @@ fn pick_agnostic_assignment( } } -/// Tunable parameters for [`assign_aware_legal`]'s A* search ([RAP] Secs. +/// Tunable parameters for assign_aware_legal's A* search (\[RAP\] Secs. /// IV-C / V-C / V-D, Eqs. (3)-(5)). Defaults are the paper's QASMBench /// parameter set (Sec. VI-A: α=0.2, β=0.2, γ=5, δ=0.6) restricted to the /// terms this port implements — see the module doc for why α (Eq. (2)'s @@ -1815,9 +1815,9 @@ pub struct AwareSearchParams { /// small nonzero penalty proportional to how many gates remain. qmap: /// `deepeningValue`. pub deepening_value: f64, - /// Expansion budget before falling back to [`assign_greedy_legal`]. + /// Expansion budget before falling back to assign_greedy_legal. pub node_budget: usize, - /// [RAP] Sec. V-D pruning: number of nearest *legal* entanglement pairs + /// \[RAP\] Sec. V-D pruning: number of nearest *legal* entanglement pairs /// considered per gate at each node expansion (bounds branching factor /// on layers with many simultaneous gates / candidate pairs). pub pruning_window: usize, @@ -1948,7 +1948,7 @@ fn std_dev(values: &[f64]) -> f64 { variance.sqrt() } -/// [RAP] Eq. (4)'s `Σ_G SD(G)`: per axis, per group, the standard deviation +/// \[RAP\] Eq. (4)'s `Σ_G SD(G)`: per axis, per group, the standard deviation /// of `value − scale·key`, where `key`/`value` are each member's *discrete /// rank* among the group's distinct source/target coordinates on that axis /// (its Sec. V-A/V-C — "the source locations of the atoms are rearranged, @@ -2069,7 +2069,7 @@ fn gate_candidates(gate: (AtomId, AtomId), inputs: &AssignInputs<'_>) -> Vec, @@ -2557,7 +2557,7 @@ mod tests { } /// Total Eq. (1) cost `Σ_G √(d_max(G))` a [`GateAssignment`] would incur, - /// recomputed independently of [`assign_aware_legal`]'s own bookkeeping so + /// recomputed independently of assign_aware_legal's own bookkeeping so /// this doubles as a check that its `placed` orientations are the ones it /// claims. fn assignment_cost( @@ -2578,7 +2578,7 @@ mod tests { } /// Issue #111 review finding: a routing-aware layer that silently falls - /// back to [`assign_greedy_legal`] (budget exhaustion or no legal full + /// back to assign_greedy_legal (budget exhaustion or no legal full /// assignment) is indistinguishable, by cost alone, from "no routing /// contention" — unless the outcome is instrumented. This is a small, /// genuinely contended two-gate/two-pair layout (no target/circuit diff --git a/quon_qec/src/expand.rs b/quon_qec/src/expand.rs index 7d454f61..dcf2e729 100644 --- a/quon_qec/src/expand.rs +++ b/quon_qec/src/expand.rs @@ -8,13 +8,13 @@ //! # Repetition ([`SourceFamily::Repetition`]) //! //! Alternating `D C D C … D` chain of length `N = 2d − 1` (architecture_model -//! §10.2 / [Kelly15]). Each check extracts ZZ parity of its two neighboring +//! §10.2 / \[Kelly15]). Each check extracts ZZ parity of its two neighboring //! data qubits via CNOT(data→check), then Z-measure + reset. //! //! # Surface ([`SourceFamily::Surface`]) //! //! Rotated surface code with `N = 2d² − 1` (architecture_model §10.1 / -//! [Bravyi24] §1; [BMD07]). Data on a `d×d` grid; X/Z check ancillas on +//! \[Bravyi24] §1; \[BMD07]). Data on a `d×d` grid; X/Z check ancillas on //! plaquettes (smooth top/bottom X boundaries, rough left/right Z). Memory //! rounds use a **serial Z-then-X** phase split (Z CXs → mid H → X CXs → //! after H → measure/reset) for hybrid NA scheduling. That is *not* Stim's diff --git a/quon_qec/src/patch_ops.rs b/quon_qec/src/patch_ops.rs index b7867ea3..0fe4cea6 100644 --- a/quon_qec/src/patch_ops.rs +++ b/quon_qec/src/patch_ops.rs @@ -19,7 +19,8 @@ //! - [`PatchOperation`] — merge, split, measure-patch, measure-ancilla, //! prepare-ancilla, frame-update (all explicit, ordered) //! - [`PatchPlan`] — ordered sequence of operations + patch registry -//! - [`PatchPlanner`] — builds a plan from a logical operation +//! - [`plan_logical_cx`] / [`plan_measure_logical`] / [`plan_rough_merge_split`] — +//! build a plan from a logical operation //! //! The plan is then lowered to [`PhysicalRound`]s by [`lower_patch_plan`]. diff --git a/quon_qec/src/qldpc.rs b/quon_qec/src/qldpc.rs index e18845c0..bf0281b3 100644 --- a/quon_qec/src/qldpc.rs +++ b/quon_qec/src/qldpc.rs @@ -289,7 +289,7 @@ pub fn generate_syndrome_rounds( Ok(rounds) } -/// A simple toy [[5,1,3]] code (5-qubit code) for testing. +/// A simple toy \[\[5,1,3\]\] code (5-qubit code) for testing. pub fn toy_5qubit_graph() -> ParityCheckGraph { ParityCheckGraph { n_data: 5, diff --git a/quonc/src/validation.rs b/quonc/src/validation.rs index d6186221..947c9036 100644 --- a/quonc/src/validation.rs +++ b/quonc/src/validation.rs @@ -2,7 +2,7 @@ //! //! A [`ValidationReport`] is a **new, separate** compiler artifact //! (`*.validation.json` / `*.validation.md`) that places the analytic compiler -//! [`ResourceReport`](quon_na::ResourceReport) beside sampled Stim/Sinter +//! [`quon_na::ResourceReport`] beside sampled Stim/Sinter //! evidence, with clear provenance. It is **not** a mutation of the primary //! `ResourceReport` DTO and **not** a threshold claim: the two evidence kinds //! stay in clearly labeled `analytic` and `sampled` sections (ADR-0020). diff --git a/quonlint-cli/Cargo.toml b/quonlint-cli/Cargo.toml index b16f57d6..ccf88f03 100644 --- a/quonlint-cli/Cargo.toml +++ b/quonlint-cli/Cargo.toml @@ -9,6 +9,7 @@ repository.workspace = true [[bin]] name = "quonlint" path = "src/main.rs" +doc = false [dependencies] quonlint = { path = "../quonlint" } diff --git a/scripts/assert-validation-docs.sh b/scripts/assert-validation-docs.sh index ac458f5d..e4b393e3 100755 --- a/scripts/assert-validation-docs.sh +++ b/scripts/assert-validation-docs.sh @@ -53,7 +53,7 @@ for needle in \ 'taskless.yml' \ 'flux.yml' \ 'release.yml' \ - '#180' + 'ci-rustdoc' do if ! grep -qF "$needle" "$VALIDATION"; then fail "validation.md missing required anchor: $needle"