Skip to content

Commit 134f086

Browse files
authored
Add a Pauli frame tracking dialect (#2188)
**Context:** A *Pauli frame tracker* [1] is a system that tracks gates from the Pauli group in classical electronics instead of physically applying them to qubits on the device. Doing so reduces the number of quantum operations applied to the system, thus reducing the probability of errors. This PR adds a Pauli frame tracking dialect to Catalyst and includes a set of abstractions and operations for interacting with an external Pauli frame tracking library. [1] Knill, E. *Quantum computing with realistically noisy devices*. Nature **434**, 39-44 (2005). https://doi.org/10.1038/nature03350. **Description of the Change:** The `PauliFrame` dialect includes the following operations: * `pauli_frame.init`, which initializes the Pauli record(s) of the target qubit(s) to *I*. * `pauli_frame.init_qreg`, same as `pauli_frame.init` except it initializes the Pauli records of all the qubits in the target quantum register. * `pauli_frame.read`, which reads the Pauli record of the target qubit. * `pauli_frame.update`, which updates the Pauli record(s) of the target qubit(s) given a new Pauli record. * `pauli_frame.update_with_clifford`, which updates the Pauli record(s) of the target qubit(s) given the conjugation relation between the given Clifford gate and the current Pauli record. * `pauli_frame.correct_measurement`, which corrects a measurement result given the Pauli record of the target qubit. * `pauli_frame.flush`, which flush the Pauli record(s) of the target qubit(s) (*flushing* means physically applying the Pauli gates in the record and re-initializing). * `pauli_frame.set`, an extra op that sets the Pauli record(s) of the target qubit(s). Note that this PR only adds the dialect itself. Future PRs will add compilation passes to insert these ops into the quantum program IR and to lower them to runtime stubs that call into a (thus far) mocked out Pauli frame tracking runtime library. [sc-103530]
1 parent c9a7711 commit 134f086

File tree

21 files changed

+715
-0
lines changed

21 files changed

+715
-0
lines changed

doc/releases/changelog-dev.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@
349349
the QEC interface `QECOpInterface` to simplify the interface.
350350
[(#2250)](https://github.com/PennyLaneAI/catalyst/pull/2250)
351351

352+
* A new `PauliFrame` dialect has been added. This dialect includes a set of abstractions and
353+
operations for interacting with an external Pauli frame tracking library.
354+
[(#2188)](https://github.com/PennyLaneAI/catalyst/pull/2188)
355+
352356
<h3>Documentation 📝</h3>
353357

354358
* A typo in the code example for :func:`~.passes.ppr_to_ppm` has been corrected.
@@ -366,6 +370,7 @@
366370
This release contains contributions from (in alphabetical order):
367371

368372
Ali Asadi,
373+
Joey Carter,
369374
Yushao Chen,
370375
Sengthai Heng,
371376
Jeffrey Kam,

mlir/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ add_subdirectory(hlo-extensions)
44
add_subdirectory(Ion)
55
add_subdirectory(MBQC)
66
add_subdirectory(Mitigation)
7+
add_subdirectory(PauliFrame)
78
add_subdirectory(QEC)
89
add_subdirectory(Quantum)
910
add_subdirectory(RTIO)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(IR)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
add_mlir_dialect(PauliFrameOps pauli_frame)
2+
add_mlir_doc(PauliFrameDialect PauliFrameDialect PauliFrame/ -gen-dialect-doc -gen-op-doc)
3+
add_mlir_doc(PauliFrameOps PauliFrameOps PauliFrame/ -gen-op-doc)
4+
5+
set(LLVM_TARGET_DEFINITIONS PauliFrameOps.td)
6+
mlir_tablegen(PauliFrameEnums.h.inc -gen-enum-decls)
7+
mlir_tablegen(PauliFrameEnums.cpp.inc -gen-enum-defs)
8+
mlir_tablegen(PauliFrameAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=pauli_frame)
9+
mlir_tablegen(PauliFrameAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=pauli_frame)
10+
add_public_tablegen_target(MLIRPauliFrameEnumsIncGen)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2025 Xanadu Quantum Technologies Inc.
2+
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
#include "mlir/IR/Dialect.h"
18+
19+
//===----------------------------------------------------------------------===//
20+
// PauliFrame dialect declarations.
21+
//===----------------------------------------------------------------------===//
22+
23+
#include "PauliFrame/IR/PauliFrameOpsDialect.h.inc"
24+
25+
//===----------------------------------------------------------------------===//
26+
// PauliFrame type declarations.
27+
//===----------------------------------------------------------------------===//
28+
29+
/// Uncomment the lines below if defining types for the PauliFrame dialect
30+
// #define GET_TYPEDEF_CLASSES
31+
// #include "PauliFrame/IR/PauliFrameOpsTypes.h.inc"
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright 2025 Xanadu Quantum Technologies Inc.
2+
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef PAULI_FRAME_DIALECT
16+
#define PAULI_FRAME_DIALECT
17+
18+
include "mlir/IR/DialectBase.td"
19+
include "mlir/IR/OpBase.td"
20+
21+
//===----------------------------------------------------------------------===//
22+
// PauliFrame dialect definition.
23+
//===----------------------------------------------------------------------===//
24+
25+
def PauliFrame_Dialect : Dialect {
26+
let summary = "A dialect for Pauli frame tracking.";
27+
let description = [{
28+
The Pauli frame tracking dialect includes a set of abstractions and operations for
29+
interacting with an external Pauli frame tracking library. A *Pauli frame tracker* [1] is a
30+
system that tracks gates from the Pauli group in classical electronics instead of applying
31+
them to qubits on the device. Doing so reduces the number of quantum operations applied to
32+
the system, thus reducing the probability of errors.
33+
34+
A single Pauli record *Rq* tracks all the Pauli gates that are applied on qubit *q*. Every
35+
set of tracked Pauli gates can be reduced to one of the elements in the set {I, X, Z, XZ},
36+
hence a single Pauli record can be stored using two bits, encoded as X- and Z-parity bits:
37+
38+
I = (0, 0), X = (1, 0), Z = (0, 1), XZ = (1, 1)
39+
40+
The operations in this dialect aim to represent the Pauli frame tracking components of the
41+
following five quantum processes required to maintain a system of universal quantum
42+
computation, as described in Ref. [2]:
43+
44+
1. Initialization of a qubit to |0>:
45+
a. Set Pauli record of target qubit to I.
46+
b. Initialize target qubit to |0>.
47+
2. Measurement:
48+
a. Measure target qubit.
49+
b. Correct measurement result based on Pauli record.
50+
3. Pauli gates:
51+
a. Update Pauli record of target qubit accordingly (the Pauli gates themselves are
52+
not physically applied to the qubit).
53+
4. Clifford gates:
54+
a. Update Pauli record(s) of target qubit(s).
55+
b. Apply Clifford gate on target qubit(s).
56+
5. Non-Clifford gates:
57+
a. Flush Pauli record(s) of target qubit(s). *Flushing* the Pauli record of a qubit
58+
refers to physically applying the Pauli gates stored in the record on that qubit
59+
and then resetting its record to I.
60+
b. Apply non-Clifford gate on target qubit(s).
61+
62+
References
63+
----------
64+
65+
[1] Knill, E. Quantum computing with realistically noisy devices. Nature 434, 39-44 (2005).
66+
https://doi.org/10.1038/nature03350.
67+
68+
[2] Riesebos, L., et al. Pauli Frames for Quantum Computer Architectures.
69+
DAC '17: Proceedings of the 54th Annual Design Automation Conference 76, 1-6 (2017).
70+
https://doi.org/10.1145/3061639.3062300.
71+
72+
> [!IMPORTANT]
73+
> The pauli_frame dialect is experimental and will not maintain API stability between releases.
74+
> Use at your own risk.
75+
}];
76+
77+
/// This is the namespace of the dialect in MLIR, which is used as a prefix for types and ops.
78+
let name = "pauli_frame";
79+
80+
/// This is the C++ namespace in which the dialect and all of its sub-components are placed.
81+
let cppNamespace = "::catalyst::pauli_frame";
82+
83+
let dependentDialects = [
84+
"quantum::QuantumDialect"
85+
];
86+
87+
/// Use the default type printing/parsing hooks, otherwise we would have to explicitly define them.
88+
let useDefaultAttributePrinterParser = 1;
89+
90+
/// Uncomment the line below if defining types for the PauliFrame dialect
91+
// let useDefaultTypePrinterParser = 1;
92+
}
93+
94+
95+
//===----------------------------------------------------------------------===//
96+
// PauliFrame dialect types.
97+
//===----------------------------------------------------------------------===//
98+
99+
/// Uncomment the lines below if defining types for the PauliFrame dialect
100+
// class PauliFrame_Type<string name, string typeMnemonic, list<Trait> traits = []>
101+
// : TypeDef<PauliFrame_Dialect, name, traits> {
102+
// let mnemonic = typeMnemonic;
103+
// }
104+
105+
106+
//===----------------------------------------------------------------------===//
107+
// PauliFrame dialect base operation.
108+
//===----------------------------------------------------------------------===//
109+
110+
class PauliFrame_Op<string mnemonic, list<Trait> traits = []> :
111+
Op<PauliFrame_Dialect, mnemonic, traits>;
112+
113+
114+
#endif // PAULI_FRAME_DIALECT
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2025 Xanadu Quantum Technologies Inc.
2+
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
#include "Quantum/IR/QuantumDialect.h"
18+
19+
#include "PauliFrame/IR/PauliFrameDialect.h"
20+
21+
//===----------------------------------------------------------------------===//
22+
// PauliFrame ops declarations.
23+
//===----------------------------------------------------------------------===//
24+
25+
#include "PauliFrame/IR/PauliFrameEnums.h.inc"
26+
27+
#define GET_ATTRDEF_CLASSES
28+
#include "PauliFrame/IR/PauliFrameAttributes.h.inc"
29+
30+
#define GET_OP_CLASSES
31+
#include "PauliFrame/IR/PauliFrameOps.h.inc"

0 commit comments

Comments
 (0)