Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
163 commits
Select commit Hold shift + click to select a range
20404bc
snapshot
taminob Sep 15, 2025
8fd23f6
copied rust code
taminob Sep 16, 2025
5e806f6
🎨 pre-commit fixes
pre-commit-ci[bot] Sep 16, 2025
70082d8
snapshot
taminob Oct 6, 2025
debe427
snapshot
taminob Oct 7, 2025
b86844b
snapshot
taminob Oct 7, 2025
e4dec47
minor additions
taminob Oct 9, 2025
9ce8ac3
add pass to Passes.td
taminob Oct 9, 2025
f45107b
snapshot
taminob Oct 9, 2025
81e6230
compiling snapshot
taminob Oct 13, 2025
588db20
tmp
taminob Oct 15, 2025
84fa825
switch to long double
taminob Oct 16, 2025
3dd1266
testing a.cpp
taminob Oct 16, 2025
3c214ad
add zgemm for testing, start euler decomposition implementation
taminob Oct 19, 2025
62aa918
non-working but finished snapshot
taminob Oct 21, 2025
eec099c
fix out-of-bounds issues
taminob Oct 22, 2025
b1a4286
test using Armadillo
taminob Oct 22, 2025
cee23a7
minor fix
taminob Oct 22, 2025
5550adc
tmp
taminob Oct 24, 2025
b541500
work on gate application
taminob Oct 27, 2025
0b80624
use laughing-umbrella implementation for decompose_two_qubit_product_…
taminob Oct 27, 2025
299d6f1
add more eigen decomposition implementations
taminob Oct 27, 2025
96b39ad
work on applySeries()
taminob Oct 27, 2025
3947566
Revert "use laughing-umbrella implementation for decompose_two_qubit_…
taminob Oct 27, 2025
ab188ae
fix transpose_conjugate
taminob Oct 27, 2025
410fadd
add test
taminob Oct 30, 2025
05885a1
actually kind of working snapshot?
taminob Oct 30, 2025
c87b02a
fix test case
taminob Oct 30, 2025
619d0d6
minor fix
taminob Oct 30, 2025
a998ef7
fix test case
taminob Oct 30, 2025
71420a2
add new test, fix tests
taminob Oct 30, 2025
bd8cdbd
iniital complexSeries test
taminob Nov 4, 2025
85b03c2
use Eigen for multiply() and determinant()
taminob Nov 4, 2025
0de0b43
fix gate matrix multiplication
taminob Nov 4, 2025
cc9f1be
add simple (too simple) series complexity
taminob Nov 4, 2025
13721df
fix insertion when operations which are not part of the series are in…
taminob Nov 4, 2025
6305604
add gate matrices
taminob Nov 4, 2025
dd130b9
sequence complexity()
taminob Nov 6, 2025
fb742d8
print debugging :)
taminob Nov 6, 2025
e6840d4
longer complex test to pass sequence complexity check
taminob Nov 6, 2025
08e1991
use CXGate() definition for decomposer
taminob Nov 10, 2025
0e6ff8e
add cnot test other direction
taminob Nov 10, 2025
5814ade
tmp (to be deleted)
taminob Nov 10, 2025
70d604e
re-write using Eigen
taminob Nov 10, 2025
a5dead7
delete pulse-optimizer code (KEEP for future; should be re-added at s…
taminob Nov 10, 2025
5aeb866
use designated initializer lists
taminob Nov 11, 2025
0714745
fix warnings, rename all variables
taminob Nov 11, 2025
579b6e8
test normalized magic basis, allow complex eigenvector decomposition
taminob Nov 11, 2025
7ca5341
finally figured some stuff out
taminob Nov 11, 2025
e1548d2
try out lauging-umbrella weyl-chamber
taminob Nov 12, 2025
9dfd453
try to implement weylchamber.c1c2c3 algorithm
taminob Nov 12, 2025
e78b4f3
on_gates two-qubit product decompose
taminob Nov 12, 2025
cf9d649
minor additions
taminob Nov 12, 2025
c02bfa6
try ordering all four eigenvectors
taminob Nov 12, 2025
3a800c6
undo ordering of all columns
taminob Nov 12, 2025
c155100
implement algorithm based on quantumflow.canonical_decomposition
taminob Nov 13, 2025
b6ff17f
sanity checks and stuff
taminob Nov 13, 2025
83c089e
add original implementation again which seems to kind of work?
taminob Nov 13, 2025
a94195f
generate openqasm code of generated sequence
taminob Nov 14, 2025
ab57b7d
some more small fixes, maybe breakthrough?
taminob Nov 14, 2025
af6f411
rework getTwoQubitSeries logic
taminob Nov 14, 2025
8a9447b
generate openqasm code of found series
taminob Nov 14, 2025
e4b68d1
fix new getTwoQubitSeries logic
taminob Nov 14, 2025
1eea4af
working except global phase?
taminob Nov 15, 2025
bb4b796
fix global phase issues
taminob Nov 15, 2025
837363f
first working snapshot
taminob Nov 16, 2025
2582c66
very minor cleanup
taminob Nov 16, 2025
8ec690b
add more sanity checks for unitary
taminob Nov 16, 2025
e26a374
find and fix minor formula mistake
taminob Nov 16, 2025
bc1475e
test update
taminob Nov 16, 2025
4048bf6
make calculations exact without approximation
taminob Nov 17, 2025
cff036c
respect gphase of circuit and fix series collection bug
taminob Nov 17, 2025
21701e8
change global phase to local phase
taminob Nov 17, 2025
85c1f86
revert to global phase, fix controlled gate qubit order
taminob Nov 18, 2025
9c0ecb4
fix first couple of tests
taminob Nov 18, 2025
00986dd
start working on basis set and remove dead code
taminob Nov 18, 2025
bcaf798
decompose for all bases, choose best
taminob Nov 18, 2025
83868c0
add checks for most tests
taminob Nov 18, 2025
b16bc9a
TMP, needs to be removed; allow OpenQASM export with round-trip pass
taminob Nov 18, 2025
8cdce44
add single-qubit backtracking
taminob Nov 19, 2025
e919bcd
fix atol issues
taminob Nov 19, 2025
1f91271
add more euler bases to pattern
taminob Nov 19, 2025
d4f1b49
minor cleanup (renaming, comments, disable printing)
taminob Nov 19, 2025
5620b9e
Revert "TMP, needs to be removed; allow OpenQASM export with round-tr…
taminob Nov 19, 2025
82ba25d
remove armadillo in cmake
taminob Nov 20, 2025
3d1dc8a
more cleanup
taminob Nov 20, 2025
1eeedba
fix (?) tests
taminob Nov 20, 2025
3afb374
fix final test
taminob Nov 20, 2025
17b02c5
another minor cleanup
taminob Nov 20, 2025
ca9c9f1
clean sanity check prints up
taminob Nov 20, 2025
0174a3d
properly add Eigen lib to cmake
taminob Nov 20, 2025
3c70713
remove unnecessary correction
taminob Nov 20, 2025
9f645a0
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 20, 2025
b8f6b0b
fix eigen compilation issues
taminob Nov 20, 2025
5cd8ca4
more cleanup
taminob Nov 20, 2025
412a829
clean up weyl decomposition creation
taminob Nov 21, 2025
6f04dbb
remove openqasm code generation
taminob Nov 21, 2025
eac38de
fix includes and use SmallVector instead of std::vector
taminob Nov 21, 2025
4ea3120
fix or silence linter
taminob Nov 21, 2025
0cf2292
incorporate coderabbitai feedback
taminob Nov 21, 2025
b4d419c
remove global phase accumulation
taminob Nov 25, 2025
75672af
fix :math: latex formatting
taminob Nov 25, 2025
fe08c78
minor comment fixes
taminob Nov 25, 2025
5128d83
replace CHECK-DAG by CHECK again
taminob Nov 25, 2025
9194ae9
add comments to weyl decomposition
taminob Nov 25, 2025
ac4fb41
extract TwoQubitWeylDecomposition::getTrace()
taminob Nov 25, 2025
56a2990
transform basis decomposer into actual class with private members
taminob Nov 25, 2025
76ca4d0
attempt to fix CI test
taminob Nov 25, 2025
ec7f8c3
add supercontrolled check
taminob Nov 26, 2025
49a769a
extract decomposition into headers
taminob Nov 26, 2025
910384e
slight improvement to weyl decomposition for testing purposes
taminob Nov 26, 2025
4c42850
add unittest for weyl decomposition
taminob Nov 26, 2025
3453d2c
fix linter issues
taminob Nov 26, 2025
7f0d1f6
add tests for basis decomposer
taminob Nov 26, 2025
e904dc1
fix linter issues
taminob Nov 27, 2025
c586338
clang-tidy: Add IgnoreHeader for include cleaner for Eigen
taminob Nov 27, 2025
f2efbcb
remove exact values from MLIR test
taminob Nov 27, 2025
78daaba
fix mlir test/linter issues
taminob Nov 27, 2025
741660e
remove std::numbers because not supported by all compilers in CI
taminob Nov 27, 2025
9a6c691
remove unused Helpers.h from src dir
taminob Nov 27, 2025
ad8da23
remove auto* because of windows build
taminob Nov 27, 2025
1e89778
try to fix windows ARM ci
taminob Nov 28, 2025
854d9a0
pass matrices by reference
taminob Nov 28, 2025
25b377d
allow non-optimal vectorization
taminob Nov 28, 2025
cd8ae96
🎨 pre-commit fixes
pre-commit-ci[bot] Nov 28, 2025
2f634f5
try to fix
taminob Nov 28, 2025
f9b033d
integrate single-qubit decomposition
taminob Nov 28, 2025
aaab4b8
add tests for single-qubit decomposition
taminob Nov 28, 2025
fa78cbb
add unittests for euler decomposition
taminob Nov 30, 2025
d103e7a
fix linter issues
taminob Nov 30, 2025
7fc31ae
fix include cleaner issues
taminob Dec 1, 2025
43e9d31
add test parametrizations for other specializations
taminob Dec 1, 2025
95424ee
add more matrix definitions
taminob Dec 1, 2025
a5c54e6
handle barrier gates in series collection
taminob Dec 1, 2025
aa3212d
🎨 pre-commit fixes
pre-commit-ci[bot] Dec 1, 2025
474a5d9
fix include cleaner issues
taminob Dec 1, 2025
21e9b7b
remove unused globalPhase from TwoQubitSeries
taminob Dec 1, 2025
6815b26
fix barrier handling at start of series
taminob Dec 1, 2025
202fa7f
simplify weyl specialization test parameters
taminob Dec 1, 2025
49a60a7
remove dynamic_casts due to RTTI issue
taminob Dec 19, 2025
8fc3b53
Revert "remove dynamic_casts due to RTTI issue"
taminob Dec 19, 2025
68890af
move GateDecompositionPass to new QCO dialect
taminob Dec 20, 2025
9a7006b
add GateDecompositionPass to compiler pipeline
taminob Dec 20, 2025
935ad7d
🎨 pre-commit fixes
pre-commit-ci[bot] Dec 20, 2025
d296638
add UnitaryMatrixType to operation and add Eigen dependency to dialect
taminob Dec 28, 2025
a8dbfcb
first non-working attempt
taminob Dec 28, 2025
e9da9b0
second non-working attempt
taminob Jan 4, 2026
5b325a5
compiling approach
taminob Jan 4, 2026
b3161cc
formatting
taminob Jan 5, 2026
01886fb
avoid use of implementation-dependent argument names
taminob Jan 5, 2026
30198a9
finally got template function working
taminob Jan 5, 2026
1c7dd1d
add to compiler pipeline and add (failing) test case
taminob Jan 5, 2026
a8fbec2
make unitary function const, remove HasMatrixDefinition bool template…
taminob Jan 6, 2026
f9f7f04
start working on ctrl matrix
taminob Jan 6, 2026
d8d7b19
use new unitary matrix functions in GateDecompositionPattern
taminob Jan 6, 2026
ce79ed2
add debug prints
taminob Jan 6, 2026
6c965ed
🎨 pre-commit fixes
pre-commit-ci[bot] Jan 6, 2026
1588388
add helpers for CtrlOp matrix
taminob Jan 7, 2026
00491d7
add matrix definition to all operations
taminob Jan 7, 2026
69ebd05
fixes for unitary matrix definition
taminob Jan 7, 2026
df22236
fixes for gate decomposition pattern
taminob Jan 7, 2026
31f4a02
fix formatting in MatrixUtils.h
taminob Jan 7, 2026
9e2e0e6
(dirty) fix for CtrlOp in gate decomposition pattern; runs, but SSA e…
taminob Jan 7, 2026
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
2 changes: 2 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,5 @@ CheckOptions:
value: CamelCase
- key: readability-identifier-naming.VariableCase
value: camelBack
- key: misc-include-cleaner.IgnoreHeaders
value: "Eigen/.*;unsupported/Eigen/.*"
12 changes: 12 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ include(PreventInSourceBuilds)
include(PackageAddTest)
include(Cache)
include(AddMQTCoreLibrary)
include(FetchContent)

FetchContent_Declare(
Eigen
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
GIT_TAG 3.4.1
GIT_SHALLOW TRUE)
FetchContent_MakeAvailable(Eigen)
if(WIN32 AND ${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL ARM64)
message(STATUS "Enabling non-optimal vectorization in Eigen to avoid alignment issues")
add_compile_definitions(EIGEN_DONT_ALIGN_STATICALLY)
endif()

option(BUILD_MQT_CORE_BINDINGS "Build the MQT Core Python bindings" OFF)
if(BUILD_MQT_CORE_BINDINGS)
Expand Down
3 changes: 2 additions & 1 deletion mlir/include/mlir/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
#
# Licensed under the MIT License

add_subdirectory(Dialect)
add_subdirectory(Conversion)
add_subdirectory(Dialect)
add_subdirectory(Passes)
5 changes: 5 additions & 0 deletions mlir/include/mlir/Compiler/CompilerPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ class QuantumCompilerPipeline {
*/
static void addCleanupPasses(PassManager& pm);

/**
* @brief Add all available optimization passes
*/
static void addOptimizationPasses(PassManager& pm);

/**
* @brief Configure PassManager with diagnostic options
*
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Dialect/QCO/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
# Licensed under the MIT License

add_mlir_dialect(QCOOps qco)
add_mlir_interface(QCOInterfaces)
add_mlir_interface(QCOInterfaces LINK_LIBS PUBLIC Eigen3::Eigen)
add_mlir_doc(QCOOps MLIRQCODialect Dialects/ -gen-dialect-doc)
add_mlir_doc(QCOInterfaces MLIRQCOInterfaces Dialects/ -gen-op-interface-docs -dialect=qco)
125 changes: 123 additions & 2 deletions mlir/include/mlir/Dialect/QCO/IR/QCODialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@
#pragma clang diagnostic pop
#endif

#include "mlir/Dialect/Utils/MatrixUtils.h"

#include <Eigen/Core>
#include <Eigen/SparseCore>
#include <mlir/Bytecode/BytecodeOpInterface.h>
#include <mlir/Dialect/Arith/IR/Arith.h>
#include <mlir/IR/Value.h>
#include <mlir/IR/ValueRange.h>
#include <mlir/Interfaces/SideEffectInterfaces.h>
#include <optional>
#include <string>
#include <unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h>
#include <variant>

#define DIALECT_NAME_QCO "qco"
Expand All @@ -43,6 +48,7 @@
//===----------------------------------------------------------------------===//

#define GET_TYPEDEF_CLASSES
#include "mlir/Dialect/QCO/IR/QCOInterfaces.h.inc"
#include "mlir/Dialect/QCO/IR/QCOOpsTypes.h.inc"

//===----------------------------------------------------------------------===//
Expand All @@ -51,6 +57,13 @@

namespace mlir::qco {

/**
* @brief Retrieve C++ type of static mlir::Value.
* @details The returned float attribute can be used to get the value of the
* given parameter as a C++ type.
*/
[[nodiscard]] inline std::optional<double>
tryGetParameterAsDouble(UnitaryOpInterface op, size_t i);
/**
* @brief Trait for operations with a fixed number of target qubits and
* parameters
Expand All @@ -60,8 +73,15 @@ namespace mlir::qco {
* verification and code generation optimizations.
* @tparam T The target arity.
* @tparam P The parameter arity.
* @tparam MatrixDefinition A function returning the matrix definition of the
* operation. The operation will be provided as the
* only argument of the function. If the operation does
* not have a matrix definition, set this value to
* nullptr.
*/
template <size_t T, size_t P> class TargetAndParameterArityTrait {
template <size_t T, size_t P, typename UnitaryMatrixType,
UnitaryMatrixType (*MatrixDefinition)(UnitaryOpInterface)>
class TargetAndParameterArityTrait {
public:
template <typename ConcreteType>
class Impl : public OpTrait::TraitBase<ConcreteType, Impl> {
Expand Down Expand Up @@ -108,6 +128,11 @@ template <size_t T, size_t P> class TargetAndParameterArityTrait {
return this->getOperation()->getOperand(T + i);
}

/**
* @brief Retrieve mlir::FloatAttr of static mlir::Value.
* @details The returned float attribute can be used to get the value of the
* given parameter as a C++ type or perform other mlir operations.
*/
[[nodiscard]] static FloatAttr getStaticParameter(Value param) {
auto constantOp = param.getDefiningOp<arith::ConstantOp>();
if (!constantOp) {
Expand All @@ -116,6 +141,13 @@ template <size_t T, size_t P> class TargetAndParameterArityTrait {
return dyn_cast<FloatAttr>(constantOp.getValue());
}

[[nodiscard]] UnitaryMatrixType getUnitaryMatrixDefinition() const
requires(MatrixDefinition != nullptr)
{
const auto* op = this->getConstOperation();
return MatrixDefinition(llvm::dyn_cast<UnitaryOpInterface>(op));
}

Value getInputForOutput(Value output) {
const auto& op = this->getOperation();
for (size_t i = 0; i < T; ++i) {
Expand All @@ -136,16 +168,105 @@ template <size_t T, size_t P> class TargetAndParameterArityTrait {
llvm::reportFatalUsageError(
"Given qubit is not an input of the operation");
}

protected:
[[nodiscard]] const Operation* getConstOperation() const {
auto* concrete = static_cast<const ConcreteType*>(this);
// use dereference operator instead of getOperation() of mlir::Op; the
// operator provides a const overload, getOperation() does not
return *concrete;
}
};
};

} // namespace mlir::qco

#include "mlir/Dialect/QCO/IR/QCOInterfaces.h.inc" // IWYU pragma: export
// #include "mlir/Dialect/QCO/IR/QCOInterfaces.h.inc" // IWYU pragma: export

//===----------------------------------------------------------------------===//
// Operations Helpers
//===----------------------------------------------------------------------===//

namespace mlir::qco {

[[nodiscard]] inline std::optional<double>
tryGetParameterAsDouble(UnitaryOpInterface op, size_t i) {
using DummyArityType =
TargetAndParameterArityTrait<0, 0, Eigen::MatrixXcd, nullptr>;
const auto param = op.getParameter(i);
const auto floatAttr =
DummyArityType::Impl<arith::ConstantOp>::getStaticParameter(param);
if (!floatAttr) {
return std::nullopt;
}
return floatAttr.getValueAsDouble();
}

[[nodiscard]] inline std::pair<Eigen::MatrixXcd, Eigen::VectorXi>
permutate(const Eigen::MatrixXcd& inputMatrix,
const Eigen::VectorXi& permutation) {
const auto swapMatrix = utils::getMatrixSWAP();

auto dim = inputMatrix.cols();
assert(inputMatrix.cols() == inputMatrix.rows());
assert(dim == permutation.size());

Eigen::MatrixXcd permutatedMatrix(dim, dim);
Eigen::VectorXi undoPermutation(permutation.size());
for (int i = 0; i < permutation.size(); ++i) {
undoPermutation(permutation(i)) = i;
// TODO
}

return {permutatedMatrix, undoPermutation};
}

[[nodiscard]] inline Eigen::MatrixXcd getBlockMatrix(size_t dim,
mlir::Region& region) {
// TODO: check if dim == region.getArguments().size()
assert(dim == 1); // TODO: remove once permutations are properly handled

Eigen::MatrixXcd result = Eigen::MatrixXcd::Identity(1 << dim, 1 << dim);
for (auto&& block : region) {
for (auto&& op : block) {
auto unitaryOp = llvm::dyn_cast<mlir::qco::UnitaryOpInterface>(op);
if (unitaryOp) {
return result;
}
auto matrix = unitaryOp.getUnitaryMatrix();
size_t matrixDim = matrix.cols();
if (matrixDim < dim) {
// TODO: permutate such that operation qubits are next to each other;
// then perform front/back padding accordingly

auto paddingDim = dim - matrixDim;
auto padding =
Eigen::MatrixXcd::Identity(1 << paddingDim, 1 << paddingDim);
matrix = Eigen::kroneckerProduct(matrix, padding);

// TODO: undo permutation
}
result = matrix * result;
}
}
return result;
}

mlir::Region& getCtrlBody(UnitaryOpInterface op);

} // namespace mlir::qco

//===----------------------------------------------------------------------===//
// Operations
//===----------------------------------------------------------------------===//

#define GET_OP_CLASSES
#include "mlir/Dialect/QCO/IR/QCOOps.h.inc" // IWYU pragma: export

namespace mlir::qco {

[[nodiscard]] inline mlir::Region& getCtrlBody(UnitaryOpInterface op) {
return llvm::cast<CtrlOp>(op).getBody();
}

} // namespace mlir::qco
27 changes: 24 additions & 3 deletions mlir/include/mlir/Dialect/QCO/IR/QCOInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def UnitaryOpInterface : OpInterface<"UnitaryOpInterface"> {

let cppNamespace = "::mlir::qco";

// TODO: fix const correctness?
let methods = [
// Qubit accessors
InterfaceMethod<
Expand Down Expand Up @@ -89,25 +90,45 @@ def UnitaryOpInterface : OpInterface<"UnitaryOpInterface"> {
InterfaceMethod<
"Returns true if the operation has any control qubits, otherwise false.",
"bool", "isControlled", (ins),
[{ return getNumControls(impl, tablegen_opaque_val) > 0; }]
[{ return $_op.getNumControls() > 0; }]
>,
InterfaceMethod<
"Returns true if the operation only acts on a single qubit.",
"bool", "isSingleQubit", (ins),
[{ return getNumQubits(impl, tablegen_opaque_val) == 1; }]
[{ return $_op.getNumQubits() == 1; }]
>,
InterfaceMethod<
"Returns true if the operation acts on two qubits.",
"bool", "isTwoQubit", (ins),
[{ return getNumQubits(impl, tablegen_opaque_val) == 2; }]
[{ return $_op.getNumQubits() == 2; }]
>,

// Identification
InterfaceMethod<
"Returns the base symbol/mnemonic of the operation.",
"StringRef", "getBaseSymbol", (ins)
>,

// Unitary matrix methods
InterfaceMethod<
"Returns the unitary matrix definition of the operation.",
"Eigen::MatrixXcd", "getUnitaryMatrix", (ins),
[{
if constexpr (requires { $_op.getUnitaryMatrixDefinition(); }) {
return $_op.getUnitaryMatrixDefinition();
} else {
llvm::reportFatalUsageError("Operation '" + $_op.getBaseSymbol() + "' has no unitary matrix definition!");
}
}]
>,
];

let extraTraitClassDeclaration = [{
template<typename MatrixType>
MatrixType getFastUnitaryMatrix() const {
return $_op.getUnitaryMatrixDefinition();
}
}];
}

#endif // QCO_INTERFACES
Loading
Loading