Skip to content
Open
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
46c39de
RTIO dialect is added to Catalyst
rniczh Nov 10, 2025
fd2dea4
Merge branch 'main' into rniczh/add-rtio-dialect
rniczh Nov 10, 2025
f127e6a
reformatting
rniczh Nov 10, 2025
eb19fa3
pulse should use f64 for duration
rniczh Nov 11, 2025
e5b170f
Update mlir/include/RTIO/IR/RTIODialect.td
rniczh Nov 17, 2025
6c9e90d
Update mlir/include/RTIO/IR/RTIODialect.td
rniczh Nov 17, 2025
a502944
Update mlir/include/RTIO/IR/RTIODialect.td
rniczh Nov 17, 2025
94927c3
Update mlir/include/RTIO/IR/RTIODialect.td
rniczh Nov 17, 2025
e9b1e84
Update mlir/include/RTIO/IR/RTIOOps.td
rniczh Nov 17, 2025
1452e7b
Update mlir/include/RTIO/IR/RTIODialect.td
rniczh Nov 17, 2025
38242f5
Update mlir/include/RTIO/IR/RTIOOps.td
rniczh Nov 17, 2025
6c00116
add empty op
rniczh Nov 18, 2025
48ecf52
Merge branch 'rniczh/add-rtio-dialect' of github.com:PennyLaneAI/cata…
rniczh Nov 18, 2025
ef5c3a6
fix formatting
rniczh Nov 18, 2025
c819333
update td
rniczh Nov 18, 2025
a26864c
Add pass to lower ion dialect to rtio dialect
rniczh Nov 18, 2025
c0e7234
update
rniczh Nov 18, 2025
f1ad990
add missing include
rniczh Nov 18, 2025
4cf83fe
update
rniczh Nov 18, 2025
27a4b98
add missing lib
rniczh Nov 18, 2025
4b3408f
Merge branch 'rniczh/add-rtio-dialect' of github.com:PennyLaneAI/cata…
rniczh Nov 18, 2025
29ffc70
remove redundant include
rniczh Nov 18, 2025
fcd540d
update
rniczh Nov 19, 2025
82bb3aa
remove other redundant functions
rniczh Nov 20, 2025
4a7430a
update pass
rniczh Nov 27, 2025
a349b1c
remove redundant code
rniczh Nov 27, 2025
cc814da
update linkage
rniczh Nov 28, 2025
5681bb3
add rtio.config
rniczh Dec 2, 2025
f326bf2
drop timeline IR
rniczh Dec 2, 2025
0e6b14f
remove unrelated thing
rniczh Dec 2, 2025
c0da830
Merge branch 'main' into rniczh/add-rtio-dialect
rniczh Dec 2, 2025
bd1c4c4
update channel ID underlying number
rniczh Dec 2, 2025
8e58bbe
Merge branch 'rniczh/add-rtio-dialect' of github.com:PennyLaneAI/cata…
rniczh Dec 2, 2025
6d57469
add bracket for if
rniczh Dec 2, 2025
cf5874e
fix
rniczh Dec 2, 2025
c4a3afa
add assert for oob
rniczh Dec 2, 2025
5e136eb
update comment
rniczh Dec 2, 2025
9fd57fc
merge from upstream
rniczh Dec 2, 2025
b623d0d
supports importing json to rtio.config
rniczh Dec 2, 2025
b127e9e
update changelog
rniczh Dec 2, 2025
1ce02ba
add deviceDB option
rniczh Dec 2, 2025
a379528
add missing comma
rniczh Dec 2, 2025
4f851ef
add missing include
rniczh Dec 2, 2025
2ff88f9
Update mlir/lib/RTIO/IR/RTIODialect.cpp
rniczh Dec 3, 2025
2486c74
Update mlir/include/RTIO/IR/RTIOOps.td
rniczh Dec 3, 2025
e6d0c7c
Add filecheck line
rniczh Dec 3, 2025
d8588ad
Merge branch 'main' into rniczh/add-rtio-dialect
rniczh Dec 3, 2025
49b2c0b
merge from upstream
rniczh Dec 3, 2025
3937ecf
revert
rniczh Dec 3, 2025
5559870
merge
rniczh Dec 3, 2025
e92d58e
Add changelog
rniczh Dec 3, 2025
7ed6c04
Merge branch 'rniczh/add-rtio-dialect' of github.com:PennyLaneAI/cata…
rniczh Dec 3, 2025
f77a12b
update changelog
rniczh Dec 3, 2025
ff777d3
merge from upstream
rniczh Dec 4, 2025
d0eba30
udpate
rniczh Dec 4, 2025
9837334
update
rniczh Dec 4, 2025
6314072
add test
rniczh Dec 5, 2025
528e0bb
remove comment
rniczh Dec 5, 2025
99a85c5
remove comment
rniczh Dec 5, 2025
7e7ee45
update changelog
rniczh Dec 5, 2025
2040912
Add scf.if and scf.for test
rniczh Dec 5, 2025
737425c
Merge branch 'main' into rniczh/lower-ion-to-rtio
mehrdad2m Dec 8, 2025
e19c29c
change variable name
rniczh Dec 8, 2025
c368eff
only support walkresult as return type
rniczh Dec 8, 2025
aa46203
fix
rniczh Dec 8, 2025
81db109
exit gracefully
rniczh Dec 8, 2025
436beaa
move ionInfo to separate file
rniczh Dec 8, 2025
820ec19
move json utils to separate files
rniczh Dec 8, 2025
8c210ca
refactor
rniczh Dec 8, 2025
4385130
reformat
rniczh Dec 8, 2025
2fa61f6
clean unused ops
rniczh Dec 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

<h3>New features since last release</h3>

* RTIO dialect is added to bypass the compilation flow from OpenAPL to ARTIQ’s LLVM IR. It is introduced to bridge the gap between ION dialect and ARTIQ’s LLVM IR. The design philosophy of RTIO dialect is primarily event-based. Every operation is asynchronous; sync behaviour occurs only via `rtio.sync` or `wait operand` in event operation. And we now support the compiling from ION dialect to RTIO dilalect.
[(#2185)](https://github.com/PennyLaneAI/catalyst/pull/2185)
[(#2204)](https://github.com/PennyLaneAI/catalyst/pull/2204)

* Added ``catalyst.switch``, a qjit compatible, index-switch style control flow decorator.
[(#2171)](https://github.com/PennyLaneAI/catalyst/pull/2171)

Expand Down Expand Up @@ -77,7 +81,7 @@
* An error is now raised if a transform is applied inside a QNode when program capture is enabled.
[(#2256)](https://github.com/PennyLaneAI/catalyst/pull/2256)

* A new ``"changed"`` option has been added to the ``keep_intermediate`` parameter of
* A new ``"changed"`` option has been added to the ``keep_intermediate`` parameter of
:func:`~.qjit`. This option saves intermediate IR files after each pass,
but only when the IR is actually modified by the pass.
[(#2186)](https://github.com/PennyLaneAI/catalyst/pull/2186)
Expand Down Expand Up @@ -139,9 +143,9 @@
* The `--adjoint-lowering` pass can now handle PPR operations.
[(#2227)](https://github.com/PennyLaneAI/catalyst/pull/2227)

* Catalyst now supports Pauli product rotations with arbitrary or dynamic angles in the
QEC dialect. This will allow :class:`qml.PauliRot` with arbitrary or dynamic angles,
angles not known at compile time, to be lowered to the QEC dialect. This is implemented
* Catalyst now supports Pauli product rotations with arbitrary or dynamic angles in the
QEC dialect. This will allow :class:`qml.PauliRot` with arbitrary or dynamic angles,
angles not known at compile time, to be lowered to the QEC dialect. This is implemented
as a new `qec.ppr.arbitrary` operation, which takes a Pauli product and an arbitrary or
dynamic angle as input. The arbitrary angles are specified as a double in terms of radian.
[(#2232)](https://github.com/PennyLaneAI/catalyst/pull/2232)
Expand All @@ -158,7 +162,7 @@

* The MLIR pipeline ``enforce-runtime-invariants-pipeline`` has been renamed to
``quantum-compilation-pipeline`` and the old ``quantum-compilation-pipeline`` has been renamed to
``gradient-lowering-pipeline``. Users who referenced these pipeline names directly would need to
``gradient-lowering-pipeline``. Users who referenced these pipeline names directly would need to
update their code to use the new names.
[(#2186)](https://github.com/PennyLaneAI/catalyst/pull/2186)

Expand Down Expand Up @@ -309,24 +313,24 @@
of identities.
[(#2192)](https://github.com/PennyLaneAI/catalyst/pull/2192)

* Renamed `annotate-function` pass to `annotate-invalid-gradient-functions` and move it to the
* Renamed `annotate-function` pass to `annotate-invalid-gradient-functions` and move it to the
gradient dialect and the `lower-gradients` compilation stage.
[(#2241)](https://github.com/PennyLaneAI/catalyst/pull/2241)

* Added support for PPRs to the :func:`~.passes.merge_rotations` pass to merge PPRs with
equivalent angles, and cancelling of PPRs with opposite angles, or angles
that sum to identity. Also supports conditions on PPRs, merging when conditions are
that sum to identity. Also supports conditions on PPRs, merging when conditions are
identical and not merging otherwise.
[(#2224)](https://github.com/PennyLaneAI/catalyst/pull/2224)
[(#2224)](https://github.com/PennyLaneAI/catalyst/pull/2224)
[(#2245)](https://github.com/PennyLaneAI/catalyst/pull/2245)
[(#2254)](https://github.com/PennyLaneAI/catalyst/pull/2254)


* Refactor QEC tablegen files to separate QEC operations into a new `QECOp.td` file
[(#2253](https://github.com/PennyLaneAI/catalyst/pull/2253)
[(#2253](https://github.com/PennyLaneAI/catalyst/pull/2253)


* Removed the `getRotationKind` and `setRotationKind` methods from
* Removed the `getRotationKind` and `setRotationKind` methods from
the QEC interface `QECOpInterface` to simplify the interface.
[(#2250)](https://github.com/PennyLaneAI/catalyst/pull/2250)

Expand Down
1 change: 1 addition & 0 deletions mlir/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ add_subdirectory(MBQC)
add_subdirectory(Mitigation)
add_subdirectory(QEC)
add_subdirectory(Quantum)
add_subdirectory(RTIO)
add_subdirectory(Test)
24 changes: 24 additions & 0 deletions mlir/include/Ion/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,28 @@ def IonConversionPass : Pass<"convert-ion-to-llvm"> {
];
}

def IonToRTIOPass : Pass<"convert-ion-to-rtio", "mlir::ModuleOp"> {
let summary = "Convert Ion dialect operations to RTIO dialect";

let dependentDialects = [
"rtio::RTIODialect",
"arith::ArithDialect",
"func::FuncDialect",
"memref::MemRefDialect",
"scf::SCFDialect",
"quantum::QuantumDialect",
"ion::IonDialect",
"linalg::LinalgDialect",
];

let options = [
Option<"kernelName", "kernel-name",
"std::string", /*default=*/"\"__kernel__\"",
"Name of the generated kernel function">,
Option<"deviceDb", "device_db",
"std::string", /*default=*/"\"\"",
"Path to the device database JSON file">,
];
}

#endif // ION_PASSES
1 change: 1 addition & 0 deletions mlir/include/RTIO/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(IR)
8 changes: 8 additions & 0 deletions mlir/include/RTIO/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_mlir_dialect(RTIOOps rtio)
add_mlir_doc(RTIODialect RTIODialect RTIO/ -gen-dialect-doc)
add_mlir_doc(RTIOOps RTIOOps RTIO/ -gen-op-doc)

set(LLVM_TARGET_DEFINITIONS RTIOOps.td)
mlir_tablegen(RTIOAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=rtio)
mlir_tablegen(RTIOAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=rtio)
add_public_tablegen_target(MLIRRTIOAttributesIncGen)
24 changes: 24 additions & 0 deletions mlir/include/RTIO/IR/RTIODialect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2025 Xanadu Quantum Technologies Inc.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/OpDefinition.h"

#include "RTIO/IR/RTIOOpsDialect.h.inc"

#define GET_TYPEDEF_CLASSES
#include "RTIO/IR/RTIOOpsTypes.h.inc"
230 changes: 230 additions & 0 deletions mlir/include/RTIO/IR/RTIODialect.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
// Copyright 2025 Xanadu Quantum Technologies Inc.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef RTIO_DIALECT
#define RTIO_DIALECT

include "mlir/IR/OpBase.td"
include "mlir/IR/DialectBase.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/BuiltinTypeInterfaces.td"

//===----------------------------------------------------------------------===//
// RTIO Dialect Definition
//===----------------------------------------------------------------------===//

def RTIO_Dialect : Dialect {
let summary = "Real-Time I/O dialect for FPGA quantum control";
let description = [{
The RTIO dialect provides operations for precise timing control
and hardware signal generation on FPGAs for quantum computing.

It provides declarative operations with explicit event dependencies for hardware control.
}];

let name = "rtio";
let cppNamespace = "::catalyst::rtio";
let useDefaultTypePrinterParser = 1;
let useDefaultAttributePrinterParser = 1;
}

//===----------------------------------------------------------------------===//
// RTIO dialect types.
//===----------------------------------------------------------------------===//

class RTIO_Type<string name, string typeMnemonic, list<Trait> traits = []>
: TypeDef<RTIO_Dialect, name, traits> {
let mnemonic = typeMnemonic;
}

// Channel type with variadic parameters
def RTIOChannelType : RTIO_Type<"Channel", "channel"> {
let summary = "A hardware I/O channel with logical and physical identification";
let description = [{
Represents a virtual hardware channel for RTIO operations

Syntax:
```
!rtio.channel<KIND, ?> // Dynamic: kind only
!rtio.channel<KIND, N> // Static: kind + channel ID
!rtio.channel<KIND, [QUALIFIERS], ?> // Dynamic: with qualifiers
!rtio.channel<KIND, [QUALIFIERS], N> // Static: with qualifiers + channel ID
```

Examples:
```mlir

// Simple DDS, channel ID TBD (to be resolved during channel resolution)
!rtio.channel<"dds", ?>

// DDS channel with qualifiers:
// Qualifiers distinguish different logical channels of the same kind.
// Example: ion 0, transition 0 -> will be distinguished from other transitions of
// the same ion. The mapping of the logical channel to the hardware channel will
// be resolved during the lowering pass from given dialect to RTIO dialect.
// User need to specifiy the mapping logic.
!rtio.channel<"dds", [0, "transition_0"], ?>

// DDS on hardware channel 0
!rtio.channel<"dds", 0>

// === Channel Resolution During Compilation ===

// Before channel resolution: Dynamic channels
!rtio.channel<"dds", [0], ?>

// After channel resolution: Resolved to hardware channel 1
!rtio.channel<"dds", [0], 1>

// Note: The qualifiers are used to provide additional information to the channel type.
// And they will be used to distinguish different channels with the same kind.
```
}];

let parameters = (ins
StringRefParameter<"channel kind">:$kind,
OptionalParameter<"mlir::ArrayAttr">:$qualifiers,
OptionalParameter<"mlir::IntegerAttr">:$channelId
);

let assemblyFormat = [{
`<` custom<ChannelTypeBody>($kind, $qualifiers, $channelId) `>`
}];

let extraClassDeclaration = [{
bool hasQualifiers() const {
return getQualifiers() && !getQualifiers().empty();
}

size_t getNumQualifiers() const {
return getQualifiers() ? getQualifiers().size() : 0;
}

mlir::Attribute getQualifier(size_t index) const {
assert(getQualifiers() && "qualifiers are not present");
assert(index < getQualifiers().size() && "index out of bounds");
return getQualifiers()[index];
}

bool isStatic() const {
auto channelId = getChannelId();
if (!channelId) {
return false;
}
return channelId.getInt() != mlir::ShapedType::kDynamic;
}

bool isDynamic() const {
return !isStatic();
}
}];
}

// Event handle type
def RTIOEventType : RTIO_Type<"Event", "event"> {
let summary = "A handle to a pending RTIO event";
let description = [{
Represents a handle to a pending RTIO event (e.g., pulse, sync).

Example:
```mlir
%event0 = rtio.pulse %ch0 duration(%dur) frequency(%freq) phase(%phase) : !rtio.event
%event1 = rtio.pulse %ch1 duration(%dur) frequency(%freq) phase(%phase) : !rtio.event
%sync = rtio.sync %event0, %event1 : !rtio.event
```
}];
}

//===----------------------------------------------------------------------===//
// RTIO Operation Base
//===----------------------------------------------------------------------===//

class RTIO_Op<string mnemonic, list<Trait> traits = []> :
Op<RTIO_Dialect, mnemonic, traits>;

//===----------------------------------------------------------------------===//
// RTIO Attributes
//===----------------------------------------------------------------------===//

class RTIO_Attr<string name, string attrMnemonic, list<Trait> traits = []>
: AttrDef<RTIO_Dialect, name, traits> {
let mnemonic = attrMnemonic;
}

def RTIOConfigAttr : RTIO_Attr<"Config", "config"> {
let summary = "A dictionary attribute for RTIO configuration";
let description = [{
A configuration attribute that wraps a DictionaryAttr for RTIO-specific metadata.
Can be used as a module-level attribute.

Example:
```mlir
module @my_module attributes {
rtio.config = #rtio.config<{
config1 = 1 : i32,
config2 = "test",
}>
} {
// ...
}
```
}];

let parameters = (ins
"mlir::DictionaryAttr":$dict
);

let assemblyFormat = "`<` $dict `>`";

let extraClassDeclaration = [{
/// The canonical attribute name for module-level config.
static llvm::StringRef getModuleAttrName() {
return "rtio.config";
}

/// Return the value for the given key, or null if not found.
mlir::Attribute get(llvm::StringRef key) const {
return getDict().get(key);
}
mlir::Attribute get(mlir::StringAttr key) const {
return getDict().get(key);
}

/// Return whether the config contains the given key.
bool contains(llvm::StringRef key) const {
return getDict().contains(key);
}
bool contains(mlir::StringAttr key) const {
return getDict().contains(key);
}

/// Return the specified named attribute if present.
std::optional<mlir::NamedAttribute> getNamed(llvm::StringRef key) const {
return getDict().getNamed(key);
}
std::optional<mlir::NamedAttribute> getNamed(mlir::StringAttr key) const {
return getDict().getNamed(key);
}

/// Support range iteration (delegates to DictionaryAttr).
using iterator = mlir::DictionaryAttr::iterator;
iterator begin() const { return getDict().begin(); }
iterator end() const { return getDict().end(); }
bool empty() const { return getDict().empty(); }
size_t size() const { return getDict().size(); }
}];
}

#endif // RTIO_DIALECT

Loading