Skip to content

Commit 2fab1a9

Browse files
committed
test using Armadillo
1 parent 0dc210e commit 2fab1a9

6 files changed

Lines changed: 84 additions & 7 deletions

File tree

CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ include(PackageAddTest)
2424
include(Cache)
2525
include(AddMQTCoreLibrary)
2626

27+
# include(FetchContent)
28+
# FetchContent_Declare(
29+
# armadillo
30+
# GIT_REPOSITORY https://gitlab.com/conradsnicta/armadillo-code.git
31+
# GIT_TAG 15.0.1
32+
# )
33+
# FetchContent_MakeAvailable(armadillo)
34+
find_package(Armadillo 15 REQUIRED)
35+
if(Armadillo_FOUND AND NOT TARGET Armadillo::Armadillo)
36+
add_library(Armadillo::Armadillo INTERFACE IMPORTED)
37+
set_target_properties(
38+
Armadillo::Armadillo
39+
PROPERTIES
40+
INTERFACE_LINK_LIBRARIES "${ARMADILLO_LIBRARIES}"
41+
INTERFACE_INCLUDE_DIRECTORIES "${ARMADILLO_INCLUDE_DIRS}"
42+
)
43+
endif()
44+
2745
option(BUILD_MQT_CORE_BINDINGS "Build the MQT Core Python bindings" OFF)
2846
if(BUILD_MQT_CORE_BINDINGS)
2947
# ensure that the BINDINGS option is set

mlir/lib/Dialect/MQTOpt/Transforms/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# Licensed under the MIT License
88

99
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
10-
set(LIBRARIES ${dialect_libs} MQT::CoreIR MQT::CoreDD)
10+
set(LIBRARIES ${dialect_libs} MQT::CoreIR MQT::CoreDD Armadillo::Armadillo)
1111
add_compile_options(-fexceptions)
1212

1313
file(GLOB TRANSFORMS_SOURCES *.cpp)

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <mlir/Support/LogicalResult.h>
2626
#include <string>
2727

28-
#include "b.h"
28+
#include "d.h"
2929

3030
namespace mqt::ir::opt {
3131

@@ -324,7 +324,7 @@ struct GateDecompositionPattern final
324324

325325
auto [U, S] = self_adjoint_evd(A);
326326

327-
return {U, S};
327+
return std::make_pair(U, S);
328328
}
329329

330330
static std::tuple<matrix2x2, matrix2x2, fp>
@@ -564,6 +564,15 @@ struct GateDecompositionPattern final
564564
llvm::errs() << "===== M2 =====\n";
565565
helpers::print(m2);
566566

567+
arma::Mat<qfp> U(4, 4);
568+
for (int i = 0; i < 4; ++i) {
569+
for (int j = 0; j < 4; ++j) {
570+
U.at(j, i) = u_p[j * 4 + i];
571+
}
572+
}
573+
auto x = U.st() * U;
574+
std::cerr << "ARMA\n" << U.t() << "\n\n" << U << "\n\n" << x << std::endl;
575+
567576
// M2 is a symmetric complex matrix. We need to decompose it as M2 = P D
568577
// P^T where P ∈ SO(4), D is diagonal with unit-magnitude elements.
569578
//
@@ -603,7 +612,7 @@ struct GateDecompositionPattern final
603612
llvm::transform(m2, m2_real.begin(), [&](const qfp& val) {
604613
return rand_a * val.real() + rand_b * val.imag();
605614
});
606-
auto p_inner_real = self_adjoint_eigen_lower(m2_real).first;
615+
rmatrix4x4 p_inner_real = self_adjoint_eigen_lower(m2_real).first;
607616
matrix4x4 p_inner;
608617
llvm::transform(p_inner_real, p_inner.begin(),
609618
[](auto&& x) { return qfp(x, 0.0); });
@@ -638,6 +647,7 @@ struct GateDecompositionPattern final
638647
std::array<fp, d.size()> d_real;
639648
llvm::transform(d, d_real.begin(),
640649
[](auto&& x) { return -std::arg(x) / 2.0; });
650+
helpers::print(d_real, "D_REAL");
641651
d_real[3] = -d_real[0] - d_real[1] - d_real[2];
642652
std::array<fp, 3> cs;
643653
for (std::size_t i = 0; i < cs.size(); ++i) {
@@ -680,6 +690,7 @@ struct GateDecompositionPattern final
680690
temp[1 * 4 + 1] = std::exp(IM * d_real[1]);
681691
temp[2 * 4 + 2] = std::exp(IM * d_real[2]);
682692
temp[3 * 4 + 3] = std::exp(IM * d_real[3]);
693+
helpers::print(temp, "TEMP");
683694
auto k1 = magic_basis_transform(dot(dot(u_p, p), temp),
684695
MagicBasisTransform::Into);
685696
auto k2 = magic_basis_transform(transpose(p), MagicBasisTransform::Into);

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,27 @@ constexpr qfp M_IM{0., -1.};
4040
namespace mqt::ir::opt::helpers {
4141

4242
// TODO: remove
43-
template <std::size_t N> void print(std::array<std::complex<fp>, N> matrix) {
43+
template <std::size_t N> void print(std::array<std::complex<fp>, N> matrix, std::string s = "") {
4444
int i{};
45+
if (!s.empty()) {
46+
llvm::errs() << "=== " << s << " ===\n";
47+
}
48+
for (auto&& a : matrix) {
49+
std::cerr << std::setprecision(17) << a.real() << 'i' << a.imag() << ' ';
50+
if (++i % 4 == 0) {
51+
llvm::errs() << '\n';
52+
}
53+
}
54+
llvm::errs() << '\n';
55+
}
56+
57+
template <std::size_t N> void print(std::array<fp, N> matrix, std::string s = "") {
58+
int i{};
59+
if (!s.empty()) {
60+
llvm::errs() << "=== " << s << " ===\n";
61+
}
4562
for (auto&& a : matrix) {
46-
std::cerr << std::setprecision(50) << a.real() << 'i' << a.imag() << ' ';
63+
std::cerr << std::setprecision(17) << a << ' ';
4764
if (++i % 4 == 0) {
4865
llvm::errs() << '\n';
4966
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ void householderSequenceEval(rmatrix4x4& m_vectors,
425425
}
426426

427427
// https://docs.rs/faer/latest/faer/mat/generic/struct.Mat.html#method.self_adjoint_eigen
428-
static std::pair<rmatrix4x4, rdiagonal4x4> self_adjoint_evd(rmatrix4x4 matrix) {
428+
inline std::pair<rmatrix4x4, rdiagonal4x4> self_adjoint_evd(rmatrix4x4 matrix) {
429429

430430
auto lowerTriangularView = [](auto matrix) {
431431
const int n = std::sqrt(matrix.size());
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include "Helpers.h"
4+
5+
#include <armadillo>
6+
7+
namespace mqt::ir::opt {
8+
9+
auto self_adjoint_evd(rmatrix4x4 A) {
10+
arma::Mat<fp> a(4, 4, arma::fill::scalar_holder<fp>(0.0));
11+
for (int i = 0; i < 4; ++i) {
12+
for (int j = 0; j < 4; ++j) {
13+
a.at(j, i) = A[j * 4 + i];
14+
}
15+
}
16+
arma::Mat<fp> vecs;
17+
arma::Col<fp> vals;
18+
arma::eig_sym(vals, vecs, a, "std");
19+
rmatrix4x4 rvecs;
20+
rdiagonal4x4 rvals;
21+
for (int i = 0; i < 4; ++i) {
22+
for (int j = 0; j < 4; ++j) {
23+
rvecs[j * 4 + i] = vecs.at(j, i);
24+
}
25+
rvals[i] = vals.at(i);
26+
}
27+
std::cerr << "========\n" << vecs << "========\n" << std::endl;
28+
std::cerr << "========\n" << vals << "========\n" << std::endl;
29+
return std::make_pair(rvecs, rvals);
30+
}
31+
} // namespace mqt::ir::opt

0 commit comments

Comments
 (0)