Skip to content

Commit d95f625

Browse files
committed
🎨 Rework unitary matrix proposal
1 parent 145facd commit d95f625

36 files changed

Lines changed: 499 additions & 504 deletions

mlir/include/mlir/Dialect/QCO/IR/QCODialect.h

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
#pragma clang diagnostic pop
2222
#endif
2323

24-
#include "mlir/Dialect/Utils/MatrixUtils.h"
25-
2624
#include <Eigen/Core>
2725
#include <mlir/Bytecode/BytecodeOpInterface.h>
2826
#include <mlir/Dialect/Arith/IR/Arith.h>
@@ -79,9 +77,7 @@ tryGetParameterAsDouble(UnitaryOpInterface op, size_t i);
7977
* not have a matrix definition, set this value to
8078
* nullptr.
8179
*/
82-
template <size_t T, size_t P, typename UnitaryMatrixType,
83-
UnitaryMatrixType (*MatrixDefinition)(UnitaryOpInterface)>
84-
class TargetAndParameterArityTrait {
80+
template <size_t T, size_t P> class TargetAndParameterArityTrait {
8581
public:
8682
template <typename ConcreteType>
8783
class Impl : public OpTrait::TraitBase<ConcreteType, Impl> {
@@ -128,13 +124,6 @@ class TargetAndParameterArityTrait {
128124
return this->getOperation()->getOperand(T + i);
129125
}
130126

131-
[[nodiscard]] UnitaryMatrixType getUnitaryMatrixDefinition() const
132-
requires(MatrixDefinition != nullptr)
133-
{
134-
const auto* op = this->getConstOperation();
135-
return MatrixDefinition(llvm::dyn_cast<UnitaryOpInterface>(op));
136-
}
137-
138127
Value getInputForOutput(Value output) {
139128
const auto& op = this->getOperation();
140129
for (size_t i = 0; i < T; ++i) {
@@ -168,29 +157,6 @@ class TargetAndParameterArityTrait {
168157

169158
} // namespace mlir::qco
170159

171-
//===----------------------------------------------------------------------===//
172-
// Operations Helpers
173-
//===----------------------------------------------------------------------===//
174-
175-
namespace mlir::qco {
176-
177-
[[nodiscard]] inline std::optional<double>
178-
tryGetParameterAsDouble(UnitaryOpInterface op, size_t i) {
179-
using DummyArityType =
180-
TargetAndParameterArityTrait<0, 0, Eigen::MatrixXcd, nullptr>;
181-
const auto param = op.getParameter(i);
182-
const auto floatAttr =
183-
DummyArityType::Impl<arith::ConstantOp>::getStaticParameter(param);
184-
if (!floatAttr) {
185-
return std::nullopt;
186-
}
187-
return floatAttr.getValueAsDouble();
188-
}
189-
190-
UnitaryOpInterface getControlledOp(UnitaryOpInterface op);
191-
192-
} // namespace mlir::qco
193-
194160
//===----------------------------------------------------------------------===//
195161
// Operations
196162
//===----------------------------------------------------------------------===//

mlir/include/mlir/Dialect/QCO/IR/QCOInterfaces.td

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -109,25 +109,29 @@ def UnitaryOpInterface : OpInterface<"UnitaryOpInterface"> {
109109
"StringRef", "getBaseSymbol", (ins)
110110
>,
111111

112-
// Unitary matrix methods
112+
// Internal helper methods, should not be used by user
113113
InterfaceMethod<
114114
"Returns the unitary matrix definition of the operation.",
115-
"Eigen::MatrixXcd", "getUnitaryMatrix", (ins),
116115
[{
117-
if constexpr (requires { $_op.getUnitaryMatrixDefinition(); }) {
118-
return $_op.getUnitaryMatrixDefinition();
119-
} else {
120-
llvm::reportFatalUsageError("Operation '" + $_op.getBaseSymbol() + "' has no unitary matrix definition!");
121-
}
122-
}]
123-
>,
124-
InterfaceMethod<
125-
"Returns the unitary matrix definition of the operation.",
126-
"std::variant<Eigen::Matrix<std::complex<double>, 1, 1>, Eigen::Matrix2cd, Eigen::Matrix4cd, Eigen::MatrixXcd>",
127-
"getFastUnitaryMatrixVariant", (ins),
116+
std::variant<
117+
std::nullopt_t,
118+
Eigen::Matrix<std::complex<double>, 1, 1>,
119+
Eigen::Matrix2cd,
120+
Eigen::Matrix4cd,
121+
Eigen::MatrixXcd
122+
>
123+
}],
124+
"internalGetUnitaryVariant", (ins),
128125
[{
129-
if constexpr (requires { $_op.getUnitaryMatrixDefinition(); }) {
130-
return $_op.getUnitaryMatrixDefinition();
126+
if constexpr (requires { $_op.getUnitaryMatrix().has_value(); }) {
127+
// is matrix in std::optional
128+
if (auto&& matrix = $_op.getUnitaryMatrix()) {
129+
return *matrix;
130+
}
131+
return std::nullopt;
132+
} else if constexpr (requires { $_op.getUnitaryMatrix(); }) {
133+
// is static matrix
134+
return $_op.getUnitaryMatrix();
131135
} else {
132136
llvm::reportFatalUsageError("Operation '" + $_op.getBaseSymbol() + "' has no unitary matrix definition!");
133137
}
@@ -137,11 +141,18 @@ def UnitaryOpInterface : OpInterface<"UnitaryOpInterface"> {
137141

138142
let extraClassDeclaration = [{
139143
template<typename MatrixType>
140-
MatrixType getFastUnitaryMatrix() const {
141-
// removing const since it's safe to say UnitaryOpInterface::getFastUnitaryMatrixVariant()
142-
// and OpType::getUnitaryMatrixDefinition() will not modify the state of this
143-
auto&& matrix = const_cast<UnitaryOpInterface*>(this)->getFastUnitaryMatrixVariant();
144-
return std::get<MatrixType>(matrix);
144+
std::optional<MatrixType> getUnitaryMatrix() {
145+
auto&& matrix = this->internalGetUnitaryVariant();
146+
147+
if constexpr (std::is_same_v<std::remove_cvref_t<MatrixType>, Eigen::MatrixXcd>) {
148+
// cast to Eigen::MatrixXcd via visitor pattern
149+
auto&& visitor = [](auto&& m) -> std::optional<MatrixType> { return m; };
150+
return std::visit(visitor, matrix);
151+
} else {
152+
// if an explicit size has been requested, use checked access to variant
153+
// to return the correct type (throws on wrong type)
154+
return std::get<MatrixType>(matrix);
155+
}
145156
}
146157
}];
147158
}

0 commit comments

Comments
 (0)