Skip to content

🧹 Unify one-qubit synthesis and clarify test ownership #2614

Description

@burgholzer

🤖 AI text below 🤖

Problem Statement

Follow-up to #2559. The focused fix preserves symbolic Euler chains and compact H/RZ synthesis, but leaves three connected maintenance problems:

  • Optional target pointers select more than native capabilities: they also select profitability, controlled-body ownership, and whether synthesis may emit general runtime expressions. U-based compilation retains a separate optimizer because native synthesis alone does not cover the same controlled-body and singleton behavior.
  • Constant one-qubit runs have both matrix-based and quaternion-based composition/Euler extraction. Symbolic composition already shares code, and two-qubit Weyl synthesis calls the matrix-based one-qubit emitter for its local factors. The overlapping one-qubit machinery needs consolidation; Weyl decomposition still serves a distinct purpose.
  • test/python/test_mlir.py mixes Python API and exporter contracts with compiler semantics that belong in C++ tests. PR 🐛 Preserve symbolic Euler chains in target synthesis #2559 trims its own additions; the rest needs an ownership audit before removing coverage.

Proposed Solution

1. Make internal synthesis contracts explicit

Resolve the requested Euler basis, native support, profitability, controlled-operation ownership, and permitted runtime expressions at pass boundaries. Stop using target nullability to choose these policies. Preserve targetless public wrappers and logical export/register semantics; do not invent physical sites for logical programs. Keep the requested basis explicit because identical native gate sets can admit different Euler orders.

Reuse existing target and basis representations where sufficient. Retain singleton behavior, native operations, site-specific support, bounded gate operands, and controlled phase. Remove the U-specific scheduling split only when compilation and synthesis cover the same supported controlled-body cases. The controlled U2-to-U restoration added in #2559 is part of this parity contract.

2. Benchmark equivalent one-qubit implementations, then consolidate

Compare matrix and quaternion implementations using identical inputs, requested bases, emission rules, and tolerances. Include constant named runs, arbitrary dense matrices, short and long runs, cancellations, phase/wrap boundaries, and the one-qubit factors emitted by Weyl synthesis. Establish feature parity before comparing speed.

Measure both isolated synthesis and complete compilation: repeated optimized-build wall times, emitted gate counts, and scalar/quantum IR size. Fix seeds, input data, compiler options, revisions, and environment, and report variation and workload-specific regressions. Keep ad hoc harnesses and raw artifacts outside the repository, following the development policy.

Correctness, exportability, and circuit quality are prerequisites. Select the faster constant implementation among equivalent candidates; choose the smaller implementation if measurements are inconclusive. Keep direct symbolic identities and the necessary runtime path, while sharing run handling, phase accounting, emission, and public pass wrappers. Avoid maintaining both constant algorithms without measured justification.

Preserve the large symbolic workload removed from routine unit tests: Qiskit efficient_su2(100, reps=3, entanglement="circular"), with global phase source.parameters[0] / 5 - 0.3, compiled for an all-to-all SX/X/RZ/CZ target with global-phase support. Check parameter identity, target membership, export, and late binding for zero, pi, 2*pi, and mixed values. Use the two-qubit version for full-matrix comparisons; do not attempt a dense 100-qubit matrix. These workloads do not imply a measured winner yet.

3. Audit Python tests by ownership

Map each numerical/compiler assertion to a C++ owner before removing it. Keep Python-specific input conversions, overloads/defaults, copy/consume behavior, exception translation, GIL release, parameter identities, late binding, and Qiskit/jeff export. Move missing numerical contracts into their owning C++ subsystem first. Use small representative integration inputs rather than reproducing exhaustive basis/angle matrices in Python.

Completion requires one shared one-qubit synthesis implementation with the necessary static and symbolic paths, removal of the redundant U scheduling branch after parity checks, a recorded benchmark comparison, and a coverage ownership map for the Python reductions. No public API break is required.

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

Metadata

Metadata

Assignees

Labels

MLIRAnything related to MLIRpythonAnything related to Python coderefactorAnything related to code refactoring

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions