You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MQT Core can represent qubit registers as memref values in QC and linear QTensor values in QCO, but reusable functions cannot carry those registers consistently across builders, QC↔QCO conversion, and compiler targets. The current paths either reject register operands, require direct allocations, flatten the function, or fail later in target conversion.
This blocks modular algorithms that operate on a complete register and makes each frontend or target solve the same ownership problem independently.
Proposed Solution
Define one shared register-call contract in QC and QCO, then implement only the target mappings that preserve it:
// QC borrows the register by reference.func.func@f(%q:memref<4x!qc.qubit>)
// QCO transfers linear state through an explicit result.func.func@f(%q:tensor<4x!qco.qubit>)
-> tensor<4x!qco.qubit>
Use ordinary func.call. Do not extend the scalar-unitary qc.call or qco.call contract.
Support rank-one static and dynamic register types in the core IR contract.
In QCO, place ordinary results first, followed by one pass-through result for every scalar-qubit or qubit-register argument in argument order.
In QC, treat corresponding register arguments as borrowed references and erase only those pass-through results during QCO→QC conversion.
Reject unsupported declarations, recursion, views, casts, uncertain aliases, and incomplete quantum-result correspondence with diagnostics.
Delivery
Implement the feature as three dependent pull requests:
These implementation issues are also attached as native sub-issues.
Target decisions
jeff
jeff already has linear qureg values and typed function calls. Existing QCO↔jeff type and call conversion should need regression coverage, not a separate implementation layer.
OpenQASM 3
OpenQASM 3 subroutines accept typed qubit[N] arguments by reference and require distinct quantum operands. Preserve a deliberately small initial subset: fixed-size, defined, non-recursive, void subroutines with whole-register operands.
QIR
QIR 2.1 Adaptive supports arrays and IR functions. Preserve fixed-size borrowed register helpers with a caller-owned array ABI. Keep Base Profile inlining. Defer dynamic register formals until an explicit (ptr, length) ABI and lifetime contract are required.
Qiskit
Qiskit Gate and Instruction use a fixed flat sequence of qubit operands and do not preserve register-formal boundaries. Register-taking helpers must be inlined before Qiskit export. Qiskit import cannot reconstruct the boundary. Do not add private metadata or claim a lossless round trip. Add target-specific selective inlining only after a concrete export use case shows that callers cannot run the existing inliner themselves.
Completion criteria
The core contract is documented, verified, and tested for static and dynamic rank-one registers.
jeff serialization preserves register helper signatures and calls.
🤖 AI text below 🤖
Problem Statement
MQT Core can represent qubit registers as
memrefvalues in QC and linearQTensorvalues in QCO, but reusable functions cannot carry those registers consistently across builders, QC↔QCO conversion, and compiler targets. The current paths either reject register operands, require direct allocations, flatten the function, or fail later in target conversion.This blocks modular algorithms that operate on a complete register and makes each frontend or target solve the same ownership problem independently.
Proposed Solution
Define one shared register-call contract in QC and QCO, then implement only the target mappings that preserve it:
func.call. Do not extend the scalar-unitaryqc.callorqco.callcontract.Delivery
Implement the feature as three dependent pull requests:
defsubset.These implementation issues are also attached as native sub-issues.
Target decisions
jeff
jeff already has linear
quregvalues and typed function calls. Existing QCO↔jeff type and call conversion should need regression coverage, not a separate implementation layer.OpenQASM 3
OpenQASM 3 subroutines accept typed
qubit[N]arguments by reference and require distinct quantum operands. Preserve a deliberately small initial subset: fixed-size, defined, non-recursive, void subroutines with whole-register operands.QIR
QIR 2.1 Adaptive supports arrays and IR functions. Preserve fixed-size borrowed register helpers with a caller-owned array ABI. Keep Base Profile inlining. Defer dynamic register formals until an explicit
(ptr, length)ABI and lifetime contract are required.Qiskit
Qiskit
GateandInstructionuse a fixed flat sequence of qubit operands and do not preserve register-formal boundaries. Register-taking helpers must be inlined before Qiskit export. Qiskit import cannot reconstruct the boundary. Do not add private metadata or claim a lossless round trip. Add target-specific selective inlining only after a concrete export use case shows that callers cannot run the existing inliner themselves.Completion criteria
arrays=trueandir_functions=true; Base Profile does not retain them.mqt-ccpipelines agree.Related issues
arrayin the OpenQASM frontend #2109 tracks general OpenQASM classical arrays.Non-goals
Register-valued unitary modifiers; arbitrary memref layouts or memory spaces; register views and slices; recursive register functions; Qiskit-specific boundary metadata; dynamic register parameters in OpenQASM or QIR.