@@ -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