From a7ba06ea47c14e1566768a2b87d0b1bbfbbc89dd Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Mon, 15 May 2023 20:39:38 +0200 Subject: [PATCH 01/43] =?UTF-8?q?=E2=9C=85=20add=20Task,=20Executor=20and?= =?UTF-8?q?=20Result=20classes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/Executor.hpp | 19 ++++++++++++++++++ include/Result.hpp | 28 ++++++++++++++++++++++++++ include/ResultBase.hpp | 22 +++++++++++++++++++++ include/SimulationTask.hpp | 17 ++++++++++++++++ include/Task.hpp | 15 ++++++++++++++ include/VerificationTask.hpp | 19 ++++++++++++++++++ src/CMakeLists.txt | 38 ++++++++++++++++++++++-------------- src/Result.cpp | 18 +++++++++++++++++ src/SimulationTask.cpp | 8 ++++++++ src/VerificationTask.cpp | 7 +++++++ 10 files changed, 176 insertions(+), 15 deletions(-) create mode 100644 include/Executor.hpp create mode 100644 include/Result.hpp create mode 100644 include/ResultBase.hpp create mode 100644 include/SimulationTask.hpp create mode 100644 include/Task.hpp create mode 100644 include/VerificationTask.hpp create mode 100644 src/Result.cpp create mode 100644 src/SimulationTask.cpp create mode 100644 src/VerificationTask.cpp diff --git a/include/Executor.hpp b/include/Executor.hpp new file mode 100644 index 0000000..a64e881 --- /dev/null +++ b/include/Executor.hpp @@ -0,0 +1,19 @@ +// +// Created by Tianyi Wang on 5/14/23. +// + +#ifndef DD_EVAL_EXECUTOR_HPP +#define DD_EVAL_EXECUTOR_HPP + +#endif //DD_EVAL_EXECUTOR_HPP + +#include "Task.hpp" + +class Executor { +private: + Task *task; +}; + +void executeTask(Task *task) { + task->execute(); +} diff --git a/include/Result.hpp b/include/Result.hpp new file mode 100644 index 0000000..e3aa8fb --- /dev/null +++ b/include/Result.hpp @@ -0,0 +1,28 @@ +// +// Created by Tianyi Wang on 5/14/23. +// + +#ifndef DD_EVAL_RESULT_HPP +#define DD_EVAL_RESULT_HPP + + +#include "ResultBase.hpp" +#include <string> +#include <nlohmann/json.hpp> + +using json = nlohmann::json; + +class Result : public ResultBase { +public: + Result(const std::string& name, double value); + + json toJson() const override; + std::string toString() const override; + +private: + std::string name_; + double value_; +}; + +#endif // DD_EVAL_RESULT_HPP + diff --git a/include/ResultBase.hpp b/include/ResultBase.hpp new file mode 100644 index 0000000..3fde0c1 --- /dev/null +++ b/include/ResultBase.hpp @@ -0,0 +1,22 @@ +// +// Created by Tianyi Wang on 5/15/23. +// + +#ifndef DD_EVAL_RESULTBASE_HPP +#define DD_EVAL_RESULTBASE_HPP + +#include <nlohmann/json.hpp> + +using json = nlohmann::json; + +class ResultBase { +public: + virtual ~ResultBase() = default; + + virtual json toJson() const = 0; + virtual std::string toString() const = 0; +}; + + +#endif //DD_EVAL_RESULTBASE_HPP + diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp new file mode 100644 index 0000000..75da9a4 --- /dev/null +++ b/include/SimulationTask.hpp @@ -0,0 +1,17 @@ +// +// Created by Tianyi Wang on 5/14/23. +// + +#ifndef DD_EVAL_SIMULATIONTASK_HPP +#define DD_EVAL_SIMULATIONTASK_HPP + +#endif //DD_EVAL_SIMULATIONTASK_HPP + +#include "Task.hpp" + +class SimulationTask : public Task { +//public: +// SimulationTask(QuantumCircuit qc); +//private: +// QuantumCircuit qc_; +}; \ No newline at end of file diff --git a/include/Task.hpp b/include/Task.hpp new file mode 100644 index 0000000..332630b --- /dev/null +++ b/include/Task.hpp @@ -0,0 +1,15 @@ +// +// Created by Tianyi Wang on 5/14/23. +// + +#ifndef DD_EVAL_TASK_HPP +#define DD_EVAL_TASK_HPP + +#endif //DD_EVAL_TASK_HPP + +#include "Result.hpp" + +class Task { +public: + virtual Result execute() = 0; +}; diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp new file mode 100644 index 0000000..702131b --- /dev/null +++ b/include/VerificationTask.hpp @@ -0,0 +1,19 @@ +// +// Created by Tianyi Wang on 5/14/23. +// + +#ifndef DD_EVAL_VERIFICATIONTASK_HPP +#define DD_EVAL_VERIFICATIONTASK_HPP + +#endif //DD_EVAL_VERIFICATIONTASK_HPP + + +#include "Task.hpp" + +class VerificationTask : public Task { +//public: +// VerificationTask(QuantumCircuit qc1, QuantumCircuit qc2); +//private: +// QuantumCircuit qc1_; +// QuantumCircuit qc2_; +}; \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 120ed07..796b04e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,26 +6,34 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim" "extern/ddsim" add_subdirectory("${PROJECT_SOURCE_DIR}/extern/qcec" "extern/qcec" EXCLUDE_FROM_ALL) -# add_library( ${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/include/checker -# ${PROJECT_SOURCE_DIR}/include/Configuration.hpp -# ${PROJECT_SOURCE_DIR}/include/EquivalenceCriterion.hpp -# ${PROJECT_SOURCE_DIR}/include/EquivalenceCheckingManager.hpp -# ${PROJECT_SOURCE_DIR}/include/ThreadSafeQueue.hpp -# EquivalenceCheckingManager.cpp checker/EquivalenceChecker.cpp -# checker/dd/DDEquivalenceChecker.cpp checker/dd/DDConstructionChecker.cpp -# checker/dd/DDSimulationChecker.cpp checker/dd/DDAlternatingChecker.cpp -# checker/dd/applicationscheme/GateCostApplicationScheme.cpp -# checker/dd/simulation/StateGenerator.cpp checker/zx/ZXChecker.cpp) +if(NOT TARGET nlohmann_json) + add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim/extern/qfr/extern/json" "qfr/json" + EXCLUDE_FROM_ALL) +endif() -add_library(${PROJECT_NAME} INTERFACE) +if(NOT TARGET ${PROJECT_NAME}) + add_library( + ${PROJECT_NAME} + ${PROJECT_SOURCE_DIR}/include/Executor.hpp + ${PROJECT_SOURCE_DIR}/include/Result.hpp + ${PROJECT_SOURCE_DIR}/include/ResultBase.hpp + ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp + ${PROJECT_SOURCE_DIR}/include/Task.hpp + ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp + Result.cpp + SimulationTask.cpp + VerificationTask.cpp) # set include directories -target_include_directories( - ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include + target_include_directories( + ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) # link to the MQT libraries -target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec) + target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec) + + target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json) # add MQT alias -add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) +endif() \ No newline at end of file diff --git a/src/Result.cpp b/src/Result.cpp new file mode 100644 index 0000000..fb055bc --- /dev/null +++ b/src/Result.cpp @@ -0,0 +1,18 @@ +// +// Created by Tianyi Wang on 5/14/23. +// + +#include "../include/Result.hpp" + +Result::Result(const std::string& name, double value) : name_(name), value_(value) {} + +json Result::toJson() const { + json resultJson; + resultJson["name"] = name_; + resultJson["value"] = value_; + return resultJson; +} + +std::string Result::toString() const { + return toJson().dump(); +} diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp new file mode 100644 index 0000000..b8d5b1c --- /dev/null +++ b/src/SimulationTask.cpp @@ -0,0 +1,8 @@ +// +// Created by Tianyi Wang on 5/14/23. +// + +#include "../include/SimulationTask.hpp" +//take one circuit + + diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp new file mode 100644 index 0000000..f44d834 --- /dev/null +++ b/src/VerificationTask.cpp @@ -0,0 +1,7 @@ +// +// Created by Tianyi Wang on 5/14/23. +// + +#include "../include/VerificationTask.hpp" +//take two circuits + From f13c774f3d289992408ee0c18f484d521c87740f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 18:50:49 +0000 Subject: [PATCH 02/43] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/Executor.hpp | 8 +++---- include/Result.hpp | 17 +++++++------ include/ResultBase.hpp | 10 ++++---- include/SimulationTask.hpp | 12 +++++----- include/Task.hpp | 4 ++-- include/VerificationTask.hpp | 15 ++++++------ src/CMakeLists.txt | 46 ++++++++++++++++++------------------ src/Result.cpp | 15 ++++++------ src/SimulationTask.cpp | 4 +--- src/VerificationTask.cpp | 3 +-- 10 files changed, 62 insertions(+), 72 deletions(-) diff --git a/include/Executor.hpp b/include/Executor.hpp index a64e881..3af7046 100644 --- a/include/Executor.hpp +++ b/include/Executor.hpp @@ -5,15 +5,13 @@ #ifndef DD_EVAL_EXECUTOR_HPP #define DD_EVAL_EXECUTOR_HPP -#endif //DD_EVAL_EXECUTOR_HPP +#endif // DD_EVAL_EXECUTOR_HPP #include "Task.hpp" class Executor { private: - Task *task; + Task* task; }; -void executeTask(Task *task) { - task->execute(); -} +void executeTask(Task* task) { task->execute(); } diff --git a/include/Result.hpp b/include/Result.hpp index e3aa8fb..481184a 100644 --- a/include/Result.hpp +++ b/include/Result.hpp @@ -5,24 +5,23 @@ #ifndef DD_EVAL_RESULT_HPP #define DD_EVAL_RESULT_HPP - #include "ResultBase.hpp" -#include <string> + #include <nlohmann/json.hpp> +#include <string> using json = nlohmann::json; class Result : public ResultBase { public: - Result(const std::string& name, double value); + Result(const std::string& name, double value); - json toJson() const override; - std::string toString() const override; + json toJson() const override; + std::string toString() const override; private: - std::string name_; - double value_; + std::string name_; + double value_; }; -#endif // DD_EVAL_RESULT_HPP - +#endif // DD_EVAL_RESULT_HPP diff --git a/include/ResultBase.hpp b/include/ResultBase.hpp index 3fde0c1..71b5c1e 100644 --- a/include/ResultBase.hpp +++ b/include/ResultBase.hpp @@ -11,12 +11,10 @@ using json = nlohmann::json; class ResultBase { public: - virtual ~ResultBase() = default; + virtual ~ResultBase() = default; - virtual json toJson() const = 0; - virtual std::string toString() const = 0; + virtual json toJson() const = 0; + virtual std::string toString() const = 0; }; - -#endif //DD_EVAL_RESULTBASE_HPP - +#endif // DD_EVAL_RESULTBASE_HPP diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp index 75da9a4..91e64ec 100644 --- a/include/SimulationTask.hpp +++ b/include/SimulationTask.hpp @@ -5,13 +5,13 @@ #ifndef DD_EVAL_SIMULATIONTASK_HPP #define DD_EVAL_SIMULATIONTASK_HPP -#endif //DD_EVAL_SIMULATIONTASK_HPP +#endif // DD_EVAL_SIMULATIONTASK_HPP #include "Task.hpp" class SimulationTask : public Task { -//public: -// SimulationTask(QuantumCircuit qc); -//private: -// QuantumCircuit qc_; -}; \ No newline at end of file + // public: + // SimulationTask(QuantumCircuit qc); + // private: + // QuantumCircuit qc_; +}; diff --git a/include/Task.hpp b/include/Task.hpp index 332630b..7ce92fb 100644 --- a/include/Task.hpp +++ b/include/Task.hpp @@ -5,11 +5,11 @@ #ifndef DD_EVAL_TASK_HPP #define DD_EVAL_TASK_HPP -#endif //DD_EVAL_TASK_HPP +#endif // DD_EVAL_TASK_HPP #include "Result.hpp" class Task { public: - virtual Result execute() = 0; + virtual Result execute() = 0; }; diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp index 702131b..1f85666 100644 --- a/include/VerificationTask.hpp +++ b/include/VerificationTask.hpp @@ -5,15 +5,14 @@ #ifndef DD_EVAL_VERIFICATIONTASK_HPP #define DD_EVAL_VERIFICATIONTASK_HPP -#endif //DD_EVAL_VERIFICATIONTASK_HPP - +#endif // DD_EVAL_VERIFICATIONTASK_HPP #include "Task.hpp" class VerificationTask : public Task { -//public: -// VerificationTask(QuantumCircuit qc1, QuantumCircuit qc2); -//private: -// QuantumCircuit qc1_; -// QuantumCircuit qc2_; -}; \ No newline at end of file + // public: + // VerificationTask(QuantumCircuit qc1, QuantumCircuit qc2); + // private: + // QuantumCircuit qc1_; + // QuantumCircuit qc2_; +}; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 796b04e..25131aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,33 +7,33 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/extern/qcec" "extern/qcec" EXCLUDE_FROM_ALL) if(NOT TARGET nlohmann_json) - add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim/extern/qfr/extern/json" "qfr/json" - EXCLUDE_FROM_ALL) + add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim/extern/qfr/extern/json" + "qfr/json" EXCLUDE_FROM_ALL) endif() if(NOT TARGET ${PROJECT_NAME}) - add_library( - ${PROJECT_NAME} - ${PROJECT_SOURCE_DIR}/include/Executor.hpp - ${PROJECT_SOURCE_DIR}/include/Result.hpp - ${PROJECT_SOURCE_DIR}/include/ResultBase.hpp - ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp - ${PROJECT_SOURCE_DIR}/include/Task.hpp - ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp - Result.cpp - SimulationTask.cpp - VerificationTask.cpp) + add_library( + ${PROJECT_NAME} + ${PROJECT_SOURCE_DIR}/include/Executor.hpp + ${PROJECT_SOURCE_DIR}/include/Result.hpp + ${PROJECT_SOURCE_DIR}/include/ResultBase.hpp + ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp + ${PROJECT_SOURCE_DIR}/include/Task.hpp + ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp + Result.cpp + SimulationTask.cpp + VerificationTask.cpp) -# set include directories - target_include_directories( - ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include - ${PROJECT_BINARY_DIR}/include) + # set include directories + target_include_directories( + ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include + ${PROJECT_BINARY_DIR}/include) -# link to the MQT libraries - target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec) + # link to the MQT libraries + target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec) - target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json) + target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json) -# add MQT alias - add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) -endif() \ No newline at end of file + # add MQT alias + add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) +endif() diff --git a/src/Result.cpp b/src/Result.cpp index fb055bc..a317706 100644 --- a/src/Result.cpp +++ b/src/Result.cpp @@ -4,15 +4,14 @@ #include "../include/Result.hpp" -Result::Result(const std::string& name, double value) : name_(name), value_(value) {} +Result::Result(const std::string& name, double value) + : name_(name), value_(value) {} json Result::toJson() const { - json resultJson; - resultJson["name"] = name_; - resultJson["value"] = value_; - return resultJson; + json resultJson; + resultJson["name"] = name_; + resultJson["value"] = value_; + return resultJson; } -std::string Result::toString() const { - return toJson().dump(); -} +std::string Result::toString() const { return toJson().dump(); } diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp index b8d5b1c..ffd5b0b 100644 --- a/src/SimulationTask.cpp +++ b/src/SimulationTask.cpp @@ -3,6 +3,4 @@ // #include "../include/SimulationTask.hpp" -//take one circuit - - +// take one circuit diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp index f44d834..a6a95b4 100644 --- a/src/VerificationTask.cpp +++ b/src/VerificationTask.cpp @@ -3,5 +3,4 @@ // #include "../include/VerificationTask.hpp" -//take two circuits - +// take two circuits From 5b501eaccc5a6f54ba1bfeba36d2c98c166d4cbc Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Tue, 16 May 2023 17:33:21 +0200 Subject: [PATCH 03/43] First review suggestions taken --- include/Executor.hpp | 28 +++++++++++++++------------- include/Result.hpp | 28 ---------------------------- include/ResultBase.hpp | 22 ---------------------- include/Results.hpp | 23 +++++++++++++++++++++++ include/SimulationTask.hpp | 22 +++++++++------------- include/Task.hpp | 14 +++++--------- include/VerificationTask.hpp | 26 +++++++++++--------------- src/CMakeLists.txt | 17 +++++------------ src/Executor.cpp | 32 ++++++++++++++++++++++++++++++++ src/SimulationTask.cpp | 6 +----- src/VerificationTask.cpp | 6 +----- 11 files changed, 102 insertions(+), 122 deletions(-) delete mode 100644 include/Result.hpp delete mode 100644 include/ResultBase.hpp create mode 100644 include/Results.hpp create mode 100644 src/Executor.cpp diff --git a/include/Executor.hpp b/include/Executor.hpp index a64e881..16f355a 100644 --- a/include/Executor.hpp +++ b/include/Executor.hpp @@ -1,19 +1,21 @@ -// -// Created by Tianyi Wang on 5/14/23. -// - -#ifndef DD_EVAL_EXECUTOR_HPP -#define DD_EVAL_EXECUTOR_HPP - -#endif //DD_EVAL_EXECUTOR_HPP +#pragma once #include "Task.hpp" +#include <memory> + class Executor { +public: + virtual ~Executor() = default; + virtual json executeTask() = 0; + + const std::shared_ptr<Task> &getTask() const; + + explicit Executor(){ + }; + + void setTask(const std::shared_ptr<Task> &task); + virtual std::string getIdentifier() = 0; private: - Task *task; + std::shared_ptr<Task> task; }; - -void executeTask(Task *task) { - task->execute(); -} diff --git a/include/Result.hpp b/include/Result.hpp deleted file mode 100644 index e3aa8fb..0000000 --- a/include/Result.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by Tianyi Wang on 5/14/23. -// - -#ifndef DD_EVAL_RESULT_HPP -#define DD_EVAL_RESULT_HPP - - -#include "ResultBase.hpp" -#include <string> -#include <nlohmann/json.hpp> - -using json = nlohmann::json; - -class Result : public ResultBase { -public: - Result(const std::string& name, double value); - - json toJson() const override; - std::string toString() const override; - -private: - std::string name_; - double value_; -}; - -#endif // DD_EVAL_RESULT_HPP - diff --git a/include/ResultBase.hpp b/include/ResultBase.hpp deleted file mode 100644 index 3fde0c1..0000000 --- a/include/ResultBase.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// Created by Tianyi Wang on 5/15/23. -// - -#ifndef DD_EVAL_RESULTBASE_HPP -#define DD_EVAL_RESULTBASE_HPP - -#include <nlohmann/json.hpp> - -using json = nlohmann::json; - -class ResultBase { -public: - virtual ~ResultBase() = default; - - virtual json toJson() const = 0; - virtual std::string toString() const = 0; -}; - - -#endif //DD_EVAL_RESULTBASE_HPP - diff --git a/include/Results.hpp b/include/Results.hpp new file mode 100644 index 0000000..7b7e2dc --- /dev/null +++ b/include/Results.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include <nlohmann/json.hpp> +#include "Task.hpp" +#include "Executor.hpp" + +using json = nlohmann::json; + +class Results { +public: + virtual ~Results() = default; + + virtual json toJson() const = 0; + virtual std::string toString() const { return toJson().dump(2); } + + Results(Task task, Executor executor) { + identifier = task.getIdentifier() + "_" + executor.getIdentifier(); + } + + +private: + std::string identifier; +}; diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp index 75da9a4..8601070 100644 --- a/include/SimulationTask.hpp +++ b/include/SimulationTask.hpp @@ -1,17 +1,13 @@ -// -// Created by Tianyi Wang on 5/14/23. -// - -#ifndef DD_EVAL_SIMULATIONTASK_HPP -#define DD_EVAL_SIMULATIONTASK_HPP - -#endif //DD_EVAL_SIMULATIONTASK_HPP +#pragma once #include "Task.hpp" +#include "QuantumComputation.hpp" class SimulationTask : public Task { -//public: -// SimulationTask(QuantumCircuit qc); -//private: -// QuantumCircuit qc_; -}; \ No newline at end of file +public: + explicit SimulationTask(qc::QuantumComputation qc) { + this->qc = qc.clone(); + }; +private: + qc::QuantumComputation qc; +}; diff --git a/include/Task.hpp b/include/Task.hpp index 332630b..9c36667 100644 --- a/include/Task.hpp +++ b/include/Task.hpp @@ -1,15 +1,11 @@ -// -// Created by Tianyi Wang on 5/14/23. -// +#pragma once -#ifndef DD_EVAL_TASK_HPP -#define DD_EVAL_TASK_HPP +#include <nlohmann/json.hpp> -#endif //DD_EVAL_TASK_HPP - -#include "Result.hpp" +using json = nlohmann::json; class Task { public: - virtual Result execute() = 0; + virtual ~Task() = default; + virtual std::string getIdentifier() = 0; }; diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp index 702131b..79ae39d 100644 --- a/include/VerificationTask.hpp +++ b/include/VerificationTask.hpp @@ -1,19 +1,15 @@ -// -// Created by Tianyi Wang on 5/14/23. -// - -#ifndef DD_EVAL_VERIFICATIONTASK_HPP -#define DD_EVAL_VERIFICATIONTASK_HPP - -#endif //DD_EVAL_VERIFICATIONTASK_HPP - +#pragma once #include "Task.hpp" +#include "QuantumComputation.hpp" class VerificationTask : public Task { -//public: -// VerificationTask(QuantumCircuit qc1, QuantumCircuit qc2); -//private: -// QuantumCircuit qc1_; -// QuantumCircuit qc2_; -}; \ No newline at end of file +public: + VerificationTask(qc::QuantumComputation qc1, qc::QuantumComputation qc2) { + this->qc1 = qc1.clone(); + this->qc2 = qc2.clone(); + }; +private: + qc::QuantumComputation qc1; + qc::QuantumComputation qc2; +}; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 796b04e..b2c6cd2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,33 +6,26 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim" "extern/ddsim" add_subdirectory("${PROJECT_SOURCE_DIR}/extern/qcec" "extern/qcec" EXCLUDE_FROM_ALL) -if(NOT TARGET nlohmann_json) - add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim/extern/qfr/extern/json" "qfr/json" - EXCLUDE_FROM_ALL) -endif() - if(NOT TARGET ${PROJECT_NAME}) add_library( ${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/include/Executor.hpp - ${PROJECT_SOURCE_DIR}/include/Result.hpp - ${PROJECT_SOURCE_DIR}/include/ResultBase.hpp + ${PROJECT_SOURCE_DIR}/include/Results.hpp ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp ${PROJECT_SOURCE_DIR}/include/Task.hpp ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp Result.cpp SimulationTask.cpp - VerificationTask.cpp) + VerificationTask.cpp + Executor.cpp CircuitSimulatorExecutor.cpp ../include/CircuitSimulatorExecutor.hpp VerificationExecutor.cpp ../include/VerificationExecutor.hpp AlternatingVerificationExecutor.cpp ../include/AlternatingVerificationExecutor.hpp) # set include directories target_include_directories( - ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include + ${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include ${PROJECT_BINARY_DIR}/include) # link to the MQT libraries - target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec) - - target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json) + target_link_libraries(${PROJECT_NAME} PUBLIC MQT::ddsim MQT::qcec) # add MQT alias add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) diff --git a/src/Executor.cpp b/src/Executor.cpp new file mode 100644 index 0000000..4f153c9 --- /dev/null +++ b/src/Executor.cpp @@ -0,0 +1,32 @@ +#include "Executor.hpp" +#include <chrono> + +class Executor::Executor { + json executeTask() { + json result; + auto start = std::chrono::high_resolution_clock::now(); + + this->executeTask(); + // Add memory usage later + + auto stop = std::chrono::high_resolution_clock::now(); + auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(stop-start); + result["runtime"] = runtime.count(); + std::string const identifier = this->getTask()->getIdentifier() + "_" + this->getIdentifier(); + result["identifier"] = identifier; + return result; + // what about the Results class? + } +}; + +//add adapter for simulators +const std::shared_ptr<Task> &Executor::getTask() const { + return task; +} + +void Executor::setTask(const std::shared_ptr<Task> &newTask) { + this->task = newTask; +} + + + diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp index b8d5b1c..0daaecf 100644 --- a/src/SimulationTask.cpp +++ b/src/SimulationTask.cpp @@ -1,8 +1,4 @@ -// -// Created by Tianyi Wang on 5/14/23. -// - -#include "../include/SimulationTask.hpp" +#include "SimulationTask.hpp" //take one circuit diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp index f44d834..eb48d02 100644 --- a/src/VerificationTask.cpp +++ b/src/VerificationTask.cpp @@ -1,7 +1,3 @@ -// -// Created by Tianyi Wang on 5/14/23. -// - -#include "../include/VerificationTask.hpp" +#include "VerificationTask.hpp" //take two circuits From ce8ba49ab95298a16d5c04541f856a195da8c89b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 15:35:36 +0000 Subject: [PATCH 04/43] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/Executor.hpp | 18 +++++++------- include/Results.hpp | 20 ++++++++-------- include/SimulationTask.hpp | 9 ++++--- include/Task.hpp | 4 ++-- include/VerificationTask.hpp | 15 ++++++------ src/CMakeLists.txt | 44 +++++++++++++++++++--------------- src/Executor.cpp | 46 +++++++++++++++++------------------- src/SimulationTask.cpp | 2 +- src/VerificationTask.cpp | 2 +- 9 files changed, 82 insertions(+), 78 deletions(-) diff --git a/include/Executor.hpp b/include/Executor.hpp index 16f355a..d1cd51f 100644 --- a/include/Executor.hpp +++ b/include/Executor.hpp @@ -1,21 +1,21 @@ #pragma once #include "Task.hpp" -#include <memory> +#include <memory> class Executor { public: - virtual ~Executor() = default; - virtual json executeTask() = 0; + virtual ~Executor() = default; + virtual json executeTask() = 0; + + const std::shared_ptr<Task>& getTask() const; - const std::shared_ptr<Task> &getTask() const; + explicit Executor(){}; - explicit Executor(){ - }; + void setTask(const std::shared_ptr<Task>& task); + virtual std::string getIdentifier() = 0; - void setTask(const std::shared_ptr<Task> &task); - virtual std::string getIdentifier() = 0; private: - std::shared_ptr<Task> task; + std::shared_ptr<Task> task; }; diff --git a/include/Results.hpp b/include/Results.hpp index 7b7e2dc..4f74340 100644 --- a/include/Results.hpp +++ b/include/Results.hpp @@ -1,23 +1,23 @@ #pragma once -#include <nlohmann/json.hpp> -#include "Task.hpp" #include "Executor.hpp" +#include "Task.hpp" + +#include <nlohmann/json.hpp> using json = nlohmann::json; class Results { public: - virtual ~Results() = default; - - virtual json toJson() const = 0; - virtual std::string toString() const { return toJson().dump(2); } + virtual ~Results() = default; - Results(Task task, Executor executor) { - identifier = task.getIdentifier() + "_" + executor.getIdentifier(); - } + virtual json toJson() const = 0; + virtual std::string toString() const { return toJson().dump(2); } + Results(Task task, Executor executor) { + identifier = task.getIdentifier() + "_" + executor.getIdentifier(); + } private: - std::string identifier; + std::string identifier; }; diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp index 8601070..6dbd207 100644 --- a/include/SimulationTask.hpp +++ b/include/SimulationTask.hpp @@ -1,13 +1,12 @@ #pragma once -#include "Task.hpp" #include "QuantumComputation.hpp" +#include "Task.hpp" class SimulationTask : public Task { public: - explicit SimulationTask(qc::QuantumComputation qc) { - this->qc = qc.clone(); - }; + explicit SimulationTask(qc::QuantumComputation qc) { this->qc = qc.clone(); }; + private: - qc::QuantumComputation qc; + qc::QuantumComputation qc; }; diff --git a/include/Task.hpp b/include/Task.hpp index 9c36667..2085fc6 100644 --- a/include/Task.hpp +++ b/include/Task.hpp @@ -6,6 +6,6 @@ using json = nlohmann::json; class Task { public: - virtual ~Task() = default; - virtual std::string getIdentifier() = 0; + virtual ~Task() = default; + virtual std::string getIdentifier() = 0; }; diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp index 79ae39d..795362a 100644 --- a/include/VerificationTask.hpp +++ b/include/VerificationTask.hpp @@ -1,15 +1,16 @@ #pragma once -#include "Task.hpp" #include "QuantumComputation.hpp" +#include "Task.hpp" class VerificationTask : public Task { public: - VerificationTask(qc::QuantumComputation qc1, qc::QuantumComputation qc2) { - this->qc1 = qc1.clone(); - this->qc2 = qc2.clone(); - }; + VerificationTask(qc::QuantumComputation qc1, qc::QuantumComputation qc2) { + this->qc1 = qc1.clone(); + this->qc2 = qc2.clone(); + }; + private: - qc::QuantumComputation qc1; - qc::QuantumComputation qc2; + qc::QuantumComputation qc1; + qc::QuantumComputation qc2; }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1f3f565..3c09bdd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,26 +7,32 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/extern/qcec" "extern/qcec" EXCLUDE_FROM_ALL) if(NOT TARGET ${PROJECT_NAME}) - add_library( - ${PROJECT_NAME} - ${PROJECT_SOURCE_DIR}/include/Executor.hpp - ${PROJECT_SOURCE_DIR}/include/Results.hpp - ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp - ${PROJECT_SOURCE_DIR}/include/Task.hpp - ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp - Result.cpp - SimulationTask.cpp - VerificationTask.cpp - Executor.cpp CircuitSimulatorExecutor.cpp ../include/CircuitSimulatorExecutor.hpp VerificationExecutor.cpp ../include/VerificationExecutor.hpp AlternatingVerificationExecutor.cpp ../include/AlternatingVerificationExecutor.hpp) + add_library( + ${PROJECT_NAME} + ${PROJECT_SOURCE_DIR}/include/Executor.hpp + ${PROJECT_SOURCE_DIR}/include/Results.hpp + ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp + ${PROJECT_SOURCE_DIR}/include/Task.hpp + ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp + Result.cpp + SimulationTask.cpp + VerificationTask.cpp + Executor.cpp + CircuitSimulatorExecutor.cpp + ../include/CircuitSimulatorExecutor.hpp + VerificationExecutor.cpp + ../include/VerificationExecutor.hpp + AlternatingVerificationExecutor.cpp + ../include/AlternatingVerificationExecutor.hpp) -# set include directories - target_include_directories( - ${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include - ${PROJECT_BINARY_DIR}/include) + # set include directories + target_include_directories( + ${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include + ${PROJECT_BINARY_DIR}/include) -# link to the MQT libraries - target_link_libraries(${PROJECT_NAME} PUBLIC MQT::ddsim MQT::qcec) + # link to the MQT libraries + target_link_libraries(${PROJECT_NAME} PUBLIC MQT::ddsim MQT::qcec) -# add MQT alias - add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + # add MQT alias + add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) endif() diff --git a/src/Executor.cpp b/src/Executor.cpp index 4f153c9..f6ea61d 100644 --- a/src/Executor.cpp +++ b/src/Executor.cpp @@ -1,32 +1,30 @@ #include "Executor.hpp" + #include <chrono> class Executor::Executor { - json executeTask() { - json result; - auto start = std::chrono::high_resolution_clock::now(); - - this->executeTask(); - // Add memory usage later - - auto stop = std::chrono::high_resolution_clock::now(); - auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(stop-start); - result["runtime"] = runtime.count(); - std::string const identifier = this->getTask()->getIdentifier() + "_" + this->getIdentifier(); - result["identifier"] = identifier; - return result; - // what about the Results class? - } + json executeTask() { + json result; + auto start = std::chrono::high_resolution_clock::now(); + + this->executeTask(); + // Add memory usage later + + auto stop = std::chrono::high_resolution_clock::now(); + auto runtime = + std::chrono::duration_cast<std::chrono::microseconds>(stop - start); + result["runtime"] = runtime.count(); + std::string const identifier = + this->getTask()->getIdentifier() + "_" + this->getIdentifier(); + result["identifier"] = identifier; + return result; + // what about the Results class? + } }; -//add adapter for simulators -const std::shared_ptr<Task> &Executor::getTask() const { - return task; -} +// add adapter for simulators +const std::shared_ptr<Task>& Executor::getTask() const { return task; } -void Executor::setTask(const std::shared_ptr<Task> &newTask) { - this->task = newTask; +void Executor::setTask(const std::shared_ptr<Task>& newTask) { + this->task = newTask; } - - - diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp index 7ddfdf6..2d38955 100644 --- a/src/SimulationTask.cpp +++ b/src/SimulationTask.cpp @@ -1,2 +1,2 @@ #include "SimulationTask.hpp" -//take one circuit +// take one circuit diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp index 935567b..9d76be3 100644 --- a/src/VerificationTask.cpp +++ b/src/VerificationTask.cpp @@ -1,2 +1,2 @@ #include "VerificationTask.hpp" -//take two circuits +// take two circuits From 3db7fe5e454464a7d9f8f33b3323e55ec073447c Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 19 May 2023 01:16:32 +0200 Subject: [PATCH 05/43] Refactored executor-task architecture --- include/AlternatingVerificationExecutor.hpp | 5 +++ include/CircuitSimulatorExecutor.hpp | 5 +++ include/Executor.hpp | 11 +++--- include/SimulationExecutor.hpp | 12 +++++++ include/VerificationExecutor.hpp | 12 +++++++ src/AlternatingVerificationExecutor.cpp | 1 + src/CMakeLists.txt | 18 +++++----- src/CircuitSimulatorExecutor.cpp | 1 + src/Executor.cpp | 8 +++-- src/Result.cpp | 38 ++++++++++++++------- src/SimulationExecutor.cpp | 3 ++ src/VerificationExecutor.cpp | 3 ++ 12 files changed, 86 insertions(+), 31 deletions(-) create mode 100644 include/AlternatingVerificationExecutor.hpp create mode 100644 include/CircuitSimulatorExecutor.hpp create mode 100644 include/SimulationExecutor.hpp create mode 100644 include/VerificationExecutor.hpp create mode 100644 src/AlternatingVerificationExecutor.cpp create mode 100644 src/CircuitSimulatorExecutor.cpp create mode 100644 src/SimulationExecutor.cpp create mode 100644 src/VerificationExecutor.cpp diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp new file mode 100644 index 0000000..4fa2263 --- /dev/null +++ b/include/AlternatingVerificationExecutor.hpp @@ -0,0 +1,5 @@ +#pragma once + +#include "VerificationExecutor.hpp" + +class AlternatingVerificationExecutor : public VerificationExecutor {}; diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp new file mode 100644 index 0000000..cc82af1 --- /dev/null +++ b/include/CircuitSimulatorExecutor.hpp @@ -0,0 +1,5 @@ +#pragma once + +#include "SimulationExecutor.hpp" + +class CircuitSimulatorExecutor : public SimulationExecutor {}; diff --git a/include/Executor.hpp b/include/Executor.hpp index d1cd51f..a11eabb 100644 --- a/include/Executor.hpp +++ b/include/Executor.hpp @@ -8,13 +8,10 @@ class Executor { public: virtual ~Executor() = default; virtual json executeTask() = 0; - - const std::shared_ptr<Task>& getTask() const; - - explicit Executor(){}; - - void setTask(const std::shared_ptr<Task>& task); - virtual std::string getIdentifier() = 0; + explicit Executor() = default; + const std::shared_ptr<Task>& getTask(); + void setTask(const std::shared_ptr<Task>& task); + virtual std::string getIdentifier() = 0; private: std::shared_ptr<Task> task; diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp new file mode 100644 index 0000000..f2c3c14 --- /dev/null +++ b/include/SimulationExecutor.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "Executor.hpp" +#include "SimulationTask.hpp" + +class SimulationExecutor : public Executor { +public: + explicit SimulationExecutor(const std::shared_ptr<SimulationTask>& task) { + setTask(task); + }; + json executeTask() override; +}; diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp new file mode 100644 index 0000000..bcfe9a4 --- /dev/null +++ b/include/VerificationExecutor.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "Executor.hpp" +#include "VerificationTask.hpp" + +class VerificationExecutor : public Executor { +public: + explicit VerificationExecutor(const std::shared_ptr<VerificationTask>& task) { + setTask(task); + }; + json executeTask() override; +}; diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp new file mode 100644 index 0000000..d3d1834 --- /dev/null +++ b/src/AlternatingVerificationExecutor.cpp @@ -0,0 +1 @@ +#include "AlternatingVerificationExecutor.hpp" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3c09bdd..e1b6044 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,20 +10,22 @@ if(NOT TARGET ${PROJECT_NAME}) add_library( ${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/include/Executor.hpp - ${PROJECT_SOURCE_DIR}/include/Results.hpp - ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp + ${PROJECT_SOURCE_DIR}/include/SimulationExecutor.hpp + ${PROJECT_SOURCE_DIR}/include/VerificationExecutor.hpp + ${PROJECT_SOURCE_DIR}/include/CircuitSimulatorExecutor.hpp + ${PROJECT_SOURCE_DIR}/include/AlternatingVerificationExecutor.hpp + # ${PROJECT_SOURCE_DIR}/include/Results.hpp ${PROJECT_SOURCE_DIR}/include/Task.hpp + ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp - Result.cpp - SimulationTask.cpp - VerificationTask.cpp + # Result.cpp Executor.cpp + SimulationExecutor.cpp CircuitSimulatorExecutor.cpp - ../include/CircuitSimulatorExecutor.hpp VerificationExecutor.cpp - ../include/VerificationExecutor.hpp AlternatingVerificationExecutor.cpp - ../include/AlternatingVerificationExecutor.hpp) + SimulationTask.cpp + VerificationTask.cpp) # set include directories target_include_directories( diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp new file mode 100644 index 0000000..ce98a6e --- /dev/null +++ b/src/CircuitSimulatorExecutor.cpp @@ -0,0 +1 @@ +#include "CircuitSimulatorExecutor.hpp" diff --git a/src/Executor.cpp b/src/Executor.cpp index f6ea61d..72f865f 100644 --- a/src/Executor.cpp +++ b/src/Executor.cpp @@ -7,8 +7,9 @@ class Executor::Executor { json result; auto start = std::chrono::high_resolution_clock::now(); - this->executeTask(); - // Add memory usage later + // this->executeTask(); + // execute the actual task + // Add memory usage auto stop = std::chrono::high_resolution_clock::now(); auto runtime = @@ -23,8 +24,9 @@ class Executor::Executor { }; // add adapter for simulators -const std::shared_ptr<Task>& Executor::getTask() const { return task; } void Executor::setTask(const std::shared_ptr<Task>& newTask) { this->task = newTask; } + +const std::shared_ptr<Task>& Executor::getTask() { return task; } diff --git a/src/Result.cpp b/src/Result.cpp index a317706..fef28a5 100644 --- a/src/Result.cpp +++ b/src/Result.cpp @@ -1,17 +1,29 @@ +// #include "Result.hpp" + +// Result::Result(const std::string& name, double value) : name_(name), +// value_(value) {} // -// Created by Tianyi Wang on 5/14/23. +// json Result::toJson() const { +// json resultJson; +// resultJson["name"] = name_; +// resultJson["value"] = value_; +// return resultJson; +// } // +// std::string Result::toString() const { +// return toJson().dump(); +// } -#include "../include/Result.hpp" - -Result::Result(const std::string& name, double value) - : name_(name), value_(value) {} - -json Result::toJson() const { - json resultJson; - resultJson["name"] = name_; - resultJson["value"] = value_; - return resultJson; -} +#include "Results.hpp" -std::string Result::toString() const { return toJson().dump(); } +// Results::Results(const std::string& name, double value) +// : name_(name), value_(value) {} +// +// json Result::toJson() const { +// json resultJson; +// resultJson["name"] = name_; +// resultJson["value"] = value_; +// return resultJson; +// } +// +// std::string Result::toString() const { return toJson().dump(); } diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp new file mode 100644 index 0000000..5acc2ab --- /dev/null +++ b/src/SimulationExecutor.cpp @@ -0,0 +1,3 @@ +#include "../include/SimulationExecutor.hpp" + +json SimulationExecutor::executeTask() { return nullptr; } diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp new file mode 100644 index 0000000..de9fcf2 --- /dev/null +++ b/src/VerificationExecutor.cpp @@ -0,0 +1,3 @@ +#include "VerificationExecutor.hpp" + +json VerificationExecutor::executeTask() { return nullptr; } From 4e133831095828a24c8af54080827e245bf4b4ea Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 19 May 2023 01:33:03 +0200 Subject: [PATCH 06/43] Refactored naming --- include/Executor.hpp | 2 +- src/Executor.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Executor.hpp b/include/Executor.hpp index a11eabb..ef5a9ab 100644 --- a/include/Executor.hpp +++ b/include/Executor.hpp @@ -14,5 +14,5 @@ class Executor { virtual std::string getIdentifier() = 0; private: - std::shared_ptr<Task> task; + std::shared_ptr<Task> m_task; }; diff --git a/src/Executor.cpp b/src/Executor.cpp index 72f865f..0d148f3 100644 --- a/src/Executor.cpp +++ b/src/Executor.cpp @@ -25,8 +25,8 @@ class Executor::Executor { // add adapter for simulators -void Executor::setTask(const std::shared_ptr<Task>& newTask) { - this->task = newTask; +void Executor::setTask(const std::shared_ptr<Task>& task) { + this->m_task = task; } -const std::shared_ptr<Task>& Executor::getTask() { return task; } +const std::shared_ptr<Task>& Executor::getTask() { return m_task; } From d602218d67aaab7e54aaa7b1c39810eb806f2cae Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Wed, 24 May 2023 17:08:51 +0200 Subject: [PATCH 07/43] Refactor simulation executor --- include/CircuitSimulatorExecutor.hpp | 6 +++- include/Results.hpp | 46 ++++++++++++++-------------- include/SimulationExecutor.hpp | 2 +- src/CircuitSimulatorExecutor.cpp | 26 ++++++++++++++++ src/SimulationExecutor.cpp | 2 ++ 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp index cc82af1..ff0bba3 100644 --- a/include/CircuitSimulatorExecutor.hpp +++ b/include/CircuitSimulatorExecutor.hpp @@ -2,4 +2,8 @@ #include "SimulationExecutor.hpp" -class CircuitSimulatorExecutor : public SimulationExecutor {}; +class CircuitSimulatorExecutor : public SimulationExecutor { +public: + json executeTask() override; + std::string getIdentifier() override; +}; diff --git a/include/Results.hpp b/include/Results.hpp index 4f74340..56d509a 100644 --- a/include/Results.hpp +++ b/include/Results.hpp @@ -1,23 +1,23 @@ -#pragma once - -#include "Executor.hpp" -#include "Task.hpp" - -#include <nlohmann/json.hpp> - -using json = nlohmann::json; - -class Results { -public: - virtual ~Results() = default; - - virtual json toJson() const = 0; - virtual std::string toString() const { return toJson().dump(2); } - - Results(Task task, Executor executor) { - identifier = task.getIdentifier() + "_" + executor.getIdentifier(); - } - -private: - std::string identifier; -}; +// #pragma once +// +// #include "Executor.hpp" +// #include "Task.hpp" +// +// #include <nlohmann/json.hpp> +// +// using json = nlohmann::json; +// +// class Results { +// public: +// virtual ~Results() = default; +// +// virtual json toJson() const = 0; +// virtual std::string toString() const { return toJson().dump(2); } +// +// Results(Task task, Executor executor) { +// identifier = task.getIdentifier() + "_" + executor.getIdentifier(); +// } +// +// private: +// std::string identifier; +// }; diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp index f2c3c14..2494975 100644 --- a/include/SimulationExecutor.hpp +++ b/include/SimulationExecutor.hpp @@ -7,6 +7,6 @@ class SimulationExecutor : public Executor { public: explicit SimulationExecutor(const std::shared_ptr<SimulationTask>& task) { setTask(task); - }; + } json executeTask() override; }; diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index ce98a6e..3cb3962 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -1 +1,27 @@ #include "CircuitSimulatorExecutor.hpp" + +class CircuitSimulatorExecutor::CircuitSimulatorExecutor {}; + +std::string CircuitSimulatorExecutor::getIdentifier() { + return std::string("This is a circuit simulator executor"); + // refactor +} + +json CircuitSimulatorExecutor::executeTask() { + json result; + auto start = std::chrono::high_resolution_clock::now(); + + // this->executeTask(); + // execute the actual task + // Add memory usage + + auto stop = std::chrono::high_resolution_clock::now(); + auto runtime = + std::chrono::duration_cast<std::chrono::microseconds>(stop - start); + result["runtime"] = runtime.count(); + std::string const identifier = + this->getTask()->getIdentifier() + "_" + this->getIdentifier(); + result["identifier"] = identifier; + return result; + // return SimulationExecutor::executeTask(); +} diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp index 5acc2ab..169b1ae 100644 --- a/src/SimulationExecutor.cpp +++ b/src/SimulationExecutor.cpp @@ -1,3 +1,5 @@ #include "../include/SimulationExecutor.hpp" json SimulationExecutor::executeTask() { return nullptr; } + +// SimulationExecutor::SimulationExecutor() {} From d5000f4efe6684943f5af188fb6a40d01b729ea5 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Thu, 1 Jun 2023 01:01:24 +0200 Subject: [PATCH 08/43] Refactored executor and simulatorexecutor --- include/CircuitSimulatorExecutor.hpp | 30 +++++++++++++ include/Executor.hpp | 9 ++-- include/SimulationExecutor.hpp | 11 ++++- include/SimulationTask.hpp | 14 ++++-- include/VerificationExecutor.hpp | 9 ++-- src/CircuitSimulatorExecutor.cpp | 67 +++++++++++++++++++++++++--- src/Executor.cpp | 51 +++++++++++---------- src/SimulationExecutor.cpp | 12 +++-- src/SimulationTask.cpp | 4 ++ src/VerificationExecutor.cpp | 2 +- test/CMakeLists.txt | 2 +- 11 files changed, 163 insertions(+), 48 deletions(-) diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp index ff0bba3..3449802 100644 --- a/include/CircuitSimulatorExecutor.hpp +++ b/include/CircuitSimulatorExecutor.hpp @@ -1,9 +1,39 @@ #pragma once +#include "CircuitSimulator.hpp" #include "SimulationExecutor.hpp" class CircuitSimulatorExecutor : public SimulationExecutor { public: + CircuitSimulatorExecutor() = default; + + // explicit CircuitSimulatorExecutor(); + // explicit CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> + // &mSimTask); + json executeTask() override; std::string getIdentifier() override; + +private: + std::unique_ptr<SimulationTask> mSimTask; + +public: + [[nodiscard]] const std::unique_ptr<SimulationTask>& getMSimTask() const; + + void setMSimTask(std::unique_ptr<SimulationTask>& simTask); + +private: + std::unique_ptr<CircuitSimulator<>> mCircuitSimulator; + +public: + const std::unique_ptr<CircuitSimulator<>>& getCircuitSimulator(); + + void + setCircuitSimulator(std::unique_ptr<CircuitSimulator<>>& circuitSimulator); + // public: + // [[nodiscard]] const CircuitSimulator<dd::DDPackageConfig> + // &getCircuitSimulator() const; + // + // void setCircuitSimulator(const CircuitSimulator<dd::DDPackageConfig> + // &circuitSimulator); }; diff --git a/include/Executor.hpp b/include/Executor.hpp index ef5a9ab..5775e04 100644 --- a/include/Executor.hpp +++ b/include/Executor.hpp @@ -9,10 +9,11 @@ class Executor { virtual ~Executor() = default; virtual json executeTask() = 0; explicit Executor() = default; - const std::shared_ptr<Task>& getTask(); - void setTask(const std::shared_ptr<Task>& task); - virtual std::string getIdentifier() = 0; + // virtual const std::unique_ptr<Task>& getTask(); + // virtual void setTask(const std::unique_ptr<Task> + // &task); + virtual std::string getIdentifier() = 0; private: - std::shared_ptr<Task> m_task; + std::unique_ptr<Task> mTask; }; diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp index 2494975..822996d 100644 --- a/include/SimulationExecutor.hpp +++ b/include/SimulationExecutor.hpp @@ -5,8 +5,15 @@ class SimulationExecutor : public Executor { public: - explicit SimulationExecutor(const std::shared_ptr<SimulationTask>& task) { + SimulationExecutor() = default; + explicit SimulationExecutor(std::unique_ptr<SimulationTask>& task) { setTask(task); } - json executeTask() override; + + const std::unique_ptr<Task>& getTask(); + + void setTask(std::unique_ptr<SimulationTask>& task); + +private: + std::unique_ptr<SimulationTask> mTask; }; diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp index 6dbd207..efde458 100644 --- a/include/SimulationTask.hpp +++ b/include/SimulationTask.hpp @@ -5,8 +5,16 @@ class SimulationTask : public Task { public: - explicit SimulationTask(qc::QuantumComputation qc) { this->qc = qc.clone(); }; + SimulationTask() = default; -private: - qc::QuantumComputation qc; + explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> qc) + : qc(std::move(qc)) {} + +protected: + std::unique_ptr<qc::QuantumComputation> qc; + +public: + std::unique_ptr<qc::QuantumComputation>& getQc() { return qc; } + + std::string getIdentifier() override; }; diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp index bcfe9a4..ed47c56 100644 --- a/include/VerificationExecutor.hpp +++ b/include/VerificationExecutor.hpp @@ -5,8 +5,9 @@ class VerificationExecutor : public Executor { public: - explicit VerificationExecutor(const std::shared_ptr<VerificationTask>& task) { - setTask(task); - }; - json executeTask() override; + // explicit VerificationExecutor(const std::shared_ptr<VerificationTask>& + // task) { + // setTask(task); + // }; + // json executeTask() override; }; diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 3cb3962..058952d 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -1,27 +1,82 @@ #include "CircuitSimulatorExecutor.hpp" -class CircuitSimulatorExecutor::CircuitSimulatorExecutor {}; +class CircuitSimulatorExecutor::CircuitSimulatorExecutor { + // CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &simTask) { + // setMSimTask(simTask); + // } + // CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &simTask) { + // mSimTask = std::move(simTask); + // } + // CircuitSimulatorExecutor() { + // mCircuitSimulator = + // CircuitSimulator(std::move(this->getMSimTask()->getQc())); + // } +}; std::string CircuitSimulatorExecutor::getIdentifier() { - return std::string("This is a circuit simulator executor"); + return {"This is a circuit simulator executor"}; // refactor } json CircuitSimulatorExecutor::executeTask() { json result; auto start = std::chrono::high_resolution_clock::now(); + std::cout << "I'm here in testa\n"; - // this->executeTask(); // execute the actual task + const auto results = mCircuitSimulator->simulate(1024U); + // std::cout << results << std::endl; + // use the results // Add memory usage auto stop = std::chrono::high_resolution_clock::now(); auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(stop - start); - result["runtime"] = runtime.count(); - std::string const identifier = - this->getTask()->getIdentifier() + "_" + this->getIdentifier(); + result["runtime"] = runtime.count(); + std::string const identifier = "test identifier"; + // this->getTask()->getIdentifier() + "_" + this->getIdentifier(); + std::cout << "I'm here in testc\n"; result["identifier"] = identifier; + + result["00"] = results.count("00"); + result["01"] = results.count("01"); + result["10"] = results.count("10"); + result["11"] = results.count("11"); + // what about more qubits? + std::cout << "I'm here in testd\n"; return result; // return SimulationExecutor::executeTask(); } + +const std::unique_ptr<SimulationTask>& +CircuitSimulatorExecutor::getMSimTask() const { + return mSimTask; +} + +void CircuitSimulatorExecutor::setMSimTask( + std::unique_ptr<SimulationTask>& simTask) { + mSimTask = std::move(simTask); +} + +const std::unique_ptr<CircuitSimulator<>>& +CircuitSimulatorExecutor::getCircuitSimulator() { + return mCircuitSimulator; +} + +void CircuitSimulatorExecutor::setCircuitSimulator( + std::unique_ptr<CircuitSimulator<>>& circuitSimulator) { + mCircuitSimulator = std::move(circuitSimulator); +} + +// CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &mSimTask) +// : SimulationExecutor(task), mSimTask(mSimTask) {} + +// const CircuitSimulator<dd::DDPackageConfig> +// &CircuitSimulatorExecutor::getCircuitSimulator() const { +// return circuitSimulator; +// } +// +// void CircuitSimulatorExecutor::setCircuitSimulator(const +// CircuitSimulator<dd::DDPackageConfig> &circuitSimulator) { +// CircuitSimulatorExecutor::circuitSimulator = circuitSimulator; +// } diff --git a/src/Executor.cpp b/src/Executor.cpp index 0d148f3..2e01da0 100644 --- a/src/Executor.cpp +++ b/src/Executor.cpp @@ -3,30 +3,33 @@ #include <chrono> class Executor::Executor { - json executeTask() { - json result; - auto start = std::chrono::high_resolution_clock::now(); + // json executeTask() { + // json result; + // auto start = std::chrono::high_resolution_clock::now(); + // + // // this->executeTask(); + // // execute the actual task + // // Add memory usage + // + // auto stop = std::chrono::high_resolution_clock::now(); + // auto runtime = + // std::chrono::duration_cast<std::chrono::microseconds>(stop - start); + // result["runtime"] = runtime.count(); + // std::string const identifier = + // this->getTask()->getIdentifier() + "_" + this->getIdentifier(); + // result["identifier"] = identifier; + // return result; + // // what about the Results class? + // json result; + // return result; + // } + //}; - // this->executeTask(); - // execute the actual task - // Add memory usage + // add adapter for simulators - auto stop = std::chrono::high_resolution_clock::now(); - auto runtime = - std::chrono::duration_cast<std::chrono::microseconds>(stop - start); - result["runtime"] = runtime.count(); - std::string const identifier = - this->getTask()->getIdentifier() + "_" + this->getIdentifier(); - result["identifier"] = identifier; - return result; - // what about the Results class? - } + // void Executor::setTask(const std::unique_ptr<Task> &task) { + // this->mTask = task; + // } + // + // const std::unique_ptr<Task>& Executor::getTask() { return mTask; } }; - -// add adapter for simulators - -void Executor::setTask(const std::shared_ptr<Task>& task) { - this->m_task = task; -} - -const std::shared_ptr<Task>& Executor::getTask() { return m_task; } diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp index 169b1ae..d8577d7 100644 --- a/src/SimulationExecutor.cpp +++ b/src/SimulationExecutor.cpp @@ -1,5 +1,11 @@ -#include "../include/SimulationExecutor.hpp" +#include "SimulationExecutor.hpp" -json SimulationExecutor::executeTask() { return nullptr; } +// json SimulationExecutor::executeTask() { return nullptr; } -// SimulationExecutor::SimulationExecutor() {} +const std::unique_ptr<Task>& SimulationExecutor::getTask() { + return std::move(mTask); +} + +void SimulationExecutor::setTask(std::unique_ptr<SimulationTask>& task) { + mTask = std::move(task); +} diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp index 2d38955..0dc1564 100644 --- a/src/SimulationTask.cpp +++ b/src/SimulationTask.cpp @@ -1,2 +1,6 @@ #include "SimulationTask.hpp" // take one circuit +std::string SimulationTask::getIdentifier() { + return "This is a simulation task"; + // refactor +} diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp index de9fcf2..e35f42e 100644 --- a/src/VerificationExecutor.cpp +++ b/src/VerificationExecutor.cpp @@ -1,3 +1,3 @@ #include "VerificationExecutor.hpp" -json VerificationExecutor::executeTask() { return nullptr; } +// json VerificationExecutor::executeTask() { return nullptr; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 70d0463..5415991 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,4 +11,4 @@ if(NOT TARGET gtest OR NOT TARGET gmock) endif() package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp - test_qcec_simple.cpp) + test_qcec_simple.cpp test_sim.cpp) From 0091d357c2bc96af82f1aabd759350fd55ac9af3 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Thu, 1 Jun 2023 01:01:56 +0200 Subject: [PATCH 09/43] Added dummy test (other tests WIP) --- test/circuits.json | 7 ++ test/test_sim.cpp | 294 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 301 insertions(+) create mode 100644 test/circuits.json create mode 100644 test/test_sim.cpp diff --git a/test/circuits.json b/test/circuits.json new file mode 100644 index 0000000..94328ef --- /dev/null +++ b/test/circuits.json @@ -0,0 +1,7 @@ +[ + { + "description": "empty_circuit", + "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[1];\n", + "expected_00": 1024 + } +] diff --git a/test/test_sim.cpp b/test/test_sim.cpp new file mode 100644 index 0000000..f35ee35 --- /dev/null +++ b/test/test_sim.cpp @@ -0,0 +1,294 @@ +#include "CircuitSimulatorExecutor.hpp" +#include "SimulationTask.hpp" + +#include "gtest/gtest.h" + +namespace cs { + +// struct TestConfiguration { +// // given input (either as tableau or as circuit) +// std::string description; +// std::string initialCircuit; +// +// // expected output +// std::size_t expected00{}; +// }; + +// NOLINTNEXTLINE (readability-identifier-naming) +// inline void from_json(const nlohmann::json &j, TestConfiguration &test) { +// test.description = j.at("description").get<std::string>(); +// if (j.contains("initial_circuit")) { +// test.initialCircuit = j.at("initial_circuit").get<std::string>(); +// } +// test.expected00 = j.at("expected_00").get<std::size_t>(); +// +// } + +// static std::vector<TestConfiguration> getTests(const std::string &path) { +// std::ifstream input(path); +// nlohmann::json j; +// input >> j; +// return j; +// } +// : public ::testing::TestWithParam<TestConfiguration> +class SimulatorTest { +protected: + // void SetUp() override { + // test = GetParam(); + // std::cout << "I'm here in setup\n"; + + // if (!test.initialCircuit.empty()) { + // std::stringstream ss(test.initialCircuit); + // qc::QuantumComputation qc{}; + // qc.import(ss, qc::Format::OpenQASM); + // std::cout << "Initial circuit:\n" << qc; + // std::cout << "NQubits:\n" << qc.getNqubits(); + // } + // else { + // throw std::runtime_error("No circuit!"); + // } + // config = Configuration(); + // config.verbosity = plog::Severity::verbose; + // config.dumpIntermediateResults = true; + // } + + // void TearDown() override { + // std::cout << "I'm here in teardown\n"; + // std::cout << "Results:\n" << results << "\n"; + + // resultTableau = synthesizer.getResultTableau(); + // std::cout << "Resulting tableau:\n" << resultTableau; + // EXPECT_EQ(resultTableau, targetTableau); + // EXPECT_EQ(expected00, 1024); + // const auto &resultCircuit = synthesizer.getResultCircuit(); + // std::cout << "Resulting Circuit:\n" << resultCircuit; + // consistencyCheck(resultCircuit); + // } + + // void consistencyCheck(const qc::QuantumComputation &qc) const { + // auto circuitTableau = initialTableau; + // for (const auto &gate: qc) { + // circuitTableau.applyGate(gate.get()); + // } + // EXPECT_EQ(resultTableau, circuitTableau); + // } + + // Tableau initialTableau; + // Tableau initialTableauWithDestabilizer; + // Tableau targetTableau; + // Tableau targetTableauWithDestabilizer; + // Configuration config; + // CliffordSynthesizer synthesizer; + // CliffordSynthesizer synthesizerWithDestabilizer; + // Results results; + // Results resultsWithDestabilizer; + // Tableau resultTableau; + // Tableau resultTableauWithDestabilizer; + // CircuitSimulatorExecutor circuitSimulatorExecutor; + // TestConfiguration test; + // SimulationTask simulationTask; + // json result; +}; + +// INSTANTIATE_TEST_SUITE_P( +// Tableaus, SynthesisTest, +// testing::ValuesIn(getTests("cliffordsynthesis/tableaus.json")), +// [](const testing::TestParamInfo<SynthesisTest::ParamType>& inf) { +// return inf.param.description; +// }); + +// INSTANTIATE_TEST_SUITE_P( +// Circuits, SimulatorTest, +// testing::ValuesIn(getTests("/Users/tianyiwang/Documents/tum/GR/repos/dd_eval/test/circuits.json")), +// [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) { +// return inf.param.description; +// }); + +TEST(SimulatorTest, EmptyCircuit) { + auto qc = std::make_unique<qc::QuantumComputation>(2U); + auto simulationTask = std::make_unique<SimulationTask>(std::move(qc)); + auto circuitSimulator = + std::make_unique<CircuitSimulator<>>(std::move(simulationTask->getQc())); + auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); + circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator); + circuitSimulatorExecutor->setMSimTask(simulationTask); + json const result = circuitSimulatorExecutor->executeTask(); + + EXPECT_EQ(1, result["00"]); +} + +// TEST_P(SynthesisTest, GatesMaxSAT) { +// config.target = TargetMetric::Gates; +// config.useMaxSAT = true; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getGates(), test.expectedMinimalGates); +// } +// +// TEST_P(SynthesisTest, Depth) { +// config.target = TargetMetric::Depth; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); +// } +// +// TEST_P(SynthesisTest, DepthMaxSAT) { +// config.target = TargetMetric::Depth; +// config.useMaxSAT = true; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); +// } +// +// TEST_P(SynthesisTest, DepthMinimalGates) { +// config.target = TargetMetric::Depth; +// config.minimizeGatesAfterDepthOptimization = true; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); +// EXPECT_EQ(results.getGates(), +// test.expectedMinimalGatesAtMinimalDepth); +// } +// +// TEST_P(SynthesisTest, DepthMinimalTimeSteps) { +// config.target = TargetMetric::Depth; +// config.minimalTimesteps = test.expectedMinimalDepth; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); +// } +// +// TEST_P(SynthesisTest, DepthMinimalGatesMaxSAT) { +// config.target = TargetMetric::Depth; +// config.useMaxSAT = true; +// config.minimizeGatesAfterDepthOptimization = true; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); +// EXPECT_EQ(results.getGates(), +// test.expectedMinimalGatesAtMinimalDepth); +// } +// +// TEST_P(SynthesisTest, TwoQubitGates) { +// config.target = TargetMetric::TwoQubitGates; +// config.tryHigherGateLimitForTwoQubitGateOptimization = true; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getTwoQubitGates(), +// test.expectedMinimalTwoQubitGates); +// } +// +// TEST_P(SynthesisTest, TwoQubitGatesMaxSAT) { +// config.target = TargetMetric::TwoQubitGates; +// config.tryHigherGateLimitForTwoQubitGateOptimization = true; +// config.useMaxSAT = true; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getTwoQubitGates(), +// test.expectedMinimalTwoQubitGates); +// } +// +// TEST_P(SynthesisTest, TwoQubitGatesMinimalGates) { +// config.target = TargetMetric::TwoQubitGates; +// config.tryHigherGateLimitForTwoQubitGateOptimization = true; +// config.minimizeGatesAfterTwoQubitGateOptimization = true; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getTwoQubitGates(), +// test.expectedMinimalTwoQubitGates); EXPECT_EQ(results.getGates(), +// test.expectedMinimalGatesAtMinimalTwoQubitGates); +// } +// +// TEST_P(SynthesisTest, TwoQubitGatesMinimalGatesMaxSAT) { +// config.target = TargetMetric::TwoQubitGates; +// config.tryHigherGateLimitForTwoQubitGateOptimization = true; +// config.minimizeGatesAfterTwoQubitGateOptimization = true; +// config.useMaxSAT = true; +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// +// EXPECT_EQ(results.getTwoQubitGates(), +// test.expectedMinimalTwoQubitGates); EXPECT_EQ(results.getGates(), +// test.expectedMinimalGatesAtMinimalTwoQubitGates); +// } +// +// TEST_P(SynthesisTest, TestDestabilizerGates) { +// if (!initialTableauWithDestabilizer.getTableau().empty()) { +// std::cout << "Testing with destabilizer" << std::endl; +// config.target = TargetMetric::Gates; +// config.useMaxSAT = true; +// +// synthesizer.synthesize(config); +// synthesizerWithDestabilizer.synthesize(config); +// results = synthesizer.getResults(); +// resultsWithDestabilizer = +// synthesizerWithDestabilizer.getResults(); +// +// EXPECT_GE(resultsWithDestabilizer.getGates(), results.getGates()); +// } else { +// std::cout << "Testing without destabilizer" << std::endl; +// config.target = TargetMetric::Gates; +// config.useMaxSAT = true; +// +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// } +// } +// +// TEST_P(SynthesisTest, TestDestabilizerDepth) { +// if (!initialTableauWithDestabilizer.getTableau().empty()) { +// std::cout << "Testing with destabilizer" << std::endl; +// config.target = TargetMetric::Depth; +// config.useMaxSAT = true; +// +// synthesizer.synthesize(config); +// synthesizerWithDestabilizer.synthesize(config); +// results = synthesizer.getResults(); +// resultsWithDestabilizer = +// synthesizerWithDestabilizer.getResults(); +// +// EXPECT_GE(resultsWithDestabilizer.getDepth(), results.getDepth()); +// } else { +// std::cout << "Testing without destabilizer" << std::endl; +// config.target = TargetMetric::Gates; +// config.useMaxSAT = true; +// +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// } +// } +// +// TEST_P(SynthesisTest, TestDestabilizerTwoQubitGates) { +// if (!initialTableauWithDestabilizer.getTableau().empty()) { +// std::cout << "Testing with destabilizer" << std::endl; +// config.target = TargetMetric::TwoQubitGates; +// config.useMaxSAT = true; +// +// synthesizer.synthesize(config); +// synthesizerWithDestabilizer.synthesize(config); +// results = synthesizer.getResults(); +// resultsWithDestabilizer = +// synthesizerWithDestabilizer.getResults(); +// +// EXPECT_GE(resultsWithDestabilizer.getTwoQubitGates(), +// results.getTwoQubitGates()); +// } else { +// std::cout << "Testing without destabilizer" << std::endl; +// config.target = TargetMetric::Gates; +// config.useMaxSAT = true; +// +// synthesizer.synthesize(config); +// results = synthesizer.getResults(); +// } +// } + +} // namespace cs From 19883ebcca906b91ae9a67616282bf712bf746e3 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Thu, 1 Jun 2023 20:02:13 +0200 Subject: [PATCH 10/43] Refactored test code to not let the task consume the qc --- src/CircuitSimulatorExecutor.cpp | 3 --- test/test_sim.cpp | 8 ++++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 058952d..6153626 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -21,7 +21,6 @@ std::string CircuitSimulatorExecutor::getIdentifier() { json CircuitSimulatorExecutor::executeTask() { json result; auto start = std::chrono::high_resolution_clock::now(); - std::cout << "I'm here in testa\n"; // execute the actual task const auto results = mCircuitSimulator->simulate(1024U); @@ -35,7 +34,6 @@ json CircuitSimulatorExecutor::executeTask() { result["runtime"] = runtime.count(); std::string const identifier = "test identifier"; // this->getTask()->getIdentifier() + "_" + this->getIdentifier(); - std::cout << "I'm here in testc\n"; result["identifier"] = identifier; result["00"] = results.count("00"); @@ -43,7 +41,6 @@ json CircuitSimulatorExecutor::executeTask() { result["10"] = results.count("10"); result["11"] = results.count("11"); // what about more qubits? - std::cout << "I'm here in testd\n"; return result; // return SimulationExecutor::executeTask(); } diff --git a/test/test_sim.cpp b/test/test_sim.cpp index f35ee35..e52e865 100644 --- a/test/test_sim.cpp +++ b/test/test_sim.cpp @@ -105,10 +105,10 @@ class SimulatorTest { // }); TEST(SimulatorTest, EmptyCircuit) { - auto qc = std::make_unique<qc::QuantumComputation>(2U); - auto simulationTask = std::make_unique<SimulationTask>(std::move(qc)); - auto circuitSimulator = - std::make_unique<CircuitSimulator<>>(std::move(simulationTask->getQc())); + auto qc = std::make_unique<qc::QuantumComputation>(2U); + auto clonedQC = std::make_unique<qc::QuantumComputation>(qc->clone()); + auto simulationTask = std::make_unique<SimulationTask>(std::move(clonedQC)); + auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc)); auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator); circuitSimulatorExecutor->setMSimTask(simulationTask); From 62db93e20611e6dad370e66d3c0d8483bfd14387 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Thu, 1 Jun 2023 20:05:42 +0200 Subject: [PATCH 11/43] Fixed a getter function in SimulationExecutor to address a warning --- include/SimulationExecutor.hpp | 2 +- src/SimulationExecutor.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp index 822996d..09b8587 100644 --- a/include/SimulationExecutor.hpp +++ b/include/SimulationExecutor.hpp @@ -10,7 +10,7 @@ class SimulationExecutor : public Executor { setTask(task); } - const std::unique_ptr<Task>& getTask(); + const std::unique_ptr<SimulationTask>& getMTask(); void setTask(std::unique_ptr<SimulationTask>& task); diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp index d8577d7..73d9c3e 100644 --- a/src/SimulationExecutor.cpp +++ b/src/SimulationExecutor.cpp @@ -2,8 +2,8 @@ // json SimulationExecutor::executeTask() { return nullptr; } -const std::unique_ptr<Task>& SimulationExecutor::getTask() { - return std::move(mTask); +const std::unique_ptr<SimulationTask>& SimulationExecutor::getMTask() { + return mTask; } void SimulationExecutor::setTask(std::unique_ptr<SimulationTask>& task) { From e54c574221ed4ea6d5c09750b83794f8256376e6 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Thu, 1 Jun 2023 21:59:05 +0200 Subject: [PATCH 12/43] Move non-parameterized simple test case to a separate file --- test/CMakeLists.txt | 2 +- test/circuits.json | 4 +- test/test_sim.cpp | 294 ----------------------------------- test/test_simexec_simple.cpp | 19 +++ 4 files changed, 22 insertions(+), 297 deletions(-) delete mode 100644 test/test_sim.cpp create mode 100644 test/test_simexec_simple.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5415991..e464a8d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,4 +11,4 @@ if(NOT TARGET gtest OR NOT TARGET gmock) endif() package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp - test_qcec_simple.cpp test_sim.cpp) + test_qcec_simple.cpp test_simexec_simple.cpp test_simexec.cpp) diff --git a/test/circuits.json b/test/circuits.json index 94328ef..b0e91e3 100644 --- a/test/circuits.json +++ b/test/circuits.json @@ -1,7 +1,7 @@ [ { "description": "empty_circuit", - "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[1];\n", - "expected_00": 1024 + "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n", + "expected_00": 1 } ] diff --git a/test/test_sim.cpp b/test/test_sim.cpp deleted file mode 100644 index e52e865..0000000 --- a/test/test_sim.cpp +++ /dev/null @@ -1,294 +0,0 @@ -#include "CircuitSimulatorExecutor.hpp" -#include "SimulationTask.hpp" - -#include "gtest/gtest.h" - -namespace cs { - -// struct TestConfiguration { -// // given input (either as tableau or as circuit) -// std::string description; -// std::string initialCircuit; -// -// // expected output -// std::size_t expected00{}; -// }; - -// NOLINTNEXTLINE (readability-identifier-naming) -// inline void from_json(const nlohmann::json &j, TestConfiguration &test) { -// test.description = j.at("description").get<std::string>(); -// if (j.contains("initial_circuit")) { -// test.initialCircuit = j.at("initial_circuit").get<std::string>(); -// } -// test.expected00 = j.at("expected_00").get<std::size_t>(); -// -// } - -// static std::vector<TestConfiguration> getTests(const std::string &path) { -// std::ifstream input(path); -// nlohmann::json j; -// input >> j; -// return j; -// } -// : public ::testing::TestWithParam<TestConfiguration> -class SimulatorTest { -protected: - // void SetUp() override { - // test = GetParam(); - // std::cout << "I'm here in setup\n"; - - // if (!test.initialCircuit.empty()) { - // std::stringstream ss(test.initialCircuit); - // qc::QuantumComputation qc{}; - // qc.import(ss, qc::Format::OpenQASM); - // std::cout << "Initial circuit:\n" << qc; - // std::cout << "NQubits:\n" << qc.getNqubits(); - // } - // else { - // throw std::runtime_error("No circuit!"); - // } - // config = Configuration(); - // config.verbosity = plog::Severity::verbose; - // config.dumpIntermediateResults = true; - // } - - // void TearDown() override { - // std::cout << "I'm here in teardown\n"; - // std::cout << "Results:\n" << results << "\n"; - - // resultTableau = synthesizer.getResultTableau(); - // std::cout << "Resulting tableau:\n" << resultTableau; - // EXPECT_EQ(resultTableau, targetTableau); - // EXPECT_EQ(expected00, 1024); - // const auto &resultCircuit = synthesizer.getResultCircuit(); - // std::cout << "Resulting Circuit:\n" << resultCircuit; - // consistencyCheck(resultCircuit); - // } - - // void consistencyCheck(const qc::QuantumComputation &qc) const { - // auto circuitTableau = initialTableau; - // for (const auto &gate: qc) { - // circuitTableau.applyGate(gate.get()); - // } - // EXPECT_EQ(resultTableau, circuitTableau); - // } - - // Tableau initialTableau; - // Tableau initialTableauWithDestabilizer; - // Tableau targetTableau; - // Tableau targetTableauWithDestabilizer; - // Configuration config; - // CliffordSynthesizer synthesizer; - // CliffordSynthesizer synthesizerWithDestabilizer; - // Results results; - // Results resultsWithDestabilizer; - // Tableau resultTableau; - // Tableau resultTableauWithDestabilizer; - // CircuitSimulatorExecutor circuitSimulatorExecutor; - // TestConfiguration test; - // SimulationTask simulationTask; - // json result; -}; - -// INSTANTIATE_TEST_SUITE_P( -// Tableaus, SynthesisTest, -// testing::ValuesIn(getTests("cliffordsynthesis/tableaus.json")), -// [](const testing::TestParamInfo<SynthesisTest::ParamType>& inf) { -// return inf.param.description; -// }); - -// INSTANTIATE_TEST_SUITE_P( -// Circuits, SimulatorTest, -// testing::ValuesIn(getTests("/Users/tianyiwang/Documents/tum/GR/repos/dd_eval/test/circuits.json")), -// [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) { -// return inf.param.description; -// }); - -TEST(SimulatorTest, EmptyCircuit) { - auto qc = std::make_unique<qc::QuantumComputation>(2U); - auto clonedQC = std::make_unique<qc::QuantumComputation>(qc->clone()); - auto simulationTask = std::make_unique<SimulationTask>(std::move(clonedQC)); - auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc)); - auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); - circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator); - circuitSimulatorExecutor->setMSimTask(simulationTask); - json const result = circuitSimulatorExecutor->executeTask(); - - EXPECT_EQ(1, result["00"]); -} - -// TEST_P(SynthesisTest, GatesMaxSAT) { -// config.target = TargetMetric::Gates; -// config.useMaxSAT = true; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getGates(), test.expectedMinimalGates); -// } -// -// TEST_P(SynthesisTest, Depth) { -// config.target = TargetMetric::Depth; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); -// } -// -// TEST_P(SynthesisTest, DepthMaxSAT) { -// config.target = TargetMetric::Depth; -// config.useMaxSAT = true; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); -// } -// -// TEST_P(SynthesisTest, DepthMinimalGates) { -// config.target = TargetMetric::Depth; -// config.minimizeGatesAfterDepthOptimization = true; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); -// EXPECT_EQ(results.getGates(), -// test.expectedMinimalGatesAtMinimalDepth); -// } -// -// TEST_P(SynthesisTest, DepthMinimalTimeSteps) { -// config.target = TargetMetric::Depth; -// config.minimalTimesteps = test.expectedMinimalDepth; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); -// } -// -// TEST_P(SynthesisTest, DepthMinimalGatesMaxSAT) { -// config.target = TargetMetric::Depth; -// config.useMaxSAT = true; -// config.minimizeGatesAfterDepthOptimization = true; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth); -// EXPECT_EQ(results.getGates(), -// test.expectedMinimalGatesAtMinimalDepth); -// } -// -// TEST_P(SynthesisTest, TwoQubitGates) { -// config.target = TargetMetric::TwoQubitGates; -// config.tryHigherGateLimitForTwoQubitGateOptimization = true; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getTwoQubitGates(), -// test.expectedMinimalTwoQubitGates); -// } -// -// TEST_P(SynthesisTest, TwoQubitGatesMaxSAT) { -// config.target = TargetMetric::TwoQubitGates; -// config.tryHigherGateLimitForTwoQubitGateOptimization = true; -// config.useMaxSAT = true; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getTwoQubitGates(), -// test.expectedMinimalTwoQubitGates); -// } -// -// TEST_P(SynthesisTest, TwoQubitGatesMinimalGates) { -// config.target = TargetMetric::TwoQubitGates; -// config.tryHigherGateLimitForTwoQubitGateOptimization = true; -// config.minimizeGatesAfterTwoQubitGateOptimization = true; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getTwoQubitGates(), -// test.expectedMinimalTwoQubitGates); EXPECT_EQ(results.getGates(), -// test.expectedMinimalGatesAtMinimalTwoQubitGates); -// } -// -// TEST_P(SynthesisTest, TwoQubitGatesMinimalGatesMaxSAT) { -// config.target = TargetMetric::TwoQubitGates; -// config.tryHigherGateLimitForTwoQubitGateOptimization = true; -// config.minimizeGatesAfterTwoQubitGateOptimization = true; -// config.useMaxSAT = true; -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// -// EXPECT_EQ(results.getTwoQubitGates(), -// test.expectedMinimalTwoQubitGates); EXPECT_EQ(results.getGates(), -// test.expectedMinimalGatesAtMinimalTwoQubitGates); -// } -// -// TEST_P(SynthesisTest, TestDestabilizerGates) { -// if (!initialTableauWithDestabilizer.getTableau().empty()) { -// std::cout << "Testing with destabilizer" << std::endl; -// config.target = TargetMetric::Gates; -// config.useMaxSAT = true; -// -// synthesizer.synthesize(config); -// synthesizerWithDestabilizer.synthesize(config); -// results = synthesizer.getResults(); -// resultsWithDestabilizer = -// synthesizerWithDestabilizer.getResults(); -// -// EXPECT_GE(resultsWithDestabilizer.getGates(), results.getGates()); -// } else { -// std::cout << "Testing without destabilizer" << std::endl; -// config.target = TargetMetric::Gates; -// config.useMaxSAT = true; -// -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// } -// } -// -// TEST_P(SynthesisTest, TestDestabilizerDepth) { -// if (!initialTableauWithDestabilizer.getTableau().empty()) { -// std::cout << "Testing with destabilizer" << std::endl; -// config.target = TargetMetric::Depth; -// config.useMaxSAT = true; -// -// synthesizer.synthesize(config); -// synthesizerWithDestabilizer.synthesize(config); -// results = synthesizer.getResults(); -// resultsWithDestabilizer = -// synthesizerWithDestabilizer.getResults(); -// -// EXPECT_GE(resultsWithDestabilizer.getDepth(), results.getDepth()); -// } else { -// std::cout << "Testing without destabilizer" << std::endl; -// config.target = TargetMetric::Gates; -// config.useMaxSAT = true; -// -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// } -// } -// -// TEST_P(SynthesisTest, TestDestabilizerTwoQubitGates) { -// if (!initialTableauWithDestabilizer.getTableau().empty()) { -// std::cout << "Testing with destabilizer" << std::endl; -// config.target = TargetMetric::TwoQubitGates; -// config.useMaxSAT = true; -// -// synthesizer.synthesize(config); -// synthesizerWithDestabilizer.synthesize(config); -// results = synthesizer.getResults(); -// resultsWithDestabilizer = -// synthesizerWithDestabilizer.getResults(); -// -// EXPECT_GE(resultsWithDestabilizer.getTwoQubitGates(), -// results.getTwoQubitGates()); -// } else { -// std::cout << "Testing without destabilizer" << std::endl; -// config.target = TargetMetric::Gates; -// config.useMaxSAT = true; -// -// synthesizer.synthesize(config); -// results = synthesizer.getResults(); -// } -// } - -} // namespace cs diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp new file mode 100644 index 0000000..bfeab3f --- /dev/null +++ b/test/test_simexec_simple.cpp @@ -0,0 +1,19 @@ +#include "CircuitSimulator.hpp" +#include "CircuitSimulatorExecutor.hpp" +#include "SimulationTask.hpp" + +#include <gtest/gtest.h> +#include <memory> + +TEST(DDSIMExecSimpleTest, EmptyCircuit) { + auto qc = std::make_unique<qc::QuantumComputation>(2U); + auto clonedQC = std::make_unique<qc::QuantumComputation>(qc->clone()); + auto simulationTask = std::make_unique<SimulationTask>(std::move(clonedQC)); + auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc)); + auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); + circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator); + circuitSimulatorExecutor->setMSimTask(simulationTask); + json const result = circuitSimulatorExecutor->executeTask(); + + EXPECT_EQ(1, result["00"]); +} From 791147757cdcd3ae006d04d1d07f407fd392ef06 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Thu, 1 Jun 2023 22:12:40 +0200 Subject: [PATCH 13/43] Clean up the test suite for SimulatorExecutors --- test/test_simexec.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test/test_simexec.cpp diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp new file mode 100644 index 0000000..ea6bd4e --- /dev/null +++ b/test/test_simexec.cpp @@ -0,0 +1,73 @@ +#include "CircuitSimulatorExecutor.hpp" +#include "SimulationTask.hpp" + +#include "gtest/gtest.h" + +struct TestConfiguration { + // given input + std::string description; + std::string initialCircuit; + + // expected output + std::size_t expected00{}; +}; + +// NOLINTNEXTLINE (readability-identifier-naming) +inline void from_json(const nlohmann::json& j, TestConfiguration& test) { + test.description = j.at("description").get<std::string>(); + test.initialCircuit = j.at("initial_circuit").get<std::string>(); + test.expected00 = j.at("expected_00").get<std::size_t>(); +} + +static std::vector<TestConfiguration> getTests(const std::string& path) { + std::ifstream input(path); + nlohmann::json j; + input >> j; + return j; +} + +class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> { +protected: + void SetUp() override { + test = GetParam(); + + if (test.initialCircuit.empty()) { + throw std::runtime_error("No circuit!"); + } + std::stringstream ss(test.initialCircuit); + qc::QuantumComputation qc{}; + qc.import(ss, qc::Format::OpenQASM); + std::cout << "Initial circuit:\n" << qc; + + qcForTask = std::make_unique<qc::QuantumComputation>(qc.clone()); + qcForSim = std::make_unique<qc::QuantumComputation>(qc.clone()); + simulationTask = std::make_unique<SimulationTask>(std::move(qcForTask)); + circuitSimulator = + std::make_unique<CircuitSimulator<>>(std::move(qcForSim)); + circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); + circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator); + circuitSimulatorExecutor->setMSimTask(simulationTask); + } + + void TearDown() override { std::cout << "Tearing down...\n"; } + + std::unique_ptr<qc::QuantumComputation> qcForTask; + std::unique_ptr<qc::QuantumComputation> qcForSim; + std::unique_ptr<SimulationTask> simulationTask; + std::unique_ptr<CircuitSimulator<>> circuitSimulator; + std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor; + TestConfiguration test; +}; + +INSTANTIATE_TEST_SUITE_P( + Circuits, SimulatorTest, + testing::ValuesIn(getTests( + "/Users/tianyiwang/Documents/tum/GR/repos/dd_eval/test/circuits.json")), + [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) { + return inf.param.description; + }); + +TEST_P(SimulatorTest, EmptyCircuit) { + json const result = circuitSimulatorExecutor->executeTask(); + EXPECT_EQ(result["00"], test.expected00); +} From 032226e2783a98425cd9feaa09c39f250d2f0d5a Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 13:58:10 +0200 Subject: [PATCH 14/43] Remove redundant comments --- include/CircuitSimulatorExecutor.hpp | 11 +-------- include/Executor.hpp | 12 ++++------ include/SimulationExecutor.hpp | 3 --- src/CMakeLists.txt | 3 --- src/CircuitSimulatorExecutor.cpp | 32 +++---------------------- src/Executor.cpp | 35 ---------------------------- src/SimulationExecutor.cpp | 2 -- src/SimulationTask.cpp | 3 ++- 8 files changed, 11 insertions(+), 90 deletions(-) delete mode 100644 src/Executor.cpp diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp index 3449802..a9ab970 100644 --- a/include/CircuitSimulatorExecutor.hpp +++ b/include/CircuitSimulatorExecutor.hpp @@ -6,10 +6,7 @@ class CircuitSimulatorExecutor : public SimulationExecutor { public: CircuitSimulatorExecutor() = default; - - // explicit CircuitSimulatorExecutor(); - // explicit CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> - // &mSimTask); + // simulator and task must be set before use json executeTask() override; std::string getIdentifier() override; @@ -30,10 +27,4 @@ class CircuitSimulatorExecutor : public SimulationExecutor { void setCircuitSimulator(std::unique_ptr<CircuitSimulator<>>& circuitSimulator); - // public: - // [[nodiscard]] const CircuitSimulator<dd::DDPackageConfig> - // &getCircuitSimulator() const; - // - // void setCircuitSimulator(const CircuitSimulator<dd::DDPackageConfig> - // &circuitSimulator); }; diff --git a/include/Executor.hpp b/include/Executor.hpp index 5775e04..5042bcd 100644 --- a/include/Executor.hpp +++ b/include/Executor.hpp @@ -6,14 +6,12 @@ class Executor { public: - virtual ~Executor() = default; - virtual json executeTask() = 0; - explicit Executor() = default; - // virtual const std::unique_ptr<Task>& getTask(); - // virtual void setTask(const std::unique_ptr<Task> - // &task); + virtual ~Executor() = default; + explicit Executor() = default; + + virtual json executeTask() = 0; virtual std::string getIdentifier() = 0; private: - std::unique_ptr<Task> mTask; + std::unique_ptr<Task> task; }; diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp index 09b8587..38cffdc 100644 --- a/include/SimulationExecutor.hpp +++ b/include/SimulationExecutor.hpp @@ -6,9 +6,6 @@ class SimulationExecutor : public Executor { public: SimulationExecutor() = default; - explicit SimulationExecutor(std::unique_ptr<SimulationTask>& task) { - setTask(task); - } const std::unique_ptr<SimulationTask>& getMTask(); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e1b6044..a113869 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,12 +14,9 @@ if(NOT TARGET ${PROJECT_NAME}) ${PROJECT_SOURCE_DIR}/include/VerificationExecutor.hpp ${PROJECT_SOURCE_DIR}/include/CircuitSimulatorExecutor.hpp ${PROJECT_SOURCE_DIR}/include/AlternatingVerificationExecutor.hpp - # ${PROJECT_SOURCE_DIR}/include/Results.hpp ${PROJECT_SOURCE_DIR}/include/Task.hpp ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp - # Result.cpp - Executor.cpp SimulationExecutor.cpp CircuitSimulatorExecutor.cpp VerificationExecutor.cpp diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 6153626..1e11f5c 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -1,21 +1,10 @@ #include "CircuitSimulatorExecutor.hpp" -class CircuitSimulatorExecutor::CircuitSimulatorExecutor { - // CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &simTask) { - // setMSimTask(simTask); - // } - // CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &simTask) { - // mSimTask = std::move(simTask); - // } - // CircuitSimulatorExecutor() { - // mCircuitSimulator = - // CircuitSimulator(std::move(this->getMSimTask()->getQc())); - // } -}; +class CircuitSimulatorExecutor::CircuitSimulatorExecutor {}; std::string CircuitSimulatorExecutor::getIdentifier() { return {"This is a circuit simulator executor"}; - // refactor + // refactor. how? } json CircuitSimulatorExecutor::executeTask() { @@ -24,7 +13,6 @@ json CircuitSimulatorExecutor::executeTask() { // execute the actual task const auto results = mCircuitSimulator->simulate(1024U); - // std::cout << results << std::endl; // use the results // Add memory usage @@ -40,9 +28,8 @@ json CircuitSimulatorExecutor::executeTask() { result["01"] = results.count("01"); result["10"] = results.count("10"); result["11"] = results.count("11"); - // what about more qubits? + // what about circuits with not 2 qubits? return result; - // return SimulationExecutor::executeTask(); } const std::unique_ptr<SimulationTask>& @@ -64,16 +51,3 @@ void CircuitSimulatorExecutor::setCircuitSimulator( std::unique_ptr<CircuitSimulator<>>& circuitSimulator) { mCircuitSimulator = std::move(circuitSimulator); } - -// CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &mSimTask) -// : SimulationExecutor(task), mSimTask(mSimTask) {} - -// const CircuitSimulator<dd::DDPackageConfig> -// &CircuitSimulatorExecutor::getCircuitSimulator() const { -// return circuitSimulator; -// } -// -// void CircuitSimulatorExecutor::setCircuitSimulator(const -// CircuitSimulator<dd::DDPackageConfig> &circuitSimulator) { -// CircuitSimulatorExecutor::circuitSimulator = circuitSimulator; -// } diff --git a/src/Executor.cpp b/src/Executor.cpp deleted file mode 100644 index 2e01da0..0000000 --- a/src/Executor.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "Executor.hpp" - -#include <chrono> - -class Executor::Executor { - // json executeTask() { - // json result; - // auto start = std::chrono::high_resolution_clock::now(); - // - // // this->executeTask(); - // // execute the actual task - // // Add memory usage - // - // auto stop = std::chrono::high_resolution_clock::now(); - // auto runtime = - // std::chrono::duration_cast<std::chrono::microseconds>(stop - start); - // result["runtime"] = runtime.count(); - // std::string const identifier = - // this->getTask()->getIdentifier() + "_" + this->getIdentifier(); - // result["identifier"] = identifier; - // return result; - // // what about the Results class? - // json result; - // return result; - // } - //}; - - // add adapter for simulators - - // void Executor::setTask(const std::unique_ptr<Task> &task) { - // this->mTask = task; - // } - // - // const std::unique_ptr<Task>& Executor::getTask() { return mTask; } -}; diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp index 73d9c3e..6371eb4 100644 --- a/src/SimulationExecutor.cpp +++ b/src/SimulationExecutor.cpp @@ -1,7 +1,5 @@ #include "SimulationExecutor.hpp" -// json SimulationExecutor::executeTask() { return nullptr; } - const std::unique_ptr<SimulationTask>& SimulationExecutor::getMTask() { return mTask; } diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp index 0dc1564..fa6fa33 100644 --- a/src/SimulationTask.cpp +++ b/src/SimulationTask.cpp @@ -1,6 +1,7 @@ #include "SimulationTask.hpp" // take one circuit + std::string SimulationTask::getIdentifier() { return "This is a simulation task"; - // refactor + // refactor. how? } From 60c8c090d881f7db072f41a70e8912e2912e27e2 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 14:25:38 +0200 Subject: [PATCH 15/43] Replace absolute path with relative path --- test/CMakeLists.txt | 3 ++- test/test_simexec.cpp | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e464a8d..92f6c5d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,6 +9,7 @@ if(NOT TARGET gtest OR NOT TARGET gmock) add_subdirectory("${PROJECT_SOURCE_DIR}/${GTEST_PATH}" "${GTEST_PATH}" EXCLUDE_FROM_ALL) endif() - +configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json + ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY) package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp test_qcec_simple.cpp test_simexec_simple.cpp test_simexec.cpp) diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index ea6bd4e..b889181 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -60,9 +60,7 @@ class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> { }; INSTANTIATE_TEST_SUITE_P( - Circuits, SimulatorTest, - testing::ValuesIn(getTests( - "/Users/tianyiwang/Documents/tum/GR/repos/dd_eval/test/circuits.json")), + Circuits, SimulatorTest, testing::ValuesIn(getTests("circuits.json")), [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) { return inf.param.description; }); From 30350b2e2239c05bd493e20dbc93409f5baf625c Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 14:26:09 +0200 Subject: [PATCH 16/43] Refactor the results json --- src/CircuitSimulatorExecutor.cpp | 21 +++++++++++---------- test/circuits.json | 2 +- test/test_simexec.cpp | 12 +++++++++++- test/test_simexec_simple.cpp | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 1e11f5c..53988ff 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -7,28 +7,29 @@ std::string CircuitSimulatorExecutor::getIdentifier() { // refactor. how? } +template <typename KTy, typename VTy> +inline void toJson(json& j, const std::map<KTy, VTy>& m) { + for (const auto& entry : m) { + j[entry.first] = entry.second; + } +} + json CircuitSimulatorExecutor::executeTask() { json result; auto start = std::chrono::high_resolution_clock::now(); - // execute the actual task const auto results = mCircuitSimulator->simulate(1024U); - // use the results + toJson(result, results); // Add memory usage auto stop = std::chrono::high_resolution_clock::now(); auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(stop - start); - result["runtime"] = runtime.count(); - std::string const identifier = "test identifier"; - // this->getTask()->getIdentifier() + "_" + this->getIdentifier(); + result["runtime"] = runtime.count(); + std::string const identifier = + this->getMSimTask()->getIdentifier() + "_" + this->getIdentifier(); result["identifier"] = identifier; - result["00"] = results.count("00"); - result["01"] = results.count("01"); - result["10"] = results.count("10"); - result["11"] = results.count("11"); - // what about circuits with not 2 qubits? return result; } diff --git a/test/circuits.json b/test/circuits.json index b0e91e3..dac448d 100644 --- a/test/circuits.json +++ b/test/circuits.json @@ -2,6 +2,6 @@ { "description": "empty_circuit", "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n", - "expected_00": 1 + "expected_00": 1024 } ] diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index b889181..2181cb7 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -37,7 +37,7 @@ class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> { std::stringstream ss(test.initialCircuit); qc::QuantumComputation qc{}; qc.import(ss, qc::Format::OpenQASM); - std::cout << "Initial circuit:\n" << qc; + std::cout << "Circuit:\n" << qc; qcForTask = std::make_unique<qc::QuantumComputation>(qc.clone()); qcForSim = std::make_unique<qc::QuantumComputation>(qc.clone()); @@ -59,6 +59,14 @@ class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> { TestConfiguration test; }; +void printAll(const json& jsonObject) { + for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) { + const auto& key = it.key(); + const auto& value = it.value(); + std::cout << key << ": " << value << std::endl; + } +} + INSTANTIATE_TEST_SUITE_P( Circuits, SimulatorTest, testing::ValuesIn(getTests("circuits.json")), [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) { @@ -67,5 +75,7 @@ INSTANTIATE_TEST_SUITE_P( TEST_P(SimulatorTest, EmptyCircuit) { json const result = circuitSimulatorExecutor->executeTask(); + std::cout << "Results:" << std::endl; + printAll(result); EXPECT_EQ(result["00"], test.expected00); } diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp index bfeab3f..5b5dfad 100644 --- a/test/test_simexec_simple.cpp +++ b/test/test_simexec_simple.cpp @@ -15,5 +15,5 @@ TEST(DDSIMExecSimpleTest, EmptyCircuit) { circuitSimulatorExecutor->setMSimTask(simulationTask); json const result = circuitSimulatorExecutor->executeTask(); - EXPECT_EQ(1, result["00"]); + EXPECT_EQ(1024, result["00"]); } From d03e6617d42721ad3a393b6f90114aa94671b7ca Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 15:14:16 +0200 Subject: [PATCH 17/43] Added verification executor classes and a simple test --- include/AlternatingVerificationExecutor.hpp | 29 ++++++++++++- include/VerificationExecutor.hpp | 14 ++++--- include/VerificationTask.hpp | 15 +++---- src/AlternatingVerificationExecutor.cpp | 46 +++++++++++++++++++++ src/SimulationTask.cpp | 1 - src/VerificationExecutor.cpp | 9 +++- src/VerificationTask.cpp | 6 ++- test/CMakeLists.txt | 10 ++++- test/test_qcecexec_simple.cpp | 26 ++++++++++++ 9 files changed, 138 insertions(+), 18 deletions(-) create mode 100644 test/test_qcecexec_simple.cpp diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp index 4fa2263..d93f83b 100644 --- a/include/AlternatingVerificationExecutor.hpp +++ b/include/AlternatingVerificationExecutor.hpp @@ -1,5 +1,32 @@ #pragma once +#include "EquivalenceCheckingManager.hpp" #include "VerificationExecutor.hpp" -class AlternatingVerificationExecutor : public VerificationExecutor {}; +class AlternatingVerificationExecutor : public VerificationExecutor { +public: + AlternatingVerificationExecutor() = default; + // checker and task must be set before use + + json executeTask() override; + std::string getIdentifier() override; + +private: + std::unique_ptr<VerificationTask> mVerTask; + +public: + [[nodiscard]] const std::unique_ptr<VerificationTask>& getMVerTask() const; + + void setMVerTask(std::unique_ptr<VerificationTask>& verTask); + +private: + std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager; + +public: + const std::unique_ptr<ec::EquivalenceCheckingManager>& + getEquivalenceCheckingManager(); + + void + setEquivalenceCheckingManager(std::unique_ptr<ec::EquivalenceCheckingManager>& + equivalenceCheckingManager); +}; diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp index ed47c56..1f2f612 100644 --- a/include/VerificationExecutor.hpp +++ b/include/VerificationExecutor.hpp @@ -5,9 +5,13 @@ class VerificationExecutor : public Executor { public: - // explicit VerificationExecutor(const std::shared_ptr<VerificationTask>& - // task) { - // setTask(task); - // }; - // json executeTask() override; + VerificationExecutor() = default; + +private: + std::unique_ptr<VerificationTask> mTask; + +public: + const std::unique_ptr<VerificationTask>& getMTask() const; + + void setMTask(std::unique_ptr<VerificationTask>& task); }; diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp index 795362a..4032287 100644 --- a/include/VerificationTask.hpp +++ b/include/VerificationTask.hpp @@ -5,12 +5,13 @@ class VerificationTask : public Task { public: - VerificationTask(qc::QuantumComputation qc1, qc::QuantumComputation qc2) { - this->qc1 = qc1.clone(); - this->qc2 = qc2.clone(); - }; + VerificationTask() = default; + VerificationTask(std::unique_ptr<qc::QuantumComputation> qc1, + std::unique_ptr<qc::QuantumComputation> qc2) + : qc1(std::move(qc1)), qc2(std::move(qc2)) {} + std::string getIdentifier() override; -private: - qc::QuantumComputation qc1; - qc::QuantumComputation qc2; +protected: + std::unique_ptr<qc::QuantumComputation> qc1; + std::unique_ptr<qc::QuantumComputation> qc2; }; diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp index d3d1834..1077342 100644 --- a/src/AlternatingVerificationExecutor.cpp +++ b/src/AlternatingVerificationExecutor.cpp @@ -1 +1,47 @@ #include "AlternatingVerificationExecutor.hpp" + +class AlternatingVerificationExecutor::AlternatingVerificationExecutor {}; + +std::string AlternatingVerificationExecutor::getIdentifier() { + return {"This is a alternating verification executor"}; + // refactor. how? +} + +json AlternatingVerificationExecutor::executeTask() { + json result; + auto start = std::chrono::high_resolution_clock::now(); + + mEquivalenceCheckingManager->run(); + result = mEquivalenceCheckingManager->getResults().json(); + // Add memory usage + auto stop = std::chrono::high_resolution_clock::now(); + auto runtime = + std::chrono::duration_cast<std::chrono::microseconds>(stop - start); + result["runtime"] = runtime.count(); + std::string const identifier = + this->getMVerTask()->getIdentifier() + "_" + this->getIdentifier(); + result["identifier"] = identifier; + + return result; +} + +const std::unique_ptr<VerificationTask>& +AlternatingVerificationExecutor::getMVerTask() const { + return mVerTask; +} + +void AlternatingVerificationExecutor::setMVerTask( + std::unique_ptr<VerificationTask>& verTask) { + mVerTask = std::move(verTask); +} + +const std::unique_ptr<ec::EquivalenceCheckingManager>& +AlternatingVerificationExecutor::getEquivalenceCheckingManager() { + return mEquivalenceCheckingManager; +} + +void AlternatingVerificationExecutor::setEquivalenceCheckingManager( + std::unique_ptr<ec::EquivalenceCheckingManager>& + equivalenceCheckingManager) { + mEquivalenceCheckingManager = std::move(equivalenceCheckingManager); +} diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp index fa6fa33..27db4c2 100644 --- a/src/SimulationTask.cpp +++ b/src/SimulationTask.cpp @@ -1,5 +1,4 @@ #include "SimulationTask.hpp" -// take one circuit std::string SimulationTask::getIdentifier() { return "This is a simulation task"; diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp index e35f42e..596852b 100644 --- a/src/VerificationExecutor.cpp +++ b/src/VerificationExecutor.cpp @@ -1,3 +1,10 @@ #include "VerificationExecutor.hpp" -// json VerificationExecutor::executeTask() { return nullptr; } +const std::unique_ptr<VerificationTask>& +VerificationExecutor::getMTask() const { + return mTask; +} + +void VerificationExecutor::setMTask(std::unique_ptr<VerificationTask>& task) { + mTask = std::move(task); +} diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp index 9d76be3..bf4c744 100644 --- a/src/VerificationTask.cpp +++ b/src/VerificationTask.cpp @@ -1,2 +1,6 @@ #include "VerificationTask.hpp" -// take two circuits + +std::string VerificationTask::getIdentifier() { + return "This is a verification task"; + // refactor. how? +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 92f6c5d..e1a6cfc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,5 +11,11 @@ if(NOT TARGET gtest OR NOT TARGET gmock) endif() configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY) -package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp - test_qcec_simple.cpp test_simexec_simple.cpp test_simexec.cpp) +package_add_test( + ${PROJECT_NAME}_test + ${PROJECT_NAME} + test_ddsim_simple.cpp + test_qcec_simple.cpp + test_simexec_simple.cpp + test_simexec.cpp + test_qcecexec_simple.cpp) diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp new file mode 100644 index 0000000..d365d20 --- /dev/null +++ b/test/test_qcecexec_simple.cpp @@ -0,0 +1,26 @@ +#include "AlternatingVerificationExecutor.hpp" +#include "EquivalenceCheckingManager.hpp" +#include "VerificationTask.hpp" + +#include <gtest/gtest.h> +#include <memory> + +TEST(QCECExecSimpleTest, EmptyCircuits) { + auto qc = std::make_unique<qc::QuantumComputation>(2U); + auto clonedQC = std::make_unique<qc::QuantumComputation>(qc->clone()); + auto clonedQC2 = qc->clone(); + auto clonedQC3 = qc->clone(); + auto verificationTask = + std::make_unique<VerificationTask>(std::move(qc), std::move(clonedQC)); + auto equivalenceCheckingManager = + std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3); + auto alternatingVerificationExecutor = + std::make_unique<AlternatingVerificationExecutor>(); + alternatingVerificationExecutor->setMVerTask(verificationTask); + alternatingVerificationExecutor->setEquivalenceCheckingManager( + equivalenceCheckingManager); + + json const result = alternatingVerificationExecutor->executeTask(); + + EXPECT_EQ("equivalent", result["equivalence"]); +} From 2f7032dd45e92d192509b60fdcbc40b8b96fb18f Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 16:10:34 +0200 Subject: [PATCH 18/43] Delete temporarily obsolete Results class --- include/Results.hpp | 23 ----------------------- src/Result.cpp | 29 ----------------------------- 2 files changed, 52 deletions(-) delete mode 100644 include/Results.hpp delete mode 100644 src/Result.cpp diff --git a/include/Results.hpp b/include/Results.hpp deleted file mode 100644 index 56d509a..0000000 --- a/include/Results.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// #pragma once -// -// #include "Executor.hpp" -// #include "Task.hpp" -// -// #include <nlohmann/json.hpp> -// -// using json = nlohmann::json; -// -// class Results { -// public: -// virtual ~Results() = default; -// -// virtual json toJson() const = 0; -// virtual std::string toString() const { return toJson().dump(2); } -// -// Results(Task task, Executor executor) { -// identifier = task.getIdentifier() + "_" + executor.getIdentifier(); -// } -// -// private: -// std::string identifier; -// }; diff --git a/src/Result.cpp b/src/Result.cpp deleted file mode 100644 index fef28a5..0000000 --- a/src/Result.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// #include "Result.hpp" - -// Result::Result(const std::string& name, double value) : name_(name), -// value_(value) {} -// -// json Result::toJson() const { -// json resultJson; -// resultJson["name"] = name_; -// resultJson["value"] = value_; -// return resultJson; -// } -// -// std::string Result::toString() const { -// return toJson().dump(); -// } - -#include "Results.hpp" - -// Results::Results(const std::string& name, double value) -// : name_(name), value_(value) {} -// -// json Result::toJson() const { -// json resultJson; -// resultJson["name"] = name_; -// resultJson["value"] = value_; -// return resultJson; -// } -// -// std::string Result::toString() const { return toJson().dump(); } From ed137ab6422d3e1c5820e9e3bc14bb3982dcad12 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 16:11:25 +0200 Subject: [PATCH 19/43] Add qcec tests (incl. refactoring ddsim tests to avoid name collisions) --- include/TestHelpers.hpp | 5 +++ src/CMakeLists.txt | 2 + src/TestHelpers.cpp | 11 ++++++ test/CMakeLists.txt | 5 ++- test/equi_circuits.json | 8 ++++ test/test_qcecexec.cpp | 86 +++++++++++++++++++++++++++++++++++++++++ test/test_simexec.cpp | 25 +++++------- 7 files changed, 125 insertions(+), 17 deletions(-) create mode 100644 include/TestHelpers.hpp create mode 100644 src/TestHelpers.cpp create mode 100644 test/equi_circuits.json create mode 100644 test/test_qcecexec.cpp diff --git a/include/TestHelpers.hpp b/include/TestHelpers.hpp new file mode 100644 index 0000000..7a90c94 --- /dev/null +++ b/include/TestHelpers.hpp @@ -0,0 +1,5 @@ +#pragma once + +#include <nlohmann/json.hpp> + +void printAll(const nlohmann::json& json); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a113869..93f09be 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,6 +17,8 @@ if(NOT TARGET ${PROJECT_NAME}) ${PROJECT_SOURCE_DIR}/include/Task.hpp ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp + ${PROJECT_SOURCE_DIR}/include/TestHelpers.hpp + TestHelpers.cpp SimulationExecutor.cpp CircuitSimulatorExecutor.cpp VerificationExecutor.cpp diff --git a/src/TestHelpers.cpp b/src/TestHelpers.cpp new file mode 100644 index 0000000..48fdbf1 --- /dev/null +++ b/src/TestHelpers.cpp @@ -0,0 +1,11 @@ +#include "TestHelpers.hpp" + +#include <iostream> + +void printAll(const nlohmann::json& jsonObject) { + for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) { + const auto& key = it.key(); + const auto& value = it.value(); + std::cout << key << ": " << value << std::endl; + } +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e1a6cfc..b286f68 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,6 +11,8 @@ if(NOT TARGET gtest OR NOT TARGET gmock) endif() configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY) +configure_file(${CMAKE_SOURCE_DIR}/test/equi_circuits.json + ${CMAKE_CURRENT_BINARY_DIR}/equi_circuits.json COPYONLY) package_add_test( ${PROJECT_NAME}_test ${PROJECT_NAME} @@ -18,4 +20,5 @@ package_add_test( test_qcec_simple.cpp test_simexec_simple.cpp test_simexec.cpp - test_qcecexec_simple.cpp) + test_qcecexec_simple.cpp + test_qcecexec.cpp) diff --git a/test/equi_circuits.json b/test/equi_circuits.json new file mode 100644 index 0000000..470aaca --- /dev/null +++ b/test/equi_circuits.json @@ -0,0 +1,8 @@ +[ + { + "description": "empty_circuits", + "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n", + "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n", + "expected_equivalence": "equivalent" + } +] diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp new file mode 100644 index 0000000..2691c42 --- /dev/null +++ b/test/test_qcecexec.cpp @@ -0,0 +1,86 @@ +#include "AlternatingVerificationExecutor.hpp" +#include "TestHelpers.hpp" +#include "VerificationTask.hpp" + +#include "gtest/gtest.h" + +struct TestConfigurationQCEC { + // given input + std::string description; + std::string initialCircuit1; + std::string initialCircuit2; + + // expected output + std::string expectedEquivalence; +}; + +// NOLINTNEXTLINE (readability-identifier-naming) +inline void from_json(const nlohmann::json& j, TestConfigurationQCEC& test) { + test.description = j.at("description").get<std::string>(); + test.initialCircuit1 = j.at("initial_circuit1").get<std::string>(); + test.initialCircuit2 = j.at("initial_circuit2").get<std::string>(); + test.expectedEquivalence = j.at("expected_equivalence").get<std::string>(); +} + +static std::vector<TestConfigurationQCEC> getTests(const std::string& path) { + std::ifstream input(path); + nlohmann::json j; + input >> j; + return j; +} + +class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { +protected: + void SetUp() override { + test = GetParam(); + + if (test.initialCircuit1.empty() or test.initialCircuit2.empty()) { + throw std::runtime_error("Circuit missing!"); + } + std::stringstream ss1(test.initialCircuit1); + qc::QuantumComputation qc1{}; + qc1.import(ss1, qc::Format::OpenQASM); + std::cout << "Circuit 1:\n" << qc1 << std::endl; + + std::stringstream ss2(test.initialCircuit2); + qc::QuantumComputation qc2{}; + qc2.import(ss2, qc::Format::OpenQASM); + std::cout << "Circuit 2:\n" << qc2 << std::endl; + + qc1ForTask = std::make_unique<qc::QuantumComputation>(qc1.clone()); + qc2ForTask = std::make_unique<qc::QuantumComputation>(qc2.clone()); + verificationTask = std::make_unique<VerificationTask>( + std::move(qc1ForTask), std::move(qc2ForTask)); + equivalenceCheckingManager = + std::make_unique<ec::EquivalenceCheckingManager>(qc1.clone(), + qc2.clone()); + alternatingVerificationExecutor = + std::make_unique<AlternatingVerificationExecutor>(); + alternatingVerificationExecutor->setEquivalenceCheckingManager( + equivalenceCheckingManager); + alternatingVerificationExecutor->setMVerTask(verificationTask); + } + + void TearDown() override { std::cout << "Tearing down...\n"; } + + std::unique_ptr<qc::QuantumComputation> qc1ForTask; + std::unique_ptr<qc::QuantumComputation> qc2ForTask; + std::unique_ptr<VerificationTask> verificationTask; + std::unique_ptr<ec::EquivalenceCheckingManager> equivalenceCheckingManager; + std::unique_ptr<AlternatingVerificationExecutor> + alternatingVerificationExecutor; + TestConfigurationQCEC test; +}; + +INSTANTIATE_TEST_SUITE_P( + Circuits, QCECExecTest, testing::ValuesIn(getTests("equi_circuits.json")), + [](const testing::TestParamInfo<QCECExecTest::ParamType>& inf) { + return inf.param.description; + }); + +TEST_P(QCECExecTest, EmptyCircuits) { + json const result = alternatingVerificationExecutor->executeTask(); + std::cout << "Results:" << std::endl; + printAll(result); + EXPECT_EQ(result["equivalence"], test.expectedEquivalence); +} diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 2181cb7..7f33ac8 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -1,9 +1,10 @@ #include "CircuitSimulatorExecutor.hpp" #include "SimulationTask.hpp" +#include "TestHelpers.hpp" #include "gtest/gtest.h" -struct TestConfiguration { +struct TestConfigurationDDSIM { // given input std::string description; std::string initialCircuit; @@ -13,20 +14,20 @@ struct TestConfiguration { }; // NOLINTNEXTLINE (readability-identifier-naming) -inline void from_json(const nlohmann::json& j, TestConfiguration& test) { +inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) { test.description = j.at("description").get<std::string>(); test.initialCircuit = j.at("initial_circuit").get<std::string>(); test.expected00 = j.at("expected_00").get<std::size_t>(); } -static std::vector<TestConfiguration> getTests(const std::string& path) { +static std::vector<TestConfigurationDDSIM> getTests(const std::string& path) { std::ifstream input(path); nlohmann::json j; input >> j; return j; } -class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> { +class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { protected: void SetUp() override { test = GetParam(); @@ -56,24 +57,16 @@ class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> { std::unique_ptr<SimulationTask> simulationTask; std::unique_ptr<CircuitSimulator<>> circuitSimulator; std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor; - TestConfiguration test; + TestConfigurationDDSIM test; }; -void printAll(const json& jsonObject) { - for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) { - const auto& key = it.key(); - const auto& value = it.value(); - std::cout << key << ": " << value << std::endl; - } -} - INSTANTIATE_TEST_SUITE_P( - Circuits, SimulatorTest, testing::ValuesIn(getTests("circuits.json")), - [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) { + Circuits, DDSIMExecTest, testing::ValuesIn(getTests("circuits.json")), + [](const testing::TestParamInfo<DDSIMExecTest::ParamType>& inf) { return inf.param.description; }); -TEST_P(SimulatorTest, EmptyCircuit) { +TEST_P(DDSIMExecTest, EmptyCircuit) { json const result = circuitSimulatorExecutor->executeTask(); std::cout << "Results:" << std::endl; printAll(result); From 10cfd3bfd7b9d6405719e3d11619090c0ffaf73a Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 16:46:07 +0200 Subject: [PATCH 20/43] Refactored exec and task identifier --- src/AlternatingVerificationExecutor.cpp | 3 +-- src/CircuitSimulatorExecutor.cpp | 3 +-- src/SimulationTask.cpp | 5 +---- src/VerificationTask.cpp | 3 +-- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp index 1077342..a24a000 100644 --- a/src/AlternatingVerificationExecutor.cpp +++ b/src/AlternatingVerificationExecutor.cpp @@ -3,8 +3,7 @@ class AlternatingVerificationExecutor::AlternatingVerificationExecutor {}; std::string AlternatingVerificationExecutor::getIdentifier() { - return {"This is a alternating verification executor"}; - // refactor. how? + return "alt_ver_exe" + mVerTask->getIdentifier(); } json AlternatingVerificationExecutor::executeTask() { diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 53988ff..224e467 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -3,8 +3,7 @@ class CircuitSimulatorExecutor::CircuitSimulatorExecutor {}; std::string CircuitSimulatorExecutor::getIdentifier() { - return {"This is a circuit simulator executor"}; - // refactor. how? + return "circ_sim_exe" + mSimTask->getIdentifier(); } template <typename KTy, typename VTy> diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp index 27db4c2..b25b4ed 100644 --- a/src/SimulationTask.cpp +++ b/src/SimulationTask.cpp @@ -1,6 +1,3 @@ #include "SimulationTask.hpp" -std::string SimulationTask::getIdentifier() { - return "This is a simulation task"; - // refactor. how? -} +std::string SimulationTask::getIdentifier() { return "sim_" + qc->getName(); } diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp index bf4c744..f1fe270 100644 --- a/src/VerificationTask.cpp +++ b/src/VerificationTask.cpp @@ -1,6 +1,5 @@ #include "VerificationTask.hpp" std::string VerificationTask::getIdentifier() { - return "This is a verification task"; - // refactor. how? + return "ver_" + qc1->getName() + "_" + qc2->getName(); } From 9ae771598b833df07fd78e9bb8b8119dcba64c8f Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 17:05:37 +0200 Subject: [PATCH 21/43] Refactor Task and Executor inheritance --- include/AlternatingVerificationExecutor.hpp | 8 -------- include/CircuitSimulatorExecutor.hpp | 8 -------- include/SimulationExecutor.hpp | 4 ++-- include/VerificationExecutor.hpp | 6 +++--- src/AlternatingVerificationExecutor.cpp | 19 ++----------------- src/CircuitSimulatorExecutor.cpp | 19 ++----------------- src/SimulationExecutor.cpp | 2 +- src/VerificationExecutor.cpp | 5 ++--- test/test_qcecexec.cpp | 2 +- test/test_qcecexec_simple.cpp | 2 +- test/test_simexec.cpp | 2 +- test/test_simexec_simple.cpp | 2 +- 12 files changed, 16 insertions(+), 63 deletions(-) diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp index d93f83b..09d464d 100644 --- a/include/AlternatingVerificationExecutor.hpp +++ b/include/AlternatingVerificationExecutor.hpp @@ -11,14 +11,6 @@ class AlternatingVerificationExecutor : public VerificationExecutor { json executeTask() override; std::string getIdentifier() override; -private: - std::unique_ptr<VerificationTask> mVerTask; - -public: - [[nodiscard]] const std::unique_ptr<VerificationTask>& getMVerTask() const; - - void setMVerTask(std::unique_ptr<VerificationTask>& verTask); - private: std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager; diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp index a9ab970..9ee2cfe 100644 --- a/include/CircuitSimulatorExecutor.hpp +++ b/include/CircuitSimulatorExecutor.hpp @@ -11,14 +11,6 @@ class CircuitSimulatorExecutor : public SimulationExecutor { json executeTask() override; std::string getIdentifier() override; -private: - std::unique_ptr<SimulationTask> mSimTask; - -public: - [[nodiscard]] const std::unique_ptr<SimulationTask>& getMSimTask() const; - - void setMSimTask(std::unique_ptr<SimulationTask>& simTask); - private: std::unique_ptr<CircuitSimulator<>> mCircuitSimulator; diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp index 38cffdc..188ca7a 100644 --- a/include/SimulationExecutor.hpp +++ b/include/SimulationExecutor.hpp @@ -7,10 +7,10 @@ class SimulationExecutor : public Executor { public: SimulationExecutor() = default; - const std::unique_ptr<SimulationTask>& getMTask(); + const std::unique_ptr<SimulationTask>& getTask(); void setTask(std::unique_ptr<SimulationTask>& task); -private: +protected: std::unique_ptr<SimulationTask> mTask; }; diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp index 1f2f612..28261f9 100644 --- a/include/VerificationExecutor.hpp +++ b/include/VerificationExecutor.hpp @@ -7,11 +7,11 @@ class VerificationExecutor : public Executor { public: VerificationExecutor() = default; -private: +protected: std::unique_ptr<VerificationTask> mTask; public: - const std::unique_ptr<VerificationTask>& getMTask() const; + [[nodiscard]] const std::unique_ptr<VerificationTask>& getTask() const; - void setMTask(std::unique_ptr<VerificationTask>& task); + void setTask(std::unique_ptr<VerificationTask>& task); }; diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp index a24a000..c90cd5f 100644 --- a/src/AlternatingVerificationExecutor.cpp +++ b/src/AlternatingVerificationExecutor.cpp @@ -3,7 +3,7 @@ class AlternatingVerificationExecutor::AlternatingVerificationExecutor {}; std::string AlternatingVerificationExecutor::getIdentifier() { - return "alt_ver_exe" + mVerTask->getIdentifier(); + return "alt_ver_exe" + mTask->getIdentifier(); } json AlternatingVerificationExecutor::executeTask() { @@ -18,27 +18,12 @@ json AlternatingVerificationExecutor::executeTask() { std::chrono::duration_cast<std::chrono::microseconds>(stop - start); result["runtime"] = runtime.count(); std::string const identifier = - this->getMVerTask()->getIdentifier() + "_" + this->getIdentifier(); + this->getTask()->getIdentifier() + "_" + this->getIdentifier(); result["identifier"] = identifier; return result; } -const std::unique_ptr<VerificationTask>& -AlternatingVerificationExecutor::getMVerTask() const { - return mVerTask; -} - -void AlternatingVerificationExecutor::setMVerTask( - std::unique_ptr<VerificationTask>& verTask) { - mVerTask = std::move(verTask); -} - -const std::unique_ptr<ec::EquivalenceCheckingManager>& -AlternatingVerificationExecutor::getEquivalenceCheckingManager() { - return mEquivalenceCheckingManager; -} - void AlternatingVerificationExecutor::setEquivalenceCheckingManager( std::unique_ptr<ec::EquivalenceCheckingManager>& equivalenceCheckingManager) { diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 224e467..8d2ffb5 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -3,7 +3,7 @@ class CircuitSimulatorExecutor::CircuitSimulatorExecutor {}; std::string CircuitSimulatorExecutor::getIdentifier() { - return "circ_sim_exe" + mSimTask->getIdentifier(); + return "circ_sim_exe" + mTask->getIdentifier(); } template <typename KTy, typename VTy> @@ -26,27 +26,12 @@ json CircuitSimulatorExecutor::executeTask() { std::chrono::duration_cast<std::chrono::microseconds>(stop - start); result["runtime"] = runtime.count(); std::string const identifier = - this->getMSimTask()->getIdentifier() + "_" + this->getIdentifier(); + this->getTask()->getIdentifier() + "_" + this->getIdentifier(); result["identifier"] = identifier; return result; } -const std::unique_ptr<SimulationTask>& -CircuitSimulatorExecutor::getMSimTask() const { - return mSimTask; -} - -void CircuitSimulatorExecutor::setMSimTask( - std::unique_ptr<SimulationTask>& simTask) { - mSimTask = std::move(simTask); -} - -const std::unique_ptr<CircuitSimulator<>>& -CircuitSimulatorExecutor::getCircuitSimulator() { - return mCircuitSimulator; -} - void CircuitSimulatorExecutor::setCircuitSimulator( std::unique_ptr<CircuitSimulator<>>& circuitSimulator) { mCircuitSimulator = std::move(circuitSimulator); diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp index 6371eb4..b497dbf 100644 --- a/src/SimulationExecutor.cpp +++ b/src/SimulationExecutor.cpp @@ -1,6 +1,6 @@ #include "SimulationExecutor.hpp" -const std::unique_ptr<SimulationTask>& SimulationExecutor::getMTask() { +const std::unique_ptr<SimulationTask>& SimulationExecutor::getTask() { return mTask; } diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp index 596852b..bc4d99c 100644 --- a/src/VerificationExecutor.cpp +++ b/src/VerificationExecutor.cpp @@ -1,10 +1,9 @@ #include "VerificationExecutor.hpp" -const std::unique_ptr<VerificationTask>& -VerificationExecutor::getMTask() const { +const std::unique_ptr<VerificationTask>& VerificationExecutor::getTask() const { return mTask; } -void VerificationExecutor::setMTask(std::unique_ptr<VerificationTask>& task) { +void VerificationExecutor::setTask(std::unique_ptr<VerificationTask>& task) { mTask = std::move(task); } diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index 2691c42..1e19272 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -58,7 +58,7 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { std::make_unique<AlternatingVerificationExecutor>(); alternatingVerificationExecutor->setEquivalenceCheckingManager( equivalenceCheckingManager); - alternatingVerificationExecutor->setMVerTask(verificationTask); + alternatingVerificationExecutor->setTask(verificationTask); } void TearDown() override { std::cout << "Tearing down...\n"; } diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp index d365d20..c49d25d 100644 --- a/test/test_qcecexec_simple.cpp +++ b/test/test_qcecexec_simple.cpp @@ -16,7 +16,7 @@ TEST(QCECExecSimpleTest, EmptyCircuits) { std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3); auto alternatingVerificationExecutor = std::make_unique<AlternatingVerificationExecutor>(); - alternatingVerificationExecutor->setMVerTask(verificationTask); + alternatingVerificationExecutor->setTask(verificationTask); alternatingVerificationExecutor->setEquivalenceCheckingManager( equivalenceCheckingManager); diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 7f33ac8..9cc6c73 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -47,7 +47,7 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { std::make_unique<CircuitSimulator<>>(std::move(qcForSim)); circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator); - circuitSimulatorExecutor->setMSimTask(simulationTask); + circuitSimulatorExecutor->setTask(simulationTask); } void TearDown() override { std::cout << "Tearing down...\n"; } diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp index 5b5dfad..5fd4a0a 100644 --- a/test/test_simexec_simple.cpp +++ b/test/test_simexec_simple.cpp @@ -12,7 +12,7 @@ TEST(DDSIMExecSimpleTest, EmptyCircuit) { auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc)); auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator); - circuitSimulatorExecutor->setMSimTask(simulationTask); + circuitSimulatorExecutor->setTask(simulationTask); json const result = circuitSimulatorExecutor->executeTask(); EXPECT_EQ(1024, result["00"]); From 505053c1f880092a9114987c59b5f8a38be721e6 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 17:05:52 +0200 Subject: [PATCH 22/43] Clean-up --- include/AlternatingVerificationExecutor.hpp | 3 --- include/CircuitSimulatorExecutor.hpp | 4 +--- include/SimulationTask.hpp | 2 -- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp index 09d464d..48888d5 100644 --- a/include/AlternatingVerificationExecutor.hpp +++ b/include/AlternatingVerificationExecutor.hpp @@ -15,9 +15,6 @@ class AlternatingVerificationExecutor : public VerificationExecutor { std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager; public: - const std::unique_ptr<ec::EquivalenceCheckingManager>& - getEquivalenceCheckingManager(); - void setEquivalenceCheckingManager(std::unique_ptr<ec::EquivalenceCheckingManager>& equivalenceCheckingManager); diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp index 9ee2cfe..7bd42e7 100644 --- a/include/CircuitSimulatorExecutor.hpp +++ b/include/CircuitSimulatorExecutor.hpp @@ -6,7 +6,7 @@ class CircuitSimulatorExecutor : public SimulationExecutor { public: CircuitSimulatorExecutor() = default; - // simulator and task must be set before use + // simulator and task must be set before use json executeTask() override; std::string getIdentifier() override; @@ -15,8 +15,6 @@ class CircuitSimulatorExecutor : public SimulationExecutor { std::unique_ptr<CircuitSimulator<>> mCircuitSimulator; public: - const std::unique_ptr<CircuitSimulator<>>& getCircuitSimulator(); - void setCircuitSimulator(std::unique_ptr<CircuitSimulator<>>& circuitSimulator); }; diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp index efde458..d71fe22 100644 --- a/include/SimulationTask.hpp +++ b/include/SimulationTask.hpp @@ -14,7 +14,5 @@ class SimulationTask : public Task { std::unique_ptr<qc::QuantumComputation> qc; public: - std::unique_ptr<qc::QuantumComputation>& getQc() { return qc; } - std::string getIdentifier() override; }; From 8bfad929d5759ca7b6114ba8a74ebf89012ecab6 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 17:21:15 +0200 Subject: [PATCH 23/43] Make sure the alternating checker was run in alternating executor --- test/test_qcecexec.cpp | 9 ++++++++- test/test_qcecexec_simple.cpp | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index 1e19272..b13d353 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -51,9 +51,16 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { qc2ForTask = std::make_unique<qc::QuantumComputation>(qc2.clone()); verificationTask = std::make_unique<VerificationTask>( std::move(qc1ForTask), std::move(qc2ForTask)); + + auto config = ec::Configuration{}; + config.execution.runAlternatingChecker = true; + config.execution.runSimulationChecker = false; + config.execution.runConstructionChecker = false; + config.execution.runZXChecker = false; + // This should probably happen inside src? equivalenceCheckingManager = std::make_unique<ec::EquivalenceCheckingManager>(qc1.clone(), - qc2.clone()); + qc2.clone(), config); alternatingVerificationExecutor = std::make_unique<AlternatingVerificationExecutor>(); alternatingVerificationExecutor->setEquivalenceCheckingManager( diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp index c49d25d..e7c5043 100644 --- a/test/test_qcecexec_simple.cpp +++ b/test/test_qcecexec_simple.cpp @@ -12,8 +12,14 @@ TEST(QCECExecSimpleTest, EmptyCircuits) { auto clonedQC3 = qc->clone(); auto verificationTask = std::make_unique<VerificationTask>(std::move(qc), std::move(clonedQC)); + auto config = ec::Configuration{}; + config.execution.runAlternatingChecker = true; + config.execution.runSimulationChecker = false; + config.execution.runConstructionChecker = false; + config.execution.runZXChecker = false; auto equivalenceCheckingManager = - std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3); + std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3, + config); auto alternatingVerificationExecutor = std::make_unique<AlternatingVerificationExecutor>(); alternatingVerificationExecutor->setTask(verificationTask); From 3927554221a499e0f7870cb97d15269b571a21f9 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 17:21:15 +0200 Subject: [PATCH 24/43] Make sure the alternating checker was run in alternating executor --- test/test_qcecexec.cpp | 7 +++++++ test/test_qcecexec_simple.cpp | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index 1e19272..e8c82b6 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -51,9 +51,16 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { qc2ForTask = std::make_unique<qc::QuantumComputation>(qc2.clone()); verificationTask = std::make_unique<VerificationTask>( std::move(qc1ForTask), std::move(qc2ForTask)); + equivalenceCheckingManager = std::make_unique<ec::EquivalenceCheckingManager>(qc1.clone(), qc2.clone()); + equivalenceCheckingManager->setAlternatingChecker(true); + equivalenceCheckingManager->setSimulationChecker(false); + equivalenceCheckingManager->setConstructionChecker(false); + equivalenceCheckingManager->setZXChecker(false); + // This should probably happen inside src? + alternatingVerificationExecutor = std::make_unique<AlternatingVerificationExecutor>(); alternatingVerificationExecutor->setEquivalenceCheckingManager( diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp index c49d25d..adc4ed9 100644 --- a/test/test_qcecexec_simple.cpp +++ b/test/test_qcecexec_simple.cpp @@ -12,8 +12,15 @@ TEST(QCECExecSimpleTest, EmptyCircuits) { auto clonedQC3 = qc->clone(); auto verificationTask = std::make_unique<VerificationTask>(std::move(qc), std::move(clonedQC)); + auto equivalenceCheckingManager = std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3); + equivalenceCheckingManager->setAlternatingChecker(true); + equivalenceCheckingManager->setSimulationChecker(false); + equivalenceCheckingManager->setConstructionChecker(false); + equivalenceCheckingManager->setZXChecker(false); + // This should probably happen inside src? + auto alternatingVerificationExecutor = std::make_unique<AlternatingVerificationExecutor>(); alternatingVerificationExecutor->setTask(verificationTask); From a7fea9aadc904c9c802b5067f4535554d7dcc6c6 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 2 Jun 2023 17:49:40 +0200 Subject: [PATCH 25/43] Fix CI issues (WIP) --- src/AlternatingVerificationExecutor.cpp | 2 -- src/CircuitSimulatorExecutor.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp index c90cd5f..96b37fe 100644 --- a/src/AlternatingVerificationExecutor.cpp +++ b/src/AlternatingVerificationExecutor.cpp @@ -1,7 +1,5 @@ #include "AlternatingVerificationExecutor.hpp" -class AlternatingVerificationExecutor::AlternatingVerificationExecutor {}; - std::string AlternatingVerificationExecutor::getIdentifier() { return "alt_ver_exe" + mTask->getIdentifier(); } diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 8d2ffb5..9e4dd20 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -1,7 +1,5 @@ #include "CircuitSimulatorExecutor.hpp" -class CircuitSimulatorExecutor::CircuitSimulatorExecutor {}; - std::string CircuitSimulatorExecutor::getIdentifier() { return "circ_sim_exe" + mTask->getIdentifier(); } From 1bb3de70da834b2be695723036b604dd683b2c7b Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Sat, 3 Jun 2023 00:13:00 +0200 Subject: [PATCH 26/43] Refactor architecture: set all necessary members inside of constructor --- include/AlternatingVerificationExecutor.hpp | 11 +++----- include/CircuitSimulatorExecutor.hpp | 10 +++---- include/SimulationTask.hpp | 6 ++--- include/VerificationExecutor.hpp | 7 +++-- include/VerificationTask.hpp | 5 ++++ src/AlternatingVerificationExecutor.cpp | 19 ++++++++----- src/CircuitSimulatorExecutor.cpp | 12 +++++---- src/SimulationTask.cpp | 4 +++ src/VerificationTask.cpp | 10 +++++++ test/test_qcecexec.cpp | 30 +++++++-------------- test/test_qcecexec_simple.cpp | 24 ++++------------- test/test_simexec.cpp | 16 ++++------- test/test_simexec_simple.cpp | 12 +++------ 13 files changed, 76 insertions(+), 90 deletions(-) diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp index 48888d5..2e9521f 100644 --- a/include/AlternatingVerificationExecutor.hpp +++ b/include/AlternatingVerificationExecutor.hpp @@ -5,17 +5,14 @@ class AlternatingVerificationExecutor : public VerificationExecutor { public: - AlternatingVerificationExecutor() = default; - // checker and task must be set before use + AlternatingVerificationExecutor() = delete; + + explicit AlternatingVerificationExecutor( + std::unique_ptr<VerificationTask> verificationTask); json executeTask() override; std::string getIdentifier() override; private: std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager; - -public: - void - setEquivalenceCheckingManager(std::unique_ptr<ec::EquivalenceCheckingManager>& - equivalenceCheckingManager); }; diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp index 7bd42e7..bc548ee 100644 --- a/include/CircuitSimulatorExecutor.hpp +++ b/include/CircuitSimulatorExecutor.hpp @@ -5,16 +5,14 @@ class CircuitSimulatorExecutor : public SimulationExecutor { public: - CircuitSimulatorExecutor() = default; - // simulator and task must be set before use + CircuitSimulatorExecutor() = delete; + + explicit CircuitSimulatorExecutor( + std::unique_ptr<SimulationTask> simulationTask); json executeTask() override; std::string getIdentifier() override; private: std::unique_ptr<CircuitSimulator<>> mCircuitSimulator; - -public: - void - setCircuitSimulator(std::unique_ptr<CircuitSimulator<>>& circuitSimulator); }; diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp index d71fe22..c67e7bd 100644 --- a/include/SimulationTask.hpp +++ b/include/SimulationTask.hpp @@ -10,9 +10,9 @@ class SimulationTask : public Task { explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> qc) : qc(std::move(qc)) {} + [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const; + std::string getIdentifier() override; + protected: std::unique_ptr<qc::QuantumComputation> qc; - -public: - std::string getIdentifier() override; }; diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp index 28261f9..0143bb0 100644 --- a/include/VerificationExecutor.hpp +++ b/include/VerificationExecutor.hpp @@ -7,11 +7,10 @@ class VerificationExecutor : public Executor { public: VerificationExecutor() = default; -protected: - std::unique_ptr<VerificationTask> mTask; - -public: [[nodiscard]] const std::unique_ptr<VerificationTask>& getTask() const; void setTask(std::unique_ptr<VerificationTask>& task); + +protected: + std::unique_ptr<VerificationTask> mTask; }; diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp index 4032287..eb71402 100644 --- a/include/VerificationTask.hpp +++ b/include/VerificationTask.hpp @@ -14,4 +14,9 @@ class VerificationTask : public Task { protected: std::unique_ptr<qc::QuantumComputation> qc1; std::unique_ptr<qc::QuantumComputation> qc2; + +public: + [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const; + + [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc2() const; }; diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp index 96b37fe..d2799cc 100644 --- a/src/AlternatingVerificationExecutor.cpp +++ b/src/AlternatingVerificationExecutor.cpp @@ -1,5 +1,18 @@ #include "AlternatingVerificationExecutor.hpp" +AlternatingVerificationExecutor::AlternatingVerificationExecutor( + std::unique_ptr<VerificationTask> verificationTask) { + mTask = std::move(verificationTask); + auto qc1 = mTask->getQc1()->clone(); + auto qc2 = mTask->getQc2()->clone(); + mEquivalenceCheckingManager = + std::make_unique<ec::EquivalenceCheckingManager>(qc1, qc2); + mEquivalenceCheckingManager->setAlternatingChecker(true); + mEquivalenceCheckingManager->setSimulationChecker(false); + mEquivalenceCheckingManager->setConstructionChecker(false); + mEquivalenceCheckingManager->setZXChecker(false); +} + std::string AlternatingVerificationExecutor::getIdentifier() { return "alt_ver_exe" + mTask->getIdentifier(); } @@ -21,9 +34,3 @@ json AlternatingVerificationExecutor::executeTask() { return result; } - -void AlternatingVerificationExecutor::setEquivalenceCheckingManager( - std::unique_ptr<ec::EquivalenceCheckingManager>& - equivalenceCheckingManager) { - mEquivalenceCheckingManager = std::move(equivalenceCheckingManager); -} diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 9e4dd20..d832f57 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -1,5 +1,12 @@ #include "CircuitSimulatorExecutor.hpp" +CircuitSimulatorExecutor::CircuitSimulatorExecutor( + std::unique_ptr<SimulationTask> simulationTask) { + mTask = std::move(simulationTask); + auto qc = std::make_unique<qc::QuantumComputation>(mTask->getQc()->clone()); + mCircuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc)); +} + std::string CircuitSimulatorExecutor::getIdentifier() { return "circ_sim_exe" + mTask->getIdentifier(); } @@ -29,8 +36,3 @@ json CircuitSimulatorExecutor::executeTask() { return result; } - -void CircuitSimulatorExecutor::setCircuitSimulator( - std::unique_ptr<CircuitSimulator<>>& circuitSimulator) { - mCircuitSimulator = std::move(circuitSimulator); -} diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp index b25b4ed..4e2a7cf 100644 --- a/src/SimulationTask.cpp +++ b/src/SimulationTask.cpp @@ -1,3 +1,7 @@ #include "SimulationTask.hpp" std::string SimulationTask::getIdentifier() { return "sim_" + qc->getName(); } + +const std::unique_ptr<qc::QuantumComputation>& SimulationTask::getQc() const { + return qc; +} diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp index f1fe270..851a286 100644 --- a/src/VerificationTask.cpp +++ b/src/VerificationTask.cpp @@ -3,3 +3,13 @@ std::string VerificationTask::getIdentifier() { return "ver_" + qc1->getName() + "_" + qc2->getName(); } + +const std::unique_ptr<qc::QuantumComputation>& +VerificationTask::getQc1() const { + return qc1; +} + +const std::unique_ptr<qc::QuantumComputation>& +VerificationTask::getQc2() const { + return qc2; +} diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index e8c82b6..3c6ef8d 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -47,33 +47,21 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { qc2.import(ss2, qc::Format::OpenQASM); std::cout << "Circuit 2:\n" << qc2 << std::endl; - qc1ForTask = std::make_unique<qc::QuantumComputation>(qc1.clone()); - qc2ForTask = std::make_unique<qc::QuantumComputation>(qc2.clone()); - verificationTask = std::make_unique<VerificationTask>( - std::move(qc1ForTask), std::move(qc2ForTask)); - - equivalenceCheckingManager = - std::make_unique<ec::EquivalenceCheckingManager>(qc1.clone(), - qc2.clone()); - equivalenceCheckingManager->setAlternatingChecker(true); - equivalenceCheckingManager->setSimulationChecker(false); - equivalenceCheckingManager->setConstructionChecker(false); - equivalenceCheckingManager->setZXChecker(false); - // This should probably happen inside src? + qc1Ver = std::make_unique<qc::QuantumComputation>(qc1.clone()); + qc2Ver = std::make_unique<qc::QuantumComputation>(qc2.clone()); + verificationTask = std::make_unique<VerificationTask>(std::move(qc1Ver), + std::move(qc2Ver)); alternatingVerificationExecutor = - std::make_unique<AlternatingVerificationExecutor>(); - alternatingVerificationExecutor->setEquivalenceCheckingManager( - equivalenceCheckingManager); - alternatingVerificationExecutor->setTask(verificationTask); + std::make_unique<AlternatingVerificationExecutor>( + std::move(verificationTask)); } void TearDown() override { std::cout << "Tearing down...\n"; } - std::unique_ptr<qc::QuantumComputation> qc1ForTask; - std::unique_ptr<qc::QuantumComputation> qc2ForTask; - std::unique_ptr<VerificationTask> verificationTask; - std::unique_ptr<ec::EquivalenceCheckingManager> equivalenceCheckingManager; + std::unique_ptr<qc::QuantumComputation> qc1Ver; + std::unique_ptr<qc::QuantumComputation> qc2Ver; + std::unique_ptr<VerificationTask> verificationTask; std::unique_ptr<AlternatingVerificationExecutor> alternatingVerificationExecutor; TestConfigurationQCEC test; diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp index adc4ed9..4abd8f2 100644 --- a/test/test_qcecexec_simple.cpp +++ b/test/test_qcecexec_simple.cpp @@ -1,31 +1,17 @@ #include "AlternatingVerificationExecutor.hpp" -#include "EquivalenceCheckingManager.hpp" #include "VerificationTask.hpp" #include <gtest/gtest.h> #include <memory> TEST(QCECExecSimpleTest, EmptyCircuits) { - auto qc = std::make_unique<qc::QuantumComputation>(2U); - auto clonedQC = std::make_unique<qc::QuantumComputation>(qc->clone()); - auto clonedQC2 = qc->clone(); - auto clonedQC3 = qc->clone(); + auto qc1 = std::make_unique<qc::QuantumComputation>(2U); + auto qc2 = std::make_unique<qc::QuantumComputation>(2U); auto verificationTask = - std::make_unique<VerificationTask>(std::move(qc), std::move(clonedQC)); - - auto equivalenceCheckingManager = - std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3); - equivalenceCheckingManager->setAlternatingChecker(true); - equivalenceCheckingManager->setSimulationChecker(false); - equivalenceCheckingManager->setConstructionChecker(false); - equivalenceCheckingManager->setZXChecker(false); - // This should probably happen inside src? - + std::make_unique<VerificationTask>(std::move(qc1), std::move(qc2)); auto alternatingVerificationExecutor = - std::make_unique<AlternatingVerificationExecutor>(); - alternatingVerificationExecutor->setTask(verificationTask); - alternatingVerificationExecutor->setEquivalenceCheckingManager( - equivalenceCheckingManager); + std::make_unique<AlternatingVerificationExecutor>( + std::move(verificationTask)); json const result = alternatingVerificationExecutor->executeTask(); diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 9cc6c73..b8b9dbb 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -40,22 +40,16 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { qc.import(ss, qc::Format::OpenQASM); std::cout << "Circuit:\n" << qc; - qcForTask = std::make_unique<qc::QuantumComputation>(qc.clone()); - qcForSim = std::make_unique<qc::QuantumComputation>(qc.clone()); - simulationTask = std::make_unique<SimulationTask>(std::move(qcForTask)); - circuitSimulator = - std::make_unique<CircuitSimulator<>>(std::move(qcForSim)); - circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); - circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator); - circuitSimulatorExecutor->setTask(simulationTask); + qcSim = std::make_unique<qc::QuantumComputation>(qc.clone()); + simulationTask = std::make_unique<SimulationTask>(std::move(qcSim)); + circuitSimulatorExecutor = + std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask)); } void TearDown() override { std::cout << "Tearing down...\n"; } - std::unique_ptr<qc::QuantumComputation> qcForTask; - std::unique_ptr<qc::QuantumComputation> qcForSim; + std::unique_ptr<qc::QuantumComputation> qcSim; std::unique_ptr<SimulationTask> simulationTask; - std::unique_ptr<CircuitSimulator<>> circuitSimulator; std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor; TestConfigurationDDSIM test; }; diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp index 5fd4a0a..2b485fe 100644 --- a/test/test_simexec_simple.cpp +++ b/test/test_simexec_simple.cpp @@ -1,4 +1,3 @@ -#include "CircuitSimulator.hpp" #include "CircuitSimulatorExecutor.hpp" #include "SimulationTask.hpp" @@ -6,13 +5,10 @@ #include <memory> TEST(DDSIMExecSimpleTest, EmptyCircuit) { - auto qc = std::make_unique<qc::QuantumComputation>(2U); - auto clonedQC = std::make_unique<qc::QuantumComputation>(qc->clone()); - auto simulationTask = std::make_unique<SimulationTask>(std::move(clonedQC)); - auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc)); - auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); - circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator); - circuitSimulatorExecutor->setTask(simulationTask); + auto qc = std::make_unique<qc::QuantumComputation>(2U); + auto simulationTask = std::make_unique<SimulationTask>(std::move(qc)); + auto circuitSimulatorExecutor = + std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask)); json const result = circuitSimulatorExecutor->executeTask(); EXPECT_EQ(1024, result["00"]); From 11c5ecf75bcf26a67eeec7210992ce1c4dc0fc42 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Sat, 3 Jun 2023 00:37:40 +0200 Subject: [PATCH 27/43] Refactor simulator test to avoid empty circuits --- test/circuits.json | 6 +++--- test/test_simexec.cpp | 8 ++++---- test/test_simexec_simple.cpp | 12 ++++++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/test/circuits.json b/test/circuits.json index dac448d..010bcf2 100644 --- a/test/circuits.json +++ b/test/circuits.json @@ -1,7 +1,7 @@ [ { - "description": "empty_circuit", - "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n", - "expected_00": 1024 + "description": "two_qubit_circuit_with_two_x_gates", + "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n", + "expected_11": 1024 } ] diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index b8b9dbb..9082aea 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -10,14 +10,14 @@ struct TestConfigurationDDSIM { std::string initialCircuit; // expected output - std::size_t expected00{}; + std::size_t expected11{}; }; // NOLINTNEXTLINE (readability-identifier-naming) inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) { test.description = j.at("description").get<std::string>(); test.initialCircuit = j.at("initial_circuit").get<std::string>(); - test.expected00 = j.at("expected_00").get<std::size_t>(); + test.expected11 = j.at("expected_11").get<std::size_t>(); } static std::vector<TestConfigurationDDSIM> getTests(const std::string& path) { @@ -60,9 +60,9 @@ INSTANTIATE_TEST_SUITE_P( return inf.param.description; }); -TEST_P(DDSIMExecTest, EmptyCircuit) { +TEST_P(DDSIMExecTest, TwoQubitCircuitWithTwoXGates) { json const result = circuitSimulatorExecutor->executeTask(); std::cout << "Results:" << std::endl; printAll(result); - EXPECT_EQ(result["00"], test.expected00); + EXPECT_EQ(result["11"], test.expected11); } diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp index 2b485fe..9ccd4ed 100644 --- a/test/test_simexec_simple.cpp +++ b/test/test_simexec_simple.cpp @@ -4,12 +4,16 @@ #include <gtest/gtest.h> #include <memory> -TEST(DDSIMExecSimpleTest, EmptyCircuit) { - auto qc = std::make_unique<qc::QuantumComputation>(2U); +TEST(DDSIMExecSimpleTest, SimpleCircuit) { + using namespace qc::literals; + auto qc = std::make_unique<qc::QuantumComputation>(2U); + qc->h(0U); + qc->x(1U, 0_pc); + auto simulationTask = std::make_unique<SimulationTask>(std::move(qc)); auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask)); json const result = circuitSimulatorExecutor->executeTask(); - - EXPECT_EQ(1024, result["00"]); + EXPECT_FALSE(result.contains("01")); + EXPECT_FALSE(result.contains("10")); } From f80e730a5f0bea4023ac2795d6a5327cf245c9b4 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Sat, 3 Jun 2023 00:50:59 +0200 Subject: [PATCH 28/43] Refactor verification tests to avoid empty circuits --- test/equi_circuits.json | 6 +++--- test/test_qcecexec_simple.cpp | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/test/equi_circuits.json b/test/equi_circuits.json index 470aaca..6d01275 100644 --- a/test/equi_circuits.json +++ b/test/equi_circuits.json @@ -1,8 +1,8 @@ [ { - "description": "empty_circuits", - "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n", - "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n", + "description": "simple_circuits", + "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n", + "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];x q[0];x q[0];\n", "expected_equivalence": "equivalent" } ] diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp index 4abd8f2..c11107f 100644 --- a/test/test_qcecexec_simple.cpp +++ b/test/test_qcecexec_simple.cpp @@ -4,9 +4,15 @@ #include <gtest/gtest.h> #include <memory> -TEST(QCECExecSimpleTest, EmptyCircuits) { +TEST(QCECExecSimpleTest, SimpleCircuit) { auto qc1 = std::make_unique<qc::QuantumComputation>(2U); + qc1->x(0U); + qc1->x(1U); auto qc2 = std::make_unique<qc::QuantumComputation>(2U); + qc2->x(0U); + qc2->x(0U); + qc2->x(0U); + qc2->x(1U); auto verificationTask = std::make_unique<VerificationTask>(std::move(qc1), std::move(qc2)); auto alternatingVerificationExecutor = From f3fea114eca9ec53eb88c6c18495b4a73363956d Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Sat, 3 Jun 2023 01:24:26 +0200 Subject: [PATCH 29/43] Remove obsolete code for coverage --- src/SimulationExecutor.cpp | 4 ---- src/VerificationExecutor.cpp | 4 ---- test/test_qcecexec.cpp | 3 --- test/test_simexec.cpp | 3 --- 4 files changed, 14 deletions(-) diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp index b497dbf..2fd4302 100644 --- a/src/SimulationExecutor.cpp +++ b/src/SimulationExecutor.cpp @@ -3,7 +3,3 @@ const std::unique_ptr<SimulationTask>& SimulationExecutor::getTask() { return mTask; } - -void SimulationExecutor::setTask(std::unique_ptr<SimulationTask>& task) { - mTask = std::move(task); -} diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp index bc4d99c..075121c 100644 --- a/src/VerificationExecutor.cpp +++ b/src/VerificationExecutor.cpp @@ -3,7 +3,3 @@ const std::unique_ptr<VerificationTask>& VerificationExecutor::getTask() const { return mTask; } - -void VerificationExecutor::setTask(std::unique_ptr<VerificationTask>& task) { - mTask = std::move(task); -} diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index 3c6ef8d..de773d7 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -34,9 +34,6 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { void SetUp() override { test = GetParam(); - if (test.initialCircuit1.empty() or test.initialCircuit2.empty()) { - throw std::runtime_error("Circuit missing!"); - } std::stringstream ss1(test.initialCircuit1); qc::QuantumComputation qc1{}; qc1.import(ss1, qc::Format::OpenQASM); diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 9082aea..895c7ac 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -32,9 +32,6 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { void SetUp() override { test = GetParam(); - if (test.initialCircuit.empty()) { - throw std::runtime_error("No circuit!"); - } std::stringstream ss(test.initialCircuit); qc::QuantumComputation qc{}; qc.import(ss, qc::Format::OpenQASM); From e737f71aa75bf70282aad71d422d910feebc86a5 Mon Sep 17 00:00:00 2001 From: tyi1025 <56802240+tyi1025@users.noreply.github.com> Date: Wed, 7 Jun 2023 01:05:15 +0200 Subject: [PATCH 30/43] Apply suggestions from code review Co-authored-by: Lukas Burgholzer <lukas.burgholzer@jku.at> --- src/CircuitSimulatorExecutor.cpp | 3 +-- test/test_simexec.cpp | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index d832f57..9c76141 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -22,8 +22,7 @@ json CircuitSimulatorExecutor::executeTask() { json result; auto start = std::chrono::high_resolution_clock::now(); - const auto results = mCircuitSimulator->simulate(1024U); - toJson(result, results); + result["measurement_results"] = mCircuitSimulator->simulate(1024U); // Add memory usage auto stop = std::chrono::high_resolution_clock::now(); diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 895c7ac..3e891aa 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -33,12 +33,11 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { test = GetParam(); std::stringstream ss(test.initialCircuit); - qc::QuantumComputation qc{}; - qc.import(ss, qc::Format::OpenQASM); + auto qc = std::make_unique<qc::QuantumComputation>(): + qc->import(ss, qc::Format::OpenQASM); std::cout << "Circuit:\n" << qc; - qcSim = std::make_unique<qc::QuantumComputation>(qc.clone()); - simulationTask = std::make_unique<SimulationTask>(std::move(qcSim)); + simulationTask = std::make_unique<SimulationTask>(std::move(qc)); circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask)); } From 0a3f9569f9b5c8cb19071e275d3ad7c45e1d399e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 23:05:21 +0000 Subject: [PATCH 31/43] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/test_simexec.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 3e891aa..6c824fd 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -32,9 +32,9 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { void SetUp() override { test = GetParam(); - std::stringstream ss(test.initialCircuit); - auto qc = std::make_unique<qc::QuantumComputation>(): - qc->import(ss, qc::Format::OpenQASM); + std::stringstream ss(test.initialCircuit); + auto qc = std::make_unique<qc::QuantumComputation>() + : qc->import(ss, qc::Format::OpenQASM); std::cout << "Circuit:\n" << qc; simulationTask = std::make_unique<SimulationTask>(std::move(qc)); From 26889231014495daf6484d88693142e84910f048 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Thu, 8 Jun 2023 02:12:52 +0200 Subject: [PATCH 32/43] Refactoring the source code according to the review suggestions --- include/AlternatingVerificationExecutor.hpp | 18 -------- include/CircuitSimulatorExecutor.hpp | 18 -------- include/Executor.hpp | 16 ++++--- include/SimulationExecutor.hpp | 16 ------- include/Task.hpp | 8 +--- include/TestHelpers.hpp | 5 --- include/VerificationExecutor.hpp | 16 ------- .../AlternatingVerificationExecutor.hpp | 15 +++++++ .../executors/CircuitSimulatorExecutor.hpp | 15 +++++++ include/{ => tasks}/SimulationTask.hpp | 11 ++++- include/{ => tasks}/VerificationTask.hpp | 14 ++++-- src/AlternatingVerificationExecutor.cpp | 43 ++++++++----------- src/CMakeLists.txt | 18 +++----- src/CircuitSimulatorExecutor.cpp | 40 ++++++----------- src/SimulationExecutor.cpp | 5 --- src/SimulationTask.cpp | 7 --- src/TestHelpers.cpp | 11 ----- src/VerificationExecutor.cpp | 5 --- src/VerificationTask.cpp | 15 ------- test/CMakeLists.txt | 11 +---- test/test_qcecexec.cpp | 15 +++---- test/test_qcecexec_simple.cpp | 25 ----------- test/test_simexec.cpp | 23 +++++----- test/test_simexec_simple.cpp | 19 -------- 24 files changed, 116 insertions(+), 273 deletions(-) delete mode 100644 include/AlternatingVerificationExecutor.hpp delete mode 100644 include/CircuitSimulatorExecutor.hpp delete mode 100644 include/SimulationExecutor.hpp delete mode 100644 include/TestHelpers.hpp delete mode 100644 include/VerificationExecutor.hpp create mode 100644 include/executors/AlternatingVerificationExecutor.hpp create mode 100644 include/executors/CircuitSimulatorExecutor.hpp rename include/{ => tasks}/SimulationTask.hpp (70%) rename include/{ => tasks}/VerificationTask.hpp (72%) delete mode 100644 src/SimulationExecutor.cpp delete mode 100644 src/SimulationTask.cpp delete mode 100644 src/TestHelpers.cpp delete mode 100644 src/VerificationExecutor.cpp delete mode 100644 src/VerificationTask.cpp delete mode 100644 test/test_qcecexec_simple.cpp delete mode 100644 test/test_simexec_simple.cpp diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp deleted file mode 100644 index 2e9521f..0000000 --- a/include/AlternatingVerificationExecutor.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "EquivalenceCheckingManager.hpp" -#include "VerificationExecutor.hpp" - -class AlternatingVerificationExecutor : public VerificationExecutor { -public: - AlternatingVerificationExecutor() = delete; - - explicit AlternatingVerificationExecutor( - std::unique_ptr<VerificationTask> verificationTask); - - json executeTask() override; - std::string getIdentifier() override; - -private: - std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager; -}; diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp deleted file mode 100644 index bc548ee..0000000 --- a/include/CircuitSimulatorExecutor.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "CircuitSimulator.hpp" -#include "SimulationExecutor.hpp" - -class CircuitSimulatorExecutor : public SimulationExecutor { -public: - CircuitSimulatorExecutor() = delete; - - explicit CircuitSimulatorExecutor( - std::unique_ptr<SimulationTask> simulationTask); - - json executeTask() override; - std::string getIdentifier() override; - -private: - std::unique_ptr<CircuitSimulator<>> mCircuitSimulator; -}; diff --git a/include/Executor.hpp b/include/Executor.hpp index 5042bcd..fafded8 100644 --- a/include/Executor.hpp +++ b/include/Executor.hpp @@ -2,16 +2,18 @@ #include "Task.hpp" -#include <memory> +#include <nlohmann/json.hpp> +#include <type_traits> + +using json = nlohmann::json; + +template <class T> class Executor { + static_assert(std::is_base_of_v<Task, T>); -class Executor { public: virtual ~Executor() = default; explicit Executor() = default; - virtual json executeTask() = 0; - virtual std::string getIdentifier() = 0; - -private: - std::unique_ptr<Task> task; + virtual json execute(const T& task) = 0; + [[nodiscard]] virtual std::string getIdentifier() const = 0; }; diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp deleted file mode 100644 index 188ca7a..0000000 --- a/include/SimulationExecutor.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "Executor.hpp" -#include "SimulationTask.hpp" - -class SimulationExecutor : public Executor { -public: - SimulationExecutor() = default; - - const std::unique_ptr<SimulationTask>& getTask(); - - void setTask(std::unique_ptr<SimulationTask>& task); - -protected: - std::unique_ptr<SimulationTask> mTask; -}; diff --git a/include/Task.hpp b/include/Task.hpp index 2085fc6..a9267a4 100644 --- a/include/Task.hpp +++ b/include/Task.hpp @@ -1,11 +1,7 @@ #pragma once -#include <nlohmann/json.hpp> - -using json = nlohmann::json; - class Task { public: - virtual ~Task() = default; - virtual std::string getIdentifier() = 0; + virtual ~Task() = default; + [[nodiscard]] virtual std::string getIdentifier() const = 0; }; diff --git a/include/TestHelpers.hpp b/include/TestHelpers.hpp deleted file mode 100644 index 7a90c94..0000000 --- a/include/TestHelpers.hpp +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include <nlohmann/json.hpp> - -void printAll(const nlohmann::json& json); diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp deleted file mode 100644 index 0143bb0..0000000 --- a/include/VerificationExecutor.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "Executor.hpp" -#include "VerificationTask.hpp" - -class VerificationExecutor : public Executor { -public: - VerificationExecutor() = default; - - [[nodiscard]] const std::unique_ptr<VerificationTask>& getTask() const; - - void setTask(std::unique_ptr<VerificationTask>& task); - -protected: - std::unique_ptr<VerificationTask> mTask; -}; diff --git a/include/executors/AlternatingVerificationExecutor.hpp b/include/executors/AlternatingVerificationExecutor.hpp new file mode 100644 index 0000000..072687e --- /dev/null +++ b/include/executors/AlternatingVerificationExecutor.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "EquivalenceCheckingManager.hpp" +#include "Executor.hpp" +#include "tasks/VerificationTask.hpp" + +class AlternatingVerificationExecutor : public Executor<VerificationTask> { +public: + AlternatingVerificationExecutor() = default; + + json execute(const VerificationTask& task) override; + [[nodiscard]] std::string getIdentifier() const override { + return "alternating_verification"; + } +}; diff --git a/include/executors/CircuitSimulatorExecutor.hpp b/include/executors/CircuitSimulatorExecutor.hpp new file mode 100644 index 0000000..d8d736b --- /dev/null +++ b/include/executors/CircuitSimulatorExecutor.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include "CircuitSimulator.hpp" +#include "Executor.hpp" +#include "tasks/SimulationTask.hpp" + +class CircuitSimulatorExecutor : public Executor<SimulationTask> { +public: + CircuitSimulatorExecutor() = default; + + json execute(const SimulationTask& task) override; + [[nodiscard]] std::string getIdentifier() const override { + return "circuit_simulator"; + }; +}; diff --git a/include/SimulationTask.hpp b/include/tasks/SimulationTask.hpp similarity index 70% rename from include/SimulationTask.hpp rename to include/tasks/SimulationTask.hpp index c67e7bd..6911824 100644 --- a/include/SimulationTask.hpp +++ b/include/tasks/SimulationTask.hpp @@ -3,6 +3,8 @@ #include "QuantumComputation.hpp" #include "Task.hpp" +#include <memory> + class SimulationTask : public Task { public: SimulationTask() = default; @@ -10,8 +12,13 @@ class SimulationTask : public Task { explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> qc) : qc(std::move(qc)) {} - [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const; - std::string getIdentifier() override; + [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const { + return qc; + }; + + [[nodiscard]] std::string getIdentifier() const override { + return "sim_" + qc->getName(); + }; protected: std::unique_ptr<qc::QuantumComputation> qc; diff --git a/include/VerificationTask.hpp b/include/tasks/VerificationTask.hpp similarity index 72% rename from include/VerificationTask.hpp rename to include/tasks/VerificationTask.hpp index eb71402..917420c 100644 --- a/include/VerificationTask.hpp +++ b/include/tasks/VerificationTask.hpp @@ -3,20 +3,28 @@ #include "QuantumComputation.hpp" #include "Task.hpp" +#include <memory> + class VerificationTask : public Task { public: VerificationTask() = default; VerificationTask(std::unique_ptr<qc::QuantumComputation> qc1, std::unique_ptr<qc::QuantumComputation> qc2) : qc1(std::move(qc1)), qc2(std::move(qc2)) {} - std::string getIdentifier() override; + [[nodiscard]] std::string getIdentifier() const override { + return "ver_" + qc1->getName() + "_" + qc2->getName(); + }; protected: std::unique_ptr<qc::QuantumComputation> qc1; std::unique_ptr<qc::QuantumComputation> qc2; public: - [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const; + [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const { + return qc1; + }; - [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc2() const; + [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc2() const { + return qc2; + }; }; diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp index d2799cc..115e791 100644 --- a/src/AlternatingVerificationExecutor.cpp +++ b/src/AlternatingVerificationExecutor.cpp @@ -1,36 +1,27 @@ -#include "AlternatingVerificationExecutor.hpp" +#include "executors/AlternatingVerificationExecutor.hpp" -AlternatingVerificationExecutor::AlternatingVerificationExecutor( - std::unique_ptr<VerificationTask> verificationTask) { - mTask = std::move(verificationTask); - auto qc1 = mTask->getQc1()->clone(); - auto qc2 = mTask->getQc2()->clone(); - mEquivalenceCheckingManager = - std::make_unique<ec::EquivalenceCheckingManager>(qc1, qc2); - mEquivalenceCheckingManager->setAlternatingChecker(true); - mEquivalenceCheckingManager->setSimulationChecker(false); - mEquivalenceCheckingManager->setConstructionChecker(false); - mEquivalenceCheckingManager->setZXChecker(false); -} - -std::string AlternatingVerificationExecutor::getIdentifier() { - return "alt_ver_exe" + mTask->getIdentifier(); -} - -json AlternatingVerificationExecutor::executeTask() { +json AlternatingVerificationExecutor::execute(const VerificationTask& task) { json result; - auto start = std::chrono::high_resolution_clock::now(); + auto start = std::chrono::steady_clock::now(); + + auto qc1 = task.getQc1()->clone(); + auto qc2 = task.getQc2()->clone(); + auto equivalenceCheckingManager = + std::make_unique<ec::EquivalenceCheckingManager>(*task.getQc1(), + *task.getQc2()); + equivalenceCheckingManager->disableAllCheckers(); + equivalenceCheckingManager->setAlternatingChecker(true); - mEquivalenceCheckingManager->run(); - result = mEquivalenceCheckingManager->getResults().json(); + equivalenceCheckingManager->run(); + result["check_results"] = equivalenceCheckingManager->getResults().json(); // Add memory usage - auto stop = std::chrono::high_resolution_clock::now(); + auto stop = std::chrono::steady_clock::now(); auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(stop - start); result["runtime"] = runtime.count(); - std::string const identifier = - this->getTask()->getIdentifier() + "_" + this->getIdentifier(); - result["identifier"] = identifier; + + result["executor"] = getIdentifier(); + result["task"] = task.getIdentifier(); return result; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 93f09be..7795456 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,21 +10,13 @@ if(NOT TARGET ${PROJECT_NAME}) add_library( ${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/include/Executor.hpp - ${PROJECT_SOURCE_DIR}/include/SimulationExecutor.hpp - ${PROJECT_SOURCE_DIR}/include/VerificationExecutor.hpp - ${PROJECT_SOURCE_DIR}/include/CircuitSimulatorExecutor.hpp - ${PROJECT_SOURCE_DIR}/include/AlternatingVerificationExecutor.hpp + ${PROJECT_SOURCE_DIR}/include/executors/CircuitSimulatorExecutor.hpp + ${PROJECT_SOURCE_DIR}/include/executors/AlternatingVerificationExecutor.hpp ${PROJECT_SOURCE_DIR}/include/Task.hpp - ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp - ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp - ${PROJECT_SOURCE_DIR}/include/TestHelpers.hpp - TestHelpers.cpp - SimulationExecutor.cpp + ${PROJECT_SOURCE_DIR}/include/tasks/SimulationTask.hpp + ${PROJECT_SOURCE_DIR}/include/tasks/VerificationTask.hpp CircuitSimulatorExecutor.cpp - VerificationExecutor.cpp - AlternatingVerificationExecutor.cpp - SimulationTask.cpp - VerificationTask.cpp) + AlternatingVerificationExecutor.cpp) # set include directories target_include_directories( diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 9c76141..6a73dd1 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -1,37 +1,21 @@ -#include "CircuitSimulatorExecutor.hpp" +#include "executors/CircuitSimulatorExecutor.hpp" -CircuitSimulatorExecutor::CircuitSimulatorExecutor( - std::unique_ptr<SimulationTask> simulationTask) { - mTask = std::move(simulationTask); - auto qc = std::make_unique<qc::QuantumComputation>(mTask->getQc()->clone()); - mCircuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc)); -} - -std::string CircuitSimulatorExecutor::getIdentifier() { - return "circ_sim_exe" + mTask->getIdentifier(); -} - -template <typename KTy, typename VTy> -inline void toJson(json& j, const std::map<KTy, VTy>& m) { - for (const auto& entry : m) { - j[entry.first] = entry.second; - } -} - -json CircuitSimulatorExecutor::executeTask() { +json CircuitSimulatorExecutor::execute(const SimulationTask& task) { json result; - auto start = std::chrono::high_resolution_clock::now(); + auto start = std::chrono::steady_clock::now(); + + auto qc = std::make_unique<qc::QuantumComputation>(task.getQc()->clone()); + auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc)); - result["measurement_results"] = mCircuitSimulator->simulate(1024U); + result["measurement_results"] = circuitSimulator->simulate(1024U); // Add memory usage - auto stop = std::chrono::high_resolution_clock::now(); - auto runtime = + auto stop = std::chrono::steady_clock::now(); + auto const runtime = std::chrono::duration_cast<std::chrono::microseconds>(stop - start); - result["runtime"] = runtime.count(); - std::string const identifier = - this->getTask()->getIdentifier() + "_" + this->getIdentifier(); - result["identifier"] = identifier; + result["runtime"] = runtime.count(); + result["executor"] = getIdentifier(); + result["task"] = task.getIdentifier(); return result; } diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp deleted file mode 100644 index 2fd4302..0000000 --- a/src/SimulationExecutor.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "SimulationExecutor.hpp" - -const std::unique_ptr<SimulationTask>& SimulationExecutor::getTask() { - return mTask; -} diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp deleted file mode 100644 index 4e2a7cf..0000000 --- a/src/SimulationTask.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "SimulationTask.hpp" - -std::string SimulationTask::getIdentifier() { return "sim_" + qc->getName(); } - -const std::unique_ptr<qc::QuantumComputation>& SimulationTask::getQc() const { - return qc; -} diff --git a/src/TestHelpers.cpp b/src/TestHelpers.cpp deleted file mode 100644 index 48fdbf1..0000000 --- a/src/TestHelpers.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "TestHelpers.hpp" - -#include <iostream> - -void printAll(const nlohmann::json& jsonObject) { - for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) { - const auto& key = it.key(); - const auto& value = it.value(); - std::cout << key << ": " << value << std::endl; - } -} diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp deleted file mode 100644 index 075121c..0000000 --- a/src/VerificationExecutor.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "VerificationExecutor.hpp" - -const std::unique_ptr<VerificationTask>& VerificationExecutor::getTask() const { - return mTask; -} diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp deleted file mode 100644 index 851a286..0000000 --- a/src/VerificationTask.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "VerificationTask.hpp" - -std::string VerificationTask::getIdentifier() { - return "ver_" + qc1->getName() + "_" + qc2->getName(); -} - -const std::unique_ptr<qc::QuantumComputation>& -VerificationTask::getQc1() const { - return qc1; -} - -const std::unique_ptr<qc::QuantumComputation>& -VerificationTask::getQc2() const { - return qc2; -} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b286f68..a5565ee 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,12 +13,5 @@ configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY) configure_file(${CMAKE_SOURCE_DIR}/test/equi_circuits.json ${CMAKE_CURRENT_BINARY_DIR}/equi_circuits.json COPYONLY) -package_add_test( - ${PROJECT_NAME}_test - ${PROJECT_NAME} - test_ddsim_simple.cpp - test_qcec_simple.cpp - test_simexec_simple.cpp - test_simexec.cpp - test_qcecexec_simple.cpp - test_qcecexec.cpp) +package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp + test_qcec_simple.cpp test_simexec.cpp test_qcecexec.cpp) diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index de773d7..9947c81 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -1,6 +1,5 @@ -#include "AlternatingVerificationExecutor.hpp" -#include "TestHelpers.hpp" -#include "VerificationTask.hpp" +#include "executors/AlternatingVerificationExecutor.hpp" +#include "tasks/VerificationTask.hpp" #include "gtest/gtest.h" @@ -50,8 +49,7 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { std::move(qc2Ver)); alternatingVerificationExecutor = - std::make_unique<AlternatingVerificationExecutor>( - std::move(verificationTask)); + std::make_unique<AlternatingVerificationExecutor>(); } void TearDown() override { std::cout << "Tearing down...\n"; } @@ -71,8 +69,9 @@ INSTANTIATE_TEST_SUITE_P( }); TEST_P(QCECExecTest, EmptyCircuits) { - json const result = alternatingVerificationExecutor->executeTask(); + json const result = + alternatingVerificationExecutor->execute(*verificationTask); std::cout << "Results:" << std::endl; - printAll(result); - EXPECT_EQ(result["equivalence"], test.expectedEquivalence); + std::cout << result.dump(2U) << std::endl; + EXPECT_EQ(result["check_results"]["equivalence"], test.expectedEquivalence); } diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp deleted file mode 100644 index c11107f..0000000 --- a/test/test_qcecexec_simple.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "AlternatingVerificationExecutor.hpp" -#include "VerificationTask.hpp" - -#include <gtest/gtest.h> -#include <memory> - -TEST(QCECExecSimpleTest, SimpleCircuit) { - auto qc1 = std::make_unique<qc::QuantumComputation>(2U); - qc1->x(0U); - qc1->x(1U); - auto qc2 = std::make_unique<qc::QuantumComputation>(2U); - qc2->x(0U); - qc2->x(0U); - qc2->x(0U); - qc2->x(1U); - auto verificationTask = - std::make_unique<VerificationTask>(std::move(qc1), std::move(qc2)); - auto alternatingVerificationExecutor = - std::make_unique<AlternatingVerificationExecutor>( - std::move(verificationTask)); - - json const result = alternatingVerificationExecutor->executeTask(); - - EXPECT_EQ("equivalent", result["equivalence"]); -} diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 6c824fd..353be67 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -1,6 +1,5 @@ -#include "CircuitSimulatorExecutor.hpp" -#include "SimulationTask.hpp" -#include "TestHelpers.hpp" +#include "executors/CircuitSimulatorExecutor.hpp" +#include "tasks/SimulationTask.hpp" #include "gtest/gtest.h" @@ -33,13 +32,12 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { test = GetParam(); std::stringstream ss(test.initialCircuit); - auto qc = std::make_unique<qc::QuantumComputation>() - : qc->import(ss, qc::Format::OpenQASM); + auto qc = std::make_unique<qc::QuantumComputation>(); + qc->import(ss, qc::Format::OpenQASM); std::cout << "Circuit:\n" << qc; - simulationTask = std::make_unique<SimulationTask>(std::move(qc)); - circuitSimulatorExecutor = - std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask)); + simulationTask = std::make_unique<SimulationTask>(std::move(qc)); + circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); } void TearDown() override { std::cout << "Tearing down...\n"; } @@ -57,8 +55,11 @@ INSTANTIATE_TEST_SUITE_P( }); TEST_P(DDSIMExecTest, TwoQubitCircuitWithTwoXGates) { - json const result = circuitSimulatorExecutor->executeTask(); + json const result = circuitSimulatorExecutor->execute(*simulationTask); std::cout << "Results:" << std::endl; - printAll(result); - EXPECT_EQ(result["11"], test.expected11); + std::cout << result.dump(2U) << std::endl; + json const expected_results = { + {"11", test.expected11}, + }; + EXPECT_EQ(result["measurement_results"], expected_results); } diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp deleted file mode 100644 index 9ccd4ed..0000000 --- a/test/test_simexec_simple.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "CircuitSimulatorExecutor.hpp" -#include "SimulationTask.hpp" - -#include <gtest/gtest.h> -#include <memory> - -TEST(DDSIMExecSimpleTest, SimpleCircuit) { - using namespace qc::literals; - auto qc = std::make_unique<qc::QuantumComputation>(2U); - qc->h(0U); - qc->x(1U, 0_pc); - - auto simulationTask = std::make_unique<SimulationTask>(std::move(qc)); - auto circuitSimulatorExecutor = - std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask)); - json const result = circuitSimulatorExecutor->executeTask(); - EXPECT_FALSE(result.contains("01")); - EXPECT_FALSE(result.contains("10")); -} From a397089b0c2b96f8b78d86454315a56d14e85693 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Thu, 8 Jun 2023 02:21:17 +0200 Subject: [PATCH 33/43] Refactor test files to remove redundant copy --- test/test_qcecexec.cpp | 23 +++++++++-------------- test/test_simexec.cpp | 11 +++++------ 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index 9947c81..11ea383 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -33,20 +33,17 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { void SetUp() override { test = GetParam(); - std::stringstream ss1(test.initialCircuit1); - qc::QuantumComputation qc1{}; - qc1.import(ss1, qc::Format::OpenQASM); + std::stringstream ss1(test.initialCircuit1); + auto qc1 = std::make_unique<qc::QuantumComputation>(); + qc1->import(ss1, qc::Format::OpenQASM); std::cout << "Circuit 1:\n" << qc1 << std::endl; - std::stringstream ss2(test.initialCircuit2); - qc::QuantumComputation qc2{}; - qc2.import(ss2, qc::Format::OpenQASM); + std::stringstream ss2(test.initialCircuit2); + auto qc2 = std::make_unique<qc::QuantumComputation>(); + qc2->import(ss2, qc::Format::OpenQASM); std::cout << "Circuit 2:\n" << qc2 << std::endl; - qc1Ver = std::make_unique<qc::QuantumComputation>(qc1.clone()); - qc2Ver = std::make_unique<qc::QuantumComputation>(qc2.clone()); - verificationTask = std::make_unique<VerificationTask>(std::move(qc1Ver), - std::move(qc2Ver)); + verificationTask = VerificationTask(std::move(qc1), std::move(qc2)); alternatingVerificationExecutor = std::make_unique<AlternatingVerificationExecutor>(); @@ -54,9 +51,7 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { void TearDown() override { std::cout << "Tearing down...\n"; } - std::unique_ptr<qc::QuantumComputation> qc1Ver; - std::unique_ptr<qc::QuantumComputation> qc2Ver; - std::unique_ptr<VerificationTask> verificationTask; + VerificationTask verificationTask; std::unique_ptr<AlternatingVerificationExecutor> alternatingVerificationExecutor; TestConfigurationQCEC test; @@ -70,7 +65,7 @@ INSTANTIATE_TEST_SUITE_P( TEST_P(QCECExecTest, EmptyCircuits) { json const result = - alternatingVerificationExecutor->execute(*verificationTask); + alternatingVerificationExecutor->execute(verificationTask); std::cout << "Results:" << std::endl; std::cout << result.dump(2U) << std::endl; EXPECT_EQ(result["check_results"]["equivalence"], test.expectedEquivalence); diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 353be67..81a71fb 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -36,14 +36,13 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { qc->import(ss, qc::Format::OpenQASM); std::cout << "Circuit:\n" << qc; - simulationTask = std::make_unique<SimulationTask>(std::move(qc)); + simulationTask = SimulationTask(std::move(qc)); circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); } void TearDown() override { std::cout << "Tearing down...\n"; } - std::unique_ptr<qc::QuantumComputation> qcSim; - std::unique_ptr<SimulationTask> simulationTask; + SimulationTask simulationTask; std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor; TestConfigurationDDSIM test; }; @@ -55,11 +54,11 @@ INSTANTIATE_TEST_SUITE_P( }); TEST_P(DDSIMExecTest, TwoQubitCircuitWithTwoXGates) { - json const result = circuitSimulatorExecutor->execute(*simulationTask); + json const result = circuitSimulatorExecutor->execute(simulationTask); std::cout << "Results:" << std::endl; std::cout << result.dump(2U) << std::endl; - json const expected_results = { + json const expectedResults = { {"11", test.expected11}, }; - EXPECT_EQ(result["measurement_results"], expected_results); + EXPECT_EQ(result["measurement_results"], expectedResults); } From a4e752f055d7f365152c26e8756bfcbb84d14b07 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Thu, 8 Jun 2023 02:24:11 +0200 Subject: [PATCH 34/43] Track both times in execution --- src/AlternatingVerificationExecutor.cpp | 18 ++++++++++++------ src/CircuitSimulatorExecutor.cpp | 19 +++++++++++++------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp index 115e791..2325a2d 100644 --- a/src/AlternatingVerificationExecutor.cpp +++ b/src/AlternatingVerificationExecutor.cpp @@ -1,8 +1,8 @@ #include "executors/AlternatingVerificationExecutor.hpp" json AlternatingVerificationExecutor::execute(const VerificationTask& task) { - json result; - auto start = std::chrono::steady_clock::now(); + json result; + auto const constructionStart = std::chrono::steady_clock::now(); auto qc1 = task.getQc1()->clone(); auto qc2 = task.getQc2()->clone(); @@ -12,13 +12,19 @@ json AlternatingVerificationExecutor::execute(const VerificationTask& task) { equivalenceCheckingManager->disableAllCheckers(); equivalenceCheckingManager->setAlternatingChecker(true); + auto const executionStart = std::chrono::steady_clock::now(); + equivalenceCheckingManager->run(); result["check_results"] = equivalenceCheckingManager->getResults().json(); // Add memory usage - auto stop = std::chrono::steady_clock::now(); - auto runtime = - std::chrono::duration_cast<std::chrono::microseconds>(stop - start); - result["runtime"] = runtime.count(); + auto const executionStop = std::chrono::steady_clock::now(); + auto const constructionTime = + std::chrono::duration_cast<std::chrono::microseconds>(executionStart - + constructionStart); + auto const execTime = std::chrono::duration_cast<std::chrono::microseconds>( + executionStop - executionStart); + result["construction_time"] = constructionTime.count(); + result["execution_time"] = execTime.count(); result["executor"] = getIdentifier(); result["task"] = task.getIdentifier(); diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 6a73dd1..2384338 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -1,19 +1,26 @@ #include "executors/CircuitSimulatorExecutor.hpp" json CircuitSimulatorExecutor::execute(const SimulationTask& task) { - json result; - auto start = std::chrono::steady_clock::now(); + json result; + auto const constructionStart = std::chrono::steady_clock::now(); auto qc = std::make_unique<qc::QuantumComputation>(task.getQc()->clone()); auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc)); + auto const executionStart = std::chrono::steady_clock::now(); + result["measurement_results"] = circuitSimulator->simulate(1024U); // Add memory usage - auto stop = std::chrono::steady_clock::now(); - auto const runtime = - std::chrono::duration_cast<std::chrono::microseconds>(stop - start); - result["runtime"] = runtime.count(); + auto const executionStop = std::chrono::steady_clock::now(); + auto const constructionTime = + std::chrono::duration_cast<std::chrono::microseconds>(executionStart - + constructionStart); + auto const execTime = std::chrono::duration_cast<std::chrono::microseconds>( + executionStop - executionStart); + result["construction_time"] = constructionTime.count(); + result["execution_time"] = execTime.count(); + result["executor"] = getIdentifier(); result["task"] = task.getIdentifier(); From 61c45d04aa76b8b3bc6882ad01f05ea61cc277e4 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 9 Jun 2023 14:36:34 +0200 Subject: [PATCH 35/43] Fix ci issues --- test/test_qcecexec.cpp | 4 ++-- test/test_simexec.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index 11ea383..53eef79 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -36,12 +36,12 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { std::stringstream ss1(test.initialCircuit1); auto qc1 = std::make_unique<qc::QuantumComputation>(); qc1->import(ss1, qc::Format::OpenQASM); - std::cout << "Circuit 1:\n" << qc1 << std::endl; + std::cout << "Circuit 1:\n" << *qc1 << std::endl; std::stringstream ss2(test.initialCircuit2); auto qc2 = std::make_unique<qc::QuantumComputation>(); qc2->import(ss2, qc::Format::OpenQASM); - std::cout << "Circuit 2:\n" << qc2 << std::endl; + std::cout << "Circuit 2:\n" << *qc2 << std::endl; verificationTask = VerificationTask(std::move(qc1), std::move(qc2)); diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 81a71fb..0b9da73 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -34,7 +34,7 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { std::stringstream ss(test.initialCircuit); auto qc = std::make_unique<qc::QuantumComputation>(); qc->import(ss, qc::Format::OpenQASM); - std::cout << "Circuit:\n" << qc; + std::cout << "Circuit:\n" << *qc; simulationTask = SimulationTask(std::move(qc)); circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); From 49f92f189c858efc77ba8a4a5f1357d07f6f04ce Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 9 Jun 2023 15:10:30 +0200 Subject: [PATCH 36/43] Fix CI issues (continued) --- include/Task.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/Task.hpp b/include/Task.hpp index a9267a4..658e71d 100644 --- a/include/Task.hpp +++ b/include/Task.hpp @@ -1,5 +1,7 @@ #pragma once +#include <string> + class Task { public: virtual ~Task() = default; From fa3c7e5638206c0b033a383ea9ae37cb03153823 Mon Sep 17 00:00:00 2001 From: Tianyi Wang <tianyi1.wang@tum.de> Date: Fri, 9 Jun 2023 15:20:52 +0200 Subject: [PATCH 37/43] Refactor tests to be more flexible --- test/circuits.json | 11 ++++++++++- test/equi_circuits.json | 6 ++++++ test/test_qcecexec.cpp | 18 +++++++++++++----- test/test_simexec.cpp | 30 ++++++++++++++++++------------ 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/test/circuits.json b/test/circuits.json index 010bcf2..75f9adc 100644 --- a/test/circuits.json +++ b/test/circuits.json @@ -2,6 +2,15 @@ { "description": "two_qubit_circuit_with_two_x_gates", "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n", - "expected_11": 1024 + "expected_meas_results": { + "11": 1024 + } + }, + { + "description": "two_qubit_circuit_with_h_z_controlled_x_swap", + "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n", + "expected_meas_results": { + "10": 1024 + } } ] diff --git a/test/equi_circuits.json b/test/equi_circuits.json index 6d01275..524fb62 100644 --- a/test/equi_circuits.json +++ b/test/equi_circuits.json @@ -4,5 +4,11 @@ "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n", "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];x q[0];x q[0];\n", "expected_equivalence": "equivalent" + }, + { + "description": "non_equi_circuits", + "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[0];t q[1];cx q[0], q[1];\n", + "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[1];cx q[0], q[1];s q[0];\n", + "expected_equivalence": "not_equivalent" } ] diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index 53eef79..5c91404 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -47,6 +47,10 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { alternatingVerificationExecutor = std::make_unique<AlternatingVerificationExecutor>(); + + result = alternatingVerificationExecutor->execute(verificationTask); + std::cout << "Results:" << std::endl; + std::cout << result.dump(2U) << std::endl; } void TearDown() override { std::cout << "Tearing down...\n"; } @@ -55,6 +59,7 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { std::unique_ptr<AlternatingVerificationExecutor> alternatingVerificationExecutor; TestConfigurationQCEC test; + json result; }; INSTANTIATE_TEST_SUITE_P( @@ -63,10 +68,13 @@ INSTANTIATE_TEST_SUITE_P( return inf.param.description; }); -TEST_P(QCECExecTest, EmptyCircuits) { - json const result = - alternatingVerificationExecutor->execute(verificationTask); - std::cout << "Results:" << std::endl; - std::cout << result.dump(2U) << std::endl; +TEST_P(QCECExecTest, Equivalence) { EXPECT_EQ(result["check_results"]["equivalence"], test.expectedEquivalence); } + +TEST_P(QCECExecTest, Entries) { + EXPECT_TRUE(result.contains("construction_time")); + EXPECT_TRUE(result.contains("execution_time")); + EXPECT_TRUE(result.contains("executor")); + EXPECT_TRUE(result.contains("task")); +} diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 0b9da73..3976447 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -9,14 +9,14 @@ struct TestConfigurationDDSIM { std::string initialCircuit; // expected output - std::size_t expected11{}; + json expectedResults{}; }; // NOLINTNEXTLINE (readability-identifier-naming) inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) { - test.description = j.at("description").get<std::string>(); - test.initialCircuit = j.at("initial_circuit").get<std::string>(); - test.expected11 = j.at("expected_11").get<std::size_t>(); + test.description = j.at("description").get<std::string>(); + test.initialCircuit = j.at("initial_circuit").get<std::string>(); + test.expectedResults = j.at("expected_meas_results").get<json>(); } static std::vector<TestConfigurationDDSIM> getTests(const std::string& path) { @@ -38,6 +38,10 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { simulationTask = SimulationTask(std::move(qc)); circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); + + result = circuitSimulatorExecutor->execute(simulationTask); + std::cout << "Results:" << std::endl; + std::cout << result.dump(2U) << std::endl; } void TearDown() override { std::cout << "Tearing down...\n"; } @@ -45,6 +49,7 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { SimulationTask simulationTask; std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor; TestConfigurationDDSIM test; + json result; }; INSTANTIATE_TEST_SUITE_P( @@ -53,12 +58,13 @@ INSTANTIATE_TEST_SUITE_P( return inf.param.description; }); -TEST_P(DDSIMExecTest, TwoQubitCircuitWithTwoXGates) { - json const result = circuitSimulatorExecutor->execute(simulationTask); - std::cout << "Results:" << std::endl; - std::cout << result.dump(2U) << std::endl; - json const expectedResults = { - {"11", test.expected11}, - }; - EXPECT_EQ(result["measurement_results"], expectedResults); +TEST_P(DDSIMExecTest, MeasResults) { + EXPECT_EQ(result["measurement_results"], test.expectedResults); +} + +TEST_P(DDSIMExecTest, Entries) { + EXPECT_TRUE(result.contains("construction_time")); + EXPECT_TRUE(result.contains("execution_time")); + EXPECT_TRUE(result.contains("executor")); + EXPECT_TRUE(result.contains("task")); } From 37592a6d2acd2863e210f179250f2ce617960a6c Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer <lukas.burgholzer@jku.at> Date: Fri, 9 Jun 2023 18:18:54 +0200 Subject: [PATCH 38/43] =?UTF-8?q?=F0=9F=8E=A8=20assorted=20cleanups?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/Executor.hpp | 6 ++-- include/Task.hpp | 3 +- .../AlternatingVerificationExecutor.hpp | 4 +-- .../executors/CircuitSimulatorExecutor.hpp | 4 +-- include/tasks/SimulationTask.hpp | 13 ++++---- include/tasks/VerificationTask.hpp | 18 +++++----- src/AlternatingVerificationExecutor.cpp | 4 +-- src/CircuitSimulatorExecutor.cpp | 2 ++ test/CMakeLists.txt | 12 +++---- test/equi_circuits.json | 14 -------- test/{circuits.json => sim_circuits.json} | 4 +-- test/test_ddsim_simple.cpp | 20 ----------- test/test_qcec_simple.cpp | 19 ----------- test/test_qcecexec.cpp | 30 ++++++++--------- test/test_simexec.cpp | 33 +++++++++---------- test/ver_circuits.json | 14 ++++++++ 16 files changed, 77 insertions(+), 123 deletions(-) delete mode 100644 test/equi_circuits.json rename test/{circuits.json => sim_circuits.json} (54%) delete mode 100644 test/test_ddsim_simple.cpp delete mode 100644 test/test_qcec_simple.cpp create mode 100644 test/ver_circuits.json diff --git a/include/Executor.hpp b/include/Executor.hpp index fafded8..4879301 100644 --- a/include/Executor.hpp +++ b/include/Executor.hpp @@ -12,8 +12,8 @@ template <class T> class Executor { public: virtual ~Executor() = default; - explicit Executor() = default; - virtual json execute(const T& task) = 0; - [[nodiscard]] virtual std::string getIdentifier() const = 0; + virtual json execute(const T& task) = 0; + + [[nodiscard]] virtual std::string getIdentifier() const = 0; }; diff --git a/include/Task.hpp b/include/Task.hpp index 658e71d..bb94571 100644 --- a/include/Task.hpp +++ b/include/Task.hpp @@ -4,6 +4,7 @@ class Task { public: - virtual ~Task() = default; + virtual ~Task() = default; + [[nodiscard]] virtual std::string getIdentifier() const = 0; }; diff --git a/include/executors/AlternatingVerificationExecutor.hpp b/include/executors/AlternatingVerificationExecutor.hpp index 072687e..f133246 100644 --- a/include/executors/AlternatingVerificationExecutor.hpp +++ b/include/executors/AlternatingVerificationExecutor.hpp @@ -1,14 +1,12 @@ #pragma once -#include "EquivalenceCheckingManager.hpp" #include "Executor.hpp" #include "tasks/VerificationTask.hpp" class AlternatingVerificationExecutor : public Executor<VerificationTask> { public: - AlternatingVerificationExecutor() = default; + json execute(const VerificationTask& task) override; - json execute(const VerificationTask& task) override; [[nodiscard]] std::string getIdentifier() const override { return "alternating_verification"; } diff --git a/include/executors/CircuitSimulatorExecutor.hpp b/include/executors/CircuitSimulatorExecutor.hpp index d8d736b..10987af 100644 --- a/include/executors/CircuitSimulatorExecutor.hpp +++ b/include/executors/CircuitSimulatorExecutor.hpp @@ -1,14 +1,12 @@ #pragma once -#include "CircuitSimulator.hpp" #include "Executor.hpp" #include "tasks/SimulationTask.hpp" class CircuitSimulatorExecutor : public Executor<SimulationTask> { public: - CircuitSimulatorExecutor() = default; + json execute(const SimulationTask& task) override; - json execute(const SimulationTask& task) override; [[nodiscard]] std::string getIdentifier() const override { return "circuit_simulator"; }; diff --git a/include/tasks/SimulationTask.hpp b/include/tasks/SimulationTask.hpp index 6911824..dae4bdd 100644 --- a/include/tasks/SimulationTask.hpp +++ b/include/tasks/SimulationTask.hpp @@ -7,19 +7,18 @@ class SimulationTask : public Task { public: - SimulationTask() = default; + explicit SimulationTask() = default; + explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> circ) + : qc(std::move(circ)) {} - explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> qc) - : qc(std::move(qc)) {} + [[nodiscard]] std::string getIdentifier() const override { + return "sim_" + qc->getName(); + }; [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const { return qc; }; - [[nodiscard]] std::string getIdentifier() const override { - return "sim_" + qc->getName(); - }; - protected: std::unique_ptr<qc::QuantumComputation> qc; }; diff --git a/include/tasks/VerificationTask.hpp b/include/tasks/VerificationTask.hpp index 917420c..8a33f2b 100644 --- a/include/tasks/VerificationTask.hpp +++ b/include/tasks/VerificationTask.hpp @@ -7,19 +7,15 @@ class VerificationTask : public Task { public: - VerificationTask() = default; - VerificationTask(std::unique_ptr<qc::QuantumComputation> qc1, - std::unique_ptr<qc::QuantumComputation> qc2) - : qc1(std::move(qc1)), qc2(std::move(qc2)) {} + explicit VerificationTask() = default; + VerificationTask(std::unique_ptr<qc::QuantumComputation> circ1, + std::unique_ptr<qc::QuantumComputation> circ2) + : qc1(std::move(circ1)), qc2(std::move(circ2)) {} + [[nodiscard]] std::string getIdentifier() const override { return "ver_" + qc1->getName() + "_" + qc2->getName(); }; -protected: - std::unique_ptr<qc::QuantumComputation> qc1; - std::unique_ptr<qc::QuantumComputation> qc2; - -public: [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const { return qc1; }; @@ -27,4 +23,8 @@ class VerificationTask : public Task { [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc2() const { return qc2; }; + +protected: + std::unique_ptr<qc::QuantumComputation> qc1; + std::unique_ptr<qc::QuantumComputation> qc2; }; diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp index 2325a2d..1ebb051 100644 --- a/src/AlternatingVerificationExecutor.cpp +++ b/src/AlternatingVerificationExecutor.cpp @@ -1,11 +1,11 @@ #include "executors/AlternatingVerificationExecutor.hpp" +#include "EquivalenceCheckingManager.hpp" + json AlternatingVerificationExecutor::execute(const VerificationTask& task) { json result; auto const constructionStart = std::chrono::steady_clock::now(); - auto qc1 = task.getQc1()->clone(); - auto qc2 = task.getQc2()->clone(); auto equivalenceCheckingManager = std::make_unique<ec::EquivalenceCheckingManager>(*task.getQc1(), *task.getQc2()); diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp index 2384338..367989a 100644 --- a/src/CircuitSimulatorExecutor.cpp +++ b/src/CircuitSimulatorExecutor.cpp @@ -1,5 +1,7 @@ #include "executors/CircuitSimulatorExecutor.hpp" +#include "CircuitSimulator.hpp" + json CircuitSimulatorExecutor::execute(const SimulationTask& task) { json result; auto const constructionStart = std::chrono::steady_clock::now(); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a5565ee..6414a6c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,9 +9,9 @@ if(NOT TARGET gtest OR NOT TARGET gmock) add_subdirectory("${PROJECT_SOURCE_DIR}/${GTEST_PATH}" "${GTEST_PATH}" EXCLUDE_FROM_ALL) endif() -configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json - ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY) -configure_file(${CMAKE_SOURCE_DIR}/test/equi_circuits.json - ${CMAKE_CURRENT_BINARY_DIR}/equi_circuits.json COPYONLY) -package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp - test_qcec_simple.cpp test_simexec.cpp test_qcecexec.cpp) +configure_file(${CMAKE_SOURCE_DIR}/test/sim_circuits.json + ${CMAKE_CURRENT_BINARY_DIR}/sim_circuits.json COPYONLY) +configure_file(${CMAKE_SOURCE_DIR}/test/ver_circuits.json + ${CMAKE_CURRENT_BINARY_DIR}/ver_circuits.json COPYONLY) +package_add_test(${PROJECT_NAME}_sim_test ${PROJECT_NAME} test_simexec.cpp) +package_add_test(${PROJECT_NAME}_ver_test ${PROJECT_NAME} test_qcecexec.cpp) diff --git a/test/equi_circuits.json b/test/equi_circuits.json deleted file mode 100644 index 524fb62..0000000 --- a/test/equi_circuits.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "description": "simple_circuits", - "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n", - "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];x q[0];x q[0];\n", - "expected_equivalence": "equivalent" - }, - { - "description": "non_equi_circuits", - "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[0];t q[1];cx q[0], q[1];\n", - "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[1];cx q[0], q[1];s q[0];\n", - "expected_equivalence": "not_equivalent" - } -] diff --git a/test/circuits.json b/test/sim_circuits.json similarity index 54% rename from test/circuits.json rename to test/sim_circuits.json index 75f9adc..1602d8a 100644 --- a/test/circuits.json +++ b/test/sim_circuits.json @@ -1,14 +1,14 @@ [ { "description": "two_qubit_circuit_with_two_x_gates", - "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n", + "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n", "expected_meas_results": { "11": 1024 } }, { "description": "two_qubit_circuit_with_h_z_controlled_x_swap", - "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n", + "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n", "expected_meas_results": { "10": 1024 } diff --git a/test/test_ddsim_simple.cpp b/test/test_ddsim_simple.cpp deleted file mode 100644 index 210cce0..0000000 --- a/test/test_ddsim_simple.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// A simple test file using googletest to ensure DDSIM is working properly - -#include "CircuitSimulator.hpp" - -#include <gtest/gtest.h> -#include <memory> - -TEST(DDSIMSimpleTest, SimpleTest) { - using namespace qc::literals; - - // Create a simple circuit - auto qc = std::make_unique<qc::QuantumComputation>(2U); - qc->h(0U); - qc->x(1U, 0_pc); - - auto sim = CircuitSimulator(std::move(qc)); - const auto results = sim.simulate(1024U); - EXPECT_EQ(results.count("01"), 0U); - EXPECT_EQ(results.count("10"), 0U); -} diff --git a/test/test_qcec_simple.cpp b/test/test_qcec_simple.cpp deleted file mode 100644 index a4323f5..0000000 --- a/test/test_qcec_simple.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// A simple test file using googletest to ensure QCEC is working properly - -#include "EquivalenceCheckingManager.hpp" - -#include <gtest/gtest.h> - -TEST(QCECSimpleTest, SimpleTest) { - using namespace qc::literals; - - // Create a simple circuit - auto qc = qc::QuantumComputation(2U); - qc.h(0U); - qc.x(1U, 0_pc); - - // check the circuit against itself - auto ecm = ec::EquivalenceCheckingManager(qc, qc); - ecm.run(); - EXPECT_TRUE(ecm.getResults().consideredEquivalent()); -} diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index 5c91404..46a9766 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -6,8 +6,8 @@ struct TestConfigurationQCEC { // given input std::string description; - std::string initialCircuit1; - std::string initialCircuit2; + std::string circuit1; + std::string circuit2; // expected output std::string expectedEquivalence; @@ -16,8 +16,8 @@ struct TestConfigurationQCEC { // NOLINTNEXTLINE (readability-identifier-naming) inline void from_json(const nlohmann::json& j, TestConfigurationQCEC& test) { test.description = j.at("description").get<std::string>(); - test.initialCircuit1 = j.at("initial_circuit1").get<std::string>(); - test.initialCircuit2 = j.at("initial_circuit2").get<std::string>(); + test.circuit1 = j.at("circuit1").get<std::string>(); + test.circuit2 = j.at("circuit2").get<std::string>(); test.expectedEquivalence = j.at("expected_equivalence").get<std::string>(); } @@ -33,12 +33,12 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { void SetUp() override { test = GetParam(); - std::stringstream ss1(test.initialCircuit1); + std::stringstream ss1(test.circuit1); auto qc1 = std::make_unique<qc::QuantumComputation>(); qc1->import(ss1, qc::Format::OpenQASM); std::cout << "Circuit 1:\n" << *qc1 << std::endl; - std::stringstream ss2(test.initialCircuit2); + std::stringstream ss2(test.circuit2); auto qc2 = std::make_unique<qc::QuantumComputation>(); qc2->import(ss2, qc::Format::OpenQASM); std::cout << "Circuit 2:\n" << *qc2 << std::endl; @@ -47,32 +47,28 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { alternatingVerificationExecutor = std::make_unique<AlternatingVerificationExecutor>(); - - result = alternatingVerificationExecutor->execute(verificationTask); - std::cout << "Results:" << std::endl; - std::cout << result.dump(2U) << std::endl; } - void TearDown() override { std::cout << "Tearing down...\n"; } - VerificationTask verificationTask; std::unique_ptr<AlternatingVerificationExecutor> alternatingVerificationExecutor; TestConfigurationQCEC test; - json result; }; INSTANTIATE_TEST_SUITE_P( - Circuits, QCECExecTest, testing::ValuesIn(getTests("equi_circuits.json")), + Circuits, QCECExecTest, testing::ValuesIn(getTests("ver_circuits.json")), [](const testing::TestParamInfo<QCECExecTest::ParamType>& inf) { return inf.param.description; }); -TEST_P(QCECExecTest, Equivalence) { +TEST_P(QCECExecTest, Tests) { + const auto result = + alternatingVerificationExecutor->execute(verificationTask); + std::cout << "Results:\n" << result.dump(2U) << std::endl; + + ASSERT_TRUE(result.contains("check_results")); EXPECT_EQ(result["check_results"]["equivalence"], test.expectedEquivalence); -} -TEST_P(QCECExecTest, Entries) { EXPECT_TRUE(result.contains("construction_time")); EXPECT_TRUE(result.contains("execution_time")); EXPECT_TRUE(result.contains("executor")); diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 3976447..27661e1 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -6,7 +6,7 @@ struct TestConfigurationDDSIM { // given input std::string description; - std::string initialCircuit; + std::string circuit; // expected output json expectedResults{}; @@ -15,54 +15,53 @@ struct TestConfigurationDDSIM { // NOLINTNEXTLINE (readability-identifier-naming) inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) { test.description = j.at("description").get<std::string>(); - test.initialCircuit = j.at("initial_circuit").get<std::string>(); + test.circuit = j.at("circuit").get<std::string>(); test.expectedResults = j.at("expected_meas_results").get<json>(); } -static std::vector<TestConfigurationDDSIM> getTests(const std::string& path) { +namespace { +std::vector<TestConfigurationDDSIM> getTests(const std::string& path) { std::ifstream input(path); nlohmann::json j; input >> j; return j; } +} // namespace class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> { protected: void SetUp() override { test = GetParam(); + std::stringstream ss(test.circuit); - std::stringstream ss(test.initialCircuit); - auto qc = std::make_unique<qc::QuantumComputation>(); + auto qc = std::make_unique<qc::QuantumComputation>(); qc->import(ss, qc::Format::OpenQASM); std::cout << "Circuit:\n" << *qc; simulationTask = SimulationTask(std::move(qc)); circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>(); - - result = circuitSimulatorExecutor->execute(simulationTask); - std::cout << "Results:" << std::endl; - std::cout << result.dump(2U) << std::endl; } - void TearDown() override { std::cout << "Tearing down...\n"; } - SimulationTask simulationTask; std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor; TestConfigurationDDSIM test; - json result; }; INSTANTIATE_TEST_SUITE_P( - Circuits, DDSIMExecTest, testing::ValuesIn(getTests("circuits.json")), + Circuits, DDSIMExecTest, testing::ValuesIn(getTests("sim_circuits.json")), [](const testing::TestParamInfo<DDSIMExecTest::ParamType>& inf) { return inf.param.description; }); -TEST_P(DDSIMExecTest, MeasResults) { - EXPECT_EQ(result["measurement_results"], test.expectedResults); -} +TEST_P(DDSIMExecTest, Tests) { + const auto result = circuitSimulatorExecutor->execute(simulationTask); + std::cout << "Results:\n" << result.dump(2U) << std::endl; + + ASSERT_TRUE(result.contains("measurement_results")); + if (!result["measurement_results"].empty()) { + EXPECT_EQ(result["measurement_results"], test.expectedResults); + } -TEST_P(DDSIMExecTest, Entries) { EXPECT_TRUE(result.contains("construction_time")); EXPECT_TRUE(result.contains("execution_time")); EXPECT_TRUE(result.contains("executor")); diff --git a/test/ver_circuits.json b/test/ver_circuits.json new file mode 100644 index 0000000..0f7814a --- /dev/null +++ b/test/ver_circuits.json @@ -0,0 +1,14 @@ +[ + { + "description": "simple_circuits", + "circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n", + "circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];x q[0];x q[0];\n", + "expected_equivalence": "equivalent" + }, + { + "description": "non_equi_circuits", + "circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[0];t q[1];cx q[0], q[1];\n", + "circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[1];cx q[0], q[1];s q[0];\n", + "expected_equivalence": "not_equivalent" + } +] From f8e3dec777f908c02e544bfe771fe243fbcdd3d2 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer <lukas.burgholzer@jku.at> Date: Fri, 9 Jun 2023 18:22:14 +0200 Subject: [PATCH 39/43] =?UTF-8?q?=E2=9A=97=EF=B8=8F=20try=20newer=20cpp-li?= =?UTF-8?q?nter=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cpp-linter.yml | 45 ++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cpp-linter.yml b/.github/workflows/cpp-linter.yml index 36f8545..3ef8ecb 100644 --- a/.github/workflows/cpp-linter.yml +++ b/.github/workflows/cpp-linter.yml @@ -2,7 +2,6 @@ name: cpp-linter on: pull_request: - merge_group: push: branches: - main @@ -12,6 +11,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true +env: + clang-version: 16 + jobs: cpp-linter: runs-on: ubuntu-latest @@ -19,21 +21,42 @@ jobs: - uses: actions/checkout@v3 with: submodules: recursive + + - name: Install clang-${{ env.clang-version }} + run: | + sudo apt-get update + wget https://apt.llvm.org/llvm.sh -O ${{ runner.temp }}/llvm_install.sh + chmod +x ${{ runner.temp }}/llvm_install.sh + if sudo ${{ runner.temp }}/llvm_install.sh ${{ env.clang-version }}; then + sudo apt-get install -y clang-format-${{ env.clang-version }} clang-tidy-${{ env.clang-version }} + fi + echo "CC=clang-${{ env.clang-version }}" >> $GITHUB_ENV + echo "CXX=clang++-${{ env.clang-version }}" >> $GITHUB_ENV + - name: Generate compilation database - run: CC=clang-14 CXX=clang++-14 cmake -S . -B build -DBUILD_DD_EVAL_TESTS=ON + run: | + echo $CC + echo $CXX + $CC --version + $CXX --version + cmake -S . -B build -DBUILD_DD_EVAL_TESTS=ON + - name: Run cpp-linter + uses: cpp-linter/cpp-linter-action@v2 id: linter env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - pipx run cpp-linter \ - --version=14 \ - --style="" \ - --tidy-checks="" \ - --thread-comments=true \ - --files-changed-only=true \ - --ignore="build" \ - --database=build + with: + style: "" + tidy-checks: "" + version: 16 + ignore: build + thread-comments: true + step-summary: true + database: "build" + extra-args: -std=c++17 + files-changed-only: true + - name: Fail if linter found errors if: steps.linter.outputs.checks-failed > 0 run: echo "Linter found errors" && exit 1 From 7a96d3cf65abd97e752f8c256429e13ad82d2056 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer <lukas.burgholzer@jku.at> Date: Fri, 9 Jun 2023 18:30:00 +0200 Subject: [PATCH 40/43] =?UTF-8?q?=F0=9F=A9=B9=20fix=20CI=20coverage=20conf?= =?UTF-8?q?iguration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cce5165..a04e5ff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,7 +45,7 @@ jobs: name: Coverage run: | cmake -S . -B buildCov -DCMAKE_BUILD_TYPE=Debug -DBUILD_DD_EVAL_TESTS=ON -DENABLE_COVERAGE=ON - cmake --build buildCov --config Debug --target DDEval_test + cmake --build buildCov --config Debug ctest -C Debug --output-on-failure --test-dir buildCov --repeat until-pass:3 --timeout 300 - if: runner.os == 'Linux' name: Upload coverage to Codecov From 1b750ea75530b98e18c1e679725b298d10e769a4 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer <lukas.burgholzer@jku.at> Date: Fri, 9 Jun 2023 18:41:53 +0200 Subject: [PATCH 41/43] =?UTF-8?q?=F0=9F=9A=A8=20another=20clang-tidy=20war?= =?UTF-8?q?ning=20fixed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/test_qcecexec.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index 46a9766..d03c12f 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -21,12 +21,14 @@ inline void from_json(const nlohmann::json& j, TestConfigurationQCEC& test) { test.expectedEquivalence = j.at("expected_equivalence").get<std::string>(); } -static std::vector<TestConfigurationQCEC> getTests(const std::string& path) { +namespace { +std::vector<TestConfigurationQCEC> getTests(const std::string& path) { std::ifstream input(path); nlohmann::json j; input >> j; return j; } +} // namespace class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> { protected: From f68f5fb1b1c1ecfc00b200fe0e68877c3da579f1 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer <lukas.burgholzer@jku.at> Date: Fri, 9 Jun 2023 18:43:37 +0200 Subject: [PATCH 42/43] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20remove=20expected=20?= =?UTF-8?q?output=20from=20simulation=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the criterion is just not generalizable in a reasonable way --- test/sim_circuits.json | 10 ++-------- test/test_simexec.cpp | 12 ++---------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/test/sim_circuits.json b/test/sim_circuits.json index 1602d8a..dd73f45 100644 --- a/test/sim_circuits.json +++ b/test/sim_circuits.json @@ -1,16 +1,10 @@ [ { "description": "two_qubit_circuit_with_two_x_gates", - "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n", - "expected_meas_results": { - "11": 1024 - } + "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n" }, { "description": "two_qubit_circuit_with_h_z_controlled_x_swap", - "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n", - "expected_meas_results": { - "10": 1024 - } + "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n" } ] diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 27661e1..3c18a85 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -7,16 +7,12 @@ struct TestConfigurationDDSIM { // given input std::string description; std::string circuit; - - // expected output - json expectedResults{}; }; // NOLINTNEXTLINE (readability-identifier-naming) inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) { - test.description = j.at("description").get<std::string>(); - test.circuit = j.at("circuit").get<std::string>(); - test.expectedResults = j.at("expected_meas_results").get<json>(); + test.description = j.at("description").get<std::string>(); + test.circuit = j.at("circuit").get<std::string>(); } namespace { @@ -58,10 +54,6 @@ TEST_P(DDSIMExecTest, Tests) { std::cout << "Results:\n" << result.dump(2U) << std::endl; ASSERT_TRUE(result.contains("measurement_results")); - if (!result["measurement_results"].empty()) { - EXPECT_EQ(result["measurement_results"], test.expectedResults); - } - EXPECT_TRUE(result.contains("construction_time")); EXPECT_TRUE(result.contains("execution_time")); EXPECT_TRUE(result.contains("executor")); From bf32253e33f47bd19b6d56ca40671cedf3054030 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer <lukas.burgholzer@jku.at> Date: Fri, 9 Jun 2023 18:54:51 +0200 Subject: [PATCH 43/43] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20some=20restructuring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also make use of forward declarartions to reduce the number of imports in headers --- include/tasks/SimulationTask.hpp | 12 ++++++------ include/tasks/VerificationTask.hpp | 12 ++++++------ src/CMakeLists.txt | 6 ++++-- .../AlternatingVerificationExecutor.cpp | 0 src/{ => executors}/CircuitSimulatorExecutor.cpp | 0 src/tasks/SimulationTask.cpp | 10 ++++++++++ src/tasks/VerificationTask.cpp | 12 ++++++++++++ test/test_qcecexec.cpp | 1 + test/test_simexec.cpp | 1 + 9 files changed, 40 insertions(+), 14 deletions(-) rename src/{ => executors}/AlternatingVerificationExecutor.cpp (100%) rename src/{ => executors}/CircuitSimulatorExecutor.cpp (100%) create mode 100644 src/tasks/SimulationTask.cpp create mode 100644 src/tasks/VerificationTask.cpp diff --git a/include/tasks/SimulationTask.hpp b/include/tasks/SimulationTask.hpp index dae4bdd..17c6c36 100644 --- a/include/tasks/SimulationTask.hpp +++ b/include/tasks/SimulationTask.hpp @@ -1,19 +1,19 @@ #pragma once -#include "QuantumComputation.hpp" #include "Task.hpp" #include <memory> +namespace qc { +class QuantumComputation; +} + class SimulationTask : public Task { public: explicit SimulationTask() = default; - explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> circ) - : qc(std::move(circ)) {} + explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> circ); - [[nodiscard]] std::string getIdentifier() const override { - return "sim_" + qc->getName(); - }; + [[nodiscard]] std::string getIdentifier() const override; [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const { return qc; diff --git a/include/tasks/VerificationTask.hpp b/include/tasks/VerificationTask.hpp index 8a33f2b..80b04d4 100644 --- a/include/tasks/VerificationTask.hpp +++ b/include/tasks/VerificationTask.hpp @@ -1,20 +1,20 @@ #pragma once -#include "QuantumComputation.hpp" #include "Task.hpp" #include <memory> +namespace qc { +class QuantumComputation; +} + class VerificationTask : public Task { public: explicit VerificationTask() = default; VerificationTask(std::unique_ptr<qc::QuantumComputation> circ1, - std::unique_ptr<qc::QuantumComputation> circ2) - : qc1(std::move(circ1)), qc2(std::move(circ2)) {} + std::unique_ptr<qc::QuantumComputation> circ2); - [[nodiscard]] std::string getIdentifier() const override { - return "ver_" + qc1->getName() + "_" + qc2->getName(); - }; + [[nodiscard]] std::string getIdentifier() const override; [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const { return qc1; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7795456..9dce18f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,8 +15,10 @@ if(NOT TARGET ${PROJECT_NAME}) ${PROJECT_SOURCE_DIR}/include/Task.hpp ${PROJECT_SOURCE_DIR}/include/tasks/SimulationTask.hpp ${PROJECT_SOURCE_DIR}/include/tasks/VerificationTask.hpp - CircuitSimulatorExecutor.cpp - AlternatingVerificationExecutor.cpp) + executors/CircuitSimulatorExecutor.cpp + executors/AlternatingVerificationExecutor.cpp + tasks/SimulationTask.cpp + tasks/VerificationTask.cpp) # set include directories target_include_directories( diff --git a/src/AlternatingVerificationExecutor.cpp b/src/executors/AlternatingVerificationExecutor.cpp similarity index 100% rename from src/AlternatingVerificationExecutor.cpp rename to src/executors/AlternatingVerificationExecutor.cpp diff --git a/src/CircuitSimulatorExecutor.cpp b/src/executors/CircuitSimulatorExecutor.cpp similarity index 100% rename from src/CircuitSimulatorExecutor.cpp rename to src/executors/CircuitSimulatorExecutor.cpp diff --git a/src/tasks/SimulationTask.cpp b/src/tasks/SimulationTask.cpp new file mode 100644 index 0000000..48bf4dd --- /dev/null +++ b/src/tasks/SimulationTask.cpp @@ -0,0 +1,10 @@ +#include "tasks/SimulationTask.hpp" + +#include "QuantumComputation.hpp" + +SimulationTask::SimulationTask(std::unique_ptr<qc::QuantumComputation> circ) + : qc(std::move(circ)) {} + +std::string SimulationTask::getIdentifier() const { + return "sim_" + qc->getName(); +} diff --git a/src/tasks/VerificationTask.cpp b/src/tasks/VerificationTask.cpp new file mode 100644 index 0000000..a3d496e --- /dev/null +++ b/src/tasks/VerificationTask.cpp @@ -0,0 +1,12 @@ +#include "tasks/VerificationTask.hpp" + +#include "QuantumComputation.hpp" + +VerificationTask::VerificationTask( + std::unique_ptr<qc::QuantumComputation> circ1, + std::unique_ptr<qc::QuantumComputation> circ2) + : qc1(std::move(circ1)), qc2(std::move(circ2)) {} + +std::string VerificationTask::getIdentifier() const { + return "ver_" + qc1->getName() + "_" + qc2->getName(); +} diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp index d03c12f..da44a00 100644 --- a/test/test_qcecexec.cpp +++ b/test/test_qcecexec.cpp @@ -1,3 +1,4 @@ +#include "QuantumComputation.hpp" #include "executors/AlternatingVerificationExecutor.hpp" #include "tasks/VerificationTask.hpp" diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp index 3c18a85..4f740cd 100644 --- a/test/test_simexec.cpp +++ b/test/test_simexec.cpp @@ -1,3 +1,4 @@ +#include "QuantumComputation.hpp" #include "executors/CircuitSimulatorExecutor.hpp" #include "tasks/SimulationTask.hpp"