♻️ Centralize and structure code generation/infrastructure#751
Conversation
f86334e to
d69a12d
Compare
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
After removing the surface/hamming codes, every supported code has a fixed (x, z) distance in the lookup table, so the caller-supplied `distance` argument was never read and the "Distance is not specified" branch was unreachable (paths and distances share identical keys). Remove the vestigial parameter and simplify the control flow to a single early return. No caller passed `distance`, so there is no behavioural change for existing usage.
The sparse 3D/4D HGP constructors created their zero padding blocks via `csr_matrix(np.zeros(dims))`, allocating a full dense array before converting it to sparse. This defeats the purpose of the sparse code path, which exists to avoid dense allocations for large codes. Construct the zero blocks directly as sparse matrices with `csr_matrix(dims, dtype=int)`, which yields an all-zero sparse matrix of the requested shape with no intermediate dense buffer.
The sparse product-code constructors used `dtype=int` (platform- dependent width) while their dense counterparts use `np.int32`. Since all entries are binary, the width is immaterial to correctness, but aligning the sparse path on `np.int32` keeps the two implementations consistent.
`_sparse_all_zeros` reduced its argument in place via `mat.data %= 2` before summing. Despite reading like a pure predicate it mutated the caller's matrix, which is a latent hazard if the helper is ever reused on a matrix the caller still needs. Reduce mod 2 on a transient copy of the data vector instead (`not np.any(mat.data % 2)`), mirroring the dense `_is_all_zeros` helper. Behaviour is unchanged: it still reports whether the matrix is zero over GF(2). Current callers only pass throwaway boundary-map products, so there is no observable change.
Replace the generic, inaccurate module docstring ("Package for code
construction") with one that describes the module's actual contents, and
fix the contradictory dual comment on the 3D return
(`# mx, hx, hzT # hx, hzT, mzT`) to the correct `# hx, hz^T, mz^T`,
matching how `create_code` unpacks the result.
The 3D/4D hypergraph product code constructors moved from `analog_information_decoding` into `codes/constructions/`, but their tests were left under `tests/analog_info/`. Relocate them to `tests/codes/constructions/` so the test tree mirrors the source tree. The tests import `mqt.qecc.codes.constructions.hypergraph_product_code` absolutely, so the move is purely organizational.
The centralization introduced `codes/instances/` but left its contents undocumented, so the example codes under `misc/` (and the lifted-product matrices) were effectively orphaned - referenced nowhere and hard to discover. Add a README describing the three groups: the named CSS codes exposed via `CSSCode.from_code_name`, the pre-generated lifted-product matrices, and the `misc/` example files that demonstrate the text formats accepted by `CSSCode.from_file`.
The HGP builders moved into codes.constructions and create_code was rewired to call generate_sparse_3d_product_code, but nothing exercised that caller. Add a test that drives create_code end-to-end with the bposd hypergraph product and the file/subprocess side effects stubbed out, and asserts the extended code is a valid CSS code (Hx Hz^T = 0 over GF(2)). Also cover the unknown-constructor error path.
# Conflicts: # src/mqt/qecc/circuit_synthesis/synthesis_utils.py
`sparse_code_constructor` imports `bposd`, whose source raises a
SyntaxWarning (invalid escape sequences) on Python >= 3.12. Under the
project's strict ``filterwarnings = ["error"]`` this turned the test's
module import into a collection error. Wrap the import in a local
``warnings.catch_warnings()`` / ``simplefilter("ignore")`` block so the
test collects and runs.
|
Danke @MaxieHelenBichmann, das sieht schon sehr gut aus und macht das Code management deutlich einheitlicher! Ich hab jetzt noch ein paar kleinere Sachen gefixed und würde jetzt dann noch Coderabbit drüber laufen lassen. Dann sollte das passen danke ich. @CodeRabbit full review |
|
(°ᴥ°) ✅ Action performedFull review finished. |
Two issues flagged by the `ty` linter: - `examples/add_new_gate_example.py` still imported `StabilizerTableau` from the pre-refactor `mqt.qecc.codes.pauli`; point it at `mqt.qecc.codes.core.pauli` (missed in the earlier import sweep, which did not cover `examples/`). - The `create_code` regression test passed NumPy arrays where the `list[csr_matrix]` signature is expected; wrap the stubbed seed codes in `csr_matrix` to match.
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (98)
💤 Files with no reviewable changes (12)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe change reorganizes code representations and construction utilities into ChangesCentralized code architecture
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 17
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/examples/atd_example.py`:
- Around line 25-28: Update the matrix-loading assignments for Hx, Hz, Lx, and
Lz in the AtdSimulator setup to preserve the sparse matrices by removing the
immediate toarray conversions, provided AtdSimulator accepts sparse inputs;
otherwise retain dense conversion and document the requirement with a concise
comment.
- Around line 27-28: Restore the missing lifted-product logical-operator
instance files expected by the example: add the corresponding `{c}_lx.npz` and
`{c}_lz.npz` artifacts under `src/mqt/qecc/codes/instances/lifted_product/`,
matching the naming and format loaded by `scipy.sparse.load_npz` in the example.
In `@src/mqt/qecc/codes/constructions/color_codes/square_octagon_color_code.py`:
- Line 152: In the loop containing the `idx += len(self.square_ancilla_qubits)`
statement, stop reassigning the `enumerate` variable `idx`: introduce a separate
variable for the adjusted offset, update subsequent uses to reference it, and
remove the `# noqa: PLW2901` suppression.
In `@src/mqt/qecc/codes/constructions/hypergraph_product_code.py`:
- Around line 58-60: Make the checks parameter keyword-only by adding the
keyword-only separator before checks in both generate_4d_product_code and
generate_sparse_4d_product_code. Preserve the existing default value and
behavior while requiring callers to pass checks by name.
- Line 61: Update the public generator docstrings at the definitions near
“Generate 4D product code” and the other referenced generators to use Google
style, adding Args, Returns, and Raises sections. Document required matrix
compatibility, the ordering and meaning of returned boundary maps, and the
validation exceptions raised, while preserving the existing generator behavior.
- Around line 40-55: The _run_checks_scipy validation currently densifies sparse
boundary-map products before checking them. Replace each .todense()-based
_is_all_zeros check with _sparse_all_zeros applied to the corresponding product
modulo two, preserving the existing error and validation behavior.
In `@src/mqt/qecc/codes/core/css_code.py`:
- Around line 202-221: Update the hamming handling in
estimate_logical_error_rate so the advertised CLI choice remains valid: add a
dedicated construct_quantum_hamming_code(4) path before calling
CSSCode.from_code_name, or remove hamming from the available choices. Ensure
CSSCode.from_code_name is not invoked with hamming.
In `@src/mqt/qecc/codes/core/pauli.py`:
- Around line 485-613: Refactor complete_stabilizer_tableau_with_destabilizers
into focused helpers for input validation, logical-row partitioning, individual
destabilizer construction, and final tableau assembly. Move the corresponding
checks and algorithm stages into independently testable functions while
preserving row ordering, phases, validation errors, and destabilizer-correction
behavior; do not suppress Ruff complexity warnings.
- Around line 29-38: Update Pauli.__init__ and the multiplication implementation
to use a phase model capable of representing ±1 and ±i, such as phases modulo
four, and include the symplectic cross-phase term so anticommuting products
produce the correct sign. Normalize or validate incoming phase values, including
accumulated values from ConcatenatedCode, while preserving correct Pauli
multiplication results such as XX * ZZ = -YY.
- Around line 140-143: Update the ndarray branch of the tableau initialization
to convert or cast the NumPy array to the declared binary dtype before passing
it to SymplecticMatrix. Remove the ty suppression and preserve the existing
behavior for already-constructed SymplecticMatrix values.
- Around line 514-530: Validate that stab_rows contains no duplicate indices
before deriving m or stab_row_set in the stabilizer-selection logic. Raise a
ValueError for duplicates so the returned tableau cannot contain repeated
stabilizers or destabilizers, while preserving the existing range and
stabilizer-count validation.
- Around line 536-545: Update complete_stabilizer_tableau_with_destabilizers to
reject incomplete stabilizer/logical row sets after calculating k: validate that
the stabilizer count plus k equals the number of qubits n, and raise a clear
ValueError when the set cannot form a full 2n × 2n tableau. Preserve the
existing matched-pair validation and logical_x_rows/logical_z_rows handling for
complete inputs.
In `@src/mqt/qecc/codes/core/symplectic.py`:
- Around line 82-84: Remove content-based __hash__ implementations from
SymplecticVector and SymplecticMatrix, or make their underlying storage
immutable. Preserve Pauli, StabilizerTableau, and CheckMatrix as unhashable
while their mutable symplectic vector or matrix state remains editable; apply
these changes at src/mqt/qecc/codes/core/symplectic.py lines 82-84 and 205-207,
and verify the existing unhashable behavior at src/mqt/qecc/codes/core/pauli.py
lines 123-125, 285-287, and 717-719.
- Around line 26-29: Validate inputs in SymplecticVector.__init__ before
computing n: require a one-dimensional vector and an even length, raising
ValueError with clear messages for invalid shapes. Apply equivalent
two-dimensional and even-column validation in SymplecticMatrix, replacing silent
// 2 truncation while preserving valid (X | Z) layouts.
- Around line 53-55: Update SymplecticVector.__neg__ so negation remains in
GF(2): return a copy of the vector or reduce the negated values modulo two,
ensuring entries remain binary and -v equals v. Preserve the existing
SymplecticVector return type.
- Around line 144-152: Update SymplecticMatrix.__matmul__ so the
SymplecticVector operand returns the computed row-wise syndrome as an
NDArray[np.int8], rather than constructing a SymplecticVector; add overloads
distinguishing vector and matrix operands and replace the Any annotation and
noqa. Update StabilizerCode.get_syndrome to return this array directly while
preserving the matrix-product behavior.
In `@tests/analog_info/test_sparse_code_constructor.py`:
- Around line 24-26: In the import block for sparse_code_constructor, replace
the broad warnings.simplefilter("ignore") call with a filter that ignores only
SyntaxWarning, leaving unrelated import warnings visible. Preserve the existing
warning-capture scope and scc import.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: ae5a3d00-a48d-4ab1-aa19-2fd9e9fec0af
📒 Files selected for processing (98)
docs/AnalogInfo.mddocs/ExactSynthesis.mdscripts/encoding_circuits/codes/css/108_8_10.txtscripts/encoding_circuits/codes/css/144_12_12.txtscripts/encoding_circuits/codes/css/15_1_3.txtscripts/encoding_circuits/codes/css/15_7_3.txtscripts/encoding_circuits/codes/css/17_1_5.txtscripts/encoding_circuits/codes/css/19_1_5.txtscripts/encoding_circuits/codes/css/23_1_7.txtscripts/encoding_circuits/codes/css/31_1_7.txtscripts/encoding_circuits/codes/css/31_21_3.txtscripts/encoding_circuits/codes/css/37_1_7.txtscripts/encoding_circuits/codes/css/72_12_6.txtscripts/encoding_circuits/codes/css/90_8_10.txtscripts/examples/atd_example.pyscripts/ft_stateprep/eval/estimate_logical_error_rate.pysrc/mqt/qecc/analog_information_decoding/code_construction/code_constructor.pysrc/mqt/qecc/analog_information_decoding/code_construction/sparse_code_constructor.pysrc/mqt/qecc/cc_decoder/__init__.pysrc/mqt/qecc/cc_decoder/decoder.pysrc/mqt/qecc/cc_decoder/utils.pysrc/mqt/qecc/circuit_synthesis/circuits.pysrc/mqt/qecc/circuit_synthesis/cnot.pysrc/mqt/qecc/circuit_synthesis/elimination.pysrc/mqt/qecc/circuit_synthesis/encoding.pysrc/mqt/qecc/circuit_synthesis/exact/encoding_depth.pysrc/mqt/qecc/circuit_synthesis/exact/encoding_gate_count.pysrc/mqt/qecc/circuit_synthesis/exact/encoding_interface.pysrc/mqt/qecc/circuit_synthesis/exact/initialization.pysrc/mqt/qecc/circuit_synthesis/exact/search.pysrc/mqt/qecc/circuit_synthesis/exact/verification.pysrc/mqt/qecc/circuit_synthesis/operations.pysrc/mqt/qecc/circuit_synthesis/simulation.pysrc/mqt/qecc/circuit_synthesis/simulation_det.pysrc/mqt/qecc/circuit_synthesis/state_prep.pysrc/mqt/qecc/circuit_synthesis/strategy.pysrc/mqt/qecc/circuit_synthesis/synthesis.pysrc/mqt/qecc/circuit_synthesis/transvection.pysrc/mqt/qecc/circuit_synthesis/types.pysrc/mqt/qecc/codes/__init__.pysrc/mqt/qecc/codes/cc_4_8_8_d5/hx.npysrc/mqt/qecc/codes/cc_4_8_8_d5/hz.npysrc/mqt/qecc/codes/constructions/__init__.pysrc/mqt/qecc/codes/constructions/bb_codes.pysrc/mqt/qecc/codes/constructions/color_codes/__init__.pysrc/mqt/qecc/codes/constructions/color_codes/color_code.pysrc/mqt/qecc/codes/constructions/color_codes/hexagonal_color_code.pysrc/mqt/qecc/codes/constructions/color_codes/square_octagon_color_code.pysrc/mqt/qecc/codes/constructions/concatenation.pysrc/mqt/qecc/codes/constructions/constructions.pysrc/mqt/qecc/codes/constructions/hypergraph_product_code.pysrc/mqt/qecc/codes/constructions/rotated_surface_code.pysrc/mqt/qecc/codes/core/__init__.pysrc/mqt/qecc/codes/core/css_code.pysrc/mqt/qecc/codes/core/pauli.pysrc/mqt/qecc/codes/core/stabilizer_code.pysrc/mqt/qecc/codes/core/symplectic.pysrc/mqt/qecc/codes/hamming_15/hx.npysrc/mqt/qecc/codes/hamming_15/hz.npysrc/mqt/qecc/codes/instances/README.mdsrc/mqt/qecc/codes/instances/carbon/hx.npysrc/mqt/qecc/codes/instances/carbon/hz.npysrc/mqt/qecc/codes/instances/golay/hx.npysrc/mqt/qecc/codes/instances/golay/hz.npysrc/mqt/qecc/codes/instances/lifted_product/lp_l=16_hx.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=16_hz.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=21_hx.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=21_hz.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=30_hx.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=30_hz.npzsrc/mqt/qecc/codes/instances/misc/15_3_5.txtsrc/mqt/qecc/codes/instances/misc/30_6_5.txtsrc/mqt/qecc/codes/instances/misc/8_3_3.txtsrc/mqt/qecc/codes/instances/shor/hx.npysrc/mqt/qecc/codes/instances/shor/hz.npysrc/mqt/qecc/codes/instances/steane/hx.npysrc/mqt/qecc/codes/instances/steane/hz.npysrc/mqt/qecc/codes/instances/tetrahedral/hx.npysrc/mqt/qecc/codes/instances/tetrahedral/hz.npysrc/mqt/qecc/codes/rotated_surface_d3/hx.npysrc/mqt/qecc/codes/rotated_surface_d3/hz.npysrc/mqt/qecc/codes/rotated_surface_d5/hx.npysrc/mqt/qecc/codes/rotated_surface_d5/hz.npytests/analog_info/test_sparse_code_constructor.pytests/circuit_synthesis/exact/conftest.pytests/circuit_synthesis/exact/test_cz_gate.pytests/circuit_synthesis/exact/test_search.pytests/circuit_synthesis/exact/test_sqrt_x_gate.pytests/circuit_synthesis/test_circuits.pytests/circuit_synthesis/test_cnot.pytests/circuit_synthesis/test_deterministic.pytests/circuit_synthesis/test_elimination.pytests/circuit_synthesis/test_encoder_synthesis.pytests/circuit_synthesis/test_operations.pytests/circuit_synthesis/test_stateprep.pytests/circuit_synthesis/test_transvection.pytests/codes/constructions/test_hypergraph_product_codes.pytests/test_code.py
💤 Files with no reviewable changes (12)
- scripts/encoding_circuits/codes/css/23_1_7.txt
- scripts/encoding_circuits/codes/css/19_1_5.txt
- scripts/encoding_circuits/codes/css/108_8_10.txt
- scripts/encoding_circuits/codes/css/90_8_10.txt
- scripts/encoding_circuits/codes/css/37_1_7.txt
- scripts/encoding_circuits/codes/css/144_12_12.txt
- scripts/encoding_circuits/codes/css/17_1_5.txt
- scripts/encoding_circuits/codes/css/15_7_3.txt
- scripts/encoding_circuits/codes/css/15_1_3.txt
- scripts/encoding_circuits/codes/css/31_21_3.txt
- scripts/encoding_circuits/codes/css/31_1_7.txt
- scripts/encoding_circuits/codes/css/72_12_6.txt
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 17
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/examples/atd_example.py`:
- Around line 25-28: Update the matrix-loading assignments for Hx, Hz, Lx, and
Lz in the AtdSimulator setup to preserve the sparse matrices by removing the
immediate toarray conversions, provided AtdSimulator accepts sparse inputs;
otherwise retain dense conversion and document the requirement with a concise
comment.
- Around line 27-28: Restore the missing lifted-product logical-operator
instance files expected by the example: add the corresponding `{c}_lx.npz` and
`{c}_lz.npz` artifacts under `src/mqt/qecc/codes/instances/lifted_product/`,
matching the naming and format loaded by `scipy.sparse.load_npz` in the example.
In `@src/mqt/qecc/codes/constructions/color_codes/square_octagon_color_code.py`:
- Line 152: In the loop containing the `idx += len(self.square_ancilla_qubits)`
statement, stop reassigning the `enumerate` variable `idx`: introduce a separate
variable for the adjusted offset, update subsequent uses to reference it, and
remove the `# noqa: PLW2901` suppression.
In `@src/mqt/qecc/codes/constructions/hypergraph_product_code.py`:
- Around line 58-60: Make the checks parameter keyword-only by adding the
keyword-only separator before checks in both generate_4d_product_code and
generate_sparse_4d_product_code. Preserve the existing default value and
behavior while requiring callers to pass checks by name.
- Line 61: Update the public generator docstrings at the definitions near
“Generate 4D product code” and the other referenced generators to use Google
style, adding Args, Returns, and Raises sections. Document required matrix
compatibility, the ordering and meaning of returned boundary maps, and the
validation exceptions raised, while preserving the existing generator behavior.
- Around line 40-55: The _run_checks_scipy validation currently densifies sparse
boundary-map products before checking them. Replace each .todense()-based
_is_all_zeros check with _sparse_all_zeros applied to the corresponding product
modulo two, preserving the existing error and validation behavior.
In `@src/mqt/qecc/codes/core/css_code.py`:
- Around line 202-221: Update the hamming handling in
estimate_logical_error_rate so the advertised CLI choice remains valid: add a
dedicated construct_quantum_hamming_code(4) path before calling
CSSCode.from_code_name, or remove hamming from the available choices. Ensure
CSSCode.from_code_name is not invoked with hamming.
In `@src/mqt/qecc/codes/core/pauli.py`:
- Around line 485-613: Refactor complete_stabilizer_tableau_with_destabilizers
into focused helpers for input validation, logical-row partitioning, individual
destabilizer construction, and final tableau assembly. Move the corresponding
checks and algorithm stages into independently testable functions while
preserving row ordering, phases, validation errors, and destabilizer-correction
behavior; do not suppress Ruff complexity warnings.
- Around line 29-38: Update Pauli.__init__ and the multiplication implementation
to use a phase model capable of representing ±1 and ±i, such as phases modulo
four, and include the symplectic cross-phase term so anticommuting products
produce the correct sign. Normalize or validate incoming phase values, including
accumulated values from ConcatenatedCode, while preserving correct Pauli
multiplication results such as XX * ZZ = -YY.
- Around line 140-143: Update the ndarray branch of the tableau initialization
to convert or cast the NumPy array to the declared binary dtype before passing
it to SymplecticMatrix. Remove the ty suppression and preserve the existing
behavior for already-constructed SymplecticMatrix values.
- Around line 514-530: Validate that stab_rows contains no duplicate indices
before deriving m or stab_row_set in the stabilizer-selection logic. Raise a
ValueError for duplicates so the returned tableau cannot contain repeated
stabilizers or destabilizers, while preserving the existing range and
stabilizer-count validation.
- Around line 536-545: Update complete_stabilizer_tableau_with_destabilizers to
reject incomplete stabilizer/logical row sets after calculating k: validate that
the stabilizer count plus k equals the number of qubits n, and raise a clear
ValueError when the set cannot form a full 2n × 2n tableau. Preserve the
existing matched-pair validation and logical_x_rows/logical_z_rows handling for
complete inputs.
In `@src/mqt/qecc/codes/core/symplectic.py`:
- Around line 82-84: Remove content-based __hash__ implementations from
SymplecticVector and SymplecticMatrix, or make their underlying storage
immutable. Preserve Pauli, StabilizerTableau, and CheckMatrix as unhashable
while their mutable symplectic vector or matrix state remains editable; apply
these changes at src/mqt/qecc/codes/core/symplectic.py lines 82-84 and 205-207,
and verify the existing unhashable behavior at src/mqt/qecc/codes/core/pauli.py
lines 123-125, 285-287, and 717-719.
- Around line 26-29: Validate inputs in SymplecticVector.__init__ before
computing n: require a one-dimensional vector and an even length, raising
ValueError with clear messages for invalid shapes. Apply equivalent
two-dimensional and even-column validation in SymplecticMatrix, replacing silent
// 2 truncation while preserving valid (X | Z) layouts.
- Around line 53-55: Update SymplecticVector.__neg__ so negation remains in
GF(2): return a copy of the vector or reduce the negated values modulo two,
ensuring entries remain binary and -v equals v. Preserve the existing
SymplecticVector return type.
- Around line 144-152: Update SymplecticMatrix.__matmul__ so the
SymplecticVector operand returns the computed row-wise syndrome as an
NDArray[np.int8], rather than constructing a SymplecticVector; add overloads
distinguishing vector and matrix operands and replace the Any annotation and
noqa. Update StabilizerCode.get_syndrome to return this array directly while
preserving the matrix-product behavior.
In `@tests/analog_info/test_sparse_code_constructor.py`:
- Around line 24-26: In the import block for sparse_code_constructor, replace
the broad warnings.simplefilter("ignore") call with a filter that ignores only
SyntaxWarning, leaving unrelated import warnings visible. Preserve the existing
warning-capture scope and scc import.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: ae5a3d00-a48d-4ab1-aa19-2fd9e9fec0af
📒 Files selected for processing (98)
docs/AnalogInfo.mddocs/ExactSynthesis.mdscripts/encoding_circuits/codes/css/108_8_10.txtscripts/encoding_circuits/codes/css/144_12_12.txtscripts/encoding_circuits/codes/css/15_1_3.txtscripts/encoding_circuits/codes/css/15_7_3.txtscripts/encoding_circuits/codes/css/17_1_5.txtscripts/encoding_circuits/codes/css/19_1_5.txtscripts/encoding_circuits/codes/css/23_1_7.txtscripts/encoding_circuits/codes/css/31_1_7.txtscripts/encoding_circuits/codes/css/31_21_3.txtscripts/encoding_circuits/codes/css/37_1_7.txtscripts/encoding_circuits/codes/css/72_12_6.txtscripts/encoding_circuits/codes/css/90_8_10.txtscripts/examples/atd_example.pyscripts/ft_stateprep/eval/estimate_logical_error_rate.pysrc/mqt/qecc/analog_information_decoding/code_construction/code_constructor.pysrc/mqt/qecc/analog_information_decoding/code_construction/sparse_code_constructor.pysrc/mqt/qecc/cc_decoder/__init__.pysrc/mqt/qecc/cc_decoder/decoder.pysrc/mqt/qecc/cc_decoder/utils.pysrc/mqt/qecc/circuit_synthesis/circuits.pysrc/mqt/qecc/circuit_synthesis/cnot.pysrc/mqt/qecc/circuit_synthesis/elimination.pysrc/mqt/qecc/circuit_synthesis/encoding.pysrc/mqt/qecc/circuit_synthesis/exact/encoding_depth.pysrc/mqt/qecc/circuit_synthesis/exact/encoding_gate_count.pysrc/mqt/qecc/circuit_synthesis/exact/encoding_interface.pysrc/mqt/qecc/circuit_synthesis/exact/initialization.pysrc/mqt/qecc/circuit_synthesis/exact/search.pysrc/mqt/qecc/circuit_synthesis/exact/verification.pysrc/mqt/qecc/circuit_synthesis/operations.pysrc/mqt/qecc/circuit_synthesis/simulation.pysrc/mqt/qecc/circuit_synthesis/simulation_det.pysrc/mqt/qecc/circuit_synthesis/state_prep.pysrc/mqt/qecc/circuit_synthesis/strategy.pysrc/mqt/qecc/circuit_synthesis/synthesis.pysrc/mqt/qecc/circuit_synthesis/transvection.pysrc/mqt/qecc/circuit_synthesis/types.pysrc/mqt/qecc/codes/__init__.pysrc/mqt/qecc/codes/cc_4_8_8_d5/hx.npysrc/mqt/qecc/codes/cc_4_8_8_d5/hz.npysrc/mqt/qecc/codes/constructions/__init__.pysrc/mqt/qecc/codes/constructions/bb_codes.pysrc/mqt/qecc/codes/constructions/color_codes/__init__.pysrc/mqt/qecc/codes/constructions/color_codes/color_code.pysrc/mqt/qecc/codes/constructions/color_codes/hexagonal_color_code.pysrc/mqt/qecc/codes/constructions/color_codes/square_octagon_color_code.pysrc/mqt/qecc/codes/constructions/concatenation.pysrc/mqt/qecc/codes/constructions/constructions.pysrc/mqt/qecc/codes/constructions/hypergraph_product_code.pysrc/mqt/qecc/codes/constructions/rotated_surface_code.pysrc/mqt/qecc/codes/core/__init__.pysrc/mqt/qecc/codes/core/css_code.pysrc/mqt/qecc/codes/core/pauli.pysrc/mqt/qecc/codes/core/stabilizer_code.pysrc/mqt/qecc/codes/core/symplectic.pysrc/mqt/qecc/codes/hamming_15/hx.npysrc/mqt/qecc/codes/hamming_15/hz.npysrc/mqt/qecc/codes/instances/README.mdsrc/mqt/qecc/codes/instances/carbon/hx.npysrc/mqt/qecc/codes/instances/carbon/hz.npysrc/mqt/qecc/codes/instances/golay/hx.npysrc/mqt/qecc/codes/instances/golay/hz.npysrc/mqt/qecc/codes/instances/lifted_product/lp_l=16_hx.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=16_hz.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=21_hx.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=21_hz.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=30_hx.npzsrc/mqt/qecc/codes/instances/lifted_product/lp_l=30_hz.npzsrc/mqt/qecc/codes/instances/misc/15_3_5.txtsrc/mqt/qecc/codes/instances/misc/30_6_5.txtsrc/mqt/qecc/codes/instances/misc/8_3_3.txtsrc/mqt/qecc/codes/instances/shor/hx.npysrc/mqt/qecc/codes/instances/shor/hz.npysrc/mqt/qecc/codes/instances/steane/hx.npysrc/mqt/qecc/codes/instances/steane/hz.npysrc/mqt/qecc/codes/instances/tetrahedral/hx.npysrc/mqt/qecc/codes/instances/tetrahedral/hz.npysrc/mqt/qecc/codes/rotated_surface_d3/hx.npysrc/mqt/qecc/codes/rotated_surface_d3/hz.npysrc/mqt/qecc/codes/rotated_surface_d5/hx.npysrc/mqt/qecc/codes/rotated_surface_d5/hz.npytests/analog_info/test_sparse_code_constructor.pytests/circuit_synthesis/exact/conftest.pytests/circuit_synthesis/exact/test_cz_gate.pytests/circuit_synthesis/exact/test_search.pytests/circuit_synthesis/exact/test_sqrt_x_gate.pytests/circuit_synthesis/test_circuits.pytests/circuit_synthesis/test_cnot.pytests/circuit_synthesis/test_deterministic.pytests/circuit_synthesis/test_elimination.pytests/circuit_synthesis/test_encoder_synthesis.pytests/circuit_synthesis/test_operations.pytests/circuit_synthesis/test_stateprep.pytests/circuit_synthesis/test_transvection.pytests/codes/constructions/test_hypergraph_product_codes.pytests/test_code.py
💤 Files with no reviewable changes (12)
- scripts/encoding_circuits/codes/css/23_1_7.txt
- scripts/encoding_circuits/codes/css/19_1_5.txt
- scripts/encoding_circuits/codes/css/108_8_10.txt
- scripts/encoding_circuits/codes/css/90_8_10.txt
- scripts/encoding_circuits/codes/css/37_1_7.txt
- scripts/encoding_circuits/codes/css/144_12_12.txt
- scripts/encoding_circuits/codes/css/17_1_5.txt
- scripts/encoding_circuits/codes/css/15_7_3.txt
- scripts/encoding_circuits/codes/css/15_1_3.txt
- scripts/encoding_circuits/codes/css/31_21_3.txt
- scripts/encoding_circuits/codes/css/31_1_7.txt
- scripts/encoding_circuits/codes/css/72_12_6.txt
🛑 Comments failed to post (17)
scripts/examples/atd_example.py (2)
25-28: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value
Consider preserving sparsity instead of
.toarray().Each loaded sparse matrix is immediately converted to a dense array via
.toarray(). For larger lifted-product codes (e.g.,l=30), this can consume significant memory. IfAtdSimulatoraccepts sparse inputs, passing the sparse matrices directly would be more efficient. If dense arrays are required, consider adding a comment noting why.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/examples/atd_example.py` around lines 25 - 28, Update the matrix-loading assignments for Hx, Hz, Lx, and Lz in the AtdSimulator setup to preserve the sparse matrices by removing the immediate toarray conversions, provided AtdSimulator accepts sparse inputs; otherwise retain dense conversion and document the requirement with a concise comment.
27-28: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # Check whether _lx.npz and _lz.npz files exist in the lifted_product instances directory. fd -t f 'lp_l=.*_l[xz]\.npz' src/mqt/qecc/codes/instances/lifted_product/Repository: munich-quantum-toolkit/qecc
Length of output: 165
🏁 Script executed:
#!/bin/bash set -euo pipefail echo "Files in lifted_product instances directory:" fd -t f . src/mqt/qecc/codes/instances/lifted_product | sed 's#^\./##' | sort echo echo "Relevant lines from scripts/examples/atd_example.py:" cat -n scripts/examples/atd_example.py | sed -n '1,120p'Repository: munich-quantum-toolkit/qecc
Length of output: 3707
Restore the missing logical-operator instance files The example still loads
lp_l={c}_lx.npzandlp_l={c}_lz.npzfromsrc/mqt/qecc/codes/instances/lifted_product/, but only*_hx.npzand*_hz.npzare present there, so running it will raiseFileNotFoundError.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/examples/atd_example.py` around lines 27 - 28, Restore the missing lifted-product logical-operator instance files expected by the example: add the corresponding `{c}_lx.npz` and `{c}_lz.npz` artifacts under `src/mqt/qecc/codes/instances/lifted_product/`, matching the naming and format loaded by `scipy.sparse.load_npz` in the example.src/mqt/qecc/codes/constructions/color_codes/square_octagon_color_code.py (1)
152-152: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the
# noqa: PLW2901suppression by renaming the loop variable.The coding guidelines prefer fixing warnings over suppressing them and require documenting the reason when
# noqais necessary. Here the fix is trivial — use a separate variable for theenumerateoffset instead of reassigningidx.As per coding guidelines: "Prefer fixing reported warnings over suppressing them (for example, avoid
# noqaunless necessary and document why)."♻️ Proposed fix
- for idx, (x, y) in enumerate(self.octagon_ancilla_qubits): - idx += len(self.square_ancilla_qubits) # noqa: PLW2901 + for offset, (x, y) in enumerate(self.octagon_ancilla_qubits): + idx = offset + len(self.square_ancilla_qubits)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.for offset, (x, y) in enumerate(self.octagon_ancilla_qubits): idx = offset + len(self.square_ancilla_qubits)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/constructions/color_codes/square_octagon_color_code.py` at line 152, In the loop containing the `idx += len(self.square_ancilla_qubits)` statement, stop reassigning the `enumerate` variable `idx`: introduce a separate variable for the adjusted offset, update subsequent uses to reference it, and remove the `# noqa: PLW2901` suppression.Source: Coding guidelines
src/mqt/qecc/codes/constructions/hypergraph_product_code.py (3)
40-55: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win
Avoid densifying boundary-map products during validation.
The products are already sparse; converting each with
.todense()can create a large temporary allocation solely to test zero modulo two. Reuse_sparse_all_zeros.- _is_all_zeros((sd_1 * sd_2).todense() % 2) - and _is_all_zeros((sd_2 * sd_3).todense() % 2) - and _is_all_zeros((sd_3 * sd_4).todense() % 2) + _sparse_all_zeros(sd_1 @ sd_2) + and _sparse_all_zeros(sd_2 @ sd_3) + and _sparse_all_zeros(sd_3 @ sd_4)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/constructions/hypergraph_product_code.py` around lines 40 - 55, The _run_checks_scipy validation currently densifies sparse boundary-map products before checking them. Replace each .todense()-based _is_all_zeros check with _sparse_all_zeros applied to the corresponding product modulo two, preserving the existing error and validation behavior.
58-60: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Make
checkskeyword-only.This resolves Ruff FBT001/FBT002 and prevents positional Boolean calls with unclear meaning. As per coding guidelines, prefer fixing reported warnings over suppressing them.
def generate_4d_product_code( - a_1: ..., a_2: ..., a_3: ..., p: ..., checks: bool = True + a_1: ..., a_2: ..., a_3: ..., p: ..., *, checks: bool = TrueApply the same change to
generate_sparse_4d_product_code.Also applies to: 120-126
🧰 Tools
🪛 Ruff (0.15.20)
[warning] 59-59: Boolean-typed positional argument in function definition
(FBT001)
[warning] 59-59: Boolean default positional argument in function definition
(FBT002)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/constructions/hypergraph_product_code.py` around lines 58 - 60, Make the checks parameter keyword-only by adding the keyword-only separator before checks in both generate_4d_product_code and generate_sparse_4d_product_code. Preserve the existing default value and behavior while requiring callers to pass checks by name.Sources: Coding guidelines, Linters/SAST tools
61-61: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Document the public generator contracts in Google style.
Add
Args,Returns, andRaisessections, including matrix compatibility, returned boundary-map ordering, and validation failures. As per coding guidelines, Python code must use Google-style docstrings.Also applies to: 95-95, 127-127, 164-164
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/constructions/hypergraph_product_code.py` at line 61, Update the public generator docstrings at the definitions near “Generate 4D product code” and the other referenced generators to use Google style, adding Args, Returns, and Raises sections. Document required matrix compatibility, the ordering and meaning of returned boundary maps, and the validation exceptions raised, while preserving the existing generator behavior.Source: Coding guidelines
src/mqt/qecc/codes/core/css_code.py (1)
202-221: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Update the remaining
hammingcaller before removing this mapping.
scripts/ft_stateprep/eval/estimate_logical_error_rate.pystill listshammingas available and routes it toCSSCode.from_code_name. Line 219 now rejects that valid CLI choice. Add a dedicatedconstruct_quantum_hamming_code(4)branch there or stop advertising it.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/css_code.py` around lines 202 - 221, Update the hamming handling in estimate_logical_error_rate so the advertised CLI choice remains valid: add a dedicated construct_quantum_hamming_code(4) path before calling CSSCode.from_code_name, or remove hamming from the available choices. Ensure CSSCode.from_code_name is not invoked with hamming.src/mqt/qecc/codes/core/pauli.py (5)
29-38: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Correct the Pauli phase model before exposing multiplication.
Adding sign bits is insufficient:
XX * ZZshould produce-YY, while the implementation returns+YY; anticommuting products additionally require phases±i, which this representation cannot encode. Either represent phases modulo four or restrict multiplication appropriately and include the symplectic cross-phase term. Also validate or normalize constructor phases—ConcatenatedCodecan currently pass accumulated values greater than one.Also applies to: 65-70
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/pauli.py` around lines 29 - 38, Update Pauli.__init__ and the multiplication implementation to use a phase model capable of representing ±1 and ±i, such as phases modulo four, and include the symplectic cross-phase term so anticommuting products produce the correct sign. Normalize or validate incoming phase values, including accumulated values from ConcatenatedCode, while preserving correct Pauli multiplication results such as XX * ZZ = -YY.
140-143: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Resolve the NumPy type instead of suppressing
ty.Convert or cast the array to the declared binary dtype before constructing
SymplecticMatrix. As per coding guidelines, prefer fixing type-checking issues reported bytybefore adding# ty: ignore[code]suppressions.- self.tableau = SymplecticMatrix(tableau) # ty: ignore[invalid-argument-type] + self.tableau = SymplecticMatrix(np.asarray(tableau, dtype=np.int8))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.if isinstance(tableau, np.ndarray): self.tableau = SymplecticMatrix(np.asarray(tableau, dtype=np.int8)) else: self.tableau = tableau🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/pauli.py` around lines 140 - 143, Update the ndarray branch of the tableau initialization to convert or cast the NumPy array to the declared binary dtype before passing it to SymplecticMatrix. Remove the ty suppression and preserve the existing behavior for already-constructed SymplecticMatrix values.Source: Coding guidelines
485-613: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift
Split the destabilizer completion routine into focused helpers.
Ruff reports 21 branches and 63 statements. Extract input validation, logical-row partitioning, single-destabilizer construction, and result assembly so this correctness-critical algorithm can be tested independently. As per coding guidelines, prefer fixing reported warnings over suppressing them.
🧰 Tools
🪛 Ruff (0.15.20)
[warning] 485-485: Too many branches (21 > 12)
(PLR0912)
[warning] 485-485: Too many statements (63 > 50)
(PLR0915)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/pauli.py` around lines 485 - 613, Refactor complete_stabilizer_tableau_with_destabilizers into focused helpers for input validation, logical-row partitioning, individual destabilizer construction, and final tableau assembly. Move the corresponding checks and algorithm stages into independently testable functions while preserving row ordering, phases, validation errors, and destabilizer-correction behavior; do not suppress Ruff complexity warnings.Sources: Coding guidelines, Linters/SAST tools
514-530: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Reject duplicate stabilizer-row indices.
Duplicates make
mdisagree withstab_row_set, causing repeated stabilizers and destabilizers in the returned tableau.stab_rows = list(range(m_total)) + if len(stab_rows) != len(set(stab_rows)): + raise ValueError("stab_rows must not contain duplicate indices.") + if not stab_rows:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.if stab_rows is None: stab_rows = list(range(m_total)) if len(stab_rows) != len(set(stab_rows)): raise ValueError("stab_rows must not contain duplicate indices.") if not stab_rows: return stabilizers.copy() if max(stab_rows) >= m_total or min(stab_rows) < 0: msg = f"Row indices in stab_rows must be between 0 and {m_total - 1}." raise ValueError(msg) m = len(stab_rows) if m > n: msg = "Cannot have more stabilizers than qubits." raise ValueError(msg) stab_row_set = set(stab_rows)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/pauli.py` around lines 514 - 530, Validate that stab_rows contains no duplicate indices before deriving m or stab_row_set in the stabilizer-selection logic. Raise a ValueError for duplicates so the returned tableau cannot contain repeated stabilizers or destabilizers, while preserving the existing range and stabilizer-count validation.
536-545: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail # Inspect the relevant function and nearby context. file="src/mqt/qecc/codes/core/pauli.py" wc -l "$file" sed -n '470,580p' "$file" # Look for the function name and any related tests/usages. rg -n "complete_stabilizer_tableau_with_destabilizers|destabilizers|logical X/Z pairs|full 2n|2n × 2n|2n x 2n" src tests -SRepository: munich-quantum-toolkit/qecc
Length of output: 7839
🏁 Script executed:
#!/bin/bash set -euo pipefail # Read the remainder of the function and the nearby caller. sed -n '580,640p' src/mqt/qecc/codes/core/pauli.py sed -n '450,520p' src/mqt/qecc/circuit_synthesis/encoding.py # Inspect the related test coverage for this function. sed -n '927,985p' tests/test_code.pyRepository: munich-quantum-toolkit/qecc
Length of output: 6999
🏁 Script executed:
#!/bin/bash set -euo pipefail # Inspect the tableau class docs/invariants around the relevant methods. sed -n '1,260p' src/mqt/qecc/codes/core/pauli.py sed -n '260,460p' src/mqt/qecc/codes/core/pauli.py # Search for any explicit "full 2n x 2n" contract on this function or its inputs. rg -n "full 2n x 2n|2n x 2n tableau|full tableau|complete_stabilizer_tableau_with_destabilizers|symplectic_submatrix requires" src/mqt/qecc/codes/core/pauli.py src/mqt/qecc/circuit_synthesis/encoding.py tests -SRepository: munich-quantum-toolkit/qecc
Length of output: 18995
Reject incomplete stabilizer/logical sets.
complete_stabilizer_tableau_with_destabilizersonly returns a full2n × 2ntableau whenm + k == n; otherwise it silently produces a non-full tableau. Add a guard here or derive the missing logical pairs before proceeding.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/pauli.py` around lines 536 - 545, Update complete_stabilizer_tableau_with_destabilizers to reject incomplete stabilizer/logical row sets after calculating k: validate that the stabilizer count plus k equals the number of qubits n, and raise a clear ValueError when the set cannot form a full 2n × 2n tableau. Preserve the existing matched-pair validation and logical_x_rows/logical_z_rows handling for complete inputs.src/mqt/qecc/codes/core/symplectic.py (4)
26-29: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Reject malformed symplectic dimensions.
Odd vector lengths or matrix column counts are silently truncated by
// 2, producing an invalid(X | Z)layout. Validate one-dimensional vectors, two-dimensional matrices, and even symplectic widths with explicitValueErrors.Proposed validation
def __init__(self, vector: npt.NDArray[np.int8]) -> None: - self.vector = vector + if vector.ndim != 1 or vector.shape[0] % 2 != 0: + raise ValueError("A symplectic vector must have even length.") + self.vector = vector self.n = vector.shape[0] // 2Apply the equivalent even-column validation to
SymplecticMatrix.Also applies to: 98-103
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/symplectic.py` around lines 26 - 29, Validate inputs in SymplecticVector.__init__ before computing n: require a one-dimensional vector and an even length, raising ValueError with clear messages for invalid shapes. Apply equivalent two-dimensional and even-column validation in SymplecticMatrix, replacing silent // 2 truncation while preserving valid (X | Z) layouts.
53-55: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Keep negation inside GF(2).
Unary negation currently introduces
-1entries. Over GF(2),-v == v; return a copy or reduce modulo two.- return SymplecticVector(-self.vector) + return SymplecticVector((-self.vector) % 2)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.def __neg__(self) -> SymplecticVector: """Negate the vector.""" return SymplecticVector((-self.vector) % 2)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/symplectic.py` around lines 53 - 55, Update SymplecticVector.__neg__ so negation remains in GF(2): return a copy of the vector or reduce the negated values modulo two, ensuring entries remain binary and -v equals v. Preserve the existing SymplecticVector return type.
82-84: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Remove content-based hashing from mutable algebra objects.
Mutation after insertion into a dictionary or set changes these hashes and breaks lookup invariants;
StabilizerCode.__hash__also transitively depends on them.
src/mqt/qecc/codes/core/symplectic.py#L82-L84: removeSymplecticVector.__hash__or make its storage immutable.src/mqt/qecc/codes/core/symplectic.py#L205-L207: removeSymplecticMatrix.__hash__or make its storage immutable.src/mqt/qecc/codes/core/pauli.py#L123-L125: keepPauliunhashable while its symplectic vector remains mutable.src/mqt/qecc/codes/core/pauli.py#L285-L287: keepStabilizerTableauunhashable because gate methods mutate it.src/mqt/qecc/codes/core/pauli.py#L717-L719: keepCheckMatrixunhashable while its public matrix can be edited.📍 Affects 2 files
src/mqt/qecc/codes/core/symplectic.py#L82-L84(this comment)src/mqt/qecc/codes/core/symplectic.py#L205-L207src/mqt/qecc/codes/core/pauli.py#L123-L125src/mqt/qecc/codes/core/pauli.py#L285-L287src/mqt/qecc/codes/core/pauli.py#L717-L719🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/symplectic.py` around lines 82 - 84, Remove content-based __hash__ implementations from SymplecticVector and SymplecticMatrix, or make their underlying storage immutable. Preserve Pauli, StabilizerTableau, and CheckMatrix as unhashable while their mutable symplectic vector or matrix state remains editable; apply these changes at src/mqt/qecc/codes/core/symplectic.py lines 82-84 and 205-207, and verify the existing unhashable behavior at src/mqt/qecc/codes/core/pauli.py lines 123-125, 285-287, and 717-719.
144-152: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Return syndrome bits instead of a malformed
SymplecticVector.A matrix-vector symplectic product has one bit per matrix row, not necessarily an even-length
(X | Z)vector. For example, three stabilizers currently produce aSymplecticVectorwhosenis incorrectly set to one. Return anNDArray[np.int8], add overloads, and updateStabilizerCode.get_syndrometo return that array directly.This also removes the unnecessary
Anyannotation and# noqa. As per coding guidelines, prefer fixing reported warnings over suppressing them.Proposed return contract
+ `@overload` + def __matmul__(self, other: SymplecticVector) -> npt.NDArray[np.int8]: ... + + `@overload` + def __matmul__(self, other: SymplecticMatrix) -> SymplecticMatrix: ... + - def __matmul__(self, other: SymplecticMatrix | SymplecticVector) -> Any: # noqa: ANN401 + def __matmul__( + self, other: SymplecticMatrix | SymplecticVector + ) -> SymplecticMatrix | npt.NDArray[np.int8]: ... if isinstance(other, SymplecticVector): - return SymplecticVector((self.matrix[:, :n] @ other[n:] + self.matrix[:, n:] @ other[:n]) % 2) + return np.asarray( + (self.matrix[:, :n] @ other[n:] + self.matrix[:, n:] @ other[:n]) % 2, + dtype=np.int8, + )📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.`@overload` def __matmul__(self, other: SymplecticVector) -> npt.NDArray[np.int8]: ... `@overload` def __matmul__(self, other: SymplecticMatrix) -> SymplecticMatrix: ... def __matmul__( self, other: SymplecticMatrix | SymplecticVector ) -> SymplecticMatrix | npt.NDArray[np.int8]: """Compute the symplectic product of two matrices.""" assert self.n == other.n, "Matrices must be of the same size." n = self.n if isinstance(other, SymplecticVector): return np.asarray( (self.matrix[:, :n] @ other[n:] + self.matrix[:, n:] @ other[:n]) % 2, dtype=np.int8, ) m1 = self.matrix m2 = other.matrix return SymplecticMatrix(((m1[:, :n] @ m2[:, n:].T) + (m1[:, n:] @ m2[:, :n].T)) % 2)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/mqt/qecc/codes/core/symplectic.py` around lines 144 - 152, Update SymplecticMatrix.__matmul__ so the SymplecticVector operand returns the computed row-wise syndrome as an NDArray[np.int8], rather than constructing a SymplecticVector; add overloads distinguishing vector and matrix operands and replace the Any annotation and noqa. Update StabilizerCode.get_syndrome to return this array directly while preserving the matrix-product behavior.Source: Coding guidelines
tests/analog_info/test_sparse_code_constructor.py (1)
24-26: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash set -euo pipefail echo '--- test file outline ---' ast-grep outline tests/analog_info/test_sparse_code_constructor.py --view expanded || true echo '--- test file lines ---' cat -n tests/analog_info/test_sparse_code_constructor.py | sed -n '1,220p' echo '--- search warning suppressions and bposd references ---' rg -n "warnings\.catch_warnings|filterwarnings|simplefilter|SyntaxWarning|bposd" tests mqt . -g '!**/.git/**' || trueRepository: munich-quantum-toolkit/qecc
Length of output: 10260
🏁 Script executed:
#!/bin/bash set -euo pipefail echo '--- pyproject warnings config ---' cat -n pyproject.toml | sed -n '110,150p' echo '--- locate installed bposd package without importing it ---' python3 - <<'PY' import importlib.util spec = importlib.util.find_spec("bposd") print("spec:", spec) if spec is not None: print("origin:", spec.origin) print("submodule_search_locations:", list(spec.submodule_search_locations or [])) PY echo '--- locate package files if present in site-packages ---' python3 - <<'PY' import importlib.util, pathlib, sys spec = importlib.util.find_spec("bposd") if spec is None: raise SystemExit("bposd not installed") paths = [] if spec.origin: paths.append(pathlib.Path(spec.origin)) for p in spec.submodule_search_locations or []: paths.append(pathlib.Path(p)) for p in paths: print(p) PYRepository: munich-quantum-toolkit/qecc
Length of output: 2245
🌐 Web query:
bposd invalid escape sequences SyntaxWarning Python 3.12 source import warning💡 Result:
In Python 3.12, the "SyntaxWarning: invalid escape sequence" occurs because Python has changed how it handles backslashes that do not form a valid escape sequence [1][2]. Background and Cause: Historically, Python treated unknown backslash-character pairs (like \d, ., or \s, commonly found in regular expressions or Windows file paths) as literal characters while issuing a silent DeprecationWarning [1][2]. Starting with Python 3.12, this behavior was upgraded to a visible SyntaxWarning to encourage developers to use correct syntax [2]. This change is part of a multi-version process to eventually make these invalid sequences a SyntaxError, which will allow Python to introduce new escape sequences in the future without breaking existing code [2][3]. How to Fix: There are two primary ways to resolve this warning: 1. Use Raw Strings (Recommended): Prefix the string literal with r or R (e.g., r"\d+.\d+"). Raw strings treat backslashes as literal characters, which is ideal for regular expressions, Windows file paths, and other strings containing many backslashes [1][3][4]. 2. Double the Backslash: If you need to keep a standard string (for example, if it contains valid escape sequences like \n that you want to keep interpreted), escape the backslash by adding a second one (e.g., "\d" instead of "\d") [5][1][3]. If you are encountering this in a third-party library, it is recommended to update the package to its latest version, as many maintainers have addressed this in recent releases [4]. Alternatively, you can suppress the warning if necessary, though fixing the code is preferred as the syntax will eventually become invalid [2].
Citations:
- 1: python/cpython#119458
- 2: python/cpython#99011
- 3: https://adamj.eu/tech/2022/11/04/why-does-python-deprecationwarning-invalid-escape-sequence/
- 4: python/cpython#125689
- 5: python/cpython#98401
Narrow the warning filter here.
simplefilter("ignore")suppresses every import warning in this block; scope it to theSyntaxWarningfrombposdinstead.Proposed narrowing
with warnings.catch_warnings(): - warnings.simplefilter("ignore") + warnings.filterwarnings( + "ignore", + category=SyntaxWarning, + module=r"bposd(?:\.|$)", + ) import mqt.qecc.analog_information_decoding.code_construction.sparse_code_constructor as scc📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.with warnings.catch_warnings(): warnings.filterwarnings( "ignore", category=SyntaxWarning, module=r"bposd(?:\.|$)", ) import mqt.qecc.analog_information_decoding.code_construction.sparse_code_constructor as scc🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/analog_info/test_sparse_code_constructor.py` around lines 24 - 26, In the import block for sparse_code_constructor, replace the broad warnings.simplefilter("ignore") call with a filter that ignores only SyntaxWarning, leaving unrelated import warnings visible. Preserve the existing warning-capture scope and scc import.Source: Coding guidelines
Removing "hamming" from `CSSCode.from_code_name` left it advertised in the script's `available_codes` while routing to `from_code_name`, so `--code hamming` now raised. Route it to `construct_quantum_hamming_code(4)` (the [[15, 7, 3]] code the removed instance provided) instead, mirroring how the `surface` case was already switched to `RotatedSurfaceCode`.
Address review feedback on the centralized product-code module: - make the `checks` flag keyword-only in the 4D generators (callers already pass it by name); - expand the four public generators' docstrings to Google style with Args/Returns/Raises, documenting the boundary-map ordering; - check the 4D boundary maps via `_sparse_all_zeros` instead of densifying the products with `.todense()`.
Scope the suppression around the `sparse_code_constructor` import to `SyntaxWarning` only, so unrelated warnings from the import remain visible.
Narrowing the filter to `SyntaxWarning` broke CI on Python 3.10/3.11:
there, bposd's invalid escape sequences raise a DeprecationWarning (only
3.12+ categorizes them as SyntaxWarning), so the filter missed them and
`filterwarnings = ["error"]` escalated the import to a collection error.
Filter by message instead ("invalid escape sequence"), which is
category-agnostic and stays narrow, so it suppresses only that warning on
every supported Python version.
# Conflicts: # src/mqt/qecc/analog_information_decoding/code_construction/code_constructor.py # src/mqt/qecc/analog_information_decoding/code_construction/sparse_code_constructor.py # src/mqt/qecc/circuit_synthesis/cnot.py # src/mqt/qecc/circuit_synthesis/exact/search.py # src/mqt/qecc/circuit_synthesis/strategy.py # src/mqt/qecc/circuit_synthesis/transvection.py
The merge commit swept in files written to the repo root by the test
suite (`res`, `results/`, `schedule_*.pkl`) via `git add -A`. The empty
`res` file broke the `license-tools` pre-commit hook ("Failed to
determine comment style"). Remove them and add matching `.gitignore`
patterns so they cannot be re-committed.
The message-based filter failed on Python 3.14: invalid escape sequences
are still only a warning there, but the message wording changed
("\"\\i\" is an invalid escape sequence" instead of "invalid escape
sequence '\\i'"), so the anchored message regex no longer matched and
`filterwarnings = ["error"]` escalated the bposd import to a collection
error.
Ignore by warning category instead (DeprecationWarning on Python <= 3.11,
SyntaxWarning on >= 3.12), which is robust to the wording changes.
Verified the import succeeds under strict warnings on 3.10 through 3.14.
Description
BREAKING CHANGES
This refactor PR restructures and unifies the concrete QECC in the project, meaning hard-coded instances, generator scripts, and representation classes. Instead of having hardcoded check-matrix files and construction scripts scattered throughout the repo, I centralized them in
src/mqt/qecc/codes/. As generator scripts, core representation classes, and check-matrix were on the same hierarchical level insrc/mqt/qecc/codes/, a new structure is introduced:Even though sometimes useful, I removed some
CSScode.from_file(...)options ("hamming", "surface") that can be generated by dedicated external scripts. The reason for that was to remove unnecessary hard-coded instances and to semantically separate the (independent) container/representation class from the construction of other, more specialized, instances.Note: Due to centralization, I moved the (previously untested) construction of 3D/4D HGP codes to
src/mqt/qecc/codes/constructions. Thus, I needed to add more tests, which are currently rather simple and should be reviewed and extended.Fixes #736
Assisted-by: Codex via GPT-5.5 as first reviewer and enhanced global search (reviewed by me)
Checklist
If PR contains AI-assisted content:
Assisted-by: [Model Name] via [Tool Name]footer.