Skip to content

Commit 4a4823a

Browse files
committed
add draft for unittest of unitary matrix
1 parent 0361c93 commit 4a4823a

File tree

4 files changed

+134
-2
lines changed

4 files changed

+134
-2
lines changed

mlir/unittests/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ add_subdirectory(translation)
1212

1313
add_custom_target(mqt-core-mlir-unittests)
1414

15-
add_dependencies(mqt-core-mlir-unittests mqt-core-mlir-compiler-pipeline-test
16-
mqt-core-mlir-translation-test mqt-core-mlir-wireiterator-test)
15+
add_dependencies(
16+
mqt-core-mlir-unittests mqt-core-mlir-compiler-pipeline-test mqt-core-mlir-qco-dialect-test
17+
mqt-core-mlir-translation-test mqt-core-mlir-wireiterator-test)

mlir/unittests/dialect/CMakeLists.txt

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

99
add_subdirectory(mqtopt)
10+
add_subdirectory(qco)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) 2023 - 2025 Chair for Design Automation, TUM
2+
# Copyright (c) 2025 Munich Quantum Software Company GmbH
3+
# All rights reserved.
4+
#
5+
# SPDX-License-Identifier: MIT
6+
#
7+
# Licensed under the MIT License
8+
9+
add_executable(mqt-core-mlir-qco-dialect-test test_unitary_matrix.cpp)
10+
11+
target_link_libraries(mqt-core-mlir-qco-dialect-test PRIVATE GTest::gtest_main MLIRQCODialect
12+
MLIRLLVMDialect MLIRQCOProgramBuilder)
13+
14+
gtest_discover_tests(mqt-core-mlir-qco-dialect-test)
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright (c) 2023 - 2025 Chair for Design Automation, TUM
3+
* Copyright (c) 2025 Munich Quantum Software Company GmbH
4+
* All rights reserved.
5+
*
6+
* SPDX-License-Identifier: MIT
7+
*
8+
* Licensed under the MIT License
9+
*/
10+
11+
#include "mlir/Dialect/QCO/Builder/QCOProgramBuilder.h"
12+
13+
#include <gtest/gtest.h>
14+
#include <mlir/Dialect/ControlFlow/IR/ControlFlow.h>
15+
#include <mlir/Dialect/Func/IR/FuncOps.h>
16+
#include <mlir/Dialect/LLVMIR/LLVMDialect.h>
17+
#include <mlir/Dialect/SCF/IR/SCF.h>
18+
19+
namespace {
20+
21+
using namespace mlir;
22+
23+
class UnitaryMatrixTest : public testing::Test {
24+
protected:
25+
void SetUp() override {
26+
DialectRegistry registry;
27+
registry
28+
.insert<qco::QCODialect, arith::ArithDialect, cf::ControlFlowDialect,
29+
func::FuncDialect, scf::SCFDialect, LLVM::LLVMDialect>();
30+
31+
context = std::make_unique<MLIRContext>();
32+
context->appendDialectRegistry(registry);
33+
context->loadAllAvailableDialects();
34+
}
35+
36+
/**
37+
* @brief Build expected QCO IR programmatically and run canonicalization
38+
*/
39+
[[nodiscard]] OwningOpRef<ModuleOp> buildQCOIR(
40+
const std::function<void(qco::QCOProgramBuilder&)>& buildFunc) const {
41+
qco::QCOProgramBuilder builder(context.get());
42+
builder.initialize();
43+
buildFunc(builder);
44+
return builder.finalize();
45+
}
46+
47+
/**
48+
* @brief Get first operation of given type in a module.
49+
*/
50+
template <typename OpType>
51+
[[nodiscard]] static OpType getFirstOp(ModuleOp moduleOp) {
52+
auto&& moduleOperations = moduleOp.getBody()->getOperations();
53+
54+
ASSERT_EQ(moduleOperations.size(), 1);
55+
auto&& funcOp = moduleOperations.front();
56+
auto&& concreteFuncOp = llvm::dyn_cast<func::FuncOp>(funcOp);
57+
ASSERT_TRUE(concreteFuncOp);
58+
59+
auto funcOperations = concreteFuncOp.getBody().getOps<qco::IdOp>();
60+
ASSERT_EQ(std::distance(funcOperations.begin(), funcOperations.end()), 1);
61+
return *funcOperations.begin();
62+
}
63+
64+
/**
65+
* @brief Get text representation of given module.
66+
*/
67+
[[nodiscard]] static std::string toString(ModuleOp moduleOp) {
68+
std::string buffer;
69+
llvm::raw_string_ostream serializeStream{buffer};
70+
moduleOp->print(serializeStream);
71+
return serializeStream.str();
72+
}
73+
74+
private:
75+
std::unique_ptr<MLIRContext> context;
76+
};
77+
78+
} // namespace
79+
80+
// ##################################################
81+
// # Standard Gates Unitary Matrix Tests
82+
// ##################################################
83+
84+
/**
85+
* @brief Test: Identity unitary matrix
86+
*
87+
* @details
88+
* Ensure the correct gate definition is returned for a IdOp.
89+
*/
90+
TEST_F(UnitaryMatrixTest, IdOpMatrix) {
91+
auto moduleOp = buildQCOIR([](qco::QCOProgramBuilder& builder) {
92+
auto reg = builder.allocQubitRegister(1, "q");
93+
builder.id(reg[0]);
94+
});
95+
auto op = getFirstOp<qco::IdOp>(*moduleOp);
96+
ASSERT_TRUE(op) << toString(*moduleOp);
97+
98+
EXPECT_EQ(op.getUnitaryMatrixDefinition(), utils::getMatrixId());
99+
}
100+
101+
/**
102+
* @brief Test: X unitary matrix
103+
*
104+
* @details
105+
* Ensure the correct gate definition is returned for a IdOp.
106+
*/
107+
TEST_F(UnitaryMatrixTest, XOpMatrix) {
108+
auto moduleOp = buildQCOIR([](qco::QCOProgramBuilder& builder) {
109+
auto reg = builder.allocQubitRegister(1, "q");
110+
builder.x(reg[0]);
111+
});
112+
auto op = getFirstOp<qco::XOp>(*moduleOp);
113+
ASSERT_TRUE(op) << toString(*moduleOp);
114+
115+
EXPECT_EQ(op.getUnitaryMatrixDefinition(), utils::getMatrixId());
116+
}

0 commit comments

Comments
 (0)