Skip to content

Commit bc98ddc

Browse files
committed
more cleanup
1 parent 1a13d1c commit bc98ddc

2 files changed

Lines changed: 45 additions & 53 deletions

File tree

mlir/lib/Dialect/MQTOpt/Transforms/GateDecompositionPattern.cpp

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010

1111
#include "Helpers.h"
12+
#include "ir/Definitions.hpp"
1213
#include "mlir/Dialect/MQTOpt/IR/MQTOptDialect.h"
1314
#include "mlir/Dialect/MQTOpt/Transforms/Passes.h"
1415

@@ -32,7 +33,9 @@
3233
namespace mqt::ir::opt {
3334

3435
/**
35-
* @brief This pattern attempts to cancel consecutive self-inverse operations.
36+
* @brief This pattern attempts to collect as many operations as possible into a
37+
* 4x4 unitary matrix and then decompose it into rotation and given basis
38+
* gates.
3639
*/
3740
struct GateDecompositionPattern final
3841
: mlir::OpInterfaceRewritePattern<UnitaryInterface> {
@@ -70,7 +73,13 @@ struct GateDecompositionPattern final
7073
*/
7174
std::vector<Gate> gates;
7275

76+
/**
77+
* Global phase adjustment required for the sequence.
78+
*/
7379
fp globalPhase{};
80+
/**
81+
* @return true if the global phase adjustment is not zero.
82+
*/
7483
[[nodiscard]] bool hasGlobalPhase() const {
7584
return std::abs(globalPhase) > DEFAULT_ATOL;
7685
}
@@ -106,7 +115,14 @@ struct GateDecompositionPattern final
106115
return unitaryMatrix;
107116
}
108117
};
118+
/**
119+
* Helper type to show that a gate sequence is supposed to only contain
120+
* single-qubit gates.
121+
*/
109122
using OneQubitGateSequence = QubitGateSequence;
123+
/**
124+
* Helper type to show that the gate sequence may contain two-qubit gates.
125+
*/
110126
using TwoQubitGateSequence = QubitGateSequence;
111127

112128
/**
@@ -1518,7 +1534,15 @@ struct GateDecompositionPattern final
15181534
}
15191535
};
15201536

1537+
/**
1538+
* Factor by which two matrices are considered to be the same when simplifying
1539+
* during a decomposition.
1540+
*/
15211541
static constexpr auto DEFAULT_FIDELITY = 1.0 - 1e-15;
1542+
/**
1543+
* Largest number that will be assumed as zero for the euler decompositions
1544+
* and the global phase.
1545+
*/
15221546
static constexpr auto DEFAULT_ATOL = 1e-12;
15231547

15241548
/**
@@ -1922,7 +1946,7 @@ struct GateDecompositionPattern final
19221946
* necessary to construct an equivalent to the canonical gate.
19231947
*/
19241948
[[nodiscard]] std::array<qfp, 4>
1925-
traces(TwoQubitWeylDecomposition target) const {
1949+
traces(const TwoQubitWeylDecomposition& target) const {
19261950
return {
19271951
static_cast<fp>(4.) *
19281952
qfp(std::cos(target.a) * std::cos(target.b) * std::cos(target.c),
@@ -1938,10 +1962,13 @@ struct GateDecompositionPattern final
19381962
};
19391963
}
19401964

1941-
static OneQubitGateSequence generateCircuit(EulerBasis targetBasis,
1942-
const matrix2x2& unitaryMatrix,
1943-
bool simplify,
1944-
std::optional<fp> atol) {
1965+
/**
1966+
* Perform single-qubit decomposition of a 2x2 unitary matrix based on a
1967+
* given euler basis.
1968+
*/
1969+
[[nodiscard]] static OneQubitGateSequence
1970+
generateCircuit(EulerBasis targetBasis, const matrix2x2& unitaryMatrix,
1971+
bool simplify, std::optional<fp> atol) {
19451972
auto [theta, phi, lambda, phase] =
19461973
anglesFromUnitary(unitaryMatrix, targetBasis);
19471974

@@ -1964,12 +1991,16 @@ struct GateDecompositionPattern final
19641991
}
19651992
}
19661993

1967-
static OneQubitGateSequence unitaryToGateSequenceInner(
1968-
matrix2x2 unitaryMat,
1994+
/**
1995+
* Decompose a single-qubit unitary matrix into a single-qubit gate
1996+
* sequence. Multiple euler bases may be specified and the one with the
1997+
* least complexity will be chosen.
1998+
*/
1999+
[[nodiscard]] static OneQubitGateSequence unitaryToGateSequenceInner(
2000+
const matrix2x2& unitaryMat,
19692001
const llvm::SmallVector<EulerBasis>& targetBasisList, QubitId /*qubit*/,
19702002
const std::vector<std::unordered_map<std::string, fp>>&
1971-
/*error_map*/, // TODO: remove error_map+qubit for platform
1972-
// independence
2003+
/*error_map*/, // per qubit a mapping of operation name to error value
19732004
bool simplify, std::optional<fp> atol) {
19742005
auto calculateError = [](const OneQubitGateSequence& sequence) -> fp {
19752006
return static_cast<fp>(sequence.complexity());

mlir/lib/Dialect/MQTOpt/Transforms/Helpers.h

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,25 @@
1010

1111
#pragma once
1212

13+
#include "ir/Definitions.hpp"
1314
#include "ir/operations/OpType.hpp"
1415
#include "mlir/Dialect/MQTOpt/IR/MQTOptDialect.h"
1516

16-
#include <algorithm>
1717
#include <Eigen/Core>
1818
#include <Eigen/Eigenvalues>
19-
#include <unsupported/Eigen/KroneckerProduct> // TODO: unstable
20-
#include <iomanip> // TODO: remove
21-
#include <iostream> // TODO: remove
19+
#include <algorithm>
2220
#include <mlir/Dialect/Arith/IR/Arith.h>
2321
#include <mlir/IR/Operation.h>
22+
#include <unsupported/Eigen/KroneckerProduct> // TODO: unstable
2423

2524
namespace mqt::ir::opt {
26-
using fp = double;
25+
using fp = qc::fp;
2726
using qfp = std::complex<fp>;
2827
using matrix2x2 = Eigen::Matrix2<qfp>;
2928
using matrix4x4 = Eigen::Matrix4<qfp>;
3029
using rmatrix4x4 = Eigen::Matrix4<fp>;
3130
using diagonal4x4 = Eigen::Vector<qfp, 4>;
3231
using rdiagonal4x4 = Eigen::Vector<fp, 4>;
33-
;
3432

3533
constexpr qfp C_ZERO{0., 0.};
3634
constexpr qfp C_ONE{1., 0.};
@@ -42,43 +40,6 @@ constexpr qfp M_IM{0., -1.};
4240

4341
namespace mqt::ir::opt::helpers {
4442

45-
inline void print(std::size_t x) { std::cerr << x; }
46-
inline void print(fp x) { std::cerr << x; }
47-
48-
inline void print(qfp x) {
49-
std::cerr << std::setprecision(17) << x.real() << 'i' << x.imag();
50-
}
51-
52-
// TODO: remove
53-
template <typename T, int N, int M>
54-
void print(Eigen::Matrix<T, N, M> matrix, const std::string& s = "",
55-
bool force = false) {
56-
if (!force) {
57-
return;
58-
}
59-
if (!s.empty()) {
60-
llvm::errs() << "=== " << s << " ===\n";
61-
}
62-
std::cerr << matrix;
63-
llvm::errs() << '\n';
64-
}
65-
66-
template <typename T>
67-
void print(T matrix, const std::string& s = "", bool force = false) {
68-
if (!force) {
69-
return;
70-
}
71-
if (!s.empty()) {
72-
llvm::errs() << "=== " << s << " ===\n";
73-
}
74-
75-
for (auto&& a : matrix) {
76-
print(a);
77-
std::cerr << ' ';
78-
}
79-
llvm::errs() << '\n';
80-
}
81-
8243
std::optional<fp> mlirValueToFp(mlir::Value value);
8344

8445
template <typename T, typename Func>

0 commit comments

Comments
 (0)