From 17a53e03ebdf98cd5a1ff7be4d0cca0717b35002 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 15:38:20 +0100 Subject: [PATCH 01/19] =?UTF-8?q?=F0=9F=8E=A8=20improve=20cmake-format=20c?= =?UTF-8?q?onfig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index de6467404..9320a1101 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -101,6 +101,8 @@ repos: additional_dependencies: [pyyaml] - id: cmake-lint additional_dependencies: [pyyaml] + types: [file] + files: (\.cmake|CMakeLists.txt)(.in)?$ # Format configuration files with prettier - repo: https://github.com/pre-commit/mirrors-prettier From bdc8e6b679eca0ecce52fd22f02bdee5547e5293 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 16:42:11 +0100 Subject: [PATCH 02/19] =?UTF-8?q?=F0=9F=94=A5=20remove=20cmake-lint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9320a1101..4a908d48b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -99,8 +99,6 @@ repos: hooks: - id: cmake-format additional_dependencies: [pyyaml] - - id: cmake-lint - additional_dependencies: [pyyaml] types: [file] files: (\.cmake|CMakeLists.txt)(.in)?$ From 9408bbb1e2ae3156f74c8f3f2ae803013a6e65ee Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 16:42:27 +0100 Subject: [PATCH 03/19] =?UTF-8?q?=F0=9F=91=A8=E2=80=8D=F0=9F=92=BB=20add?= =?UTF-8?q?=20uninstall=20cmake=20target?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 5 +++++ cmake/cmake_uninstall.cmake.in | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 cmake/cmake_uninstall.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 54897ed09..eb9ab1c1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,3 +60,8 @@ if(BUILD_MQT_QMAP_TESTS) include(GoogleTest) add_subdirectory(test) endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY) +add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P + ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in new file mode 100644 index 000000000..1e5d2bb87 --- /dev/null +++ b/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,23 @@ +# Source: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake + +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif() + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS + "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif() + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif() +endforeach() From 0643bfc420ad83b1200104a0bc2a2c4bf3e13894 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 16:45:00 +0100 Subject: [PATCH 04/19] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20update=20max.=20supp?= =?UTF-8?q?orted=20CMake=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb9ab1c1d..833135c57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # set required cmake version -cmake_minimum_required(VERSION 3.19...3.27) +cmake_minimum_required(VERSION 3.19...3.28) project( qmap From 1c75e599f67d903c64d0f78fdee9b65932bd1045 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 16:46:02 +0100 Subject: [PATCH 05/19] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20remove=20non-existin?= =?UTF-8?q?g=20session=20from=20nox=20sessions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index c1fc7be23..96c950a34 100644 --- a/noxfile.py +++ b/noxfile.py @@ -12,7 +12,7 @@ if TYPE_CHECKING: from collections.abc import Sequence -nox.options.sessions = ["lint", "pylint", "tests"] +nox.options.sessions = ["lint", "tests"] PYTHON_ALL_VERSIONS = ["3.8", "3.9", "3.10", "3.11", "3.12"] From cb6eee77fdcbb99c75d2b0d1abcf7124882ae4f3 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 16:47:37 +0100 Subject: [PATCH 06/19] =?UTF-8?q?=F0=9F=A9=B9=20do=20not=20try=20to=20buil?= =?UTF-8?q?d=20stable=20ABI=20wheels?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a38480d67..9b1e0c49a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,9 +91,6 @@ ninja.minimum-version = "1.10" # Setuptools-style build caching in a local directory build-dir = "build/{wheel_tag}" -# Build stable ABI wheels for CPython 3.12+ -wheel.py-api = "cp312" - # Explicitly set the package directory wheel.packages = ["src/mqt"] From dc20d1ad87db911e7178b931d5125abec9d53321 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 16:52:28 +0100 Subject: [PATCH 07/19] =?UTF-8?q?=F0=9F=94=A7=20optimize=20pybind11=20modu?= =?UTF-8?q?le=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++-- src/CMakeLists.txt | 4 ++-- src/python/CMakeLists.txt | 49 ++++++++++++++------------------------- 3 files changed, 21 insertions(+), 36 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9b1e0c49a..82e6255cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,8 +81,8 @@ Discussions = "https://github.com/cda-tum/mqt-qmap/discussions" # Protect the configuration against future changes in scikit-build-core minimum-version = "0.6.1" -# Set the target to build -cmake.targets = ["pyqmap"] +# Set the wheel install directory +wheel.install-dir = "mqt/qmap" # Set required CMake and Ninja versions cmake.minimum-version = "3.19" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cca697ca8..e3a28af81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -91,8 +91,8 @@ target_link_libraries(${PROJECT_NAME}_exact_lib PUBLIC logicblocks::Logic logicb add_synthesis_library(cliffordsynthesis CliffordSynthesizer) # add LogicBlocks library -target_link_libraries(${PROJECT_NAME}_cliffordsynthesis_lib PUBLIC logicblocks::Logic - logicblocks::Encodings) +target_link_libraries(${PROJECT_NAME}_cliffordsynthesis_lib + PUBLIC logicblocks::Logic logicblocks::Encodings nlohmann_json::nlohmann_json) # heuristic mapper project library add_qmap_library(heuristic HeuristicMapper) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 866553ace..06f81c6bf 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -1,28 +1,3 @@ -if(NOT SKBUILD) - message( - NOTICE - "\ - This CMake file is meant to be executed using 'scikit-build'. Running - it directly will almost certainly not produce the desired result. If - you are a user trying to install this package, please use the command - below, which will install all necessary build dependencies, compile - the package in an isolated environment, and then install it. - ===================================================================== - $ pip install . - ===================================================================== - If you are a software developer, and this is your own package, then - it is usually much more efficient to install the build dependencies - in your environment once and use the following command that avoids - a costly creation of a new virtual environment at every compilation: - ===================================================================== - $ pip install 'scikit-build-core[pyproject]' setuptools_scm pybind11 - $ pip install --no-build-isolation -ve . - ===================================================================== - You may optionally add -Ceditable.rebuild=true to auto-rebuild when - the package is imported. Otherwise, you need to re-run the above - after editing C++ files.") -endif() - if(NOT SKBUILD) # Manually detect the installed pybind11 package and import it into CMake. execute_process( @@ -36,12 +11,22 @@ endif() find_package(pybind11 CONFIG REQUIRED) # We are now ready to compile the actual extension module -pybind11_add_module(py${PROJECT_NAME} bindings.cpp) -target_compile_definitions(py${PROJECT_NAME} PRIVATE Z3_FOUND) -target_link_libraries(py${PROJECT_NAME} PRIVATE MQT::CorePython) -target_link_libraries(py${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_exact_lib) -target_link_libraries(py${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_heuristic_lib) -target_link_libraries(py${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_cliffordsynthesis_lib) +pybind11_add_module( + pyqmap + # Prefer thin LTO if available + THIN_LTO + # Optimize the bindings for size + OPT_SIZE + # Source code goes here + bindings.cpp) +target_compile_definitions(pyqmap PRIVATE Z3_FOUND) +target_link_libraries(pyqmap PRIVATE MQT::CorePython) +target_link_libraries(pyqmap PRIVATE qmap_exact_lib) +target_link_libraries(pyqmap PRIVATE qmap_heuristic_lib) +target_link_libraries(pyqmap PRIVATE qmap_cliffordsynthesis_lib) # Install directive for scikit-build-core -install(TARGETS py${PROJECT_NAME} LIBRARY DESTINATION mqt/qmap) +install( + TARGETS pyqmap + DESTINATION . + COMPONENT mqt-qmap_PythonModule) From b72d071f464464678ace864f9b5cb86d0a720a8e Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 18:40:13 +0100 Subject: [PATCH 08/19] =?UTF-8?q?=F0=9F=91=BD=20adapt=20to=20latest=20mqt-?= =?UTF-8?q?core=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extern/mqt-core | 2 +- include/DataLogger.hpp | 4 ++-- include/Mapper.hpp | 2 +- .../cliffordsynthesis/CliffordSynthesizer.hpp | 2 +- include/cliffordsynthesis/Results.hpp | 2 +- src/DataLogger.cpp | 2 +- src/cliffordsynthesis/Tableau.cpp | 2 ++ src/python/bindings.cpp | 4 ++-- test/cliffordsynthesis/test_synthesis.cpp | 2 +- test/test_exact.cpp | 16 ++++++------- test/test_heuristic.cpp | 24 +++++++++---------- 11 files changed, 32 insertions(+), 30 deletions(-) diff --git a/extern/mqt-core b/extern/mqt-core index d39959ee7..6d9a08ed8 160000 --- a/extern/mqt-core +++ b/extern/mqt-core @@ -1 +1 @@ -Subproject commit d39959ee774f9a8bf5c888958f223529eae43a01 +Subproject commit 6d9a08ed81019bd120065ca511721a500bc52aca diff --git a/include/DataLogger.hpp b/include/DataLogger.hpp index 501e3c0a2..5cef6d0fe 100644 --- a/include/DataLogger.hpp +++ b/include/DataLogger.hpp @@ -55,13 +55,13 @@ class DataLogger { if (deactivated) { return; } - qc.dump(dataLoggingPath + "/input.qasm", qc::Format::OpenQASM); + qc.dump(dataLoggingPath + "/input.qasm", qc::Format::OpenQASM3); }; void logOutputCircuit(qc::QuantumComputation& qc) { if (deactivated) { return; } - qc.dump(dataLoggingPath + "/output.qasm", qc::Format::OpenQASM); + qc.dump(dataLoggingPath + "/output.qasm", qc::Format::OpenQASM3); } void close(); diff --git a/include/Mapper.hpp b/include/Mapper.hpp index 109c7781a..d0807e970 100644 --- a/include/Mapper.hpp +++ b/include/Mapper.hpp @@ -289,7 +289,7 @@ class Mapper { if (extension == "real") { dumpResult(outputFilename, qc::Format::Real); } else if (extension == "qasm") { - dumpResult(outputFilename, qc::Format::OpenQASM); + dumpResult(outputFilename, qc::Format::OpenQASM3); } else { throw QMAPException("[dump] Extension " + extension + " not recognized/supported for dumping."); diff --git a/include/cliffordsynthesis/CliffordSynthesizer.hpp b/include/cliffordsynthesis/CliffordSynthesizer.hpp index ecdd4ec30..05aca3d68 100644 --- a/include/cliffordsynthesis/CliffordSynthesizer.hpp +++ b/include/cliffordsynthesis/CliffordSynthesizer.hpp @@ -51,7 +51,7 @@ class CliffordSynthesizer { std::stringstream ss; ss << results.getResultCircuit(); resultCircuit = std::make_unique(); - resultCircuit->import(ss, qc::Format::OpenQASM); + resultCircuit->import(ss, qc::Format::OpenQASM3); } [[nodiscard]] qc::QuantumComputation& getResultCircuit() { diff --git a/include/cliffordsynthesis/Results.hpp b/include/cliffordsynthesis/Results.hpp index 53f88f979..fc90f732b 100644 --- a/include/cliffordsynthesis/Results.hpp +++ b/include/cliffordsynthesis/Results.hpp @@ -58,7 +58,7 @@ class Results { void setResultCircuit(qc::QuantumComputation& qc) { std::stringstream ss; - qc.dumpOpenQASM(ss); + qc.dumpOpenQASM3(ss); resultCircuit = ss.str(); } void setResultTableau(const Tableau& tableau) { diff --git a/src/DataLogger.cpp b/src/DataLogger.cpp index b354da480..f7ac9ee68 100644 --- a/src/DataLogger.cpp +++ b/src/DataLogger.cpp @@ -109,7 +109,7 @@ void DataLogger::logFinalizeLayer( } nlohmann::json json; std::stringstream qasmStream; - ops.dumpOpenQASM(qasmStream, qregs, cregs); + ops.dumpOpenQASM3(qasmStream, qregs, cregs); json["qasm"] = qasmStream.str(); if (twoQubitMultiplicity.empty()) { json["two_qubit_multiplicity"] = nlohmann::json::array(); diff --git a/src/cliffordsynthesis/Tableau.cpp b/src/cliffordsynthesis/Tableau.cpp index 132f4ccc7..009a5d58c 100644 --- a/src/cliffordsynthesis/Tableau.cpp +++ b/src/cliffordsynthesis/Tableau.cpp @@ -7,6 +7,8 @@ #include "utils.hpp" +#include + namespace cs { void Tableau::dump(const std::string& filename) const { auto of = std::ofstream(filename); diff --git a/src/python/bindings.cpp b/src/python/bindings.cpp index 38832e9b8..766c3d4a6 100644 --- a/src/python/bindings.cpp +++ b/src/python/bindings.cpp @@ -67,7 +67,7 @@ MappingResults map(const py::object& circ, Architecture& arch, auto& results = mapper->getResults(); std::stringstream qasm{}; - mapper->dumpResult(qasm, qc::Format::OpenQASM); + mapper->dumpResult(qasm, qc::Format::OpenQASM3); results.mappedCircuit = qasm.str(); return results; @@ -672,7 +672,7 @@ PYBIND11_MODULE(pyqmap, m) { [](const std::string& qasm) { std::stringstream ss(qasm); qc::QuantumComputation qc{}; - qc.import(ss, qc::Format::OpenQASM); + qc.import(ss, qc::Format::OpenQASM3); return qc; }, "qasm"_a, "Reads a quantum circuit from a qasm string."); diff --git a/test/cliffordsynthesis/test_synthesis.cpp b/test/cliffordsynthesis/test_synthesis.cpp index 6361b570c..ea5077fde 100644 --- a/test/cliffordsynthesis/test_synthesis.cpp +++ b/test/cliffordsynthesis/test_synthesis.cpp @@ -67,7 +67,7 @@ class SynthesisTest : public ::testing::TestWithParam { if (!test.initialCircuit.empty()) { std::stringstream ss(test.initialCircuit); qc::QuantumComputation qc{}; - qc.import(ss, qc::Format::OpenQASM); + qc.import(ss, qc::Format::OpenQASM3); std::cout << "Initial circuit:\n" << qc; targetTableau = Tableau(qc); targetTableauWithDestabilizer = diff --git a/test/test_exact.cpp b/test/test_exact.cpp index 563dc0e05..a0cf3ab56 100644 --- a/test/test_exact.cpp +++ b/test/test_exact.cpp @@ -391,7 +391,7 @@ TEST_F(ExactTest, CircuitWithOnlySingleQubitGates) { qc.x(1); ibmQX4Mapper = std::make_unique(qc, ibmQX4); ibmQX4Mapper->map(settings); - ibmQX4Mapper->dumpResult(std::cout, qc::Format::OpenQASM); + ibmQX4Mapper->dumpResult(std::cout, qc::Format::OpenQASM3); SUCCEED() << "Mapping successful"; } @@ -405,10 +405,10 @@ TEST_F(ExactTest, MapToSubsetNotIncludingQ0) { mapper.map(settings); std::ostringstream oss{}; - mapper.dumpResult(oss, qc::Format::OpenQASM); + mapper.dumpResult(oss, qc::Format::OpenQASM3); auto qcMapped = qc::QuantumComputation(); std::istringstream iss{oss.str()}; - qcMapped.import(iss, qc::Format::OpenQASM); + qcMapped.import(iss, qc::Format::OpenQASM3); std::cout << qcMapped << std::endl; EXPECT_EQ(qcMapped.initialLayout.size(), 4U); EXPECT_EQ(qcMapped.initialLayout[0], 3); @@ -502,8 +502,8 @@ TEST_F(ExactTest, NoMeasurmentsAdded) { // get the resulting circuit auto qcMapped = qc::QuantumComputation(); std::stringstream qasm{}; - ibmqLondonMapper->dumpResult(qasm, qc::Format::OpenQASM); - qcMapped.import(qasm, qc::Format::OpenQASM); + ibmqLondonMapper->dumpResult(qasm, qc::Format::OpenQASM3); + qcMapped.import(qasm, qc::Format::OpenQASM3); // check no measurements were added EXPECT_EQ(qcMapped.getNops(), 4U); @@ -522,7 +522,7 @@ TEST_F(ExactTest, Test4QCircuitThatUsesAll5Q) { "cx q[1],q[2];\n" "cx q[2],q[3];\n" "cx q[3],q[0];\n"}; - qc.import(ss, qc::Format::OpenQASM); + qc.import(ss, qc::Format::OpenQASM3); auto mapper = ExactMapper(qc, arch); // explicitly do not use subsets, but the full architecture @@ -582,7 +582,7 @@ TEST_F(ExactTest, RegressionTestExactMapperPerformance) { Architecture arch; const CouplingMap cm = {{1, 0}, {2, 0}, {2, 1}, {3, 2}, {3, 4}, {4, 2}}; arch.loadCouplingMap(5, cm); - qc.import(ss, qc::Format::OpenQASM); + qc.import(ss, qc::Format::OpenQASM3); auto mapper = ExactMapper(qc, arch); settings.swapReduction = SwapReduction::CouplingLimit; @@ -614,7 +614,7 @@ TEST_F(ExactTest, RegressionTestExactMapperPerformance2) { Architecture arch; const CouplingMap cm = {{1, 0}, {2, 0}, {2, 1}, {3, 2}, {3, 4}, {4, 2}}; arch.loadCouplingMap(5, cm); - qc.import(ss, qc::Format::OpenQASM); + qc.import(ss, qc::Format::OpenQASM3); auto mapper = ExactMapper(qc, arch); settings.swapReduction = SwapReduction::CouplingLimit; diff --git a/test/test_heuristic.cpp b/test/test_heuristic.cpp index 2f64c10d0..786d5a498 100644 --- a/test/test_heuristic.cpp +++ b/test/test_heuristic.cpp @@ -1118,8 +1118,8 @@ TEST(Functionality, NoMeasurmentsAdded) { // get the resulting circuit auto qcMapped = qc::QuantumComputation(); std::stringstream qasm{}; - mapper.dumpResult(qasm, qc::Format::OpenQASM); - qcMapped.import(qasm, qc::Format::OpenQASM); + mapper.dumpResult(qasm, qc::Format::OpenQASM3); + qcMapped.import(qasm, qc::Format::OpenQASM3); // check no measurements were added EXPECT_EQ(qcMapped.getNops(), 3U); @@ -1392,7 +1392,7 @@ TEST(Functionality, DataLogger) { std::stringstream inputFileBuffer; inputFileBuffer << inputQasmFile.rdbuf(); std::stringstream inputQasmBuffer; - qc.dumpOpenQASM(inputQasmBuffer); + qc.dumpOpenQASM3(inputQasmBuffer); EXPECT_EQ(inputFileBuffer.str(), inputQasmBuffer.str()); auto outputQasmFile = @@ -1404,7 +1404,7 @@ TEST(Functionality, DataLogger) { std::stringstream outputFileBuffer; outputFileBuffer << outputQasmFile.rdbuf(); std::stringstream outputQasmBuffer; - mapper->dumpResult(outputQasmBuffer, qc::Format::OpenQASM); + mapper->dumpResult(outputQasmBuffer, qc::Format::OpenQASM3); EXPECT_EQ(outputFileBuffer.str(), outputQasmBuffer.str()); // checking logged search graph info against known values (correct qubit @@ -1652,12 +1652,12 @@ TEST(Functionality, InitialLayoutDump) { mapper.map(config); std::stringstream qasmStream{}; - mapper.dumpResult(qasmStream, qc::Format::OpenQASM); + mapper.dumpResult(qasmStream, qc::Format::OpenQASM3); const std::string qasm = qasmStream.str(); qasmStream = std::stringstream(qasm); auto qcMapped = qc::QuantumComputation(); - qcMapped.import(qasmStream, qc::Format::OpenQASM); + qcMapped.import(qasmStream, qc::Format::OpenQASM3); qasmStream = std::stringstream(qasm); std::string line; @@ -1726,8 +1726,8 @@ TEST_F(LayeringTest, Disjoint2qBlocks) { // get mapped circuit auto qcMapped = qc::QuantumComputation(); std::stringstream qasm{}; - mapper->dumpResult(qasm, qc::Format::OpenQASM); - qcMapped.import(qasm, qc::Format::OpenQASM); + mapper->dumpResult(qasm, qc::Format::OpenQASM3); + qcMapped.import(qasm, qc::Format::OpenQASM3); // check barrier count std::size_t barriers = 0; for (const auto& op : qcMapped) { @@ -1746,8 +1746,8 @@ TEST_F(LayeringTest, DisjointQubits) { // get mapped circuit auto qcMapped = qc::QuantumComputation(); std::stringstream qasm{}; - mapper->dumpResult(qasm, qc::Format::OpenQASM); - qcMapped.import(qasm, qc::Format::OpenQASM); + mapper->dumpResult(qasm, qc::Format::OpenQASM3); + qcMapped.import(qasm, qc::Format::OpenQASM3); // check barrier count std::size_t barriers = 0; for (const auto& op : qcMapped) { @@ -1766,8 +1766,8 @@ TEST_F(LayeringTest, IndividualGates) { // get mapped circuit auto qcMapped = qc::QuantumComputation(); std::stringstream qasm{}; - mapper->dumpResult(qasm, qc::Format::OpenQASM); - qcMapped.import(qasm, qc::Format::OpenQASM); + mapper->dumpResult(qasm, qc::Format::OpenQASM3); + qcMapped.import(qasm, qc::Format::OpenQASM3); // check barrier count std::size_t barriers = 0; for (const auto& op : qcMapped) { From bd193b4c4fb883e12dde6f1295fad99bef17f1f8 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 18:43:54 +0100 Subject: [PATCH 09/19] =?UTF-8?q?=F0=9F=9A=A8=20remove=20unused=20type=20i?= =?UTF-8?q?gnores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mqt/qmap/subarchitectures.py | 12 ++++++------ test/python/test_subarchitectures.py | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/mqt/qmap/subarchitectures.py b/src/mqt/qmap/subarchitectures.py index 52dd7d07b..7d2855331 100644 --- a/src/mqt/qmap/subarchitectures.py +++ b/src/mqt/qmap/subarchitectures.py @@ -242,7 +242,7 @@ def draw_subarchitecture(self, subarchitecture: Graph | tuple[int, int]) -> figu colors = [SubarchitectureOrder.inactive_color for _ in range(self.arch.num_nodes())] for node in subarchitecture.nodes(): colors[node] = SubarchitectureOrder.active_color - return rxviz.mpl_draw(self.arch, node_color=colors) # type: ignore[no-untyped-call] + return rxviz.mpl_draw(self.arch, node_color=colors) # type: ignore[call-arg] def draw_subarchitectures(self, subarchitectures: list[Graph] | list[tuple[int, int]]) -> list[figure.Figure]: """Create matplotlib figures showing subarchitectures within the entire architecture. @@ -266,10 +266,10 @@ def __compute_subarchs(self) -> None: for i in range(1, self.arch.num_nodes() + 1): node_combinations = combinations(range(self.arch.num_nodes()), i) for sg in (self.arch.subgraph(selected_nodes) for selected_nodes in node_combinations): - if rx.is_connected(sg): # type: ignore[attr-defined] + if rx.is_connected(sg): new_class = True for g in self.sgs[i]: - if rx.is_isomorphic(g, sg): # type: ignore[attr-defined] + if rx.is_isomorphic(g, sg): new_class = False break if new_class: @@ -286,7 +286,7 @@ def __compute_subarch_order(self) -> None: for n, sgs_n in enumerate(self.sgs[:-1]): for i, sg in enumerate(sgs_n): for j, parent_sg in enumerate(self.sgs[n + 1]): - matcher = rx.graph_vf2_mapping(parent_sg, sg, subgraph=True) # type: ignore[attr-defined] + matcher = rx.graph_vf2_mapping(parent_sg, sg, subgraph=True) for iso in matcher: self.subarch_order[(n, i)].add((n + 1, j)) iso_rev = {val: key for key, val in iso.items()} @@ -360,8 +360,8 @@ def __path_order_less(self, n: int, i: int, n_prime: int, i_prime: int) -> bool: if v is w: continue if ( - rx.dijkstra_shortest_path_lengths(lhs, v, lambda _x: 1, goal=w)[w] # type: ignore[attr-defined] - > rx.dijkstra_shortest_path_lengths(rhs, iso[v], lambda _x: 1, goal=iso[w])[iso[w]] # type: ignore[attr-defined] + rx.dijkstra_shortest_path_lengths(lhs, v, lambda _x: 1, goal=w)[w] + > rx.dijkstra_shortest_path_lengths(rhs, iso[v], lambda _x: 1, goal=iso[w])[iso[w]] ): return True return False diff --git a/test/python/test_subarchitectures.py b/test/python/test_subarchitectures.py index 309856c70..6b28279ed 100644 --- a/test/python/test_subarchitectures.py +++ b/test/python/test_subarchitectures.py @@ -115,7 +115,7 @@ def test_singleton_graph(singleton_graph: Graph) -> None: assert len(order.sgs) == 2 assert len(order.sgs[0]) == 0 assert len(order.sgs[1]) == 1 - assert rx.is_isomorphic(order.optimal_candidates(1)[0], singleton_graph) # type: ignore[attr-defined] + assert rx.is_isomorphic(order.optimal_candidates(1)[0], singleton_graph) def test_two_node_graph(singleton_graph: Graph) -> None: @@ -125,8 +125,8 @@ def test_two_node_graph(singleton_graph: Graph) -> None: assert len(order.sgs[0]) == 0 assert len(order.sgs[1]) == 1 assert len(order.sgs[2]) == 1 - assert rx.is_isomorphic(order.optimal_candidates(2)[0], order.sgs[2][0]) # type: ignore[attr-defined] - assert rx.is_isomorphic(order.optimal_candidates(1)[0], singleton_graph) # type: ignore[attr-defined] + assert rx.is_isomorphic(order.optimal_candidates(2)[0], order.sgs[2][0]) + assert rx.is_isomorphic(order.optimal_candidates(1)[0], singleton_graph) def test_ibm_guadalupe_opt(ibm_guadalupe: SubarchitectureOrder) -> None: @@ -135,7 +135,7 @@ def test_ibm_guadalupe_opt(ibm_guadalupe: SubarchitectureOrder) -> None: assert len(opt_cand_9) == 2 assert opt_cand_9[0].num_nodes() == 15 assert opt_cand_9[1].num_nodes() == 15 - assert not rx.is_isomorphic(opt_cand_9[0], opt_cand_9[1]) # type: ignore[attr-defined] + assert not rx.is_isomorphic(opt_cand_9[0], opt_cand_9[1]) def test_ibm_guadalupe_cov(ibm_guadalupe: SubarchitectureOrder) -> None: @@ -146,7 +146,7 @@ def test_ibm_guadalupe_cov(ibm_guadalupe: SubarchitectureOrder) -> None: for sg in ibm_guadalupe.sgs[9]: covered = False for co in cov: - if rx.is_subgraph_isomorphic(co, sg): # type: ignore[attr-defined] + if rx.is_subgraph_isomorphic(co, sg): covered = True break assert covered @@ -158,7 +158,7 @@ def test_rigetti16_opt(rigetti16: SubarchitectureOrder, rigetti16_opt: Graph) -> assert len(opt) == 1 opt_cand = opt[0] - assert rx.is_isomorphic(opt_cand, rigetti16_opt) # type: ignore[attr-defined] + assert rx.is_isomorphic(opt_cand, rigetti16_opt) def test_rigetti16_opt_library(rigetti16_opt: Graph) -> None: @@ -167,7 +167,7 @@ def test_rigetti16_opt_library(rigetti16_opt: Graph) -> None: assert len(opt) == 1 opt_cand = opt[0] - assert rx.is_isomorphic(opt_cand, rigetti16_opt) # type: ignore[attr-defined] + assert rx.is_isomorphic(opt_cand, rigetti16_opt) def test_rigetti16_opt_library_from_str(rigetti16_opt: Graph) -> None: @@ -176,7 +176,7 @@ def test_rigetti16_opt_library_from_str(rigetti16_opt: Graph) -> None: assert len(opt) == 1 opt_cand = opt[0] - assert rx.is_isomorphic(opt_cand, rigetti16_opt) # type: ignore[attr-defined] + assert rx.is_isomorphic(opt_cand, rigetti16_opt) def test_ibm_guadalupe_library() -> None: @@ -185,7 +185,7 @@ def test_ibm_guadalupe_library() -> None: assert len(opt_cand_9) == 2 assert opt_cand_9[0].num_nodes() == 15 assert opt_cand_9[1].num_nodes() == 15 - assert not rx.is_isomorphic(opt_cand_9[0], opt_cand_9[1]) # type: ignore[attr-defined] + assert not rx.is_isomorphic(opt_cand_9[0], opt_cand_9[1]) def test_store_subarch(ibm_guadalupe: SubarchitectureOrder) -> None: @@ -204,7 +204,7 @@ def test_store_subarch(ibm_guadalupe: SubarchitectureOrder) -> None: assert len(opt_origin) == len(opt_loaded) for opt_cand_orig, opt_cand_load in zip(opt_origin, opt_loaded): - assert rx.is_isomorphic(opt_cand_load, opt_cand_orig) # type: ignore[attr-defined] + assert rx.is_isomorphic(opt_cand_load, opt_cand_orig) def test_subarchitecture_from_qmap_arch() -> None: From 35e78a00b34e29741cd12b247c7f26628038fdfe Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 18:44:13 +0100 Subject: [PATCH 10/19] =?UTF-8?q?=F0=9F=A9=B9=20small=20fixes=20in=20the?= =?UTF-8?q?=20pyqmap=20stub=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mqt/qmap/pyqmap.pyi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mqt/qmap/pyqmap.pyi b/src/mqt/qmap/pyqmap.pyi index 15b2822d3..5805bf7bd 100644 --- a/src/mqt/qmap/pyqmap.pyi +++ b/src/mqt/qmap/pyqmap.pyi @@ -318,9 +318,9 @@ class LayerHeuristicBenchmarkInfo: class MappingResults: configuration: Configuration - input: Any # noqa: A003 + input: CircuitInfo # noqa: A003 mapped_circuit: str - output: Any + output: CircuitInfo time: float timeout: bool wcnf: str @@ -479,7 +479,7 @@ class QuantumComputation: class Tableau: @overload - def __init__(self, n: int, include_stabilizers: bool) -> None: ... + def __init__(self, n: int, include_stabilizers: bool = False) -> None: ... @overload def __init__(self, description: str) -> None: ... @overload From 65dee105d8a41caf87988fd4407a49144f92f2a1 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 18:44:40 +0100 Subject: [PATCH 11/19] =?UTF-8?q?=F0=9F=94=A7=20do=20not=20enable=20IPO=20?= =?UTF-8?q?by=20default=20in=20package=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 82e6255cd..9c61ed940 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -117,7 +117,6 @@ sdist.exclude = [ [tool.scikit-build.cmake.define] BUILD_MQT_QMAP_TESTS = "OFF" BUILD_MQT_QMAP_BINDINGS = "ON" -ENABLE_IPO = "ON" [tool.check-sdist] From 838f3b9a41eaa2df9324ddcd71b88d5e397e211b Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 18:44:54 +0100 Subject: [PATCH 12/19] =?UTF-8?q?=F0=9F=94=A7=20slight=20configuration=20t?= =?UTF-8?q?weaks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9c61ed940..b23fcf530 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -153,18 +153,20 @@ run.omit = ["*/visualization/*"] report.exclude_also = [ '\.\.\.', 'if TYPE_CHECKING:', + 'raise AssertionError', + 'raise NotImplementedError', ] [tool.mypy] files = ["src/mqt", "test/python"] mypy_path = ["$MYPY_CONFIG_FILE_DIR/src"] python_version = "3.8" -strict = true -show_error_codes = true +warn_unused_configs = true enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] -warn_unreachable = true +strict = true +disallow_untyped_defs = false explicit_package_bases = true -pretty = true +warn_unreachable = true [[tool.mypy.overrides]] module = ["qiskit.*", "matplotlib.*", "networkx.*", "plotly.*", "_plotly_utils.*", "distinctipy.*", "ipywidgets.*", "walkerlayout.*"] From f5f80c0545c3fc05506bb77e27926fb9972b209e Mon Sep 17 00:00:00 2001 From: burgholzer Date: Sat, 27 Jan 2024 11:47:27 +0100 Subject: [PATCH 13/19] =?UTF-8?q?=E2=9C=85=20also=20test=20on=20Python=203?= =?UTF-8?q?.12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b23fcf530..157164a3a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -254,7 +254,6 @@ build = "cp3*" skip = "*-musllinux*" archs = "auto64" test-command = "python -c \"from mqt import qmap\"" -test-skip = "cp312-*" # Qiskit Terra does not support Python 3.12 yet build-frontend = "build" [tool.cibuildwheel.linux] From 09c744ef8aefa7be95493dbfdfb3f6b6463ed4e5 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Sat, 27 Jan 2024 16:09:38 +0100 Subject: [PATCH 14/19] =?UTF-8?q?=F0=9F=9A=A8=20ignore=20unrelated=20depre?= =?UTF-8?q?cation=20warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 157164a3a..257102897 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -145,6 +145,7 @@ filterwarnings = [ "ignore:.*qiskit.__qiskit_version__.*:DeprecationWarning:qiskit:", "ignore:.*qiskit.utils.algorithm_globals.QiskitAlgorithmGlobals*:DeprecationWarning:qiskit", "ignore:.*qiskit.extensions module is pending deprecation*:PendingDeprecationWarning:qiskit", + 'ignore:.*datetime\.datetime\.utcfromtimestamp.*:DeprecationWarning:', ] [tool.coverage] From ff355417fe79c0abc6d5697f92bc2ed8d9348b1a Mon Sep 17 00:00:00 2001 From: burgholzer Date: Fri, 26 Jan 2024 19:09:27 +0100 Subject: [PATCH 15/19] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20rely=20on=20a=20more?= =?UTF-8?q?=20modern=20version=20of=20Qiskit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- pyproject.toml | 4 ++-- test/python/constraints.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 257102897..077d196a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ classifiers = [ ] requires-python = ">=3.8" dependencies = [ - "qiskit-terra>=0.20.2", + "qiskit[qasm3-import]>=0.45.0", "rustworkx[all]>=0.13.0", "importlib_resources>=5.0; python_version < '3.10'", "typing_extensions>=4.0" @@ -59,7 +59,7 @@ docs = [ "nbsphinx", "sphinxext-opengraph", "sphinx-autodoc-typehints", - "qiskit-terra[visualization]", + "qiskit[visualization]", "mqt.qmap[visualization]" ] visualization = [ diff --git a/test/python/constraints.txt b/test/python/constraints.txt index 4a020c3f4..a6b63750d 100644 --- a/test/python/constraints.txt +++ b/test/python/constraints.txt @@ -4,7 +4,7 @@ pybind11==2.11.0 pytest==7.0.0 importlib_resources==5.0.0 typing_extensions==4.0.0 -qiskit-terra==0.20.2 +qiskit==0.45.0 rustworkx==0.13.0 mqt.qcec==2.0.0 distinctipy==1.2.2 From 1219382901aa927f6e5cf241e2abda2815d77b81 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Mon, 29 Jan 2024 17:03:32 +0100 Subject: [PATCH 16/19] =?UTF-8?q?=F0=9F=91=BD=20adjust=20to=20newer=20qisk?= =?UTF-8?q?it=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- src/mqt/qmap/clifford_synthesis.py | 22 ++++++++-------------- src/mqt/qmap/compile.py | 19 ++++++------------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/mqt/qmap/clifford_synthesis.py b/src/mqt/qmap/clifford_synthesis.py index ac8b33689..444d32afb 100644 --- a/src/mqt/qmap/clifford_synthesis.py +++ b/src/mqt/qmap/clifford_synthesis.py @@ -4,8 +4,9 @@ from typing import Any -from qiskit import QuantumCircuit +from qiskit import QuantumCircuit, qasm3 from qiskit.quantum_info import Clifford, PauliList +from qiskit.transpiler.layout import TranspileLayout from .compile import extract_initial_layout_from_qasm from .pyqmap import ( @@ -81,19 +82,12 @@ def _config_from_kwargs(kwargs: dict[str, Any]) -> SynthesisConfiguration: def _circuit_from_qasm(qasm: str) -> QuantumCircuit: """Create a proper :class:`qiskit.QuantumCircuit` from a QASM string (including layout information).""" - circ = QuantumCircuit.from_qasm_str(qasm) + circ = qasm3.loads(qasm) layout = extract_initial_layout_from_qasm(qasm, circ.qregs) - # qiskit-terra 0.22.0 introduced a breaking change in the `_layout` of the `QuantumCircuit` class. - # To maintain backwards compatibility, the following `try... except` block is necessary. - try: - from qiskit.transpiler.layout import TranspileLayout - - circ._layout = TranspileLayout( # noqa: SLF001 - initial_layout=layout, input_qubit_mapping=layout.get_virtual_bits() - ) - except ImportError: - circ._layout = layout # noqa: SLF001 + circ._layout = TranspileLayout( # noqa: SLF001 + initial_layout=layout, input_qubit_mapping=layout.get_virtual_bits() + ) return circ @@ -102,7 +96,7 @@ def synthesize_clifford( target_tableau: str | Clifford | PauliList | Tableau, initial_tableau: str | Clifford | PauliList | Tableau | None = None, include_destabilizers: bool = False, - **kwargs: Any | None, # noqa: ANN401 + **kwargs: Any, # noqa: ANN401 ) -> tuple[QuantumCircuit, SynthesisResults]: """Synthesize a Clifford circuit from a given tableau starting from an (optional) initial tableau. @@ -147,7 +141,7 @@ def optimize_clifford( circuit: str | QuantumCircuit | QuantumComputation, initial_tableau: str | Clifford | PauliList | Tableau | None = None, include_destabilizers: bool = False, - **kwargs: Any | None, # noqa: ANN401 + **kwargs: Any, # noqa: ANN401 ) -> tuple[QuantumCircuit, SynthesisResults]: """Optimize a Clifford circuit starting from an (optional) initial tableau. diff --git a/src/mqt/qmap/compile.py b/src/mqt/qmap/compile.py index 128c3c35d..4f9d99dc8 100644 --- a/src/mqt/qmap/compile.py +++ b/src/mqt/qmap/compile.py @@ -4,8 +4,8 @@ from typing import TYPE_CHECKING -from qiskit import QuantumCircuit, QuantumRegister -from qiskit.transpiler import Layout +from qiskit import QuantumCircuit, QuantumRegister, qasm3 +from qiskit.transpiler import Layout, TranspileLayout if TYPE_CHECKING: from qiskit.providers import Backend @@ -187,18 +187,11 @@ def compile( # noqa: A001 results = map(circ, architecture, config) - circ = QuantumCircuit.from_qasm_str(results.mapped_circuit) + circ = qasm3.loads(results.mapped_circuit) layout = extract_initial_layout_from_qasm(results.mapped_circuit, circ.qregs) - # qiskit-terra 0.22.0 introduced a breaking change in the `_layout` of the `QuantumCircuit` class. - # To maintain backwards compatibility, the following `try... except` block is necessary. - try: - from qiskit.transpiler.layout import TranspileLayout - - circ._layout = TranspileLayout( # noqa: SLF001 - initial_layout=layout, input_qubit_mapping=layout.get_virtual_bits() - ) - except ImportError: - circ._layout = layout # noqa: SLF001 + circ._layout = TranspileLayout( # noqa: SLF001 + initial_layout=layout, input_qubit_mapping=layout.get_virtual_bits() + ) return circ, results From d46408a83e4b5a5f30709519bc5b85664e1e3f74 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Mon, 29 Jan 2024 17:31:14 +0100 Subject: [PATCH 17/19] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20update=20mqt-core?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- extern/mqt-core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/mqt-core b/extern/mqt-core index 6d9a08ed8..3d5e14b20 160000 --- a/extern/mqt-core +++ b/extern/mqt-core @@ -1 +1 @@ -Subproject commit 6d9a08ed81019bd120065ca511721a500bc52aca +Subproject commit 3d5e14b20809108b90de6df03fa25def3d2851c9 From 192ae4efc2376dcba4a54cb6f5ca7b40ac6ef3e5 Mon Sep 17 00:00:00 2001 From: burgholzer Date: Mon, 29 Jan 2024 17:31:44 +0100 Subject: [PATCH 18/19] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor=20parts=20o?= =?UTF-8?q?f=20the=20CMake=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- CMakeLists.txt | 37 ++++------- cmake/ExternalDependencies.cmake | 108 +++++++++++++++++++++++++++++++ src/CMakeLists.txt | 84 ++++++++++++------------ src/python/CMakeLists.txt | 26 +++----- test/CMakeLists.txt | 26 ++------ 5 files changed, 177 insertions(+), 104 deletions(-) create mode 100644 cmake/ExternalDependencies.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 833135c57..6bf5c8b8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,38 +2,29 @@ cmake_minimum_required(VERSION 3.19...3.28) project( - qmap + mqt-qmap LANGUAGES CXX DESCRIPTION "MQT QMAP - A library for mapping of quantum circuits to quantum architectures") -# check whether the submodule ``modulename`` is correctly cloned in the ``/extern`` directory. -macro(CHECK_SUBMODULE_PRESENT modulename) - if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/${modulename}/CMakeLists.txt") - message( - FATAL_ERROR - "${modulename} submodule not cloned properly. \ - Please run `git submodule update --init --recursive` \ - from the main project directory") - endif() -endmacro() - -check_submodule_present(mqt-core) -check_submodule_present(LogicBlocks) - +option(BUILD_MQT_QMAP_TESTS "Also build tests for the MQT QMAP project" ON) option(BUILD_MQT_QMAP_BINDINGS "Build the MQT QMAP Python bindings" OFF) + if(BUILD_MQT_QMAP_BINDINGS) # ensure that the BINDINGS option is set set(BINDINGS ON - CACHE BOOL "Enable settings related to Python bindings" FORCE) - # cmake-lint: disable=C0103 + CACHE INTERNAL "Enable settings related to Python bindings") + # Some common settings for finding Python set(Python_FIND_VIRTUALENV FIRST CACHE STRING "Give precedence to virtualenvs when searching for Python") - # cmake-lint: disable=C0103 + set(Python_FIND_FRAMEWORK + LAST + CACHE STRING "Prefer Brew/Conda to Apple framework Python") set(Python_ARTIFACTS_INTERACTIVE ON CACHE BOOL "Prevent multiple searches for Python and instead cache the results.") + # top-level call to find Python find_package( Python 3.8 REQUIRED @@ -44,17 +35,15 @@ endif() # Add path for custom modules list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -# search for Z3 -find_package(Z3 4.8.15) -if(NOT Z3_FOUND) - message(WARNING "Did not find Z3. Exact library and other depending target will not be available") -endif() +include(cmake/ExternalDependencies.cmake) + +# set the include directory for the build tree +set(MQT_QMAP_INCLUDE_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") # add main library code add_subdirectory(src) # add test code -option(BUILD_MQT_QMAP_TESTS "Also build tests for the MQT QMAP project" ON) if(BUILD_MQT_QMAP_TESTS) enable_testing() include(GoogleTest) diff --git a/cmake/ExternalDependencies.cmake b/cmake/ExternalDependencies.cmake new file mode 100644 index 000000000..b8b9b5bab --- /dev/null +++ b/cmake/ExternalDependencies.cmake @@ -0,0 +1,108 @@ +# Declare all external dependencies and make sure that they are available. + +include(FetchContent) +set(FETCH_PACKAGES "") + +# search for Z3 +find_package(Z3 4.8.15) +if(NOT Z3_FOUND) + message(WARNING "Did not find Z3. Exact library and other depending target will not be available") +endif() + +if(BUILD_MQT_QMAP_BINDINGS) + if(NOT SKBUILD) + # Manually detect the installed pybind11 package. + execute_process( + COMMAND "${Python_EXECUTABLE}" -m pybind11 --cmakedir + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE pybind11_DIR) + + # Add the detected directory to the CMake prefix path. + list(APPEND CMAKE_PREFIX_PATH "${pybind11_DIR}") + endif() + + # add pybind11 library + find_package(pybind11 CONFIG REQUIRED) +endif() + +set(FETCHCONTENT_SOURCE_DIR_MQT-CORE + ${PROJECT_SOURCE_DIR}/extern/mqt-core + CACHE + PATH + "Path to the source directory of the mqt-core library. This variable is used by FetchContent to download the library if it is not already available." +) +set(MQT_CORE_VERSION + 2.2.2 + CACHE STRING "MQT Core version") +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) + FetchContent_Declare( + mqt-core + GIT_REPOSITORY https://github.com/cda-tum/mqt-core.git + GIT_TAG v${MQT_CORE_VERSION} + FIND_PACKAGE_ARGS ${MQT_CORE_VERSION}) + list(APPEND FETCH_PACKAGES mqt-core) +else() + find_package(mqt-core ${MQT_CORE_VERSION} QUIET) + if(NOT mqt-core_FOUND) + FetchContent_Declare( + mqt-core + GIT_REPOSITORY https://github.com/cda-tum/mqt-core.git + GIT_TAG v${MQT_CORE_VERSION}) + list(APPEND FETCH_PACKAGES mqt-core) + endif() +endif() + +set(BUILD_LB_TESTS + OFF + CACHE BOOL "Build LogicBlocks tests") +set(FETCHCONTENT_SOURCE_DIR_LOGICBLOCKS + ${PROJECT_SOURCE_DIR}/extern/LogicBlocks + CACHE + PATH + "Path to the source directory of the LogicBlocks library. This variable is used by FetchContent to download the library if it is not already available." +) +FetchContent_Declare( + LogicBlocks + GIT_REPOSITORY https://github.com/cda-tum/LogicBlocks.git + GIT_TAG main) +list(APPEND FETCH_PACKAGES LogicBlocks) + +if(BUILD_MQT_QMAP_TESTS) + set(gtest_force_shared_crt + ON + CACHE BOOL "" FORCE) + set(GTEST_VERSION + 1.14.0 + CACHE STRING "Google Test version") + set(GTEST_URL https://github.com/google/googletest/archive/refs/tags/v${GTEST_VERSION}.tar.gz) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) + FetchContent_Declare(googletest URL ${GTEST_URL} FIND_PACKAGE_ARGS ${GTEST_VERSION} NAMES GTest) + list(APPEND FETCH_PACKAGES googletest) + else() + find_package(googletest ${GTEST_VERSION} QUIET NAMES GTest) + if(NOT googletest_FOUND) + FetchContent_Declare(googletest URL ${GTEST_URL}) + list(APPEND FETCH_PACKAGES googletest) + endif() + endif() +endif() + +if(BUILD_MQT_QMAP_BINDINGS) + # add pybind11_json library + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) + FetchContent_Declare( + pybind11_json + GIT_REPOSITORY https://github.com/pybind/pybind11_json + FIND_PACKAGE_ARGS) + list(APPEND FETCH_PACKAGES pybind11_json) + else() + find_package(pybind11_json QUIET) + if(NOT pybind11_json_FOUND) + FetchContent_Declare(pybind11_json GIT_REPOSITORY https://github.com/pybind/pybind11_json) + list(APPEND FETCH_PACKAGES pybind11_json) + endif() + endif() +endif() + +# Make all declared dependencies available. +FetchContent_MakeAvailable(${FETCH_PACKAGES}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e3a28af81..37a45bee1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,75 +1,62 @@ -# add LogicBlocks target -set(BUILD_LB_TESTS - OFF - CACHE BOOL "Build LogicBlocks tests") -add_subdirectory("${PROJECT_SOURCE_DIR}/extern/LogicBlocks" "extern/LogicBlocks" EXCLUDE_FROM_ALL) -# add MQT::Core target -set(BUILD_MQT_CORE_TESTS - OFF - CACHE BOOL "Build MQT Core tests") -add_subdirectory("${PROJECT_SOURCE_DIR}/extern/mqt-core" "extern/mqt-core" EXCLUDE_FROM_ALL) +set(MQT_QMAP_TARGET_NAME mqt-qmap) # macro to add core libraries macro(ADD_INTERNAL_LIBRARY libname) set(lib ${libname}) # set include directories - target_include_directories(${lib} PUBLIC ${PROJECT_SOURCE_DIR}/include - ${PROJECT_BINARY_DIR}/include) + target_include_directories(${lib} PUBLIC $) # add MQT::qfr library - target_link_libraries(${lib} PUBLIC MQT::Core) - - # add MQT alias - add_library(MQT::${lib} ALIAS ${lib}) - + target_link_libraries(${lib} PUBLIC MQT::Core nlohmann_json::nlohmann_json) + target_link_libraries(${lib} PRIVATE MQT::ProjectOptions MQT::ProjectWarnings) endmacro() # macro to add mapping libraries macro(ADD_QMAP_LIBRARY libname srcfile) - set(lib ${PROJECT_NAME}_${libname}_lib) + set(lib ${MQT_QMAP_TARGET_NAME}-${libname}) # main project library add_library( ${lib} ${libname}/${srcfile}.cpp - ${PROJECT_SOURCE_DIR}/include/${libname}/${srcfile}.hpp - ${PROJECT_SOURCE_DIR}/include/Architecture.hpp - ${PROJECT_SOURCE_DIR}/include/configuration - ${PROJECT_SOURCE_DIR}/include/DataLogger.hpp - ${PROJECT_SOURCE_DIR}/include/heuristic/UniquePriorityQueue.hpp - ${PROJECT_SOURCE_DIR}/include/Mapper.hpp - ${PROJECT_SOURCE_DIR}/include/MappingResults.hpp - ${PROJECT_SOURCE_DIR}/include/utils.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/${libname}/${srcfile}.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/Architecture.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/configuration + ${MQT_QMAP_INCLUDE_BUILD_DIR}/DataLogger.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/heuristic/UniquePriorityQueue.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/Mapper.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/MappingResults.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/utils.hpp Architecture.cpp configuration/Configuration.cpp DataLogger.cpp Mapper.cpp utils.cpp) - add_internal_library(${lib} ${srcfile}) + add_internal_library(${lib}) endmacro() # macro to add synthesis libraries macro(ADD_SYNTHESIS_LIBRARY libname srcfile) - set(lib ${PROJECT_NAME}_${libname}_lib) + set(lib ${MQT_QMAP_TARGET_NAME}-${libname}) # main project library add_library( ${lib} ${libname}/${srcfile}.cpp - ${PROJECT_SOURCE_DIR}/include/${libname}/${srcfile}.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/Configuration.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/encoding/GateEncoder.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/encoding/MultiGateEncoder.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/encoding/ObjectiveEncoder.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/encoding/SATEncoder.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/encoding/SingleGateEncoder.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/encoding/TableauEncoder.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/Results.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/Tableau.hpp - ${PROJECT_SOURCE_DIR}/include/cliffordsynthesis/TargetMetric.hpp - ${PROJECT_SOURCE_DIR}/include/utils.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/${libname}/${srcfile}.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/Configuration.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/encoding/GateEncoder.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/encoding/MultiGateEncoder.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/encoding/ObjectiveEncoder.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/encoding/SATEncoder.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/encoding/SingleGateEncoder.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/encoding/TableauEncoder.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/Results.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/Tableau.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/cliffordsynthesis/TargetMetric.hpp + ${MQT_QMAP_INCLUDE_BUILD_DIR}/utils.hpp cliffordsynthesis/encoding/GateEncoder.cpp cliffordsynthesis/encoding/MultiGateEncoder.cpp cliffordsynthesis/encoding/ObjectiveEncoder.cpp @@ -79,24 +66,33 @@ macro(ADD_SYNTHESIS_LIBRARY libname srcfile) cliffordsynthesis/Tableau.cpp utils.cpp) - add_internal_library(${lib} ${srcfile}) + add_internal_library(${lib}) endmacro() # exact mapper project library add_qmap_library(exact ExactMapper) +# enable PIC for LogicBlocks +set_target_properties(LogicTerm_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) + # add LogicBlocks library -target_link_libraries(${PROJECT_NAME}_exact_lib PUBLIC logicblocks::Logic logicblocks::Encodings) +target_link_libraries(${MQT_QMAP_TARGET_NAME}-exact PUBLIC logicblocks::Logic + logicblocks::Encodings) add_synthesis_library(cliffordsynthesis CliffordSynthesizer) # add LogicBlocks library -target_link_libraries(${PROJECT_NAME}_cliffordsynthesis_lib - PUBLIC logicblocks::Logic logicblocks::Encodings nlohmann_json::nlohmann_json) +target_link_libraries(${MQT_QMAP_TARGET_NAME}-cliffordsynthesis PUBLIC logicblocks::Logic + logicblocks::Encodings) # heuristic mapper project library add_qmap_library(heuristic HeuristicMapper) +# add MQT alias targets +add_library(MQT::QMapExact ALIAS ${MQT_QMAP_TARGET_NAME}-exact) +add_library(MQT::QMapCliffordSynthesis ALIAS ${MQT_QMAP_TARGET_NAME}-cliffordsynthesis) +add_library(MQT::QMapHeuristic ALIAS ${MQT_QMAP_TARGET_NAME}-heuristic) + if(BUILD_MQT_QMAP_BINDINGS) add_subdirectory(python) endif() diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 06f81c6bf..e35ba3a65 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -1,16 +1,3 @@ -if(NOT SKBUILD) - # Manually detect the installed pybind11 package and import it into CMake. - execute_process( - COMMAND "${Python_EXECUTABLE}" -m pybind11 --cmakedir - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE pybind11_DIR) - list(APPEND CMAKE_PREFIX_PATH "${pybind11_DIR}") -endif() - -# Import pybind11 through CMake's find_package mechanism -find_package(pybind11 CONFIG REQUIRED) - -# We are now ready to compile the actual extension module pybind11_add_module( pyqmap # Prefer thin LTO if available @@ -20,10 +7,15 @@ pybind11_add_module( # Source code goes here bindings.cpp) target_compile_definitions(pyqmap PRIVATE Z3_FOUND) -target_link_libraries(pyqmap PRIVATE MQT::CorePython) -target_link_libraries(pyqmap PRIVATE qmap_exact_lib) -target_link_libraries(pyqmap PRIVATE qmap_heuristic_lib) -target_link_libraries(pyqmap PRIVATE qmap_cliffordsynthesis_lib) +target_link_libraries( + pyqmap + PRIVATE MQT::QMapExact + MQT::QMapHeuristic + MQT::QMapCliffordSynthesis + MQT::CorePython + MQT::ProjectOptions + MQT::ProjectWarnings + pybind11_json) # Install directive for scikit-build-core install( diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 6e39ecedc..1fc35eda1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,31 +1,19 @@ -if(NOT TARGET gtest OR NOT TARGET gmock) - # Prevent overriding the parent project's compiler/linker settings on Windows - set(gtest_force_shared_crt # cmake-lint: disable=C0103 - ON - CACHE BOOL "" FORCE) - add_subdirectory("${PROJECT_SOURCE_DIR}/extern/mqt-core/extern/googletest" - "extern/mqt-core/extern/googletest" EXCLUDE_FROM_ALL) - set_target_properties(gtest gtest_main gmock gmock_main PROPERTIES FOLDER extern) -endif() - package_add_test( - ${PROJECT_NAME}_heuristic_test ${PROJECT_NAME}_heuristic_lib - ${CMAKE_CURRENT_SOURCE_DIR}/test_heuristic.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_general.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/test_architecture.cpp) + mqt-qmap-heuristic-test MQT::QMapHeuristic ${CMAKE_CURRENT_SOURCE_DIR}/test_heuristic.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_general.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_architecture.cpp) -if(TARGET ${PROJECT_NAME}_exact_lib) - package_add_test( - ${PROJECT_NAME}_exact_test ${PROJECT_NAME}_exact_lib ${CMAKE_CURRENT_SOURCE_DIR}/test_exact.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/test_encodings.cpp) +if(TARGET MQT::QMapExact) + package_add_test(mqt-qmap-exact-test MQT::QMapExact ${CMAKE_CURRENT_SOURCE_DIR}/test_exact.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_encodings.cpp) endif() -if(TARGET ${PROJECT_NAME}_cliffordsynthesis_lib) +if(TARGET MQT::QMapCliffordSynthesis) configure_file(${CMAKE_SOURCE_DIR}/test/cliffordsynthesis/tableaus.json ${CMAKE_CURRENT_BINARY_DIR}/cliffordsynthesis/tableaus.json COPYONLY) configure_file(${CMAKE_SOURCE_DIR}/test/cliffordsynthesis/circuits.json ${CMAKE_CURRENT_BINARY_DIR}/cliffordsynthesis/circuits.json COPYONLY) package_add_test( - ${PROJECT_NAME}_cliffordsynthesis_test ${PROJECT_NAME}_cliffordsynthesis_lib + mqt-qmap-cliffordsynthesis-test MQT::QMapCliffordSynthesis ${CMAKE_CURRENT_SOURCE_DIR}/test_tableau.cpp ${CMAKE_CURRENT_SOURCE_DIR}/cliffordsynthesis/test_synthesis.cpp) endif() From 6b394626da313a456cf849b57810fe4ff3b4120c Mon Sep 17 00:00:00 2001 From: burgholzer Date: Mon, 29 Jan 2024 17:35:18 +0100 Subject: [PATCH 19/19] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20update=20LogicBlocks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: burgholzer --- extern/LogicBlocks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/LogicBlocks b/extern/LogicBlocks index 43a8247ac..2d4d66b49 160000 --- a/extern/LogicBlocks +++ b/extern/LogicBlocks @@ -1 +1 @@ -Subproject commit 43a8247ac22feb266d5eb9e635f9d3fb046ace9d +Subproject commit 2d4d66b49615353902658ee6c8035b9573d980b3