Skip to content

Commit

Permalink
🚸♻️ Refactor library structure for cleaner separation of concerns (#518)
Browse files Browse the repository at this point in the history
  • Loading branch information
burgholzer authored Sep 6, 2024
2 parents 95bf8fe + a94f48f commit 4d430cb
Show file tree
Hide file tree
Showing 69 changed files with 1,121 additions and 1,007 deletions.
7 changes: 4 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ repos:

# Python linting using ruff
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.3
rev: v0.6.4
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
Expand All @@ -76,18 +76,19 @@ repos:
rev: v1.11.2
hooks:
- id: mypy
files: ^(src/mqt|test/python)
files: ^(src/mqt|test/python|noxfile.py)
args: []
additional_dependencies:
- importlib_resources
- nox
- numpy
- pytest
- rustworkx
- mqt.qcec

# Check for spelling
- repo: https://github.com/crate-ci/typos
rev: v1.24.1
rev: v1.24.5
hooks:
- id: typos

Expand Down
33 changes: 23 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# set required cmake version
cmake_minimum_required(VERSION 3.19...3.28)
cmake_minimum_required(VERSION 3.19...3.30)

project(
mqt-qmap
LANGUAGES CXX
DESCRIPTION "MQT QMAP - A library for mapping of quantum circuits to quantum architectures")

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)
# Add path for custom modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

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
Expand Down Expand Up @@ -37,8 +38,14 @@ if(BUILD_MQT_QMAP_BINDINGS)
OPTIONAL_COMPONENTS Development.SABIModule)
endif()

# Add path for custom modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# check if this is the master project or used via add_subdirectory
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(MQT_QMAP_MASTER_PROJECT ON)
else()
set(MQT_QMAP_MASTER_PROJECT OFF)
endif()

option(BUILD_MQT_QMAP_TESTS "Also build tests for the MQT QMAP project" ${MQT_QMAP_MASTER_PROJECT})

include(cmake/ExternalDependencies.cmake)

Expand All @@ -55,9 +62,15 @@ if(BUILD_MQT_QMAP_TESTS)
add_subdirectory(test)
endif()

if(NOT TARGET mqt-qmap-uninstall)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY)
add_custom_target(mqt-qmap-uninstall COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
if(MQT_QMAP_MASTER_PROJECT)
if(NOT TARGET mqt-qmap-uninstall)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY)
add_custom_target(mqt-qmap-uninstall COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
else()
set(mqt-qmap_FOUND
TRUE
CACHE INTERNAL "True if mqt-qmap is found on the system")
endif()
46 changes: 6 additions & 40 deletions include/cliffordsynthesis/Results.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,21 @@

#pragma once

#include "circuit_optimizer/CircuitOptimizer.hpp"
#include "cliffordsynthesis/Tableau.hpp"
#include "ir/QuantumComputation.hpp"
#include "logicblocks/Logic.hpp"

#include <cstddef>
#include <limits>
#include <nlohmann/json.hpp>
#include <nlohmann/json_fwd.hpp>
#include <ostream>
#include <sstream>
#include <string>

namespace cs {
class Results {
public:
Results() = default;
Results(qc::QuantumComputation& qc, const Tableau& tableau) {
// SWAP gates are not natively supported in the encoding, so we need to
// decompose them into sequences of three CNOTs.
qc::CircuitOptimizer::decomposeSWAP(qc, false);

setResultCircuit(qc);
setResultTableau(tableau);
setDepth(qc.getDepth());
setSingleQubitGates(qc.getNsingleQubitOps());
setTwoQubitGates(qc.getNindividualOps() - singleQubitGates);
setSolverResult(logicbase::Result::SAT);
}
Results(qc::QuantumComputation& qc, const Tableau& tableau);

virtual ~Results() = default;

Expand Down Expand Up @@ -60,16 +47,8 @@ class Results {
void setSolverResult(const logicbase::Result r) { solverResult = r; }
void setSolverCalls(const std::size_t c) { solverCalls = c; }

void setResultCircuit(qc::QuantumComputation& qc) {
std::stringstream ss;
qc.dumpOpenQASM3(ss);
resultCircuit = ss.str();
}
void setResultTableau(const Tableau& tableau) {
std::stringstream ss;
ss << tableau;
resultTableau = ss.str();
}
void setResultCircuit(qc::QuantumComputation& qc);
void setResultTableau(const Tableau& tableau);

[[nodiscard]] bool sat() const {
return getSolverResult() == logicbase::Result::SAT;
Expand All @@ -78,22 +57,9 @@ class Results {
return getSolverResult() == logicbase::Result::UNSAT;
}

[[nodiscard]] virtual nlohmann::basic_json<> json() const {
nlohmann::basic_json resultJSON{};
resultJSON["solver_result"] = toString(solverResult);
resultJSON["single_qubit_gates"] = singleQubitGates;
resultJSON["two_qubit_gates"] = twoQubitGates;
resultJSON["depth"] = depth;
resultJSON["runtime"] = runtime;
resultJSON["solver_calls"] = solverCalls;
[[nodiscard]] virtual nlohmann::basic_json<> json() const;

return resultJSON;
}

friend std::ostream& operator<<(std::ostream& os, const Results& config) {
os << config.json().dump(2);
return os;
}
friend std::ostream& operator<<(std::ostream& os, const Results& config);

protected:
logicbase::Result solverResult = logicbase::Result::NDEF;
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

#pragma once

#include "Mapper.hpp"
#include "MappingResults.hpp"
#include "configuration/Configuration.hpp"
#include "utils.hpp"
#include "sc/Mapper.hpp"
#include "sc/MappingResults.hpp"
#include "sc/configuration/Configuration.hpp"
#include "sc/utils.hpp"

#include <cmath>
#include <cstddef>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
// See README.md or go to https://github.com/cda-tum/qmap for more information.
//

#include "Architecture.hpp"
#include "DataLogger.hpp"
#include "Mapper.hpp"
#include "configuration/Configuration.hpp"
#include "heuristic/UniquePriorityQueue.hpp"
#include "utils.hpp"
#include "sc/Architecture.hpp"
#include "sc/DataLogger.hpp"
#include "sc/Mapper.hpp"
#include "sc/configuration/Configuration.hpp"
#include "sc/heuristic/UniquePriorityQueue.hpp"
#include "sc/utils.hpp"

#include <array>
#include <cmath>
Expand Down
File renamed without changes.
File renamed without changes.
11 changes: 6 additions & 5 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
nox.needs_version = ">=2024.3.2"
nox.options.default_venv_backend = "uv|virtualenv"

nox.options.sessions = ["lint", "tests"]
nox.options.sessions = ["lint", "tests", "minimums"]

PYTHON_ALL_VERSIONS = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]

Expand All @@ -39,8 +39,10 @@
@nox.session(reuse_venv=True)
def lint(session: nox.Session) -> None:
"""Run the linter."""
session.install("pre-commit")
session.run("pre-commit", "run", "--all-files", *session.posargs)
if shutil.which("pre-commit") is None:
session.install("pre-commit")

session.run("pre-commit", "run", "--all-files", *session.posargs, external=True)


def _run_tests(
Expand All @@ -51,8 +53,7 @@ def _run_tests(
extras: Sequence[str] = (),
) -> None:
posargs = list(session.posargs)
env = {"PIP_DISABLE_PIP_VERSION_CHECK": "1"}

env = {}
if os.environ.get("CI", None) and sys.platform == "win32":
env["SKBUILD_CMAKE_ARGS"] = "-T ClangCL"

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ report.exclude_also = [
]

[tool.mypy]
files = ["src/mqt", "test/python"]
files = ["src/mqt", "test/python", "noxfile.py"]
mypy_path = ["$MYPY_CONFIG_FILE_DIR/src"]
python_version = "3.8"
warn_unused_configs = true
Expand Down
125 changes: 3 additions & 122 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,135 +1,16 @@
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 $<BUILD_INTERFACE:${MQT_QMAP_INCLUDE_BUILD_DIR}>)

# add MQT::qfr library
target_link_libraries(
${lib}
PUBLIC MQT::CoreIR MQT::CoreCircuitOptimizer nlohmann_json::nlohmann_json
PRIVATE MQT::ProjectOptions MQT::ProjectWarnings)
endmacro()

# macro to add mapping libraries
macro(ADD_QMAP_LIBRARY libname srcfile)
set(lib ${MQT_QMAP_TARGET_NAME}-${libname})

# main project library
add_library(
${lib}
${libname}/${srcfile}.cpp
${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})
endmacro()

# macro to add synthesis libraries
macro(ADD_SYNTHESIS_LIBRARY libname srcfile)
set(lib ${MQT_QMAP_TARGET_NAME}-${libname})

# main project library
add_library(
${lib}
${libname}/${srcfile}.cpp
${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
cliffordsynthesis/encoding/SATEncoder.cpp
cliffordsynthesis/encoding/SingleGateEncoder.cpp
cliffordsynthesis/encoding/TableauEncoder.cpp
cliffordsynthesis/Tableau.cpp
utils.cpp)

add_internal_library(${lib})
target_link_libraries(${lib} PUBLIC MQT::CoreNA)
endmacro()

# macro to add hybrid neutral atom mapping libraries
macro(ADD_HYBRIDMAP_LIBRARY libname srcfile)
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/${libname}/NeutralAtomUtils.hpp
${PROJECT_SOURCE_DIR}/include/${libname}/NeutralAtomScheduler.hpp
${PROJECT_SOURCE_DIR}/include/${libname}/NeutralAtomArchitecture.hpp
${PROJECT_SOURCE_DIR}/include/${libname}/HardwareQubits.hpp
${PROJECT_SOURCE_DIR}/include/${libname}/Mapping.hpp
${PROJECT_SOURCE_DIR}/include/${libname}/NeutralAtomDefinitions.hpp
${PROJECT_SOURCE_DIR}/include/${libname}/MoveToAodConverter.hpp
${PROJECT_SOURCE_DIR}/include/${libname}/NeutralAtomLayer.hpp
${PROJECT_SOURCE_DIR}/include/${libname}/HybridAnimation.hpp
hybridmap/NeutralAtomUtils.cpp
hybridmap/NeutralAtomScheduler.cpp
hybridmap/NeutralAtomArchitecture.cpp
hybridmap/HardwareQubits.cpp
hybridmap/Mapping.cpp
hybridmap/MoveToAodConverter.cpp
hybridmap/HybridAnimation.cpp
hybridmap/NeutralAtomLayer.cpp)

add_internal_library(${lib})
endmacro()

# exact mapper project library
if(Z3_FOUND)
# add LogicBlocks library
add_subdirectory(logicblocks)

add_qmap_library(exact ExactMapper)
target_link_libraries(${MQT_QMAP_TARGET_NAME}-exact PRIVATE MQT::LogicBlocks)

add_synthesis_library(cliffordsynthesis CliffordSynthesizer)
target_link_libraries(
${MQT_QMAP_TARGET_NAME}-cliffordsynthesis
PUBLIC plog::plog
PRIVATE MQT::LogicBlocks)

# 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_subdirectory(cliffordsynthesis)
endif()

# heuristic mapper project library
add_qmap_library(heuristic HeuristicMapper)

# hybrid neutral atom mapper project library
add_hybridmap_library(hybridmap HybridNeutralAtomMapper)
add_subdirectory(sc)

# add MQT alias targets
add_library(MQT::QMapHeuristic ALIAS ${MQT_QMAP_TARGET_NAME}-heuristic)
add_library(MQT::QMapHybrid ALIAS ${MQT_QMAP_TARGET_NAME}-hybridmap)
add_subdirectory(hybridmap)

add_subdirectory(na)

Expand Down
Loading

0 comments on commit 4d430cb

Please sign in to comment.