Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel
### Added

- ✨ Add Sampler and Estimator Primitives to the QDMI-Qiskit Interface ([#1507]) ([**@marcelwa**])
- ✨ Add conversions between Jeff and QCO ([#1479], [#1548]) ([**@denialhaag**])
- ✨ Add conversions between Jeff and QCO ([#1479], [#1548], [#1565]) ([**@denialhaag**])
- ✨ Add a `place-and-route` pass for mapping circuits to architectures with restricted topologies ([#1537], [#1547], [#1568]) ([**@MatthiasReumann**])
- ✨ Add initial infrastructure for new QC and QCO MLIR dialects
([#1264], [#1330], [#1402], [#1428], [#1430], [#1436], [#1443], [#1446], [#1464], [#1465], [#1470], [#1471], [#1472], [#1474], [#1475], [#1506], [#1510], [#1513], [#1521], [#1548], [#1550], [#1554])
Expand Down Expand Up @@ -332,6 +332,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool
<!-- PR links -->

[#1568]: https://github.com/munich-quantum-toolkit/core/pull/1568
[#1565]: https://github.com/munich-quantum-toolkit/core/pull/1565
[#1554]: https://github.com/munich-quantum-toolkit/core/pull/1554
[#1550]: https://github.com/munich-quantum-toolkit/core/pull/1550
[#1549]: https://github.com/munich-quantum-toolkit/core/pull/1549
Expand Down
2 changes: 1 addition & 1 deletion cmake/ExternalDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ if(BUILD_MQT_CORE_MLIR)
FetchContent_Declare(
jeff-mlir
GIT_REPOSITORY https://github.com/PennyLaneAI/jeff-mlir.git
GIT_TAG c22047e0ebe361126f042baf3c439e0042827a03)
GIT_TAG c7e0d0340e470c9097a79a430b633b97dcd864e9)
list(APPEND FETCH_PACKAGES jeff-mlir)
endif()

Expand Down
30 changes: 16 additions & 14 deletions mlir/include/mlir/Conversion/JeffToQCO/JeffToQCO.td
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,26 @@ def JeffToQCO : Pass<"jeff-to-qco"> {
let summary = "Convert Jeff operations to QCO operations";

let description = [{
This pass converts all operations from the Jeff dialect to their equivalent operations in the QCO dialect.
It ensures that the returned module is a valid QCO module.
This pass converts all operations from the Jeff dialect to their equivalent operations in the QCO dialect.
It ensures that the returned module is a valid QCO module.

Note that this pass is still in development as QCO and Jeff do not have full feature parity yet.
Note that this pass is still in development as QCO and Jeff do not have full feature parity yet.

Known limitations:
Known limitations:

- Gates with a non-trivial power are currently not supported
- Only specific `CustomOp`s are currently supported
- Only specific `PPROp`s are currently supported
- `Qureg_Op`s are currently not supported
- `SCF_Op`s are currently not supported
- Support for multiple functions is currently limited
}];
- Gates with a non-trivial power are currently not supported
- Only specific `CustomOp`s are currently supported
- Only specific `PPROp`s are currently supported
- `Qureg_Op`s are currently not supported
- `SCF_Op`s are currently not supported
- Support for multiple functions is currently limited
}];

let dependentDialects = [
"mlir::arith::ArithDialect",
"mlir::jeff::JeffDialect",
"mlir::qco::QCODialect",
"mlir::arith::ArithDialect",
"mlir::math::MathDialect",
"mlir::tensor::TensorDialect",
Comment thread
burgholzer marked this conversation as resolved.
"mlir::jeff::JeffDialect",
"mlir::qco::QCODialect",
];
}
15 changes: 9 additions & 6 deletions mlir/include/mlir/Conversion/QCOToJeff/QCOToJeff.td
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ def QCOToJeff : Pass<"qco-to-jeff"> {
let summary = "Convert QCO operations to Jeff operations";

let description = [{
This pass converts all operations from the QCO dialect to their equivalent operations in the Jeff dialect.
It ensures that the returned module is a valid Jeff module that can be serialized.
This pass converts all operations from the QCO dialect to their equivalent operations in the Jeff dialect.
It ensures that the returned module is a valid Jeff module that can be serialized.

Note that this pass is still in development as QCO and Jeff do not have full feature parity yet.
}];
Note that this pass is still in development as QCO and Jeff do not have full feature parity yet.
}];

let dependentDialects = [
"mlir::jeff::JeffDialect",
"mlir::qco::QCODialect",
"mlir::arith::ArithDialect",
"mlir::math::MathDialect",
"mlir::tensor::TensorDialect",
Comment thread
burgholzer marked this conversation as resolved.
"mlir::jeff::JeffDialect",
"mlir::qco::QCODialect",
];
}
4 changes: 1 addition & 3 deletions mlir/lib/Conversion/JeffToQCO/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ add_mlir_conversion_library(
JeffToQCOIncGen
LINK_LIBS
MLIRJeff
MLIRJeffToNative
MLIRQCODialect
MLIRTransforms
DISABLE_INSTALL)

target_include_directories(MLIRJeffToQCO PRIVATE ${jeff-mlir_SOURCE_DIR}/include
${jeff-mlir_BINARY_DIR}/include)
118 changes: 24 additions & 94 deletions mlir/lib/Conversion/JeffToQCO/JeffToQCO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@
#include "mlir/Dialect/QCO/IR/QCODialect.h"
#include "mlir/Dialect/QCO/IR/QCOOps.h"

#include <jeff/Conversion/JeffToNative/JeffToNative.h>
#include <jeff/IR/JeffDialect.h>
#include <jeff/IR/JeffOps.h>
#include <llvm/ADT/STLFunctionalExtras.h>
#include <llvm/Support/Casting.h>
#include <llvm/Support/ErrorHandling.h>
#include <mlir/Dialect/Arith/IR/Arith.h>
#include <mlir/Dialect/Func/IR/FuncOps.h>
#include <mlir/Dialect/Math/IR/Math.h>
#include <mlir/Dialect/Tensor/IR/Tensor.h>
#include <mlir/IR/Builders.h>
#include <mlir/IR/BuiltinAttributes.h>
#include <mlir/IR/BuiltinOps.h>
Expand Down Expand Up @@ -883,78 +886,6 @@ struct ConvertJeffMainToQCO final : OpConversionPattern<func::FuncOp> {
}
};

/**
* @brief Converts jeff.int_const1 to arith.constant
*
* @par Example:
* ```mlir
* %0 = jeff.int_const1(true) : i1
* ```
* is converted to
* ```mlir
* %0 = arith.constant true : i1
* ```
*/
struct ConvertJeffIntConst1OpToArith final
: OpConversionPattern<jeff::IntConst1Op> {
using OpConversionPattern::OpConversionPattern;

LogicalResult
matchAndRewrite(jeff::IntConst1Op op, OpAdaptor /*adaptor*/,
ConversionPatternRewriter& rewriter) const override {
rewriter.replaceOpWithNewOp<arith::ConstantOp>(op, op.getValAttr());
return success();
}
};

/**
* @brief Converts jeff.int_const64 to arith.constant
*
* @par Example:
* ```mlir
* %0 = jeff.int_const64(3) : i64
* ```
* is converted to
* ```mlir
* %0 = arith.constant 3 : i64
* ```
*/
struct ConvertJeffIntConst64OpToArith final
: OpConversionPattern<jeff::IntConst64Op> {
using OpConversionPattern::OpConversionPattern;

LogicalResult
matchAndRewrite(jeff::IntConst64Op op, OpAdaptor /*adaptor*/,
ConversionPatternRewriter& rewriter) const override {
rewriter.replaceOpWithNewOp<arith::ConstantOp>(op, op.getValAttr());
return success();
}
};

/**
* @brief Converts jeff.float_const64 to arith.constant
*
* @par Example:
* ```mlir
* %0 = jeff.float_const64(0.3) : f64
* ```
* is converted to
* ```mlir
* %0 = arith.constant 0.3 : f64
* ```
*/
struct ConvertJeffFloatConst64OpToArith final
: OpConversionPattern<jeff::FloatConst64Op> {
using OpConversionPattern::OpConversionPattern;

LogicalResult
matchAndRewrite(jeff::FloatConst64Op op, OpAdaptor /*adaptor*/,
ConversionPatternRewriter& rewriter) const override {
rewriter.replaceOpWithNewOp<arith::ConstantOp>(op, op.getValAttr());
return success();
}
};

/**
* @brief Type converter for Jeff-to-QCO conversion
*
Expand Down Expand Up @@ -990,7 +921,8 @@ struct JeffToQCO final : impl::JeffToQCOBase<JeffToQCO> {

// Configure conversion target
target.addIllegalDialect<jeff::JeffDialect>();
target.addLegalDialect<QCODialect, arith::ArithDialect>();
target.addLegalDialect<QCODialect, arith::ArithDialect, math::MathDialect,
tensor::TensorDialect>();

target.addDynamicallyLegalOp<func::FuncOp>([&](func::FuncOp op) {
return !(op.getSymName() == getEntryPointName(module) &&
Expand All @@ -999,27 +931,25 @@ struct JeffToQCO final : impl::JeffToQCOBase<JeffToQCO> {
target.addLegalOp<func::ReturnOp>();

// Register operation conversion patterns
patterns
.add<ConvertJeffQubitAllocOpToQCO, ConvertJeffQubitFreeOpToQCO,
ConvertJeffQubitFreeZeroOpToQCO, ConvertJeffQubitMeasureOpToQCO,
ConvertJeffQubitMeasureNDOpToQCO, ConvertJeffQubitResetOpToQCO,
ConvertJeffGPhaseOpToQCO,
ConvertJeffOneTargetZeroParameterToQCO<jeff::IOp, qco::IdOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::XOp, qco::XOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::YOp, qco::YOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::ZOp, qco::ZOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::HOp, qco::HOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::SOp, qco::SOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::TOp, qco::TOp>,
ConvertJeffOneTargetOneParameterToQCO<jeff::RxOp, qco::RXOp>,
ConvertJeffOneTargetOneParameterToQCO<jeff::RyOp, qco::RYOp>,
ConvertJeffOneTargetOneParameterToQCO<jeff::RzOp, qco::RZOp>,
ConvertJeffOneTargetOneParameterToQCO<jeff::R1Op, qco::POp>,
ConvertJeffUOpToQCO, ConvertJeffSwapOpToQCO,
ConvertJeffCustomOpToQCO, ConvertJeffPPROpToQCO,
ConvertJeffMainToQCO, ConvertJeffIntConst1OpToArith,
ConvertJeffIntConst64OpToArith, ConvertJeffFloatConst64OpToArith>(
typeConverter, context);
jeff::populateJeffToNativeConversionPatterns(patterns);
patterns.add<
ConvertJeffQubitAllocOpToQCO, ConvertJeffQubitFreeOpToQCO,
ConvertJeffQubitFreeZeroOpToQCO, ConvertJeffQubitMeasureOpToQCO,
ConvertJeffQubitMeasureNDOpToQCO, ConvertJeffQubitResetOpToQCO,
ConvertJeffGPhaseOpToQCO,
ConvertJeffOneTargetZeroParameterToQCO<jeff::IOp, qco::IdOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::XOp, qco::XOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::YOp, qco::YOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::ZOp, qco::ZOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::HOp, qco::HOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::SOp, qco::SOp>,
ConvertJeffOneTargetZeroParameterToQCO<jeff::TOp, qco::TOp>,
ConvertJeffOneTargetOneParameterToQCO<jeff::RxOp, qco::RXOp>,
ConvertJeffOneTargetOneParameterToQCO<jeff::RyOp, qco::RYOp>,
ConvertJeffOneTargetOneParameterToQCO<jeff::RzOp, qco::RZOp>,
ConvertJeffOneTargetOneParameterToQCO<jeff::R1Op, qco::POp>,
ConvertJeffUOpToQCO, ConvertJeffSwapOpToQCO, ConvertJeffCustomOpToQCO,
ConvertJeffPPROpToQCO, ConvertJeffMainToQCO>(typeConverter, context);

// Apply the conversion
if (applyPartialConversion(module, target, std::move(patterns)).failed()) {
Expand Down
4 changes: 1 addition & 3 deletions mlir/lib/Conversion/QCOToJeff/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@ add_mlir_conversion_library(
LINK_LIBS
MLIRDialect
MLIRJeff
MLIRNativeToJeff
MLIRQCODialect
MLIRTransforms
DISABLE_INSTALL)

target_include_directories(MLIRQCOToJeff PRIVATE ${jeff-mlir_SOURCE_DIR}/include
${jeff-mlir_BINARY_DIR}/include)

if(TARGET MLIRQCOToJeff)
target_compile_definitions(MLIRQCOToJeff PRIVATE MQT_CORE_VERSION="${MQT_CORE_VERSION}")
endif()
Expand Down
68 changes: 7 additions & 61 deletions mlir/lib/Conversion/QCOToJeff/QCOToJeff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@
#include "mlir/Dialect/QCO/IR/QCODialect.h"
#include "mlir/Dialect/QCO/IR/QCOOps.h"

#include <jeff/Conversion/NativeToJeff/NativeToJeff.h>
#include <jeff/IR/JeffDialect.h>
#include <jeff/IR/JeffOps.h>
#include <llvm/ADT/STLExtras.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/TypeSwitch.h>
#include <llvm/Support/Casting.h>
#include <mlir/Dialect/Arith/IR/Arith.h>
#include <mlir/Dialect/Func/IR/FuncOps.h>
#include <mlir/Dialect/Math/IR/Math.h>
#include <mlir/Dialect/Tensor/IR/Tensor.h>
#include <mlir/IR/Builders.h>
#include <mlir/IR/BuiltinAttributes.h>
#include <mlir/IR/BuiltinOps.h>
Expand Down Expand Up @@ -1312,63 +1314,6 @@ struct ConvertQCOMainToJeff final : StatefulOpConversionPattern<func::FuncOp> {
}
};

/**
* @brief Converts arith.constant to Jeff
*
* @par Example:
* ```mlir
* %0 = arith.constant 0 : i64
* ```
* is converted to
* ```mlir
* %0 = jeff.int_const64(0) : i64
* ```
*/
struct ConvertArithConstOpToJeff final
: StatefulOpConversionPattern<arith::ConstantOp> {
using StatefulOpConversionPattern::StatefulOpConversionPattern;

LogicalResult
matchAndRewrite(arith::ConstantOp op, OpAdaptor /*adaptor*/,
ConversionPatternRewriter& rewriter) const override {
auto value = op.getValue();
return llvm::TypeSwitch<Type, LogicalResult>(op.getType())
.Case<FloatType>([&](auto type) -> LogicalResult {
auto floatAttr = llvm::dyn_cast<FloatAttr>(value);
if (!floatAttr) {
return rewriter.notifyMatchFailure(op, "Expected float attribute");
}
switch (type.getWidth()) {
case 64:
rewriter.replaceOpWithNewOp<jeff::FloatConst64Op>(op, floatAttr);
return success();
default:
return rewriter.notifyMatchFailure(op, "Unsupported type");
}
})
.Case<IntegerType>([&](auto type) -> LogicalResult {
auto intAttr = llvm::dyn_cast<IntegerAttr>(value);
if (!intAttr) {
return rewriter.notifyMatchFailure(op,
"Expected integer attribute");
}
switch (type.getWidth()) {
case 1:
rewriter.replaceOpWithNewOp<jeff::IntConst1Op>(op, intAttr);
return success();
case 64:
rewriter.replaceOpWithNewOp<jeff::IntConst64Op>(op, intAttr);
return success();
default:
return rewriter.notifyMatchFailure(op, "Unsupported type");
}
})
.Default([&](auto) -> LogicalResult {
return rewriter.notifyMatchFailure(op, "Unsupported type");
});
}
};

/**
* @brief Type converter for QCO-to-Jeff conversion
*
Expand Down Expand Up @@ -1405,14 +1350,16 @@ struct QCOToJeff final : impl::QCOToJeffBase<QCOToJeff> {
LoweringState state;

// Configure conversion target
target.addIllegalDialect<QCODialect>();
target.addIllegalDialect<QCODialect, arith::ArithDialect, math::MathDialect,
tensor::TensorDialect>();
target.addLegalDialect<jeff::JeffDialect>();

target.addDynamicallyLegalOp<func::FuncOp>(
[](func::FuncOp op) { return !op->hasAttr("passthrough"); });
target.addLegalOp<func::ReturnOp>();

// Register operation conversion patterns
jeff::populateNativeToJeffConversionPatterns(patterns);
patterns.add<
ConvertQCOAllocOpToJeff, ConvertQCODeallocOpToJeff,
ConvertQCOMeasureOpToJeff, ConvertQCOResetOpToJeff,
Expand All @@ -1439,8 +1386,7 @@ struct QCOToJeff final : impl::QCOToJeffBase<QCOToJeff> {
ConvertQCORZZOpToJeff, ConvertQCOXXMinusYYOpToJeff,
ConvertQCOXXPlusYYOpToJeff, ConvertQCOBarrierOpToJeff,
ConvertQCOCtrlOpToJeff, ConvertQCOInvOpToJeff, ConvertQCOYieldOpToJeff,
ConvertQCOMainToJeff, ConvertArithConstOpToJeff>(typeConverter, context,
&state);
ConvertQCOMainToJeff>(typeConverter, context, &state);

// Apply the conversion
if (applyPartialConversion(module, target, std::move(patterns)).failed()) {
Expand Down
3 changes: 0 additions & 3 deletions mlir/unittests/Conversion/JeffRoundTrip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ target_link_libraries(
MLIRJeffToQCO
MLIRQCOToJeff)

target_include_directories(${target_name} PRIVATE ${jeff-mlir_SOURCE_DIR}/include
${jeff-mlir_BINARY_DIR}/include)

mqt_mlir_configure_unittest_target(${target_name})

gtest_discover_tests(${target_name} PROPERTIES LABELS mqt-mlir-unittests DISCOVERY_TIMEOUT 60)
Loading