Skip to content

Initial support for leakage - #195

Open
david-pl wants to merge 16 commits into
mainfrom
david/leakage
Open

Initial support for leakage#195
david-pl wants to merge 16 commits into
mainfrom
david/leakage

Conversation

@david-pl

@david-pldavid-pl commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Adds support for leakage on GeneralizedTableau by replacing the is_lost: Vec<bool> by an enum. Leaked qubits are fixed to either 0 or 1 depending on the given probabilities and are detected as such.

Note, that GeneralizedTableauSum does not support leakage yet.

@github-actions

github-actionsBot commented Jul 24, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://QuEraComputing.github.io/ppvm/pr-preview/pr-195/

Built to branch gh-pages at 2026-09-03 07:47 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@david-pl
david-pl marked this pull request as ready for review September 2, 2026 06:54
CopilotAI lite review requested due to automatic review settings September 2, 2026 06:54

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A compile-breaking invalid import was introduced (use std::debug_assert;) and should be fixed before merging.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adds initial leakage support to the GeneralizedTableau simulation stack by introducing a per-qubit status enum (live/leaked/lost), extending the Stim parser/executor to handle I_ERROR[leakage](p0, p1), and exposing leakage state through the Python bindings.

Changes:

  • Introduces QubitStatus to represent Live / Leaked / Lost, and updates gate/noise behavior to skip non-live qubits while preserving distinct measurement behavior for leakage vs loss.
  • Extends stim-parser + ppvm-stim to parse/lower/print/execute the leakage tag on I_ERROR.
  • Exposes is_leaked() / leakage_values() through Python bindings and adds Python/Rust tests for leakage behavior.
File summaries
FileDescription
ppvm-python/test/generalized_tableau/test_stim.pyAdds Stim-driven leakage execution tests
ppvm-python/test/generalized_tableau/test_loss.pyAdds Python API tests for leakage state helpers
ppvm-python/src/ppvm/generalized_tableau.pyAdds Python-facing is_leaked / leakage_values
ppvm-python/src/ppvm/_core.pyiUpdates core stub with leakage APIs
crates/stim-parser/tests/tags.rsTests parsing of leakage tag args
crates/stim-parser/tests/roundtrip.rsAdds leakage to roundtrip corpus
crates/stim-parser/tests/proptest_parse.rsAdds [leakage] token to proptests
crates/stim-parser/tests/proptest_ast.rsGenerates ExtendedInstruction::Leakage in proptests
crates/stim-parser/tests/extended.rsTests lowering/tag validation for leakage
crates/stim-parser/src/print/mod.rsPrints leakage instruction canonically
crates/stim-parser/src/pipeline/lower.rsLowers I_ERROR[leakage] into extended AST
crates/stim-parser/src/ast/extended.rsAdds ExtendedInstruction::Leakage variant
crates/ppvm-traits/src/traits/noise.rsAdds leakage-related noise traits
crates/ppvm-traits/src/traits/mod.rsRe-exports leakage traits from traits module
crates/ppvm-tableau/tests/gates.rsUpdates tests for qubit_status replacing is_lost
crates/ppvm-tableau/src/qubit_status.rsNew enum + helpers for live/leaked/lost handling
crates/ppvm-tableau/src/noise.rsImplements leakage channel + updates loss logic for status
crates/ppvm-tableau/src/measure.rsUpdates lost-measurement check for status
crates/ppvm-tableau/src/measure_all.rsUpdates measure-all lost checks for status
crates/ppvm-tableau/src/lib.rsExposes qubit_status module + prelude export
crates/ppvm-tableau/src/gates/tgate.rsSkips T gates on inactive (lost/leaked) qubits
crates/ppvm-tableau/src/gates/rot2.rsUpdates rot2 fallback/skip logic for inactive qubits
crates/ppvm-tableau/src/gates/rot1.rsSkips rot1 on inactive qubits
crates/ppvm-tableau/src/gates/reset.rsPrevents reset from re-zeroing leaked qubits
crates/ppvm-tableau/src/gates/clifford.rsSkips Clifford ops on inactive qubits; batch filtering updates
crates/ppvm-tableau/src/display.rsUpdates display output to show qubit_status
crates/ppvm-tableau/src/data.rsReplaces is_lost storage with qubit_status
crates/ppvm-tableau-sum/src/storage/vec.rsAdapts storage sizing to qubit_status
crates/ppvm-tableau-sum/src/storage/mod.rsAdapts hashing/equality to qubit_status
crates/ppvm-tableau-sum/src/storage/map.rsAdapts mask sizing to qubit_status
crates/ppvm-tableau-sum/src/noise.rsUpdates loss branching to write QubitStatus::Lost
crates/ppvm-tableau-sum/src/measure.rsUpdates lost checks to use is_lost() method
crates/ppvm-tableau-sum/src/data.rsUpdates tests for qubit_status instead of is_lost
crates/ppvm-tableau-sum/benches/parallelization_test.rsUpdates bench to use is_lost()
crates/ppvm-stim/tests/executor.rsAdds executor tests for leakage behavior
crates/ppvm-stim/src/validate.rsAllows leakage instruction through validation
crates/ppvm-stim/src/executor.rsExecutes leakage instructions via leakage_channel
crates/ppvm-stim/benches/stim-circuits.rsCounts leakage targets for required-qubits computation
crates/ppvm-python-native/src/interface_tableau.rsExposes leakage state through Python native interface
crates/ppvm-python-native/ppvm_python_native.pyiUpdates native stub with leakage APIs
Review details
  • Files reviewed: 40/40 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment threadcrates/ppvm-tableau/src/noise.rs
Comment threadcrates/ppvm-traits/src/traits/noise.rs
Comment threadcrates/ppvm-traits/src/traits/noise.rs
CopilotAI review requested due to automatic review settings September 2, 2026 07:12

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It changes core simulator state semantics across multiple crates/languages (tableau, stim parsing/execution, Python bindings), warranting final human review despite strong test additions.

Review details
  • Files reviewed: 40/40 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

CopilotAI review requested due to automatic review settings September 2, 2026 15:02

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It changes core simulator semantics across multiple Rust crates and the Python binding surface, so a final human review is needed to confirm correctness of the leakage model end-to-end.

Review details

Suppressed comments (1)

crates/ppvm-tableau/src/data.rs:789

  • Same as above: any_lost now includes leaked qubits via is_inactive, so the name is inaccurate and can cause confusion when reasoning about leakage behavior.
 let any_lost = (0..count).any(|i| {
let c = word_c * bits_per_word + base_bit_c + i;
let t = word_t * bits_per_word + base_bit_t + i;
self.is_inactive(c) || self.is_inactive(t)
});
  • Files reviewed: 40/40 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment threadcrates/ppvm-tableau/src/data.rs Outdated
Comment on lines 755 to 759
// Check if any qubit in the range is lost or leaked
let any_lost =
(0..count).any(|i| self.is_lost[base + i] || self.is_lost[base + offset + i]);
(0..count).any(|i| self.is_inactive(base + i) || self.is_inactive(base + offset + i));
if !any_lost {
self.tableau.cz_block_pairs(base, offset, count);
// record entry it pushed (mirrors `loss_channel`).
let m = self
.measure(addr0)
.expect("Loss was checked before, this should be unreachable");
CopilotAI review requested due to automatic review settings September 2, 2026 15:45

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The leakage feature is implemented end-to-end (parser → executor → tableau → Python bindings) with targeted tests covering the new behavior and updated loss/leakage interactions.

Review details
  • Files reviewed: 40/40 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

CopilotAI review requested due to automatic review settings September 3, 2026 07:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The change spans core simulator semantics, Stim parsing/execution, and Python bindings, so it warrants final human review despite strong test coverage.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

crates/ppvm-tableau-sum/src/storage/mod.rs:160

  • Doc/comments for phase_loss_hash still refer to is_lost, but the code now uses qubit_status. This is misleading (and qubit_status can represent more than just loss). Update the wording to reflect that this hash tracks the loss state via qubit_status and fix the inline len() comment accordingly.

This issue also appears on line 317 of the same file.

crates/ppvm-tableau-sum/src/storage/mod.rs:319

  • The BranchMutation::Loss doc comment still mentions the removed is_lost field; it should describe the new qubit_status representation so future readers don't look for a non-existent boolean vector.
 BranchMutation::Loss { q } => {
tab.qubit_status[q] = QubitStatus::Lost;
}
  • Files reviewed: 41/41 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@david-pl