๐บ๏ธ RFC: MQT MLIR Compilation Infrastructure #1225
Replies: 31 comments 82 replies
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
-
|
I just wanted to quickly add the thoughts I had when reading the proposal - mainly regarding implementation details:
|
Beta Was this translation helpful? Give feedback.
-
I don't exactly understand what the implications of this (true statement) are in terms of canonicalization. Do we want to canonicalize diagonal gates into a certain order? |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
|
For the barrier gate of any size to have valid traits, do we need to define a trait |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
|
I'm struggling to imagine how to use the C++ builders with nested modifiers (in particular, for the Flux case). Wouldn't the input targets of the outer modifier depend on the return values of the lambda pf the inner modifier? Or would we then also have a Maybe this is more complicated in my head than it is in reality. |
Beta Was this translation helpful? Give feedback.
-
|
Regarding the section on integration tests and just for clarification, do we plan to provide a direct translation between OpenQASM 3.0 and MQT MLIR, or will this go through the |
Beta Was this translation helpful? Give feedback.
-
|
Regarding the First, why is a barrier a unitary? Second, would it make sense to (following a similar argument as to the allocQubitRegisters) to define a barrier for a single qubit SSA value to make the def-use chain clearer? Currently, it's necessary to traverse the inputs to find the respective index to get the corresponding output qubit. |
Beta Was this translation helpful? Give feedback.
-
|
A separate comment to discuss the "unitary matrix" proposal: I think the current approach of simply providing the matrix only for non-parameterized gates is insufficient if we want to fully replace the matrix definitions of the Although there is still much work required (e.g. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Note
This document is a working version and not necessarily up to date.
#1264 is the first in a series of PRs addressing the redesign.
MQT MLIR Compilation Infrastructure: Technical Concept
Executive Summary
This document describes the technical design of the MQT's MLIR-based compilation infrastructure for quantum computing.
The infrastructure provides a unified, extensible framework for quantum circuit representation, optimization, and compilation through a multi-dialect architecture built on MLIR (Multi-Level Intermediate Representation).
Architecture Overview:
The MQT MLIR infrastructure consists of two complementary dialects that work together to enable flexible quantum program representation and optimization:
quartz): Uses reference semantics with in-place qubit mutation, optimized for direct hardware mapping and straightforward translation to/from existing quantum programming languages.flux): Uses SSA value semantics with functional-style transformations, designed for powerful compiler optimizations and circuit transformations.Both dialects implement a unified unitary interface, composable gate modifiers, and comprehensive canonicalization frameworks that enable seamless interoperability and progressive optimization strategies.
Key Features:
Design Rationale:
The dual-dialect architecture reflects a fundamental insight: different stages of quantum compilation benefit from different representations.
Reference semantics (Quartz) provides a natural bridge to hardware and existing quantum programming ecosystems, while value semantics (Flux) unlocks the full power of compiler analysis and optimization.
Conversion passes between dialects enable compilation strategies that leverage the strengths of each representation at the appropriate stage.
1. Overview and Design Philosophy
The MQT MLIR compilation infrastructure represents a comprehensive approach to quantum program compilation, building on MLIR's proven multi-level intermediate representation framework.
This design enables quantum computing to benefit from decades of classical compiler research while addressing the unique challenges of quantum circuits.
Design Goals:
negctrl โ ctrl โ pow โ inv) to simplify pattern matching and optimizationArchitectural Principles:
2. Motivation and Context
The MLIR Opportunity:
MLIR provides a proven framework for building progressive compilation pipelines with multiple levels of abstraction.
By building quantum compilation infrastructure on MLIR, we gain:
Why Dual Dialects?
The Quartz/Flux dual-dialect architecture reflects a key insight: quantum compilation benefits from different semantic models at different stages:
Quartz (Reference Semantics): Provides an intuitive, hardware-like model where gates modify qubits in place. These semantics align naturally with:
Flux (Value Semantics): Provides a functional, SSA-based model where operations produce new quantum values. These semantics enable:
Conversion passes between dialects allow compilation strategies to use the right representation at the right time.
3. Dialect Architecture
The MQT MLIR infrastructure consists of two parallel dialects with identical operation sets but different operational semantics.
This section describes the architectural design shared across both dialects.
3.1 Dialect Overview
Quartz Dialect (
quartz):Quartz uses reference semantics where quantum operations modify qubits in place, similar to how hardware physically transforms quantum states.
This model provides:
The name "Quartz" reflects the crystalline, structured nature of hardware-oriented representationsโoperations have fixed positions and transform states in place, like atoms in a crystal lattice.
Example:
Flux Dialect (
flux):Flux uses value semantics where quantum operations consume input qubits and produce new output values, following the functional programming and SSA paradigm.
This model enables:
The name "Flux" captures the flowing, transformative nature of value-based representationsโquantum states flow through operations, each transformation producing new values like a river flowing through a landscape.
Example:
Dialect Interoperability:
Both dialects share operation names and core semantics, differing only in their type systems and value threading models. Bidirectional conversion passes enable flexible compilation strategies:
This architecture allows:
Future Extensibility:
The architecture anticipates additional dialects for:
Each dialect can target specific optimization goals while maintaining interoperability through conversion passes.
3.2 Operation Categories
All operations fall into three primary categories:
UnitaryOpInterface(base gates, modifiers, sequences, custom gates)3.3 Resource Operations
Purpose: Manage qubit lifetime and references.
Qubit and Register Allocation:
The MQT MLIR dialects represent quantum and classical registers using MLIR-native
memrefoperations rather than custom types. This design choice offers several advantages:Quantum Register Representation:
A quantum register is represented by a
memrefof type!quartz.Qubitor!flux.Qubit:Classical Register Representation:
Classical registers follow the same pattern but use the
i1type for Boolean measurement results:Quartz Dialect (Reference Semantics):
Flux Dialect (Value Semantics):
Canonicalization Patterns:
allocoperations (DCE)3.4 Measurement and Reset
Non-unitary operations that do not implement the
UnitaryOpInterface.Measurement Basis: All measurements are performed in the computational basis (Z-basis). Measurements in other bases must be implemented by applying appropriate basis-change gates before measurement.
Single-Qubit Measurements Only: Multi-qubit measurements are explicitly not supported. Joint measurements must be decomposed into individual single-qubit measurements.
Quartz Dialect (Reference Semantics):
Flux Dialect (Value Semantics):
Canonicalization Patterns:
resetimmediately afterallocโ removereset(already in ground state)reseton same qubit (reference semantics) โ single instance3.5 Unified Unitary Interface Design
All unitary-applying operations implement a common
UnitaryOpInterfacethat provides uniform introspection and composition capabilities. This applies to base gates, modifiers, sequences, and user-defined operations.Interface Methods:
Canonical Descriptor Tuple:
Each unitary can be uniquely identified by the tuple:
This enables canonical equality tests and efficient deduplication.
Parameter Model:
quartz.u(%theta, 1.5708, %lambda) %qhas three parameters: dynamic, static, dynamicStatic Matrix Extraction:
std::nullopt_tfor symbolic or dynamic parameterizationsModifier Interaction:
invmodifier introducesinvertedFlagin the canonical descriptorpowmodifier stores exponent; negative exponents are canonicalized toinv(pow(+exp))then reorderedctrl,negctrl) extend control sets; interface aggregates flattened sets across nested modifiers4. Base Gate Operations
4.1 Philosophy and Design Principles
Core Principles:
Benefits:
4.2 Base Gate Specification Template
For every named base gate operation
G:Specification Elements:
OneTarget,TwoTarget), parameter arity (e.g.,OneParameter), special properties (e.g.,Hermitian,Diagonal)quartz.G(param_list?) %targets : (param_types..., qubit_types...)%out_targets = flux.G(param_list?) %in_targets : (param_types..., qubit_types...) -> (qubit_types...)G(params?) targetswhere params are in parentheses, qubits as trailing operandsgetNumTargets()fixed by target arity traithasStaticUnitary()returns true iff all parameters are staticugate)General Canonicalization Patterns Based on Traits:
The following canonicalization patterns apply automatically to all gates with the specified traits (not repeated for individual gates):
inv(G) โ G(self-adjoint)G %q; G %q โ remove(cancellation)pow(n: even_integer) G โ idpow(n: odd_integer) G โ G4.3 Gate Catalog
Gate Organization:
4.3.1
gphaseGate (Global Phase)exp(iฮธ)to the quantum stateNoTarget,OneParameterquartz.gphase(%theta)flux.gphase(%theta)quartz.gphase(3.14159)quartz.gphase(%theta)gphase(0) โ removeinv(gphase(ฮธ)) โ gphase(-ฮธ)gphase(a); gphase(b) โ gphase(a + b)(consecutive phases merge within same scope)ctrl(%q) { gphase(ฮธ) } โ p(ฮธ) %q(controlled global phase becomes phase gate)negctrl(%q) { gphase(ฮธ) } โ gphase(ฯ); p(ฮธ) %q(negative control specialization)pow(n) { gphase(ฮธ) } โ gphase(n*ฮธ)[exp(iฮธ)](1ร1 scalar, static if ฮธ constant)4.3.2
idGate (Identity)OneTarget,NoParameter,Hermitian,Diagonalquartz.id %q%q_out = flux.id %q_inid โ remove(no effect)pow(r) id โ id(any power is still id)ctrl(...) { id } โ id(control with id is just id)negctrl(...) { id } โ id[1, 0; 0, 1](2x2 identity matrix)u:u(0, 0, 0) %q4.3.3
xGate (Pauli-X)OneTarget,NoParameter,Hermitianquartz.x %q%q_out = flux.x %q_inpow(1/2) x โ gphase(-ฯ/4); sx(square root with global phase correction)pow(-1/2) x โ gphase(ฯ/4); sxdgpow(r) x โ gphase(-r*ฯ/2); rx(r*ฯ)(general power translates to rotation with global phase)[0, 1; 1, 0](2x2 matrix)u:u(ฯ, 0, ฯ) %qrx(ฯ)differ by a global phase:X = -iยทexp(-iฯ/2ยทX) = -iยทrx(ฯ). When raising X to fractional powers, the result is expressed as a rotation with an appropriate global phase factor.4.3.4
yGate (Pauli-Y)OneTarget,NoParameter,Hermitianquartz.y %q%q_out = flux.y %q_inpow(r) y โ gphase(-r*ฯ/2); ry(r*ฯ)(general power translates to rotation with global phase)[0, -i; i, 0](2x2 matrix)u:u(ฯ, ฯ/2, ฯ/2) %qry(ฯ)differ by a global phase:Y = -iยทexp(-iฯ/2ยทY) = -iยทry(ฯ).4.3.5
zGate (Pauli-Z)OneTarget,NoParameter,Hermitian,Diagonalquartz.z %q%q_out = flux.z %q_inpow(1/2) z โ spow(-1/2) z โ sdgpow(1/4) z โ tpow(-1/4) z โ tdgpow(r) z โ p(ฯ * r)for real r[1, 0; 0, -1](2x2 matrix)u:u(0, 0, ฯ) %q4.3.6
hGate (Hadamard)OneTarget,NoParameter,Hermitianquartz.h %q%q_out = flux.h %q_in1/sqrt(2) * [1, 1; 1, -1](2x2 matrix)u:u(ฯ/2, 0, ฯ) %q4.3.7
sGate (S/Phase-90)OneTarget,NoParameter,Diagonalquartz.s %q%q_out = flux.s %q_ininv s โ sdgs %q; s %q โ z %qpow(n: int) s โ if n % 4 == 0 then id else if n % 4 == 1 then s else if n % 4 == 2 then z else sdgpow(1/2) s โ tpow(-1/2) s โ tdgpow(+-2) s โ zpow(r) s โ p(ฯ/2 * r)for real r[1, 0; 0, i](2x2 matrix)u:u(0, 0, ฯ/2) %q4.3.8
sdgGate (S-Dagger)OneTarget,NoParameter,Diagonalquartz.sdg %q%q_out = flux.sdg %q_ininv sdg โ ssdg %q; sdg %q โ z %qpow(n: int) sdg โ if n % 4 == 0 then id else if n % 4 == 1 then sdg else if n % 4 == 2 then z else spow(1/2) sdg โ tdgpow(-1/2) sdg โ tpow(+-2) sdg โ zpow(r) sdg โ p(-ฯ/2 * r)for real r[1, 0; 0, -i](2x2 matrix)u:u(0, 0, -ฯ/2) %q4.3.9
tGate (T/ฯ-8)OneTarget,NoParameter,Diagonalquartz.t %q%q_out = flux.t %q_ininv t โ tdgt %q; t %q; โ s %qpow(2) t โ spow(-2) t โ sdgpow(+-4) t โ zpow(r) t โ p(ฯ/4 * r)for real r[1, 0; 0, exp(i ฯ/4)](2x2 matrix)u:u(0, 0, ฯ/4) %q4.3.10
tdgGate (T-Dagger)OneTarget,NoParameter,Diagonalquartz.tdg %q%q_out = flux.tdg %q_ininv tdg โ ttdg %q; tdg %q; โ sdg %qpow(2) tdg โ sdgpow(-2) tdg โ spow(+-4) tdg โ zpow(r) tdg โ p(-ฯ/4 * r)for real r[1, 0; 0, exp(-i ฯ/4)](2x2 matrix)u:u(0, 0, -ฯ/4) %q4.3.11
sxGate (โX)OneTarget,NoParameterquartz.sx %q%q_out = flux.sx %q_ininv sx โ sxdgsx %q; sx %q โ x %qpow(+-2) sx โ xpow(r) sx โ gphase(-r*ฯ/4); rx(r*ฯ/2)(power translates to rotation with global phase)1/2 * [1 + i, 1 - i; 1 - i, 1 + i](2x2 matrix)sx = exp(-iฯ/4)ยทrx(ฯ/2). Powers are handled by translating to the rotation form with appropriate global phase correction.4.3.12
sxdgGate (โX-Dagger)OneTarget,NoParameterquartz.sxdg %q%q_out = flux.sxdg %q_ininv sxdg โ sxsxdg %q; sxdg %q โ x %qpow(+-2) sxdg โ xpow(r) sxdg โ gphase(r*ฯ/4); rx(-r*ฯ/2)(power translates to rotation with global phase)1/2 * [1 - i, 1 + i; 1 + i, 1 - i](2x2 matrix)sxdg = exp(iฯ/4)ยทrx(-ฯ/2). Powers are handled by translating to the rotation form with appropriate global phase correction.4.3.13
rxGate (X-Rotation)OneTarget,OneParameterquartz.rx(%theta) %q%q_out = flux.rx(%theta) %q_inquartz.rx(3.14159) %qrx(a) %q; rx(b) %q โ rx(a + b) %qinv rx(ฮธ) โ rx(-ฮธ)pow(r) rx(ฮธ) โ rx(r * ฮธ)for real rexp(-i ฮธ/2 X) = [cos(ฮธ/2), -i sin(ฮธ/2); -i sin(ฮธ/2), cos(ฮธ/2)](2x2 matrix). Static if ฮธ constant.u:u(ฮธ, -ฯ/2, ฯ/2) %q4.3.14
ryGate (Y-Rotation)OneTarget,OneParameterquartz.ry(%theta) %q%q_out = flux.ry(%theta) %q_inquartz.ry(3.14159) %qry(a) %q; ry(b) %q โ ry(a + b) %qinv ry(ฮธ) โ ry(-ฮธ)pow(r) ry(ฮธ) โ ry(r * ฮธ)for real rexp(-i ฮธ/2 Y) = [cos(ฮธ/2), -sin(ฮธ/2); sin(ฮธ/2), cos(ฮธ/2)](2x2 matrix). Static if ฮธ constant.u:u(ฮธ, 0, 0) %q4.3.15
rzGate (Z-Rotation)OneTarget,OneParameter,Diagonalquartz.rz(%theta) %q%q_out = flux.rz(%theta) %q_inquartz.rz(3.14159) %qrz(a) %q; rz(b) %q โ rz(a + b) %qinv rz(ฮธ) โ rz(-ฮธ)pow(r) rz(ฮธ) โ rz(r * ฮธ)for real rexp(-i ฮธ/2 Z) = [exp(-i ฮธ/2), 0; 0, exp(i ฮธ/2)](2x2 matrix). Static if ฮธ constant.pgate: Therzandpgates differ by a global phase:rz(ฮธ) = exp(iฮธ/2)ยทp(ฮธ). However,rzandpshould remain separate and are not canonicalized into each other, as they represent different conventions that may be important for hardware backends or algorithm implementations.4.3.16
pGate (Phase)OneTarget,OneParameter,Diagonalquartz.p(%theta) %q%q_out = flux.p(%theta) %q_inquartz.p(3.14159) %qp(a) %q; p(b) %q โ p(a + b) %qinv p(ฮธ) โ p(-ฮธ)pow(r) p(ฮธ) โ p(r * ฮธ)for real r[1, 0; 0, exp(i ฮธ)](2x2 matrix). Static if ฮธ constant.u:u(0, 0, ฮธ) %q4.3.17
rGate (Arbitrary Axis Rotation)OneTarget,TwoParameterquartz.r(%theta, %phi) %q%q_out = flux.r(%theta, %phi) %q_inquartz.r(3.14159, 1.5708) %qquartz.r(%theta, 1.5708) %qinv r(ฮธ, ฯ) โ r(-ฮธ, ฯ)pow(real) r(ฮธ, ฯ) โ r(real * ฮธ, ฯ)for realrealr(ฮธ, 0) โ rx(ฮธ)r(ฮธ, ฯ/2) โ ry(ฮธ)exp(-i ฮธ (cos(ฯ) X + sin(ฯ) Y)) = [cos(ฮธ/2), -i exp(-i ฯ) sin(ฮธ/2); -i exp(i ฯ) sin(ฮธ/2), cos(ฮธ/2)](2x2 matrix). Static if ฮธ and ฯ constant.u:u(ฮธ, -ฯ/2 + ฯ, ฯ/2 - ฯ) %q4.3.18
uGate (Universal Single-Qubit)OneTarget,ThreeParameterquartz.u(%theta, %phi, %lambda) %q%q_out = flux.u(%theta, %phi, %lambda) %q_inquartz.u(3.14159, 1.5708, 0.785398) %qquartz.u(%theta, 1.5708, 0.785398) %qinv u(ฮธ, ฯ, ฮป) โ u(-ฮธ, -ฯ, -ฮป)rx(ฮธ) == u(ฮธ, -ฯ/2, ฯ/2)ry(ฮธ) == u(ฮธ, 0, 0)p(ฮป) == u(0, 0, ฮป)p(ฯ) ry(ฮธ) p(ฮป) = exp(i (ฯ + ฮป)/2) * rz(ฯ) ry(ฮธ) rz(ฮป) = [cos(ฮธ/2), -exp(i ฮป) sin(ฮธ/2); exp(i ฯ) sin(ฮธ/2), exp(i (ฯ + ฮป)) cos(ฮธ/2)](2x2 matrix). Static if ฮธ, ฯ, ฮป constant.4.3.19
u2Gate (Simplified Universal)ugate)OneTarget,TwoParameterquartz.u2(%phi, %lambda) %q%q_out = flux.u2(%phi, %lambda) %q_inquartz.u2(1.5708, 0.785398) %qquartz.u2(%phi, 0.785398) %qinv u2(ฯ, ฮป) โ u2(-ฮป - ฯ, -ฯ + ฯ)u2(0, ฯ) โ hu2(0, 0) โ ry(ฯ/2)u2(-ฯ/2, ฯ/2) โ rx(ฯ/2)1/sqrt(2) * [1, -exp(i ฮป); exp(i ฯ), exp(i (ฯ + ฮป))](2x2 matrix). Static if ฯ, ฮป constant.u:u2(ฯ, ฮป) == u(ฯ/2, ฯ, ฮป)4.3.20
swapGateTwoTarget,NoParameter,Hermitianquartz.swap %q0, %q1%q0_out, %q1_out = flux.swap %q0_in, %q1_in[1, 0, 0, 0; 0, 0, 1, 0; 0, 1, 0, 0; 0, 0, 0, 1](4x4 matrix)4.3.21
iswapGateTwoTarget,NoParameterquartz.iswap %q0, %q1%q0_out, %q1_out = flux.iswap %q0_in, %q1_inpow(r) iswap โ xx_plus_yy(-ฯ * r)[1, 0, 0, 0; 0, 0, 1j, 0; 0, 1j, 0, 0; 0, 0, 0, 1](4x4 matrix)4.3.22
dcxGate (Double CNOT)TwoTarget,NoParameterquartz.dcx %q0, %q1%q0_out, %q1_out = flux.dcx %q0_in, %q1_ininv dcx %q0, q1 => dcx %q1, %q0[1, 0, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1; 0, 1, 0, 0](4x4 matrix)4.3.23
ecrGate (Echoed Cross-Resonance)TwoTarget,NoParameter,Hermitianquartz.ecr %q0, %q1%q0_out, %q1_out = flux.ecr %q0_in, %q1_in1/sqrt(2) * [0, 0, 1, 1j; 0, 0, 1j, 1; 1, -1j, 0, 0; -1j, 1, 0, 0](4x4 matrix)4.3.24
rxxGate (XX-Rotation)TwoTarget,OneParameterquartz.rxx(%theta) %q0, %q1%q0_out, %q1_out = flux.rxx(%theta) %q0_in, %q1_inquartz.rxx(3.14159) %q0, %q1inv rxx(%theta) => rxx(-%theta)pow(r) rxx(%theta) => rxx(r * %theta)for real rrxx(0) => removerxx(a) %q0, %q1; rxx(b) %q0, %q1 => rxx(a + b) %q0, %q1cos(ฮธ/2) * [1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1] - 1j * sin(ฮธ/2) * [0, 0, 0, 1; 0, 0, 1, 0; 0, 1, 0, 0; 1, 0, 0, 0](4x4 matrix). Static if ฮธ constant.4.3.25
ryyGate (YY-Rotation)TwoTarget,OneParameterquartz.ryy(%theta) %q0, %q1%q0_out, %q1_out = flux.ryy(%theta) %q0_in, %q1_inquartz.ryy(3.14159) %q0, %q1inv ryy(%theta) => ryy(-%theta)pow(r) ryy(%theta) => ryy(r * %theta)for real rryy(0) => removeryy(a) %q0, %q1; ryy(b) %q0, %q1 => ryy(a + b) %q0, %q1cos(ฮธ/2) * [1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1] + 1j * sin(ฮธ/2) * [0, 0, 0, 1; 0, 0, -1, 0; 0, -1, 0, 0; 1, 0, 0, 0](4x4 matrix). Static if ฮธ constant.4.3.26
rzxGate (ZX-Rotation)TwoTarget,OneParameterquartz.rzx(%theta) %q0, %q1%q0_out, %q1_out = flux.rzx(%theta) %q0_in, %q1_inquartz.rzx(3.14159) %q0, %q1inv rzx(%theta) => rzx(-%theta)pow(r) rzx(%theta) => rzx(r * %theta)for real rrzx(0) => removerzx(a) %q0, %q1; rzx(b) %q0, %q1 => rzx(a + b) %q0, %q1cos(ฮธ/2) * [1, 0, 0, 0; 0, 1, 0, 0; 0, 0, 1, 0; 0, 0, 0, 1] + 1j * sin(ฮธ/2) * [0, -1, 0, 0; -1, 0, 0, 0; 0, 0, 0, 1; 0, 0, 1, 0](4x4 matrix). Static if ฮธ constant.4.3.27
rzzGate (ZZ-Rotation)TwoTarget,OneParameter,Diagonalquartz.rzz(%theta) %q0, %q1%q0_out, %q1_out = flux.rzz(%theta) %q0_in, %q1_inquartz.rzz(3.14159) %q0, %q1inv rzz(%theta) => rzz(-%theta)pow(r) rzz(%theta) => rzz(r * %theta)for real rrzz(0) => removerzz(a) %q0, %q1; rzz(b) %q0, %q1 => rzz(a + b) %q0, %q1diag[exp(-i ฮธ/2), exp(i ฮธ/2), exp(i ฮธ/2), exp(-i ฮธ/2)](4x4 matrix). Static if ฮธ constant.4.3.28
xx_plus_yyGateTwoTarget,TwoParameterquartz.xx_plus_yy(%theta, %beta) %q0, %q1%q0_out, %q1_out = flux.xx_plus_yy(%theta, %beta) %q0_in, %q1_inquartz.xx_plus_yy(3.14159, 1.5708) %q0, %q1quartz.xx_plus_yy(%theta, 1.5708) %q0, %q1inv xx_plus_yy(ฮธ, ฮฒ) => xx_plus_yy(-ฮธ, ฮฒ)pow(r) xx_plus_yy(ฮธ, ฮฒ) => xx_plus_yy(r * ฮธ, ฮฒ)for real rxx_plus_yy(ฮธ1, ฮฒ) %q0, %q1; xx_plus_yy(ฮธ2, ฮฒ) %q0, %q1 => xx_plus_yy(ฮธ1 + ฮธ2, ฮฒ) %q0, %q1[1, 0, 0, 0; 0, cos(ฮธ/2), sin(ฮธ/2) * exp(-i ฮฒ), 0; 0, -sin(ฮธ/2) * exp(i ฮฒ), cos(ฮธ/2), 0; 0, 0, 0, 1](4x4 matrix). Static if ฮธ and ฮฒ constant.4.3.29
xx_minus_yyGateTwoTarget,TwoParameterquartz.xx_minus_yy(%theta, %beta) %q0, %q1%q0_out, %q1_out = flux.xx_minus_yy(%theta, %beta) %q0_in, %q1_inquartz.xx_minus_yy(3.14159, 1.5708) %q0, %q1quartz.xx_minus_yy(%theta, 1.5708) %q0, %q1inv xx_minus_yy(ฮธ, ฮฒ) => xx_minus_yy(-ฮธ, ฮฒ)pow(r) xx_minus_yy(ฮธ, ฮฒ) => xx_minus_yy(r * ฮธ, ฮฒ)for real rxx_minus_yy(ฮธ1, ฮฒ) %q0, %q1; xx_minus_yy(ฮธ2, ฮฒ) %q0, %q1 => xx_minus_yy(ฮธ1 + ฮธ2, ฮฒ) %q0, %q1[cos(ฮธ/2), 0, 0, -sin(ฮธ/2) * exp(i ฮฒ); 0, 1, 0, 0; 0, 0, 1, 0; sin(ฮธ/2) * exp(-i ฮฒ), 0, 0, cos(ฮธ/2)](4x4 matrix). Static if ฮธ and ฮฒ constant.4.3.30
barrierGateOneTarget,TwoTarget,NoParameter(overloaded for different qubit counts)quartz.barrier %q0, %q1, ...%q0_out, %q1_out, ... = flux.barrier %q0_in, %q1_in, ...barrieroperation implements theUnitaryOpInterfaceand is treated similarly to the identity gate from a unitary perspective. However, it serves as a compiler directive that constrains optimization: operations cannot be moved across a barrier boundary.barrier; barrieron same qubits โ singlebarrier(adjacent barriers merge)inv { barrier } โ barrier(barrier is self-adjoint)pow(r) { barrier } โ barrier(any power of barrier is still barrier)5. Modifier Operations
5.1 Overview and Philosophy
What Are Modifiers?
Modifiers are wrapper operations that transform or extend unitary operations without modifying the base gate definitions. They provide a composable mechanism for:
Key Design Principles:
UnitaryOpInterfacenegctrl โ ctrl โ pow โ invquartzandfluxvariants with corresponding semanticsValue vs. Reference Semantics:
flux โ quartzis straightforward;quartz โ fluxrequires adding SSA values to region arguments and yields5.2 Control Modifiers (
ctrlandnegctrl)Purpose: Add additional control qubits to an operation. Control qubits can be positive (1-state control via
ctrl) or negative (0-state control vianegctrl).Signatures (shown for
ctrl;negctrlis analogous):Quartz (Reference Semantics):
Flux (Value Semantics):
Interface Implementation:
Canonicalization:
ctrl(%c1) { ctrl(%c2) { U } } โ ctrl(%c1, %c2) { U }ctrl() { U } โ Uctrl(%c) { gphase(ฮธ) } โ p(ฮธ) %cctrl { negctrl { U } } โ negctrl { ctrl { U } }Verifiers:
ctrl) and negative (negctrl) control modifiers. The sets of positive and negative controls must be disjoint with no overlap. If a qubit appears in both, the operation is invalid and must be rejected during verification.Unitary Computation:
The unitary is computed by expanding the child operation's unitary to the larger Hilbert space defined by the additional control qubits:
For negative controls,
|1โฉโจ1|is replaced with|0โฉโจ0|.5.3 Inverse Modifier (
inv)Purpose: Take the adjoint (conjugate transpose) of a unitary operation.
Signatures:
Quartz (Reference Semantics):
Flux (Value Semantics):
Interface Implementation:
trueCanonicalization:
inv { inv { U } } โ Uinv { G } โ G(for Hermitian gates)inv { rx(ฮธ) } โ rx(-ฮธ)(and similar for ry, rz, p, etc.)inv { ctrl { U } } โ ctrl { inv { U } }Unitary Computation:
Given unitary matrix
U, the inverse is computed asUโ = (Uฬ )แต(conjugate transpose).5.4 Power Modifier (
pow)Purpose: Raise a unitary operation to a given power (exponent can be integer, rational, or real).
Signatures:
Quartz (Reference Semantics):
Static variant:
quartz.pow {exponent = 2.0 : f64} { ... }Flux (Value Semantics):
Interface Implementation:
Canonicalization:
pow(a) { pow(b) { U } } โ pow(a*b) { U }pow(1) { U } โ Upow(0) { U } โ remove(becomes identity, then eliminated)pow(-r) { U } โ pow(r) { inv { U } }pow(r) { rx(ฮธ) } โ rx(r*ฮธ)(for rotation gates)pow(2) { sx } โ x)pow { ctrl { U } } โ ctrl { pow { U } }Unitary Computation:
U^n = U ยท U ยท ... ยท U(n times)U^r = V ยท D^r ยท VโwhereU = V ยท D ยท Vโis the eigendecompositionWell-Definedness: Since all quantum gates are unitary matrices, they are always diagonalizable (unitaries are normal operators). Therefore, non-integer powers are always well-defined through eigendecomposition, regardless of the specific gate.
Numerical Precision: Matrix exponentiation should be computed to machine precision (typically double precision floating point, ~15-16 decimal digits). Implementations should use numerically stable algorithms for eigendecomposition.
Complex Exponents: Complex exponents are not supported and will not be supported in the future, as they do not have meaningful physical interpretations for quantum gates. Only real-valued exponents are permitted.
6. Box Operation (
box)Purpose: Scoped composition of unitary operations with timing and optimization constraints. Inspired by OpenQASM 3.0's
boxstatement, this operation encapsulates a sequence of operations while constraining how optimizations may interact with them.Signatures:
Quartz (Reference Semantics):
Flux (Value Semantics):
Interface Implementation:
Canonicalization:
box { } โ removebox { U } โ Ubox { box { U; V }; W } โ box { U; V; W }Verifiers:
UnitaryOpInterfaceUnitary Computation:
The composite unitary is computed as the product of child unitaries in reverse order (right-to-left multiplication, since operations apply left-to-right):
Conversion Between Dialects:
flux โ quartz: Remove block arguments and results; replace argument uses with direct value referencesquartz โ flux: Add block arguments for all used qubits; thread SSA values through operations; add yield with final values7. User-Defined Gates & Matrix/Composite Definitions
Purpose: Enable users to define custom gates that can be referenced and instantiated throughout the program, similar to function definitions and calls.
7.1 Overview
User-defined gates follow a
func.func-like design pattern with definitions and application sites:func.func)func.call)Two definition mechanisms are provided to accommodate different use cases:
Matrix-based definitions (
define_matrix_gate): Define a gate via its unitary matrix representationComposite definitions (
define_composite_gate): Define a gate as a sequence of existing unitary operationsSeparation Rationale: The distinction between matrix and composite definitions is fundamental:
7.2 Design Principles
Symbol Management:
applyoperations for instantiationParameterization:
Unitary Interface Implementation:
define_matrix_gateanddefine_composite_gateimplement the unitary interfaceapply) delegate to their referenced definitionsConsistency:
7.3 Integration with Modifier System
User-defined gates integrate seamlessly with the modifier system described in Section 5:
inv,pow,ctrl, andnegctrlcan wrapapplyoperationsinv(pow(apply(@my_gate), 2))7.4 Future Work
The detailed specification of user-defined gatesโincluding concrete syntax, verification rules, inlining strategies, and builder API integrationโis deferred to a subsequent design phase. Key open questions include:
This deferred specification allows the infrastructure to stabilize around core operations before committing to user-defined gate semantics.
8. Builder API
Purpose: Provide a programmatic API for constructing quantum programs within the MQT MLIR infrastructure. The builder APIs offer type-safe, ergonomic interfaces for both Quartz and Flux dialects.
8.1 Design Goals
8.2 Quartz Builder (Reference Semantics)
8.3 Flux Builder (Value Semantics)
The
FluxProgramBuilderfollows the same design principles as the Quartz builder but with SSA value threading:Key Differences:
!flux.qubitinstead of!quartz.qubitExample API Sketch:
8.4 Usage Examples
9. Testing Strategy
9.1 Philosophy
Priority: Structural and semantic testing > textual pattern matching
Move away from brittle FileCheck tests toward robust programmatic testing:
UnitaryOpInterfacefor semantic checks9.2 Unit Testing Framework (GoogleTest)
Test Categories:
UnitaryOpInterfacemethodsExample Test Structure:
Coverage Requirements:
9.3 Parser/Printer Round-Trip Tests (Minimal FileCheck)
Purpose: Ensure textual representation is stable and parseable.
Scope: Limited to basic round-trip validation, avoiding brittle SSA name checks.
Example:
Principles:
9.4 Integration Tests
Integration tests validate the complete MQT MLIR compilation infrastructure, covering end-to-end scenarios from frontend ingestion through optimization to backend emission.
Test Coverage:
Frontend Translation:
QuantumCircuitobjects to Quartz/Flux dialectsqc::QuantumComputationโ MLIR: Translate from existing MQT Core IR to MLIR representationCompiler Pipeline Integration:
Backend Translation:
End-to-End Scenarios:
9.5 Default Compiler Passes
Purpose: Define a standard set of compiler passes that should be applied by default to ensure consistent, optimized IR across the MQT MLIR infrastructure.
Rationale:
The MQT MLIR dialects define extensive canonicalization patterns for all operations (base gates, modifiers, boxes, and custom gates).
To ensure these canonicalization are consistently applied and to maintain clean IR for downstream passes, certain compiler passes should be run by default in most compilation scenarios.
Recommended Default Passes:
Canonicalization Pass (
-canonicalize):inv { inv { U } } โ U)negctrl โ ctrl โ pow โ inv)rx(a); rx(b) โ rx(a+b))Remove Dead Values Pass (
-remove-dead-values):Default Pass Pipeline:
For most compilation scenarios, the following minimal pass pipeline should be applied:
For more aggressive optimization, this can be extended:
Testing Implications:
Integration with Custom Passes:
Custom optimization passes should be inserted into pipelines alongside the default passes:
This pattern ensures that custom passes operate on normalized IR and that their outputs are subsequently normalized.
Builder API Integration:
The builder APIs may optionally apply these passes automatically when
finalize()is called, controlled by a configuration flag:Future Considerations:
As the dialect matures, additional passes may be added to the default pipeline:
However, the core default passes (
-canonicalizeand-remove-dead-values) should remain stable and universally applicable.10. Implementation Roadmap
Timeline: 14-week implementation plan to complete the MQT MLIR compilation infrastructure.
Phase 1: Foundation (Weeks 1-2)
Goal: Establish core infrastructure
Week 1:
quartz.qubit,flux.qubit)UnitaryOpInterfacedefinitionWeek 2:
Deliverable: Compiling infrastructure with basic qubit operations
Phase 2: Base Gates - Core Set (Weeks 2-3)
Goal: Implement essential gates for basic circuits
Deliverable: Core single-qubit gate set with tests
Phase 3: Base Gates - Two-Qubit Set (Week 4)
Goal: Complete two-qubit gate library
Deliverable: Complete base gate set
Phase 4: Modifiers (Week 5)
Goal: Implement composable modifier system
ctrlmodifier (positive controls)negctrlmodifier (negative controls)invmodifierpowmodifierDeliverable: Working modifier system with canonicalization
Phase 5: Composition & Box (Week 6)
Goal: Enable circuit composition
boxoperation (replacesseq)Deliverable: Box operation with proper scoping
Phase 6: Custom Gates (Week 7)
Goal: User-defined gate support
applyoperationDeliverable: Custom gate definition and application
Phase 7: Builder API & Convenience (Week 8)
Goal: Ergonomic programmatic construction
Deliverable: Production-ready builder APIs
Phase 8: Dialect Conversion (Week 9)
Goal: Enable transformations between dialects
Deliverable: Working dialect conversion infrastructure
Phase 9: Frontend Integration (Week 10)
Goal: Connect to existing quantum software
qc::QuantumComputationโ MLIR translationDeliverable: Multiple input format support
Phase 10: Optimization Passes (Week 11)
Goal: Implement optimization infrastructure
Deliverable: Optimization pass suite
Phase 11: Backend Integration (Week 12)
Goal: QIR lowering
Deliverable: Complete compilation pipeline
Phase 12: Testing & Documentation (Week 13)
Goal: Production readiness
Deliverable: Production-ready system with documentation
Phase 13: Polish & Release (Week 14)
Goal: Release preparation
Deliverable: Released dialect system
Parallelization Strategy:
Risk Mitigation:
Beta Was this translation helpful? Give feedback.
All reactions