From 2c5b4a3546d29306364500df4e1127fb87c7978e Mon Sep 17 00:00:00 2001 From: Durganshu Date: Fri, 12 Apr 2024 17:26:53 +0200 Subject: [PATCH 01/34] Initial commit with qdmi and fomac --- cmake/Findqdmi.cmake | 9 ++++ cmake/Findqinfo.cmake | 9 ++++ examples/CMakeLists.txt | 1 + examples/qdmi-test.cpp | 20 +++++++ src/CMakeLists.txt | 33 ++++++++++-- src/fomac.cpp | 114 ++++++++++++++++++++++++++++++++++++++++ src/fomac.hpp | 43 +++++++++++++++ src/sys-sage.hpp | 1 + 8 files changed, 226 insertions(+), 4 deletions(-) create mode 100644 cmake/Findqdmi.cmake create mode 100644 cmake/Findqinfo.cmake create mode 100644 examples/qdmi-test.cpp create mode 100644 src/fomac.cpp create mode 100644 src/fomac.hpp diff --git a/cmake/Findqdmi.cmake b/cmake/Findqdmi.cmake new file mode 100644 index 0000000..4d91a76 --- /dev/null +++ b/cmake/Findqdmi.cmake @@ -0,0 +1,9 @@ +include(FetchContent) + +FetchContent_Declare( + qdmi + GIT_REPOSITORY git@github.com:Munich-Quantum-Software-Stack/QDMI.git + GIT_TAG testing +) + +FetchContent_MakeAvailable(qdmi) diff --git a/cmake/Findqinfo.cmake b/cmake/Findqinfo.cmake new file mode 100644 index 0000000..c32c398 --- /dev/null +++ b/cmake/Findqinfo.cmake @@ -0,0 +1,9 @@ +include(FetchContent) + +FetchContent_Declare( + qinfo + GIT_REPOSITORY git@github.com:Munich-Quantum-Software-Stack/QInfo.git + GIT_TAG testing +) + +FetchContent_MakeAvailable(qinfo) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ac50848..0857ecc 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable(larger_topo larger_topo.cpp) add_executable(sys-sage-benchmarking sys-sage-benchmarking.cpp) add_executable(use_custom_parser custom_parser_musa/use_custom_parser.cpp custom_parser_musa/musa_parser.cpp custom_parser_musa/musa_parser.hpp) add_executable(cccbenchplushwloc cccbenchplushwloc.cpp) +add_executable(qdmi-test qdmi-test.cpp) install(TARGETS basic_usage gpu-topo-parser custom_attributes larger_topo sys-sage-benchmarking use_custom_parser cccbenchplushwloc DESTINATION bin/examples) install(DIRECTORY example_data DESTINATION bin/examples) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp new file mode 100644 index 0000000..57c7f87 --- /dev/null +++ b/examples/qdmi-test.cpp @@ -0,0 +1,20 @@ +#include +#include + +#include "sys-sage.hpp" + + +int main() +{ + auto vec = FOMAC_available_devices(); + int count = 0; + std::cout << "Total number of devices: " << vec.size() << "\n"; + for (auto dev : vec) + { + std::cout << "Printing for device id: " << ++count << "\n"; + FOMAC_print_coupling_mappings(dev); + } + + + return 0; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54e0049..0c26212 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,7 @@ configure_file(${PROJECT_SOURCE_DIR}/src/defines.hpp.in ${PROJECT_SOURCE_DIR}/sr set(SOURCES Topology.cpp DataPath.cpp + fomac.cpp CAT_aware.cpp cpuinfo.cpp nvidia_mig.cpp @@ -21,6 +22,7 @@ set(HEADERS defines.hpp Topology.hpp DataPath.hpp + fomac.hpp xml_dump.hpp parsers/hwloc.hpp parsers/caps-numa-benchmark.hpp @@ -30,11 +32,32 @@ set(HEADERS add_library(sys-sage SHARED ${SOURCES} ${HEADERS}) -target_include_directories(sys-sage PUBLIC - $ - $ - $ +# For Quantum Systems +# Find QDMI package +find_package(qdmi REQUIRED) + +# Find QInfo package +find_package(qinfo REQUIRED) + +# Find nlohmann_json package +find_package(nlohmann_json REQUIRED) + +target_link_libraries(sys-sage PRIVATE + qdmi + qinfo + nlohmann_json::nlohmann_json + ) + +target_include_directories(sys-sage + PRIVATE ${CMAKE_BINARY_DIR}/_deps/qdmi-src/src/include/ + PUBLIC $ + $ + $ ) + + + + install( TARGETS sys-sage EXPORT sys-sage-targets @@ -62,3 +85,5 @@ install( install(DIRECTORY "." DESTINATION inc FILES_MATCHING PATTERN "*.hpp") + +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) \ No newline at end of file diff --git a/src/fomac.cpp b/src/fomac.cpp new file mode 100644 index 0000000..4c6c861 --- /dev/null +++ b/src/fomac.cpp @@ -0,0 +1,114 @@ +/** + * @file fomac.cpp + * @brief Implementation of global FoMaC. + */ + +#include "fomac.hpp" + +/** + * @brief TODO + * @return TODO + * @todo Should this become a daemon? In which node should it run? + */ +extern "C" std::vector FOMAC_available_devices() +{ + // TODO REPEAT PERIODICALLY WITH A DELAY + + char **available_devices = get_qdmi_library_list_names(); + if (available_devices == NULL) + { + std::cout << " [FoMaC]...............Failed to get " + << "qdmi_library_list from QDMI" << std::endl; + + return std::vector(); + } + + int i = 0, err = 0, status = 0; + std::vector registered_devices; + while (available_devices[i] != NULL) + { + QDMI_Device device = + (QDMI_Device)malloc(sizeof(struct QDMI_Device_impl_d)); + + QDMI_Library lib = find_library_by_name(available_devices[i]); + + if (!lib) + { + std::cout << " [FoMaC]...............A backend's library " + << "could not be found" << std::endl; + + free(available_devices[i++]); + continue; + } + + device->library = *lib; + + // TODO HANDLE err + err = QDMI_device_status(device, device->library.info, &status); + + if (status) + { + const char *device_name = strrchr(available_devices[i], '/'); + std::cout << " [FoMaC]...............Available device " + << "found: " << device_name << std::endl; + + registered_devices.push_back(device); + } + + free(available_devices[i++]); + } + free(available_devices); + + return registered_devices; +} + +/** + * @brief TODO + * @return TODO + * @todo Should this become a daemon? In which node should it run? + */ +extern "C" void FOMAC_print_coupling_mappings(QDMI_Device dev) +{ + // TODO REPEAT PERIODICALLY WITH A DELAY + + QDMI_Qubit qubits; + int err, num_qubits = 0; + + err = QDMI_query_all_qubits(dev, &qubits); + + if (err != QDMI_SUCCESS || qubits == NULL) + { + std::cout << " [FoMaC]...............Could not obtain available " + << "qubits via QDMI\n"; + return; + } + + err = QDMI_query_qubits_num(dev, &num_qubits); + + if (err != QDMI_SUCCESS || num_qubits == 0) + { + std::cout << " [FoMaC]...............Could not obtain number of " + << "available qubits via QDMI\n"; + return; + } + + for (int i = 0; i < num_qubits; i++) + { + if (qubits[i].coupling_mapping == NULL) + { + std::cout << " [FoMaC]...............No coupling mapping" + << std::endl; + continue; + } + + std::cout << " [FoMaC]...............Coupling mapping of qubit[" << i + << "]: { "; + for (int j = 0; j < qubits[i].size_coupling_mapping; j++) + std::cout << qubits[i].coupling_mapping[j] << " "; + std::cout << "}" << std::endl; + } + + free(qubits); + + return; +} \ No newline at end of file diff --git a/src/fomac.hpp b/src/fomac.hpp new file mode 100644 index 0000000..fc27bd8 --- /dev/null +++ b/src/fomac.hpp @@ -0,0 +1,43 @@ +/** + * @file fomac.hpp + * @brief Header of the global FoMaC. + */ + +#ifndef FOMAC_HPP +#define FOMAC_HPP + +#include +#include +#include + +#include +#include + +//const char *registered_devices[] = { +// "/bin/lib/libbackend_qlm.so", +// "/bin/lib/libbackend_ibm.so", +// "/bin/lib/libbackend_wmi.so", +// "/bin/lib/libbackend_q7.so", +//}; + +/** + * @brief TODO + * @return TODO + * @todo To be implemented + */ +extern "C" +{ + std::vector FOMAC_available_devices(); +} + +/** + * @brief TODO + * @return TODO + * @todo To be implemented + */ +extern "C" +{ + void FOMAC_print_coupling_mappings(QDMI_Device dev); +} + +#endif // FOMAC_HPP \ No newline at end of file diff --git a/src/sys-sage.hpp b/src/sys-sage.hpp index c2f1748..e845c1f 100644 --- a/src/sys-sage.hpp +++ b/src/sys-sage.hpp @@ -4,6 +4,7 @@ //includes all other headers #include "Topology.hpp" #include "DataPath.hpp" +#include "fomac.hpp" #include "xml_dump.hpp" #include "parsers/hwloc.hpp" #include "parsers/caps-numa-benchmark.hpp" From 0f1514de567680e66a733ea4b08c232f120c34cf Mon Sep 17 00:00:00 2001 From: Durganshu Date: Sun, 14 Apr 2024 16:07:52 +0200 Subject: [PATCH 02/34] Added Qubit, gate and Quantumbackend classes --- src/CMakeLists.txt | 4 +- src/DataPath.hpp | 27 ++++++++ src/Topology.cpp | 6 ++ src/Topology.hpp | 66 +++++++++++++++++++ src/{fomac.cpp => parsers/qdmi-interface.cpp} | 6 +- src/{fomac.hpp => parsers/qdmi-interface.hpp} | 10 +-- src/sys-sage.hpp | 3 +- 7 files changed, 110 insertions(+), 12 deletions(-) rename src/{fomac.cpp => parsers/qdmi-interface.cpp} (95%) rename src/{fomac.hpp => parsers/qdmi-interface.hpp} (76%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0c26212..3068829 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,6 @@ configure_file(${PROJECT_SOURCE_DIR}/src/defines.hpp.in ${PROJECT_SOURCE_DIR}/sr set(SOURCES Topology.cpp DataPath.cpp - fomac.cpp CAT_aware.cpp cpuinfo.cpp nvidia_mig.cpp @@ -15,6 +14,7 @@ set(SOURCES parsers/caps-numa-benchmark.cpp parsers/gpu-topo.cpp parsers/cccbench.cpp + parsers/qdmi-interface.cpp ) set(HEADERS @@ -22,12 +22,12 @@ set(HEADERS defines.hpp Topology.hpp DataPath.hpp - fomac.hpp xml_dump.hpp parsers/hwloc.hpp parsers/caps-numa-benchmark.hpp parsers/gpu-topo.hpp parsers/cccbench.cpp + parsers/qdmi-interface.hpp ) add_library(sys-sage SHARED ${SOURCES} ${HEADERS}) diff --git a/src/DataPath.hpp b/src/DataPath.hpp index 3464bc1..dafe6b2 100644 --- a/src/DataPath.hpp +++ b/src/DataPath.hpp @@ -24,6 +24,11 @@ #define SYS_SAGE_DATAPATH_TYPE_DATATRANSFER 1024 /**< DataPath type describing data transfer attributes. */ #define SYS_SAGE_DATAPATH_TYPE_C2C 2048 /**< DataPath type describing cache-to-cache latencies (cccbench data source). */ +// QuantumGate type +#define SYS_SAGE_QUANTUMGATE_TYPE_ID 32 /**< Identity Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_RZ 64 /**< RZ Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_CNOT 128 /**< CNOT Gate */ + using namespace std; class Component; class DataPath; @@ -136,4 +141,26 @@ class DataPath { }; +/** +Class DataPath represents Data Paths in the topology -- Data Paths represent an arbitrary relation (or data movement) between two Components from the Component Tree. +\n Data Paths create a Data-Path graph, which is a structure orthogonal to the Component Tree. +\n Each Component contains a reference to all Data Paths going to or from this components (as well as parents and children in the Component Tree). Using these references, it is possible to navigate between the Components and to view the data stores in the Components or the Data Paths. +*/ +class QuantumGate : public DataPath { + +public: + /** + QuantumGate constructor. + @param _qubits - An array of all qubits that the gate acts on. + @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. + \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 + */ + QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); +private: + std::vector qubits; /**< TODO */ + int** coupling_mapping; + char *unitary; + float fidelity; +}; + #endif diff --git a/src/Topology.cpp b/src/Topology.cpp index 76d7e74..4b502aa 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -568,3 +568,9 @@ Core::Core(Component * parent, int _id, string _name):Component(parent, _id, _na Thread::Thread(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_THREAD){} Thread::Thread(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_THREAD){} + +QuantumBackend::QuantumBackend(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} +QuantumBackend::QuantumBackend(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} + +Qubit::Qubit(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUBIT){} +Qubit::Qubit(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUBIT){} diff --git a/src/Topology.hpp b/src/Topology.hpp index 031910a..9eb4ed6 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -23,6 +23,13 @@ #define SYS_SAGE_COMPONENT_NODE 512 /**< class Node */ #define SYS_SAGE_COMPONENT_TOPOLOGY 1024 /**< class Topology */ +/* To-do: Add defines for different quantum backends +* For e.g.: SYS_SAGE_COMPONENT_NEUTRAL_ATOMS, SYS_SAGE_COMPONENT_SUPERCONDUCTING, etc. + +*/ +#define SYS_SAGE_COMPONENT_QUANTUM_BACKEND 2048 /**< class QuantumBackend */ +#define SYS_SAGE_COMPONENT_QUBIT 4096 /**< class Qubit */ + #define SYS_SAGE_SUBDIVISION_TYPE_NONE 1 /**< Generic Subdivision type. */ #define SYS_SAGE_SUBDIVISION_TYPE_GPU_SM 2 /**< Subdivision type for GPU SMs */ @@ -830,4 +837,63 @@ class Thread : public Component { private: }; +class QuantumBackend : public Component { +public: + /** + QuantumBackend constructor (no automatic insertion in the Component Tree). Sets: + @param _id = id, default 0 + @param _name = name, default "QuantumBackend" + @param componentType=>SYS_SAGE_COMPONENT_QUANTUM_BACKEND + */ + QuantumBackend(int _id = 0, string _name = "QuantumBackend"); + /** + QuantumBackend constructor with insertion into the Component Tree as the parent 's child (as long as parent is an existing Component). Sets: + @param parent = the parent + @param _id = id, default 0 + @param _name = name, default "QuantumBackend" + @param componentType=>SYS_SAGE_COMPONENT_QUANTUM_BACKEND + */ + QuantumBackend(Component * parent, int _id = 0, string _name = "QuantumBackend"); + /** + * TODO + */ + ~QuantumBackend() override = default; + +private: + int num_qubits; + std::vector gate_types; +}; + +class Qubit : public Component { +public: + /** + Qubit constructor (no automatic insertion in the Component Tree). Sets: + @param _id = id, default 0 + @param _name = name, default "Qubit" + @param componentType=>SYS_SAGE_COMPONENT_QUBIT + */ + Qubit(int _id = 0, string _name = "Qubit"); + /** + Qubit constructor with insertion into the Component Tree as the parent 's child (as long as parent is an existing Component). Sets: + @param parent = the parent + @param _id = id, default 0 + @param _name = name, default "Qubit0" + @param componentType=>SYS_SAGE_COMPONENT_QUBIT + */ + Qubit(Component * parent, int _id = 0, string _name = "Qubit"); + + void SetCouplingMapping(int* _coupling_mapping, int _size_coupling_mapping); + /** + * TODO + */ + ~Qubit() override = default; + +private: + int* coupling_mapping; + int size_coupling_mapping; + float fidelity; +}; + #endif + + diff --git a/src/fomac.cpp b/src/parsers/qdmi-interface.cpp similarity index 95% rename from src/fomac.cpp rename to src/parsers/qdmi-interface.cpp index 4c6c861..b390af7 100644 --- a/src/fomac.cpp +++ b/src/parsers/qdmi-interface.cpp @@ -1,9 +1,9 @@ /** - * @file fomac.cpp - * @brief Implementation of global FoMaC. + * @file qdmi-interface.hpp + * @brief sys-sage's interface to QDMI. Based on MQSS's global FOMAC. */ -#include "fomac.hpp" +#include "qdmi-interface.hpp" /** * @brief TODO diff --git a/src/fomac.hpp b/src/parsers/qdmi-interface.hpp similarity index 76% rename from src/fomac.hpp rename to src/parsers/qdmi-interface.hpp index fc27bd8..b6b4811 100644 --- a/src/fomac.hpp +++ b/src/parsers/qdmi-interface.hpp @@ -1,10 +1,10 @@ /** - * @file fomac.hpp - * @brief Header of the global FoMaC. + * @file qdmi-interface.hpp + * @brief sys-sage's interface to QDMI. Based on MQSS's global FOMAC. */ -#ifndef FOMAC_HPP -#define FOMAC_HPP +#ifndef QDMI_INTERFACE_HPP +#define QDMI_INTERFACE_HPP #include #include @@ -40,4 +40,4 @@ extern "C" void FOMAC_print_coupling_mappings(QDMI_Device dev); } -#endif // FOMAC_HPP \ No newline at end of file +#endif // QDMI_INTERFACE_HPP \ No newline at end of file diff --git a/src/sys-sage.hpp b/src/sys-sage.hpp index e845c1f..ec94653 100644 --- a/src/sys-sage.hpp +++ b/src/sys-sage.hpp @@ -4,11 +4,10 @@ //includes all other headers #include "Topology.hpp" #include "DataPath.hpp" -#include "fomac.hpp" #include "xml_dump.hpp" #include "parsers/hwloc.hpp" #include "parsers/caps-numa-benchmark.hpp" #include "parsers/gpu-topo.hpp" #include "parsers/cccbench.hpp" - +#include "parsers/qdmi-interface.hpp" #endif //SYS_SAGE From 43c2082e9d7d9d3aad160c5fd14c551b6eb7cced Mon Sep 17 00:00:00 2001 From: Durganshu Date: Tue, 16 Apr 2024 01:27:21 +0200 Subject: [PATCH 03/34] update qdmi-interface and qubit function calls --- examples/CMakeLists.txt | 5 + examples/qdmi-test.cpp | 50 +++++++-- src/Topology.cpp | 10 ++ src/Topology.hpp | 6 +- src/parsers/qdmi-interface.cpp | 193 +++++++++++++++++++++++++++++---- src/parsers/qdmi-interface.hpp | 49 +++++++-- 6 files changed, 274 insertions(+), 39 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0857ecc..86143fa 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,3 +37,8 @@ if(NVIDIA_MIG) add_executable(nvidia-mig nvidia-mig.cpp) install(TARGETS nvidia-mig DESTINATION bin/examples) endif() + +target_link_libraries(qdmi-test PRIVATE + qdmi + qinfo + ) \ No newline at end of file diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 57c7f87..ac2cac8 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -1,20 +1,56 @@ #include -#include - +#include #include "sys-sage.hpp" +#define CHECK_ERR(a,b) { if (a!=QDMI_SUCCESS) { printf("\n[Error]: %i at %s",a,b); return 1; }} int main() { - auto vec = FOMAC_available_devices(); + int err = 0, status = 0; + int index = 0; + int n_shots = 100; + QInfo info = NULL; + QDMI_Session session = NULL; + QDMI_Job job; + QDMI_Fragment frag = (QDMI_Fragment) malloc(sizeof(QDMI_Fragment)); + QDMI_Device device = (QDMI_Device) malloc(sizeof(QDMI_Device)); + + err = QInfo_create(&info); + CHECK_ERR(err, "QInfo_create"); + + err = QDMI_session_init(info, &session); + CHECK_ERR(err, "QDMI_session_init"); + + auto vec = get_available_backends(); int count = 0; - std::cout << "Total number of devices: " << vec.size() << "\n"; - for (auto dev : vec) + std::cout << "Total " << vec.size() << " devices found.\n"; + // for (auto dev : vec) + // { + // std::cout << "Printing for device id: " << count++ << "\n"; + // print_coupling_mappings(dev); + // } + + //create root quantum backend + QuantumBackend* qc = new QuantumBackend(); + int num_qubits = get_num_qubits(vec[vec.size()-1]); + + if(num_qubits == -1) { - std::cout << "Printing for device id: " << ++count << "\n"; - FOMAC_print_coupling_mappings(dev); + std::cout << "Error in getting number of qubits\n"; + return 1; } + set_qubits(vec[vec.size()-1], vec.size()-1); + + for (int i = 0; i < num_qubits; i++) + { + Qubit* q = new Qubit(qc, i); + setCouplingMapping(q, vec.size()-1, i); + } + + + cout << "---------------- Printing the configuration of QC ----------------" << endl; + qc->PrintSubtree(); return 0; } diff --git a/src/Topology.cpp b/src/Topology.cpp index 4b502aa..1e7c7dd 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -311,6 +311,11 @@ string Component::GetComponentTypeStr() return "Node"; case SYS_SAGE_COMPONENT_TOPOLOGY: return "Topology"; + case SYS_SAGE_COMPONENT_QUANTUM_BACKEND: + return "Quantum Backend"; + case SYS_SAGE_COMPONENT_QUBIT: + return "Qubit"; + } return ""; } @@ -574,3 +579,8 @@ QuantumBackend::QuantumBackend(Component * parent, int _id, string _name):Compon Qubit::Qubit(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUBIT){} Qubit::Qubit(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUBIT){} +void Qubit::SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping) +{ + _coupling_mapping = coupling_mapping; + _size_coupling_mapping = size_coupling_mapping; +} \ No newline at end of file diff --git a/src/Topology.hpp b/src/Topology.hpp index 9eb4ed6..7f5714d 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -882,15 +882,15 @@ class Qubit : public Component { */ Qubit(Component * parent, int _id = 0, string _name = "Qubit"); - void SetCouplingMapping(int* _coupling_mapping, int _size_coupling_mapping); + void SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping); /** * TODO */ ~Qubit() override = default; private: - int* coupling_mapping; - int size_coupling_mapping; + std::vector _coupling_mapping; + int _size_coupling_mapping; float fidelity; }; diff --git a/src/parsers/qdmi-interface.cpp b/src/parsers/qdmi-interface.cpp index b390af7..f4bbe11 100644 --- a/src/parsers/qdmi-interface.cpp +++ b/src/parsers/qdmi-interface.cpp @@ -5,19 +5,17 @@ #include "qdmi-interface.hpp" -/** - * @brief TODO - * @return TODO - * @todo Should this become a daemon? In which node should it run? - */ -extern "C" std::vector FOMAC_available_devices() +static std::map < int, std::vector > _qubits; + +// TODO: Change function name (like FOMAC_available_devices) +extern "C" std::vector get_available_backends() { // TODO REPEAT PERIODICALLY WITH A DELAY char **available_devices = get_qdmi_library_list_names(); if (available_devices == NULL) { - std::cout << " [FoMaC]...............Failed to get " + std::cout << " [sys-sage]...............Failed to get " << "qdmi_library_list from QDMI" << std::endl; return std::vector(); @@ -34,7 +32,7 @@ extern "C" std::vector FOMAC_available_devices() if (!lib) { - std::cout << " [FoMaC]...............A backend's library " + std::cout << " [sys-sage]...............A backend's library " << "could not be found" << std::endl; free(available_devices[i++]); @@ -49,7 +47,7 @@ extern "C" std::vector FOMAC_available_devices() if (status) { const char *device_name = strrchr(available_devices[i], '/'); - std::cout << " [FoMaC]...............Available device " + std::cout << " [sys-sage]...............Available device " << "found: " << device_name << std::endl; registered_devices.push_back(device); @@ -62,15 +60,34 @@ extern "C" std::vector FOMAC_available_devices() return registered_devices; } -/** - * @brief TODO - * @return TODO - * @todo Should this become a daemon? In which node should it run? - */ -extern "C" void FOMAC_print_coupling_mappings(QDMI_Device dev) +extern "C" int get_num_qubits(QDMI_Device dev) { - // TODO REPEAT PERIODICALLY WITH A DELAY + QDMI_Qubit qubits; + int err, num_qubits = 0; + + err = QDMI_query_all_qubits(dev, &qubits); + + if (err != QDMI_SUCCESS || qubits == NULL) + { + std::cout << " [sys-sage]...............Could not obtain available " + << "qubits via QDMI\n"; + return -1; + } + + err = QDMI_query_qubits_num(dev, &num_qubits); + + if (err != QDMI_SUCCESS || num_qubits == 0) + { + std::cout << " [sys-sage]...............Could not obtain number of " + << "available qubits via QDMI\n"; + return -1; + } + return num_qubits; +} + +extern "C" void set_qubits(QDMI_Device dev, int device_index) +{ QDMI_Qubit qubits; int err, num_qubits = 0; @@ -78,30 +95,166 @@ extern "C" void FOMAC_print_coupling_mappings(QDMI_Device dev) if (err != QDMI_SUCCESS || qubits == NULL) { - std::cout << " [FoMaC]...............Could not obtain available " + std::cout << " [sys-sage]...............Could not obtain available " << "qubits via QDMI\n"; return; } err = QDMI_query_qubits_num(dev, &num_qubits); + + if (err != QDMI_SUCCESS || num_qubits == 0) + { + std::cout << " [sys-sage]...............Could not obtain number of " + << "available qubits via QDMI\n"; + return; + } + else + { + std::cout << " [sys-sage]...............Found " + << num_qubits << " qubits.\n"; + } + + _qubits[device_index] = std::vector(); + + for (int i = 0; i < num_qubits; i++) + { + _qubits[device_index].push_back(&qubits[i]); + } + for(auto &qubit : _qubits) + { + std::cout << " [sys-sage]...............Device index: " << qubit.first << "\n"; + for(auto &qubit_impl : qubit.second) + { + std::cout << " [sys-sage]...............Qubit index: " << qubit_impl->index << "\n"; + } + } + + // TODO remove this after testing + // for (int i = 0; i < num_qubits; i++) + // { + // if (_qubits[device_index][i]->coupling_mapping == NULL) + // { + // std::cout << " [sys-sage]...............No coupling mapping" + // << std::endl; + // continue; + // } + // std::cout << " [sys-sage]...............Coupling mapping of qubit[" << i + // << "]: { "; + // for (int j = 0; j < _qubits[device_index][i]->size_coupling_mapping; j++) + // std::cout << _qubits[device_index][i]->coupling_mapping[j] << " "; + // std::cout << "}" << std::endl; + // } + + free(qubits); + + return; + +} + +extern "C" void setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index) +{ + for(auto &qubit : _qubits) + { + std::cout << " [sys-sage]...............Device index: " << qubit.first << "\n"; + for(auto &qubit_impl : qubit.second) + { + std::cout << " [sys-sage]...............Qubit index: " << qubit_impl->index << "\n"; + } + } + + // std::cout << " [sys-sage]...............Coupling mapping of qubit[" << qubit_index + // << "]: { "; + // for (int j = 0; j < _qubits[device_index][qubit_index]->size_coupling_mapping; j++) + // std::cout << _qubits[device_index][qubit_index]->coupling_mapping[j] << " "; + // std::cout << "}" << std::endl; + + // std::cout << "printed all the coupling maps\n"; + // if (_qubits.find(device_index) == _qubits.end()) + // { + // std::cout << " [sys-sage]...............No qubits found for device " + // << device_index << std::endl; + // return; + // } + + // // Ensure the qubit index is valid + // if (qubit_index >= _qubits[device_index].size() || qubit_index < 0) + // { + // std::cout << " [sys-sage]...............Qubit index out of range for " + // << "device " << device_index << std::endl; + // return; + // } + + // QDMI_Qubit qubit_impl = _qubits[device_index][qubit_index]; + // if (!qubit_impl) + // { + // std::cout << " [sys-sage]...............Qubit is null for device " + // << device_index << " and qubit index " << qubit_index << std::endl; + // return; + // } + + // int size = qubit_impl->size_coupling_mapping; //qubit_impl->size_coupling_mapping; + // if (size <= 0) + // { + // std::cout << " [sys-sage]...............Invalid size of coupling mapping for qubit " + // << "with device index " << device_index << " and qubit index " << qubit_index << std::endl; + // return; + // } + + // std::cout << "Size of coupling mapping: " << size << "\n"; + + // std::vector coupling_mapping(size); + + // // Copy the coupling_mapping from qubit_impl + // std::copy(qubit_impl->coupling_mapping, qubit_impl->coupling_mapping + size, coupling_mapping.begin()); + + // std::cout << " [sys-sage]...............Setting coupling mapping for qubit with size: " << size << "\n"; + // _qubit->SetCouplingMapping(coupling_mapping, size); + + return; +} + +// TODO: change function name (like FOMAC_print_coupling_mappings) +extern "C" void print_coupling_mappings(QDMI_Device dev) +{ + // TODO REPEAT PERIODICALLY WITH A DELAY + + QDMI_Qubit qubits; + int err, num_qubits = 0; + + err = QDMI_query_all_qubits(dev, &qubits); + + if (err != QDMI_SUCCESS || qubits == NULL) + { + std::cout << " [sys-sage]...............Could not obtain available " + << "qubits via QDMI\n"; + return; + } + + err = QDMI_query_qubits_num(dev, &num_qubits); + if (err != QDMI_SUCCESS || num_qubits == 0) { - std::cout << " [FoMaC]...............Could not obtain number of " + std::cout << " [sys-sage]...............Could not obtain number of " << "available qubits via QDMI\n"; return; } + else + { + std::cout << " [sys-sage]...............Found " + << num_qubits << " qubits.\n"; + } for (int i = 0; i < num_qubits; i++) { if (qubits[i].coupling_mapping == NULL) { - std::cout << " [FoMaC]...............No coupling mapping" + std::cout << " [sys-sage]...............No coupling mapping" << std::endl; continue; } - std::cout << " [FoMaC]...............Coupling mapping of qubit[" << i + std::cout << " [sys-sage]...............Coupling mapping of qubit[" << i << "]: { "; for (int j = 0; j < qubits[i].size_coupling_mapping; j++) std::cout << qubits[i].coupling_mapping[j] << " "; diff --git a/src/parsers/qdmi-interface.hpp b/src/parsers/qdmi-interface.hpp index b6b4811..ac30149 100644 --- a/src/parsers/qdmi-interface.hpp +++ b/src/parsers/qdmi-interface.hpp @@ -9,16 +9,47 @@ #include #include #include - +#include +#include "Topology.hpp" #include #include -//const char *registered_devices[] = { -// "/bin/lib/libbackend_qlm.so", -// "/bin/lib/libbackend_ibm.so", -// "/bin/lib/libbackend_wmi.so", -// "/bin/lib/libbackend_q7.so", -//}; +/** + * @brief TODO + * @return TODO + * @todo To be implemented + */ +extern "C" +{ + std::vector get_available_backends(); +} + + +/** + * @brief TODO + * @return TODO + * @todo To be implemented + */ +extern "C" +{ + int get_num_qubits(QDMI_Device dev); +} + +/** + * @brief TODO + * @return TODO + * @todo To be implemented + */ +extern "C" +{ + void set_qubits(QDMI_Device dev, int device_index); +} + +extern "C" +{ + void setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index); +} + /** * @brief TODO @@ -27,7 +58,7 @@ */ extern "C" { - std::vector FOMAC_available_devices(); + void get_qubit(QDMI_Device dev, int index); } /** @@ -37,7 +68,7 @@ extern "C" */ extern "C" { - void FOMAC_print_coupling_mappings(QDMI_Device dev); + void print_coupling_mappings(QDMI_Device dev); } #endif // QDMI_INTERFACE_HPP \ No newline at end of file From c61f870c9de8a5201c599d90ea7f1fd48bfe0859 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Tue, 16 Apr 2024 13:19:40 +0200 Subject: [PATCH 04/34] Internal representation now being generated through QDMI Interface --- examples/qdmi-test.cpp | 41 ++++++------ src/Topology.cpp | 4 ++ src/Topology.hpp | 2 + src/parsers/qdmi-interface.cpp | 110 ++++++++------------------------- src/parsers/qdmi-interface.hpp | 66 +++++--------------- 5 files changed, 68 insertions(+), 155 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index ac2cac8..6a0630f 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -6,14 +6,9 @@ int main() { - int err = 0, status = 0; - int index = 0; - int n_shots = 100; + int err = 0; QInfo info = NULL; QDMI_Session session = NULL; - QDMI_Job job; - QDMI_Fragment frag = (QDMI_Fragment) malloc(sizeof(QDMI_Fragment)); - QDMI_Device device = (QDMI_Device) malloc(sizeof(QDMI_Device)); err = QInfo_create(&info); CHECK_ERR(err, "QInfo_create"); @@ -21,18 +16,13 @@ int main() err = QDMI_session_init(info, &session); CHECK_ERR(err, "QDMI_session_init"); - auto vec = get_available_backends(); - int count = 0; + QDMI_Interface qdmi; + auto vec = qdmi.get_available_backends(); std::cout << "Total " << vec.size() << " devices found.\n"; - // for (auto dev : vec) - // { - // std::cout << "Printing for device id: " << count++ << "\n"; - // print_coupling_mappings(dev); - // } - + //create root quantum backend QuantumBackend* qc = new QuantumBackend(); - int num_qubits = get_num_qubits(vec[vec.size()-1]); + int num_qubits = qdmi.get_num_qubits(vec[vec.size()-1]); // Using Device index = vec.size()-1 if(num_qubits == -1) { @@ -40,15 +30,30 @@ int main() return 1; } - set_qubits(vec[vec.size()-1], vec.size()-1); + qdmi.set_qubits(vec[vec.size()-1], vec.size()-1); // Using Device index = vec.size()-1 for (int i = 0; i < num_qubits; i++) { Qubit* q = new Qubit(qc, i); - setCouplingMapping(q, vec.size()-1, i); + qdmi.setCouplingMapping(q, vec.size()-1, i); // Using Device index = vec.size()-1 + auto coupling_map = q->GetCouplingMapping(); } - + cout << "---------------- Printing Qubit Coupling Mappings ----------------" << endl; + int total_qubits = qc->CountAllSubcomponents(); + for (int i = 0; i < total_qubits; i++) + { + // TODO: Dynamic cast or static cast? + Qubit* q = dynamic_cast(qc->GetChild(i)); + std::cout << "Qubit " << i << " has coupling map { "; + auto coupling_map = q->GetCouplingMapping(); + for (long unsigned j = 0; j < coupling_map.size(); j++) + { + std::cout << coupling_map[j] << " "; + } + std::cout << "}\n"; + } + cout << "---------------- Printing the configuration of QC ----------------" << endl; qc->PrintSubtree(); diff --git a/src/Topology.cpp b/src/Topology.cpp index 1e7c7dd..77867fd 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -583,4 +583,8 @@ void Qubit::SetCouplingMapping( const std::vector &coupling_mapping, const { _coupling_mapping = coupling_mapping; _size_coupling_mapping = size_coupling_mapping; +} +const std::vector & Qubit::GetCouplingMapping() const +{ + return _coupling_mapping; } \ No newline at end of file diff --git a/src/Topology.hpp b/src/Topology.hpp index 7f5714d..7582a1b 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -883,6 +883,8 @@ class Qubit : public Component { Qubit(Component * parent, int _id = 0, string _name = "Qubit"); void SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping); + + const std::vector &GetCouplingMapping() const; /** * TODO */ diff --git a/src/parsers/qdmi-interface.cpp b/src/parsers/qdmi-interface.cpp index f4bbe11..ca35538 100644 --- a/src/parsers/qdmi-interface.cpp +++ b/src/parsers/qdmi-interface.cpp @@ -5,10 +5,9 @@ #include "qdmi-interface.hpp" -static std::map < int, std::vector > _qubits; // TODO: Change function name (like FOMAC_available_devices) -extern "C" std::vector get_available_backends() +extern "C" std::vector QDMI_Interface::get_available_backends() { // TODO REPEAT PERIODICALLY WITH A DELAY @@ -60,20 +59,10 @@ extern "C" std::vector get_available_backends() return registered_devices; } -extern "C" int get_num_qubits(QDMI_Device dev) +extern "C" int QDMI_Interface::get_num_qubits(QDMI_Device dev) { - QDMI_Qubit qubits; int err, num_qubits = 0; - err = QDMI_query_all_qubits(dev, &qubits); - - if (err != QDMI_SUCCESS || qubits == NULL) - { - std::cout << " [sys-sage]...............Could not obtain available " - << "qubits via QDMI\n"; - return -1; - } - err = QDMI_query_qubits_num(dev, &num_qubits); if (err != QDMI_SUCCESS || num_qubits == 0) @@ -86,7 +75,7 @@ extern "C" int get_num_qubits(QDMI_Device dev) } -extern "C" void set_qubits(QDMI_Device dev, int device_index) +extern "C" void QDMI_Interface::set_qubits(QDMI_Device dev, int device_index) { QDMI_Qubit qubits; int err, num_qubits = 0; @@ -114,78 +103,31 @@ extern "C" void set_qubits(QDMI_Device dev, int device_index) << num_qubits << " qubits.\n"; } - _qubits[device_index] = std::vector(); + _qubits[device_index] = std::vector (); - for (int i = 0; i < num_qubits; i++) - { - _qubits[device_index].push_back(&qubits[i]); - } - for(auto &qubit : _qubits) + for(int i = 0; i < num_qubits; ++i) { - std::cout << " [sys-sage]...............Device index: " << qubit.first << "\n"; - for(auto &qubit_impl : qubit.second) - { - std::cout << " [sys-sage]...............Qubit index: " << qubit_impl->index << "\n"; - } + _qubits[device_index].push_back(qubits[i]); } - // TODO remove this after testing - // for (int i = 0; i < num_qubits; i++) - // { - // if (_qubits[device_index][i]->coupling_mapping == NULL) - // { - // std::cout << " [sys-sage]...............No coupling mapping" - // << std::endl; - // continue; - // } - - // std::cout << " [sys-sage]...............Coupling mapping of qubit[" << i - // << "]: { "; - // for (int j = 0; j < _qubits[device_index][i]->size_coupling_mapping; j++) - // std::cout << _qubits[device_index][i]->coupling_mapping[j] << " "; - // std::cout << "}" << std::endl; - // } - free(qubits); return; } -extern "C" void setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index) +extern "C" void QDMI_Interface::setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index) { - for(auto &qubit : _qubits) + + if (_qubits.find(device_index) == _qubits.end()) { - std::cout << " [sys-sage]...............Device index: " << qubit.first << "\n"; - for(auto &qubit_impl : qubit.second) - { - std::cout << " [sys-sage]...............Qubit index: " << qubit_impl->index << "\n"; - } + std::cout << " [sys-sage]...............No qubits found for device " + << device_index << std::endl; + return; } - - // std::cout << " [sys-sage]...............Coupling mapping of qubit[" << qubit_index - // << "]: { "; - // for (int j = 0; j < _qubits[device_index][qubit_index]->size_coupling_mapping; j++) - // std::cout << _qubits[device_index][qubit_index]->coupling_mapping[j] << " "; - // std::cout << "}" << std::endl; - - // std::cout << "printed all the coupling maps\n"; - // if (_qubits.find(device_index) == _qubits.end()) - // { - // std::cout << " [sys-sage]...............No qubits found for device " - // << device_index << std::endl; - // return; - // } - // // Ensure the qubit index is valid - // if (qubit_index >= _qubits[device_index].size() || qubit_index < 0) - // { - // std::cout << " [sys-sage]...............Qubit index out of range for " - // << "device " << device_index << std::endl; - // return; - // } - // QDMI_Qubit qubit_impl = _qubits[device_index][qubit_index]; + auto qubit_impl = _qubits[device_index][qubit_index]; // if (!qubit_impl) // { // std::cout << " [sys-sage]...............Qubit is null for device " @@ -193,29 +135,27 @@ extern "C" void setCouplingMapping(Qubit *_qubit, int device_index, int qubit_in // return; // } - // int size = qubit_impl->size_coupling_mapping; //qubit_impl->size_coupling_mapping; - // if (size <= 0) - // { - // std::cout << " [sys-sage]...............Invalid size of coupling mapping for qubit " - // << "with device index " << device_index << " and qubit index " << qubit_index << std::endl; - // return; - // } + int size = qubit_impl.size_coupling_mapping; //qubit_impl->size_coupling_mapping; + if (size <= 0) + { + std::cout << " [sys-sage]...............Invalid size of coupling mapping for qubit " + << "with device index " << device_index << " and qubit index " << qubit_index << std::endl; + return; + } - // std::cout << "Size of coupling mapping: " << size << "\n"; - // std::vector coupling_mapping(size); + std::vector coupling_mapping(size); - // // Copy the coupling_mapping from qubit_impl - // std::copy(qubit_impl->coupling_mapping, qubit_impl->coupling_mapping + size, coupling_mapping.begin()); + // Copy the coupling_mapping from qubit_impl + std::copy(qubit_impl.coupling_mapping, qubit_impl.coupling_mapping + size, coupling_mapping.begin()); - // std::cout << " [sys-sage]...............Setting coupling mapping for qubit with size: " << size << "\n"; - // _qubit->SetCouplingMapping(coupling_mapping, size); + _qubit->SetCouplingMapping(coupling_mapping, size); return; } // TODO: change function name (like FOMAC_print_coupling_mappings) -extern "C" void print_coupling_mappings(QDMI_Device dev) +extern "C" void QDMI_Interface::print_coupling_mappings(QDMI_Device dev) { // TODO REPEAT PERIODICALLY WITH A DELAY diff --git a/src/parsers/qdmi-interface.hpp b/src/parsers/qdmi-interface.hpp index ac30149..255c30e 100644 --- a/src/parsers/qdmi-interface.hpp +++ b/src/parsers/qdmi-interface.hpp @@ -14,61 +14,23 @@ #include #include -/** - * @brief TODO - * @return TODO - * @todo To be implemented - */ -extern "C" -{ - std::vector get_available_backends(); -} - -/** - * @brief TODO - * @return TODO - * @todo To be implemented - */ -extern "C" -{ - int get_num_qubits(QDMI_Device dev); -} - -/** - * @brief TODO - * @return TODO - * @todo To be implemented - */ -extern "C" -{ - void set_qubits(QDMI_Device dev, int device_index); -} - -extern "C" -{ - void setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index); -} - - -/** - * @brief TODO - * @return TODO - * @todo To be implemented - */ -extern "C" -{ - void get_qubit(QDMI_Device dev, int index); -} - -/** - * @brief TODO - * @return TODO - * @todo To be implemented - */ extern "C" { - void print_coupling_mappings(QDMI_Device dev); + class QDMI_Interface + { + public: + std::vector get_available_backends(); + int get_num_qubits(QDMI_Device dev); + void set_qubits(QDMI_Device dev, int device_index); + void get_qubit(QDMI_Device dev, int index); + void print_coupling_mappings(QDMI_Device dev); + void setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index); + private: + //TODO: Try storing the QDMI_Qubit instead of QDMI_Qubit_impl_d + std::map < int, std::vector > _qubits; + }; + } #endif // QDMI_INTERFACE_HPP \ No newline at end of file From 42d5a82ae03ef2f7baf448dd46452c1e09acf317 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Tue, 23 Apr 2024 16:44:21 +0200 Subject: [PATCH 05/34] QDMI_Interface provides high-level API calls for user to create the topology --- examples/qdmi-test.cpp | 75 +++++++++++++------------- src/Topology.cpp | 2 + src/Topology.hpp | 4 ++ src/parsers/qdmi-interface.cpp | 98 ++++++++++++++++++++++++---------- src/parsers/qdmi-interface.hpp | 17 ++++-- 5 files changed, 128 insertions(+), 68 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 6a0630f..205c152 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -1,49 +1,33 @@ +/* Possible exports +* CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qinfo-src/include/ +* export CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qdmi-src/include +* export CONF_IBM=/home/diogenes/qdmi.git/inputs/conf.json +* export QDMI_CONFIG_FILE=/home/diogenes/sys-sage/build/_deps/qdmi-src/.qdmi-config +*/ + #include #include #include "sys-sage.hpp" -#define CHECK_ERR(a,b) { if (a!=QDMI_SUCCESS) { printf("\n[Error]: %i at %s",a,b); return 1; }} - int main() { - int err = 0; - QInfo info = NULL; - QDMI_Session session = NULL; - - err = QInfo_create(&info); - CHECK_ERR(err, "QInfo_create"); - - err = QDMI_session_init(info, &session); - CHECK_ERR(err, "QDMI_session_init"); + // Create an instance of the interface QDMI_Interface qdmi; - auto vec = qdmi.get_available_backends(); - std::cout << "Total " << vec.size() << " devices found.\n"; - - //create root quantum backend - QuantumBackend* qc = new QuantumBackend(); - int num_qubits = qdmi.get_num_qubits(vec[vec.size()-1]); // Using Device index = vec.size()-1 - - if(num_qubits == -1) - { - std::cout << "Error in getting number of qubits\n"; - return 1; - } - qdmi.set_qubits(vec[vec.size()-1], vec.size()-1); // Using Device index = vec.size()-1 + // Use QDMI_Interface to create the topology of either all the backends or one of the backends + /*******************************************Method 1**********************************************/ - for (int i = 0; i < num_qubits; i++) - { - Qubit* q = new Qubit(qc, i); - qdmi.setCouplingMapping(q, vec.size()-1, i); // Using Device index = vec.size()-1 - auto coupling_map = q->GetCouplingMapping(); - } + Topology* qc_topo = new Topology(); + qdmi.createQcTopo(qc_topo); - cout << "---------------- Printing Qubit Coupling Mappings ----------------" << endl; + cout << "---------------- Printing the configuration of QLM ----------------" << endl; + qc_topo->PrintSubtree(); + cout << "---------------- Printing Qubit Coupling Mappings of QLM Backend----------------" << endl; + QuantumBackend* qc = dynamic_cast(qc_topo->GetChild(0)); int total_qubits = qc->CountAllSubcomponents(); for (int i = 0; i < total_qubits; i++) { - // TODO: Dynamic cast or static cast? Qubit* q = dynamic_cast(qc->GetChild(i)); std::cout << "Qubit " << i << " has coupling map { "; auto coupling_map = q->GetCouplingMapping(); @@ -53,9 +37,28 @@ int main() } std::cout << "}\n"; } - - cout << "---------------- Printing the configuration of QC ----------------" << endl; - qc->PrintSubtree(); - + + /*******************************************Method 2**********************************************/ + // auto quantum_backends = qdmi.get_available_backends(); + // std::cout << "Total " << quantum_backends.size() << " devices found.\n"; + // QuantumBackend* qc_topo = new QuantumBackend(0, quantum_backends[0].first); + // qdmi.createQcTopo(qc_topo, quantum_backends[0].second); + + // cout << "---------------- Printing the configuration of QLM Backend ----------------" << endl; + // qc_topo->PrintSubtree(); + // cout << "---------------- Printing Qubit Coupling Mappings of QLM Backend----------------" << endl; + // int total_qubits = qc_topo->CountAllSubcomponents(); + // for (int i = 0; i < total_qubits; i++) + // { + // Qubit* q = dynamic_cast(qc_topo->GetChild(i)); + // std::cout << "Qubit " << i << " has coupling map { "; + // auto coupling_map = q->GetCouplingMapping(); + // for (long unsigned j = 0; j < coupling_map.size(); j++) + // { + // std::cout << coupling_map[j] << " "; + // } + // std::cout << "}\n"; + // } + return 0; } diff --git a/src/Topology.cpp b/src/Topology.cpp index 77867fd..3c62ae4 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -576,6 +576,8 @@ Thread::Thread(Component * parent, int _id, string _name):Component(parent, _id, QuantumBackend::QuantumBackend(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} QuantumBackend::QuantumBackend(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} +void QuantumBackend::SetNumberofQubits(int _num_qubits) { num_qubits = _num_qubits; } +int QuantumBackend::GetNumberofQubits() const { return num_qubits; } Qubit::Qubit(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUBIT){} Qubit::Qubit(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUBIT){} diff --git a/src/Topology.hpp b/src/Topology.hpp index 7582a1b..99e767f 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -854,6 +854,10 @@ class QuantumBackend : public Component { @param componentType=>SYS_SAGE_COMPONENT_QUANTUM_BACKEND */ QuantumBackend(Component * parent, int _id = 0, string _name = "QuantumBackend"); + + void SetNumberofQubits(int _num_qubits); + + int GetNumberofQubits () const; /** * TODO */ diff --git a/src/parsers/qdmi-interface.cpp b/src/parsers/qdmi-interface.cpp index ca35538..e402fb1 100644 --- a/src/parsers/qdmi-interface.cpp +++ b/src/parsers/qdmi-interface.cpp @@ -6,8 +6,36 @@ #include "qdmi-interface.hpp" +extern "C" QDMI_Interface::QDMI_Interface() +{ + initiateSession(); +} + +extern "C" int QDMI_Interface::initiateSession() +{ + int err = 0; + info = NULL; + session = NULL; + + err = QInfo_create(&info); + CHECK_ERR(err, "QInfo_create"); + + err = QDMI_session_init(info, &session); + CHECK_ERR(err, "QDMI_session_init"); + if (err != QDMI_SUCCESS) + { + std::cout << " [sys-sage]...............Unable to initiate " + << "QDMI session\n"; + exit(0); + } + std::cout << " [sys-sage]...............Initiated " + << "QDMI session\n"; + return 0; + +} + // TODO: Change function name (like FOMAC_available_devices) -extern "C" std::vector QDMI_Interface::get_available_backends() +extern "C" std::vector> QDMI_Interface::get_available_backends() { // TODO REPEAT PERIODICALLY WITH A DELAY @@ -17,11 +45,11 @@ extern "C" std::vector QDMI_Interface::get_available_backends() std::cout << " [sys-sage]...............Failed to get " << "qdmi_library_list from QDMI" << std::endl; - return std::vector(); + return std::vector>(); } int i = 0, err = 0, status = 0; - std::vector registered_devices; + std::vector> registered_devices; while (available_devices[i] != NULL) { QDMI_Device device = @@ -49,7 +77,7 @@ extern "C" std::vector QDMI_Interface::get_available_backends() std::cout << " [sys-sage]...............Available device " << "found: " << device_name << std::endl; - registered_devices.push_back(device); + registered_devices.push_back(std::pair (device_name, device)); } free(available_devices[i++]); @@ -154,11 +182,8 @@ extern "C" void QDMI_Interface::setCouplingMapping(Qubit *_qubit, int device_ind return; } -// TODO: change function name (like FOMAC_print_coupling_mappings) -extern "C" void QDMI_Interface::print_coupling_mappings(QDMI_Device dev) +extern "C" void QDMI_Interface::setQubits(QuantumBackend * backend, QDMI_Device dev) { - // TODO REPEAT PERIODICALLY WITH A DELAY - QDMI_Qubit qubits; int err, num_qubits = 0; @@ -171,37 +196,54 @@ extern "C" void QDMI_Interface::print_coupling_mappings(QDMI_Device dev) return; } - err = QDMI_query_qubits_num(dev, &num_qubits); + num_qubits = backend->GetNumberofQubits(); - if (err != QDMI_SUCCESS || num_qubits == 0) - { - std::cout << " [sys-sage]...............Could not obtain number of " - << "available qubits via QDMI\n"; - return; - } - else - { - std::cout << " [sys-sage]...............Found " - << num_qubits << " qubits.\n"; - } - for (int i = 0; i < num_qubits; i++) { + Qubit* q = new Qubit(backend, i); + if (qubits[i].coupling_mapping == NULL) { - std::cout << " [sys-sage]...............No coupling mapping" - << std::endl; + std::cout << " [sys-sage]...............No coupling mapping for qubit " + << i << "\n"; continue; } - std::cout << " [sys-sage]...............Coupling mapping of qubit[" << i - << "]: { "; - for (int j = 0; j < qubits[i].size_coupling_mapping; j++) - std::cout << qubits[i].coupling_mapping[j] << " "; - std::cout << "}" << std::endl; + int coupling_map_size = qubits[i].size_coupling_mapping; + + std::vector coupling_mapping(coupling_map_size); + + for (int j = 0; j < coupling_map_size; j++) + { + // Copy the coupling_mapping from qubit_impl + std::copy(qubits[i].coupling_mapping, qubits[i].coupling_mapping + coupling_map_size, coupling_mapping.begin()); + } + q->SetCouplingMapping(coupling_mapping, coupling_map_size); } free(qubits); return; +} +extern "C" void QDMI_Interface::createQcTopo(Topology * topo) +{ + auto quantum_backends = get_available_backends(); + + + int total_quantum_backends = quantum_backends.size(); + + for (auto i = 0; i < total_quantum_backends; ++i) + { + QuantumBackend* qc = new QuantumBackend(topo, i, quantum_backends[i].first); + createQcTopo(qc, quantum_backends[i].second); + } + +} + +extern "C" void QDMI_Interface::createQcTopo(QuantumBackend * backend, QDMI_Device dev) +{ + backend->SetNumberofQubits(get_num_qubits(dev)); + setQubits(backend, dev); + + // setGateSets; } \ No newline at end of file diff --git a/src/parsers/qdmi-interface.hpp b/src/parsers/qdmi-interface.hpp index 255c30e..05f7400 100644 --- a/src/parsers/qdmi-interface.hpp +++ b/src/parsers/qdmi-interface.hpp @@ -14,20 +14,29 @@ #include #include +#define CHECK_ERR(a,b) { if (a!=QDMI_SUCCESS) { printf("\n[Error]: %i at %s",a,b); return 1; }} extern "C" { class QDMI_Interface { public: - std::vector get_available_backends(); + QDMI_Interface(); + int initiateSession(); + std::vector> get_available_backends(); + int get_num_qubits(QDMI_Device dev); + /**********Maybe remove these*****************************/ void set_qubits(QDMI_Device dev, int device_index); - void get_qubit(QDMI_Device dev, int index); - void print_coupling_mappings(QDMI_Device dev); void setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index); + /*********************************************************/ + void setQubits(QuantumBackend * backend, QDMI_Device dev); + void createQcTopo(Topology * topo); + void createQcTopo(QuantumBackend * topo, QDMI_Device dev); private: - //TODO: Try storing the QDMI_Qubit instead of QDMI_Qubit_impl_d + QInfo info; + QDMI_Session session; + //TODO: Is this needed? std::map < int, std::vector > _qubits; }; From 87919512fe0ef6208f2d4c7d23687aee7fc8164f Mon Sep 17 00:00:00 2001 From: Durganshu Date: Tue, 23 Apr 2024 17:27:37 +0200 Subject: [PATCH 06/34] Add method to save gate types in the qunatum backend --- examples/qdmi-test.cpp | 11 ++++++-- src/Topology.cpp | 7 +++++ src/Topology.hpp | 15 ++++++---- src/parsers/qdmi-interface.cpp | 51 ++++++++++++++++++++++++++++++---- src/parsers/qdmi-interface.hpp | 7 +++-- 5 files changed, 75 insertions(+), 16 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 205c152..f9155ae 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -21,9 +21,9 @@ int main() Topology* qc_topo = new Topology(); qdmi.createQcTopo(qc_topo); - cout << "---------------- Printing the configuration of QLM ----------------" << endl; + cout << "---------------- Printing the configuration of QLM Backend----------------" << endl; qc_topo->PrintSubtree(); - cout << "---------------- Printing Qubit Coupling Mappings of QLM Backend----------------" << endl; + cout << "---------------- Printing Qubit Coupling Mappings for QLM Backend----------------" << endl; QuantumBackend* qc = dynamic_cast(qc_topo->GetChild(0)); int total_qubits = qc->CountAllSubcomponents(); for (int i = 0; i < total_qubits; i++) @@ -37,6 +37,13 @@ int main() } std::cout << "}\n"; } + cout << "---------------- Printing Supported Gate Types for QLM Backend----------------" << endl; + int num_gates = qc->GetNumberofGates(); + auto gates = qc->GetGateTypes(); + for (int i = 0; i < num_gates; ++i) + { + std::cout << gates[i] << "\n"; + } /*******************************************Method 2**********************************************/ // auto quantum_backends = qdmi.get_available_backends(); diff --git a/src/Topology.cpp b/src/Topology.cpp index 3c62ae4..fa561fe 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -578,6 +578,13 @@ QuantumBackend::QuantumBackend(int _id, string _name):Component(_id, _name, SYS_ QuantumBackend::QuantumBackend(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} void QuantumBackend::SetNumberofQubits(int _num_qubits) { num_qubits = _num_qubits; } int QuantumBackend::GetNumberofQubits() const { return num_qubits; } +void QuantumBackend::SetGateTypes(const std::vector &_gate_types, int _num_gates) +{ + gate_types = _gate_types; + num_gates = _num_gates; +} +std::vector QuantumBackend::GetGateTypes() const { return gate_types; } +int QuantumBackend::GetNumberofGates() const { return num_gates; } Qubit::Qubit(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUBIT){} Qubit::Qubit(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUBIT){} diff --git a/src/Topology.hpp b/src/Topology.hpp index 99e767f..bdd6d8d 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -858,13 +858,18 @@ class QuantumBackend : public Component { void SetNumberofQubits(int _num_qubits); int GetNumberofQubits () const; - /** - * TODO - */ + + void SetGateTypes(const std::vector &_gate_types, int _num_gates); + + std::vector GetGateTypes() const; + + int GetNumberofGates() const; + ~QuantumBackend() override = default; private: int num_qubits; + int num_gates; std::vector gate_types; }; @@ -889,9 +894,7 @@ class Qubit : public Component { void SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping); const std::vector &GetCouplingMapping() const; - /** - * TODO - */ + ~Qubit() override = default; private: diff --git a/src/parsers/qdmi-interface.cpp b/src/parsers/qdmi-interface.cpp index e402fb1..f5f7f20 100644 --- a/src/parsers/qdmi-interface.cpp +++ b/src/parsers/qdmi-interface.cpp @@ -182,7 +182,7 @@ extern "C" void QDMI_Interface::setCouplingMapping(Qubit *_qubit, int device_ind return; } -extern "C" void QDMI_Interface::setQubits(QuantumBackend * backend, QDMI_Device dev) +extern "C" void QDMI_Interface::setQubits(QuantumBackend *backend, QDMI_Device dev) { QDMI_Qubit qubits; int err, num_qubits = 0; @@ -225,7 +225,49 @@ extern "C" void QDMI_Interface::setQubits(QuantumBackend * backend, QDMI_Device return; } -extern "C" void QDMI_Interface::createQcTopo(Topology * topo) + +extern "C" void QDMI_Interface::setGateSets(QuantumBackend *backend, QDMI_Device dev) +{ + QDMI_Gate gates; + int err, num_gates; + + err = QDMI_query_all_gates(dev, &gates); + + if (err != QDMI_SUCCESS || gates == NULL) + { + std::cout << " [sys-sage]...............Could not obtain available " + << "gates via QDMI\n"; + return; + } + + err = QDMI_query_gateset_num(dev, &num_gates); + + if (err != QDMI_SUCCESS || num_gates == 0) + { + std::cout << " [sys-sage]...............Could not obtain number of " + << "available gates via QDMI\n"; + return; + } + else + { + std::cout << " [sys-sage]...............Found " + << num_gates << " supported gates.\n"; + } + std::vector gatesets(num_gates); + + for (int i = 0; i < num_gates; i++) + { + gatesets[i] = gates[i].name; + } + + backend->SetGateTypes(gatesets, num_gates); + + free(gates); + + return; +} + +extern "C" void QDMI_Interface::createQcTopo(Topology *topo) { auto quantum_backends = get_available_backends(); @@ -240,10 +282,9 @@ extern "C" void QDMI_Interface::createQcTopo(Topology * topo) } -extern "C" void QDMI_Interface::createQcTopo(QuantumBackend * backend, QDMI_Device dev) +extern "C" void QDMI_Interface::createQcTopo(QuantumBackend *backend, QDMI_Device dev) { backend->SetNumberofQubits(get_num_qubits(dev)); setQubits(backend, dev); - - // setGateSets; + setGateSets(backend, dev); } \ No newline at end of file diff --git a/src/parsers/qdmi-interface.hpp b/src/parsers/qdmi-interface.hpp index 05f7400..d91d268 100644 --- a/src/parsers/qdmi-interface.hpp +++ b/src/parsers/qdmi-interface.hpp @@ -30,9 +30,10 @@ extern "C" void set_qubits(QDMI_Device dev, int device_index); void setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index); /*********************************************************/ - void setQubits(QuantumBackend * backend, QDMI_Device dev); - void createQcTopo(Topology * topo); - void createQcTopo(QuantumBackend * topo, QDMI_Device dev); + void setQubits(QuantumBackend *backend, QDMI_Device dev); + void setGateSets(QuantumBackend *backend, QDMI_Device dev); + void createQcTopo(Topology *topo); + void createQcTopo(QuantumBackend *topo, QDMI_Device dev); private: QInfo info; QDMI_Session session; From c72c0d9ef89a9f42afa3774d53d7f925e6f91b71 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Wed, 24 Apr 2024 13:34:07 +0200 Subject: [PATCH 07/34] Updated exports --- examples/qdmi-test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index f9155ae..7e3f8be 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -1,8 +1,8 @@ /* Possible exports -* CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qinfo-src/include/ -* export CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qdmi-src/include -* export CONF_IBM=/home/diogenes/qdmi.git/inputs/conf.json -* export QDMI_CONFIG_FILE=/home/diogenes/sys-sage/build/_deps/qdmi-src/.qdmi-config +export CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qinfo-src/include/ +export CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qdmi-src/include +export CONF_IBM=/home/diogenes/qdmi.git/inputs/conf.json +export QDMI_CONFIG_FILE=/home/diogenes/sys-sage/build/_deps/qdmi-src/.qdmi-config */ #include From 4481d9224f8c73e8fe0cdd7e0293874ac3931c5c Mon Sep 17 00:00:00 2001 From: Durganshu Date: Tue, 30 Apr 2024 01:13:08 +0200 Subject: [PATCH 08/34] Dynamic information retrieval --- examples/qdmi-test.cpp | 4 +- src/Topology.hpp | 4 ++ src/parsers/qdmi-interface.cpp | 79 ++++++++++++++++++++++++++++------ src/parsers/qdmi-interface.hpp | 22 +++++++--- 4 files changed, 86 insertions(+), 23 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 7e3f8be..d893446 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -13,9 +13,9 @@ int main() { // Create an instance of the interface - QDMI_Interface qdmi; + QDMI_Parser qdmi; - // Use QDMI_Interface to create the topology of either all the backends or one of the backends + // Use QDMI_Parser to create the topology of either all the backends or one of the backends /*******************************************Method 1**********************************************/ Topology* qc_topo = new Topology(); diff --git a/src/Topology.hpp b/src/Topology.hpp index bdd6d8d..61284a1 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -865,6 +865,8 @@ class QuantumBackend : public Component { int GetNumberofGates() const; + void RefreshTopology(); + ~QuantumBackend() override = default; private: @@ -895,6 +897,8 @@ class Qubit : public Component { const std::vector &GetCouplingMapping() const; + void RefreshProperties(); + ~Qubit() override = default; private: diff --git a/src/parsers/qdmi-interface.cpp b/src/parsers/qdmi-interface.cpp index f5f7f20..cce5508 100644 --- a/src/parsers/qdmi-interface.cpp +++ b/src/parsers/qdmi-interface.cpp @@ -5,22 +5,24 @@ #include "qdmi-interface.hpp" +QInfo QDMI_Parser::info; +QDMI_Session QDMI_Parser::session; -extern "C" QDMI_Interface::QDMI_Interface() +extern "C" QDMI_Parser::QDMI_Parser() { initiateSession(); } -extern "C" int QDMI_Interface::initiateSession() +extern "C" int QDMI_Parser::initiateSession() { int err = 0; - info = NULL; - session = NULL; + QDMI_Parser::info = NULL; + QDMI_Parser::session = NULL; - err = QInfo_create(&info); + err = QInfo_create(&QDMI_Parser::info); CHECK_ERR(err, "QInfo_create"); - err = QDMI_session_init(info, &session); + err = QDMI_session_init(QDMI_Parser::info, &QDMI_Parser::session); CHECK_ERR(err, "QDMI_session_init"); if (err != QDMI_SUCCESS) { @@ -35,7 +37,7 @@ extern "C" int QDMI_Interface::initiateSession() } // TODO: Change function name (like FOMAC_available_devices) -extern "C" std::vector> QDMI_Interface::get_available_backends() +extern "C" std::vector> QDMI_Parser::get_available_backends() { // TODO REPEAT PERIODICALLY WITH A DELAY @@ -87,7 +89,7 @@ extern "C" std::vector> QDMI_Interface::get return registered_devices; } -extern "C" int QDMI_Interface::get_num_qubits(QDMI_Device dev) +extern "C" int QDMI_Parser::get_num_qubits(QDMI_Device dev) { int err, num_qubits = 0; @@ -103,7 +105,7 @@ extern "C" int QDMI_Interface::get_num_qubits(QDMI_Device dev) } -extern "C" void QDMI_Interface::set_qubits(QDMI_Device dev, int device_index) +extern "C" void QDMI_Parser::set_qubits(QDMI_Device dev, int device_index) { QDMI_Qubit qubits; int err, num_qubits = 0; @@ -144,7 +146,7 @@ extern "C" void QDMI_Interface::set_qubits(QDMI_Device dev, int device_index) } -extern "C" void QDMI_Interface::setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index) +extern "C" void QDMI_Parser::setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index) { if (_qubits.find(device_index) == _qubits.end()) @@ -182,7 +184,7 @@ extern "C" void QDMI_Interface::setCouplingMapping(Qubit *_qubit, int device_ind return; } -extern "C" void QDMI_Interface::setQubits(QuantumBackend *backend, QDMI_Device dev) +extern "C" void QDMI_Parser::setQubits(QuantumBackend *backend, QDMI_Device dev) { QDMI_Qubit qubits; int err, num_qubits = 0; @@ -226,7 +228,7 @@ extern "C" void QDMI_Interface::setQubits(QuantumBackend *backend, QDMI_Device d return; } -extern "C" void QDMI_Interface::setGateSets(QuantumBackend *backend, QDMI_Device dev) +extern "C" void QDMI_Parser::setGateSets(QuantumBackend *backend, QDMI_Device dev) { QDMI_Gate gates; int err, num_gates; @@ -262,12 +264,35 @@ extern "C" void QDMI_Interface::setGateSets(QuantumBackend *backend, QDMI_Device backend->SetGateTypes(gatesets, num_gates); + for(int num = 0; num < num_gates; ++num) + { + auto mapping = gates[num].coupling_mapping; + auto size_coupling_map = gates[num].size_coupling_map; + auto gate_size = gates[num].gate_size; + if(mapping != NULL) + { + + std::cout << "[sys-sage] Coupling map of gate: " << gates[num].name <<", size_coupling_map: "<< size_coupling_map << ", gate_size: " << gate_size<< "\n"; + + for (size_t i = 0; i < size_coupling_map; ++i) { + std::cout << "["; + for (size_t j = 0; j < gate_size; ++j) + { + std::cout << mapping[i][j] << ", "; + } + + printf("]\n"); + } + } + + } + free(gates); return; } -extern "C" void QDMI_Interface::createQcTopo(Topology *topo) +extern "C" void QDMI_Parser::createQcTopo(Topology *topo) { auto quantum_backends = get_available_backends(); @@ -282,9 +307,35 @@ extern "C" void QDMI_Interface::createQcTopo(Topology *topo) } -extern "C" void QDMI_Interface::createQcTopo(QuantumBackend *backend, QDMI_Device dev) +extern "C" void QDMI_Parser::createQcTopo(QuantumBackend *backend, QDMI_Device dev) { backend->SetNumberofQubits(get_num_qubits(dev)); setQubits(backend, dev); setGateSets(backend, dev); +} + +// extern "C" static void refreshQubitProprties(QuantumBackend *qc, Qubit *qubit) +// { +// //auto quantum_backends = get_available_backends(); + +// // Search for required QuantumBackend in the device and call these: +// //QDMI_Device dev = qc-> +// //QDMI_query_qubit_property(QDMI_Device dev, QDMI_Qubit_property prop, QDMI_Qubit qubit, int* coupling_map); +// } + +void QuantumBackend::RefreshTopology() +{ + + for (auto child : *(this->GetChildren())) { + if (auto qubit = dynamic_cast(child)) { + qubit->RefreshProperties(); + } + } +} + +void Qubit::RefreshProperties() +{ + QuantumBackend *qc = dynamic_cast (this->GetParent()); + QDMI_Parser::refreshQubitProprties(qc, this); + } \ No newline at end of file diff --git a/src/parsers/qdmi-interface.hpp b/src/parsers/qdmi-interface.hpp index d91d268..4782046 100644 --- a/src/parsers/qdmi-interface.hpp +++ b/src/parsers/qdmi-interface.hpp @@ -3,8 +3,8 @@ * @brief sys-sage's interface to QDMI. Based on MQSS's global FOMAC. */ -#ifndef QDMI_INTERFACE_HPP -#define QDMI_INTERFACE_HPP +#ifndef QDMI_Parser_HPP +#define QDMI_Parser_HPP #include #include @@ -18,10 +18,10 @@ extern "C" { - class QDMI_Interface + class QDMI_Parser { public: - QDMI_Interface(); + QDMI_Parser(); int initiateSession(); std::vector> get_available_backends(); @@ -34,13 +34,21 @@ extern "C" void setGateSets(QuantumBackend *backend, QDMI_Device dev); void createQcTopo(Topology *topo); void createQcTopo(QuantumBackend *topo, QDMI_Device dev); + static void refreshQubitProprties(QuantumBackend *qc, Qubit *qubit) + { + // //auto quantum_backends = get_available_backends(); + + // // Search for required QuantumBackend in the device and call these: + // //QDMI_Device dev = qc-> + // //QDMI_query_qubit_property(QDMI_Device dev, QDMI_Qubit_property prop, QDMI_Qubit qubit, int* coupling_map); + } private: - QInfo info; - QDMI_Session session; + static QInfo info; + static QDMI_Session session; //TODO: Is this needed? std::map < int, std::vector > _qubits; }; } -#endif // QDMI_INTERFACE_HPP \ No newline at end of file +#endif // QDMI_Parser_HPP \ No newline at end of file From a10ea90d1209ea254c3d247b5e1ff32a162b2c11 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Mon, 6 May 2024 16:35:08 +0200 Subject: [PATCH 09/34] Added calls for querying backend properties --- examples/qdmi-test.cpp | 21 ++- src/CMakeLists.txt | 4 +- src/Topology.cpp | 16 ++- src/Topology.hpp | 16 ++- .../{qdmi-interface.cpp => qdmi-parser.cpp} | 126 +++++++++--------- .../{qdmi-interface.hpp => qdmi-parser.hpp} | 7 +- src/sys-sage.hpp | 2 +- 7 files changed, 117 insertions(+), 75 deletions(-) rename src/parsers/{qdmi-interface.cpp => qdmi-parser.cpp} (71%) rename src/parsers/{qdmi-interface.hpp => qdmi-parser.hpp} (84%) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index d893446..95d4e4f 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -3,15 +3,17 @@ export CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qinfo-src/include/ export CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qdmi-src/include export CONF_IBM=/home/diogenes/qdmi.git/inputs/conf.json export QDMI_CONFIG_FILE=/home/diogenes/sys-sage/build/_deps/qdmi-src/.qdmi-config +export PROP_IBM=/home/diogenes/qdmi.git/inputs/props.json */ #include #include +#include #include "sys-sage.hpp" int main() { - + std::cout << std::setprecision(15); // Create an instance of the interface QDMI_Parser qdmi; @@ -21,9 +23,9 @@ int main() Topology* qc_topo = new Topology(); qdmi.createQcTopo(qc_topo); - cout << "---------------- Printing the configuration of QLM Backend----------------" << endl; + cout << "---------------- Printing the configuration of IBM Backend----------------" << endl; qc_topo->PrintSubtree(); - cout << "---------------- Printing Qubit Coupling Mappings for QLM Backend----------------" << endl; + cout << "---------------- Printing Qubit Coupling Mappings for IBM Backend----------------" << endl; QuantumBackend* qc = dynamic_cast(qc_topo->GetChild(0)); int total_qubits = qc->CountAllSubcomponents(); for (int i = 0; i < total_qubits; i++) @@ -37,7 +39,7 @@ int main() } std::cout << "}\n"; } - cout << "---------------- Printing Supported Gate Types for QLM Backend----------------" << endl; + cout << "---------------- Printing Supported Gate Types for IBM Backend----------------" << endl; int num_gates = qc->GetNumberofGates(); auto gates = qc->GetGateTypes(); for (int i = 0; i < num_gates; ++i) @@ -45,6 +47,17 @@ int main() std::cout << gates[i] << "\n"; } + std::cout << "---------------- Printing Qubit Properties for IBM Backend----------------" << endl; + for (int i = 0; i < total_qubits; i++) + { + Qubit* q = dynamic_cast(qc->GetChild(i)); + std::cout << "Qubit " << i << " has following properties: \n"; + std::cout << " T1: " << q->GetT1() << "\n"; + std::cout << " T2: " << q->GetT2() << "\n"; + std::cout << " Readout Error: " << q->GetReadoutError() << "\n"; + std::cout << " Readout Length: " << q->GetReadoutLength() << "\n"; + } + /*******************************************Method 2**********************************************/ // auto quantum_backends = qdmi.get_available_backends(); // std::cout << "Total " << quantum_backends.size() << " devices found.\n"; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3068829..eb35b15 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,7 +14,7 @@ set(SOURCES parsers/caps-numa-benchmark.cpp parsers/gpu-topo.cpp parsers/cccbench.cpp - parsers/qdmi-interface.cpp + parsers/qdmi-parser.cpp ) set(HEADERS @@ -27,7 +27,7 @@ set(HEADERS parsers/caps-numa-benchmark.hpp parsers/gpu-topo.hpp parsers/cccbench.cpp - parsers/qdmi-interface.hpp + parsers/qdmi-parser.hpp ) add_library(sys-sage SHARED ${SOURCES} ${HEADERS}) diff --git a/src/Topology.cpp b/src/Topology.cpp index fa561fe..4466bb5 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -596,4 +596,18 @@ void Qubit::SetCouplingMapping( const std::vector &coupling_mapping, const const std::vector & Qubit::GetCouplingMapping() const { return _coupling_mapping; -} \ No newline at end of file +} + +void Qubit::SetProperties(double t1, double t2, double readout_error, double readout_length) +{ + _t1 = t1; + _t2 = t2; + _readout_error = readout_error; + _readout_length = readout_length; + +} + +const double Qubit::GetT1() const { return _t1; } +const double Qubit::GetT2() const { return _t2; } +const double Qubit::GetReadoutError() const { return _readout_error; } +const double Qubit::GetReadoutLength() const { return _readout_length; } diff --git a/src/Topology.hpp b/src/Topology.hpp index 61284a1..80e4106 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -895,8 +895,18 @@ class Qubit : public Component { void SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping); + void SetProperties(double t1, double t2, double readout_error, double readout_length); + const std::vector &GetCouplingMapping() const; + const double GetT1() const; + + const double GetT2() const; + + const double GetReadoutError() const; + + const double GetReadoutLength() const; + void RefreshProperties(); ~Qubit() override = default; @@ -904,7 +914,11 @@ class Qubit : public Component { private: std::vector _coupling_mapping; int _size_coupling_mapping; - float fidelity; + double fidelity; + double _t1; + double _t2; + double _readout_error; + double _readout_length; }; #endif diff --git a/src/parsers/qdmi-interface.cpp b/src/parsers/qdmi-parser.cpp similarity index 71% rename from src/parsers/qdmi-interface.cpp rename to src/parsers/qdmi-parser.cpp index cce5508..88f4934 100644 --- a/src/parsers/qdmi-interface.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -1,9 +1,9 @@ /** - * @file qdmi-interface.hpp + * @file qdmi-parser.hpp * @brief sys-sage's interface to QDMI. Based on MQSS's global FOMAC. */ -#include "qdmi-interface.hpp" +#include "qdmi-parser.hpp" QInfo QDMI_Parser::info; QDMI_Session QDMI_Parser::session; @@ -146,42 +146,51 @@ extern "C" void QDMI_Parser::set_qubits(QDMI_Device dev, int device_index) } -extern "C" void QDMI_Parser::setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index) +extern "C" void QDMI_Parser::getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubit, std::vector &coupling_mapping, int &coupling_map_size) { - if (_qubits.find(device_index) == _qubits.end()) + if (qubit->size_coupling_mapping == 0) { - std::cout << " [sys-sage]...............No qubits found for device " - << device_index << std::endl; + std::cout << " [sys-sage]...............No coupling mapping for qubit\n"; return; } + coupling_map_size = qubit->size_coupling_mapping; + coupling_mapping.resize(coupling_map_size); - auto qubit_impl = _qubits[device_index][qubit_index]; - // if (!qubit_impl) - // { - // std::cout << " [sys-sage]...............Qubit is null for device " - // << device_index << " and qubit index " << qubit_index << std::endl; - // return; - // } + //for (int j = 0; j < coupling_map_size; j++) + //{ + // Copy the coupling_mapping from qubit_impl + std::copy(qubit->coupling_mapping, qubit->coupling_mapping + coupling_map_size, coupling_mapping.begin()); + //} +} - int size = qubit_impl.size_coupling_mapping; //qubit_impl->size_coupling_mapping; - if (size <= 0) +extern "C" void QDMI_Parser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit) +{ + int scope; + // Declare prop as a vector + //std::vector prop{QDMI_T1_TIME, QDMI_T2_TIME, QDMI_READOUT_ERROR, QDMI_READOUT_LENGTH}; + std::array prop{1, 2, 4, 5}; + std::array properties{"T1", "T2", "readout_error", "readout_length"}; + double value; + for (size_t i = 0; i < 4; ++i) { - std::cout << " [sys-sage]...............Invalid size of coupling mapping for qubit " - << "with device index " << device_index << " and qubit index " << qubit_index << std::endl; - return; - } - - - std::vector coupling_mapping(size); - - // Copy the coupling_mapping from qubit_impl - std::copy(qubit_impl.coupling_mapping, qubit_impl.coupling_mapping + size, coupling_mapping.begin()); - - _qubit->SetCouplingMapping(coupling_mapping, size); + int err = QDMI_query_qubit_property_exists(dev, prop[i], qubit, &scope); + if(err) + { + std::cout << " [sys-sage]...............Queried property doesn't exist: " << i <<"\n"; + continue; + } + err = QDMI_query_qubit_property(dev, prop[i], qubit, &value); + if(err) + { + std::cout << " [sys-sage]...............Unable to query property: " << i <<"\n"; + continue; + } + //std::cout << " [sys-sage]...............Value of " << properties[i] << ": " << value << "\n"; - return; + } + } extern "C" void QDMI_Parser::setQubits(QuantumBackend *backend, QDMI_Device dev) @@ -204,27 +213,18 @@ extern "C" void QDMI_Parser::setQubits(QuantumBackend *backend, QDMI_Device dev) { Qubit* q = new Qubit(backend, i); - if (qubits[i].coupling_mapping == NULL) - { - std::cout << " [sys-sage]...............No coupling mapping for qubit " - << i << "\n"; - continue; - } - - int coupling_map_size = qubits[i].size_coupling_mapping; - - std::vector coupling_mapping(coupling_map_size); - - for (int j = 0; j < coupling_map_size; j++) - { - // Copy the coupling_mapping from qubit_impl - std::copy(qubits[i].coupling_mapping, qubits[i].coupling_mapping + coupling_map_size, coupling_mapping.begin()); - } + // Set coupling map + int coupling_map_size; + std::vector coupling_mapping; + getCouplingMapping(dev, &qubits[i], coupling_mapping, coupling_map_size); q->SetCouplingMapping(coupling_mapping, coupling_map_size); + + // Set all the qubit properties + getQubitProperties(dev, &qubits[i]); + q->SetProperties(qubits[i].t1, qubits[i].t2, qubits[i].readout_error, qubits[i].readout_length); } free(qubits); - return; } @@ -264,28 +264,28 @@ extern "C" void QDMI_Parser::setGateSets(QuantumBackend *backend, QDMI_Device de backend->SetGateTypes(gatesets, num_gates); - for(int num = 0; num < num_gates; ++num) - { - auto mapping = gates[num].coupling_mapping; - auto size_coupling_map = gates[num].size_coupling_map; - auto gate_size = gates[num].gate_size; - if(mapping != NULL) - { + // for(int num = 0; num < num_gates; ++num) + // { + // auto mapping = gates[num].coupling_mapping; + // auto size_coupling_map = gates[num].sizcde_coupling_map; + // auto gate_size = gates[num].gate_size; + // if(mapping != NULL) + // { - std::cout << "[sys-sage] Coupling map of gate: " << gates[num].name <<", size_coupling_map: "<< size_coupling_map << ", gate_size: " << gate_size<< "\n"; + // // std::cout << "[sys-sage] Coupling map of gate: " << gates[num].name <<", size_coupling_map: "<< size_coupling_map << ", gate_size: " << gate_size<< "\n"; - for (size_t i = 0; i < size_coupling_map; ++i) { - std::cout << "["; - for (size_t j = 0; j < gate_size; ++j) - { - std::cout << mapping[i][j] << ", "; - } + // for (size_t i = 0; i < size_coupling_map; ++i) { + // std::cout << "["; + // for (size_t j = 0; j < gate_size; ++j) + // { + // std::cout << mapping[i][j] << ", "; + // } - printf("]\n"); - } - } + // printf("]\n"); + // } + // } - } + // } free(gates); diff --git a/src/parsers/qdmi-interface.hpp b/src/parsers/qdmi-parser.hpp similarity index 84% rename from src/parsers/qdmi-interface.hpp rename to src/parsers/qdmi-parser.hpp index 4782046..a7e4078 100644 --- a/src/parsers/qdmi-interface.hpp +++ b/src/parsers/qdmi-parser.hpp @@ -1,5 +1,5 @@ /** - * @file qdmi-interface.hpp + * @file qdmi-parser.hpp * @brief sys-sage's interface to QDMI. Based on MQSS's global FOMAC. */ @@ -26,10 +26,11 @@ extern "C" std::vector> get_available_backends(); int get_num_qubits(QDMI_Device dev); - /**********Maybe remove these*****************************/ + /**********Maybe remove this*****************************/ void set_qubits(QDMI_Device dev, int device_index); - void setCouplingMapping(Qubit *_qubit, int device_index, int qubit_index); /*********************************************************/ + void getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubit, std::vector &coupling_mapping, int &coupling_map_size); + void getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit); void setQubits(QuantumBackend *backend, QDMI_Device dev); void setGateSets(QuantumBackend *backend, QDMI_Device dev); void createQcTopo(Topology *topo); diff --git a/src/sys-sage.hpp b/src/sys-sage.hpp index ec94653..21f0c02 100644 --- a/src/sys-sage.hpp +++ b/src/sys-sage.hpp @@ -9,5 +9,5 @@ #include "parsers/caps-numa-benchmark.hpp" #include "parsers/gpu-topo.hpp" #include "parsers/cccbench.hpp" -#include "parsers/qdmi-interface.hpp" +#include "parsers/qdmi-parser.hpp" #endif //SYS_SAGE From d7a3172b61bc6f5606e16f7db85faf43625c76eb Mon Sep 17 00:00:00 2001 From: Durganshu Date: Thu, 9 May 2024 19:14:45 +0200 Subject: [PATCH 10/34] Updated qubit query updates according to the newer QDMI query calls --- src/parsers/qdmi-parser.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index 88f4934..edcb516 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -169,25 +169,30 @@ extern "C" void QDMI_Parser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubi { int scope; // Declare prop as a vector - //std::vector prop{QDMI_T1_TIME, QDMI_T2_TIME, QDMI_READOUT_ERROR, QDMI_READOUT_LENGTH}; - std::array prop{1, 2, 4, 5}; + std::vector prop{QDMI_T1_TIME, QDMI_T2_TIME, QDMI_READOUT_ERROR, QDMI_READOUT_LENGTH}; std::array properties{"T1", "T2", "readout_error", "readout_length"}; double value; for (size_t i = 0; i < 4; ++i) { - int err = QDMI_query_qubit_property_exists(dev, prop[i], qubit, &scope); + // QDMI_Qubit_property prop_index; + QDMI_Qubit_property prop_index = new (QDMI_Qubit_property_impl_t); + prop_index->name = prop[i]; + int err = QDMI_query_qubit_property_exists(dev, prop_index, qubit, &scope); if(err) { std::cout << " [sys-sage]...............Queried property doesn't exist: " << i <<"\n"; continue; } - err = QDMI_query_qubit_property(dev, prop[i], qubit, &value); - if(err) - { - std::cout << " [sys-sage]...............Unable to query property: " << i <<"\n"; - continue; + if(prop_index->type == QDMI_DOUBLE){ + err = QDMI_query_qubit_property_d(dev, qubit, prop_index, &value); + if(err) + { + std::cout << " [sys-sage]...............Unable to query property: " << i <<"\n"; + continue; + } + //std::cout << " [sys-sage]...............Value of " << properties[i] << ": " << value << "\n"; } - //std::cout << " [sys-sage]...............Value of " << properties[i] << ": " << value << "\n"; + delete prop_index; } From ec351155eaa5591a2bf3fad66dec186ff33f449c Mon Sep 17 00:00:00 2001 From: Durganshu Date: Wed, 15 May 2024 01:22:59 +0200 Subject: [PATCH 11/34] QuantumGate is now an independent class (not a DataPath) --- src/DataPath.hpp | 22 ---------------------- src/Topology.hpp | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/DataPath.hpp b/src/DataPath.hpp index dafe6b2..8369424 100644 --- a/src/DataPath.hpp +++ b/src/DataPath.hpp @@ -141,26 +141,4 @@ class DataPath { }; -/** -Class DataPath represents Data Paths in the topology -- Data Paths represent an arbitrary relation (or data movement) between two Components from the Component Tree. -\n Data Paths create a Data-Path graph, which is a structure orthogonal to the Component Tree. -\n Each Component contains a reference to all Data Paths going to or from this components (as well as parents and children in the Component Tree). Using these references, it is possible to navigate between the Components and to view the data stores in the Components or the Data Paths. -*/ -class QuantumGate : public DataPath { - -public: - /** - QuantumGate constructor. - @param _qubits - An array of all qubits that the gate acts on. - @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. - \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 - */ - QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); -private: - std::vector qubits; /**< TODO */ - int** coupling_mapping; - char *unitary; - float fidelity; -}; - #endif diff --git a/src/Topology.hpp b/src/Topology.hpp index 80e4106..9a487ec 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -41,7 +41,7 @@ using namespace std; class DataPath; - +class QuantumGate; /** Generic class Component - all components inherit from this class, i.e. this class defines attributes and methods common to all components. \n Therefore, these can be used universally among all components. Usually, a Component instance would be an instance of one of the child classes, but a generic component (instance of class Component) is also possible. @@ -872,6 +872,8 @@ class QuantumBackend : public Component { private: int num_qubits; int num_gates; + + // TO-DO: make it a std::vector < QuantumGate*> std::vector gate_types; }; @@ -921,6 +923,35 @@ class Qubit : public Component { double _readout_length; }; + +class QuantumGate { + +public: + /** + QuantumGate constructor. + @param _qubits - An array of all qubits that the gate acts on. + @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. + \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 + */ + //QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); + + QuantumGate(); + + void setGateProperties(); + + void setAdditionalProperties(); + +private: + std::string _name; + int _gate_size; // "No. of qubits involved" + int _gate_length; // "Time needed to execute that gate operation" + std::string _unitary; + double fidelity; + std::vector> coupling_mapping; + std::vector qubits; /**< TODO */ + std::map _additional_properties; +}; + #endif From ee7234f962e61801487949602c64b0283f78a422 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Thu, 16 May 2024 01:01:54 +0200 Subject: [PATCH 12/34] QuantumGate internal representation working --- examples/qdmi-test.cpp | 39 +++++++++++++--- src/Topology.cpp | 88 ++++++++++++++++++++++++++++++++++--- src/Topology.hpp | 46 ++++++++++++++----- src/parsers/qdmi-parser.cpp | 17 +++++-- 4 files changed, 163 insertions(+), 27 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 95d4e4f..802af01 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -40,12 +40,41 @@ int main() std::cout << "}\n"; } cout << "---------------- Printing Supported Gate Types for IBM Backend----------------" << endl; - int num_gates = qc->GetNumberofGates(); - auto gates = qc->GetGateTypes(); - for (int i = 0; i < num_gates; ++i) - { - std::cout << gates[i] << "\n"; + auto _1q_gates = qc->Get1QGates(); + auto _2q_gates = qc->Get2QGates(); + auto _mq_gates = qc->GetMQGates(); + + if(_1q_gates.size()) + { + int size = _1q_gates.size(); + std::cout << "Total " << size << " 1-Qubit gates\n"; + for (int i = 0; i < size; ++i) + { + std::cout << " Gate name:" << _1q_gates[i]->GetName() << "\n"; + } + + } + if(_2q_gates.size()) + { + int size = _2q_gates.size(); + std::cout << "Total " << size << " 2-Qubit gates\n"; + for (int i = 0; i < size; ++i) + { + std::cout << " Gate name:" << _2q_gates[i]->GetName() << "\n"; + } + + } + if(_mq_gates.size()) + { + int size = _mq_gates.size(); + std::cout << "Total " << size << " M-Qubit gates\n"; + for (int i = 0; i < size; ++i) + { + std::cout << " Gate name:" << _mq_gates[i]->GetName() << "\n"; + } + } + std::cout << "---------------- Printing Qubit Properties for IBM Backend----------------" << endl; for (int i = 0; i < total_qubits; i++) diff --git a/src/Topology.cpp b/src/Topology.cpp index 4466bb5..90d297f 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -575,16 +575,42 @@ Thread::Thread(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_T Thread::Thread(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_THREAD){} QuantumBackend::QuantumBackend(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} -QuantumBackend::QuantumBackend(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} +QuantumBackend::QuantumBackend(Component * _parent, int _id, string _name):Component(_parent, _id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} void QuantumBackend::SetNumberofQubits(int _num_qubits) { num_qubits = _num_qubits; } int QuantumBackend::GetNumberofQubits() const { return num_qubits; } -void QuantumBackend::SetGateTypes(const std::vector &_gate_types, int _num_gates) -{ - gate_types = _gate_types; - num_gates = _num_gates; +// void QuantumBackend::SetGateTypes(const std::vector &_gate_types, int _num_gates) +// { +// gate_types = _gate_types; +// num_gates = _num_gates; +// } +void QuantumBackend::addGate(QuantumGate *_gate) +{ + if(_gate->GetGateType() == SYS_SAGE_1Q_QUANTUM_GATE) + _1q_gates.push_back(_gate); + else if(_gate->GetGateType() == SYS_SAGE_2Q_QUANTUM_GATE) + _2q_gates.push_back(_gate); + else if(_gate->GetGateType() == SYS_SAGE_MQ_QUANTUM_GATE) + _mq_gates.push_back(_gate); +} +std::vector QuantumBackend::Get1QGates() const { return _1q_gates; } + +std::vector QuantumBackend::Get2QGates() const { return _2q_gates; } + +std::vector QuantumBackend::GetMQGates() const { return _mq_gates; } + +std::vector QuantumBackend::GetGatesByTypes(int _gate_type) const +{ + if(_gate_type == SYS_SAGE_1Q_QUANTUM_GATE) + return _1q_gates; + else if(_gate_type == SYS_SAGE_2Q_QUANTUM_GATE) + return _2q_gates; + else if(_gate_type == SYS_SAGE_MQ_QUANTUM_GATE) + return _mq_gates; + else + return {}; } -std::vector QuantumBackend::GetGateTypes() const { return gate_types; } -int QuantumBackend::GetNumberofGates() const { return num_gates; } + +int QuantumBackend::GetNumberofGates() const { return (_1q_gates.size() + _2q_gates.size() + _mq_gates.size()); } Qubit::Qubit(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUBIT){} Qubit::Qubit(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUBIT){} @@ -611,3 +637,51 @@ const double Qubit::GetT1() const { return _t1; } const double Qubit::GetT2() const { return _t2; } const double Qubit::GetReadoutError() const { return _readout_error; } const double Qubit::GetReadoutLength() const { return _readout_length; } + +QuantumGate::QuantumGate() +{ + gate_size = 1; + type = SYS_SAGE_1Q_QUANTUM_GATE; +} +QuantumGate::QuantumGate(size_t _gate_size) : gate_size(_gate_size) +{ + if (gate_size == 1) + type = SYS_SAGE_1Q_QUANTUM_GATE; + else if (gate_size == 2) + type = SYS_SAGE_2Q_QUANTUM_GATE; + else if(gate_size > 2) + type = SYS_SAGE_MQ_QUANTUM_GATE; + else + { + type = SYS_SAGE_NO_TYPE_QUANTUM_GATE; + } + +} + +void QuantumGate::SetGateProperties(std::string _name, double _fidelity, std::string _unitary) +{ + name = _name; + fidelity = _fidelity; + unitary = _unitary; +} +int QuantumGate::GetGateType() const +{ + return type; +} + +double QuantumGate::GetFidelity() const +{ + return fidelity; +} +size_t QuantumGate::GetGateSize() const +{ + return gate_size; +} +std::string QuantumGate::GetUnitary() const +{ + return unitary; +} +std::string QuantumGate::GetName() const +{ + return name; +} \ No newline at end of file diff --git a/src/Topology.hpp b/src/Topology.hpp index 9a487ec..50f621e 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -38,6 +38,10 @@ #define SYS_SAGE_CHIP_TYPE_CPU_SOCKET 4 /**< Chip type used for one CPU socket. */ #define SYS_SAGE_CHIP_TYPE_GPU 8 /**< Chip type used for a GPU.*/ +#define SYS_SAGE_1Q_QUANTUM_GATE 1 /**< Quantum Gate of size 1-Qubit. */ +#define SYS_SAGE_2Q_QUANTUM_GATE 2 /**< Quantum Gate of size 2-Qubits. */ +#define SYS_SAGE_MQ_QUANTUM_GATE 4 /**< Quantum Gate of size M-Qubits (where M >2). */ +#define SYS_SAGE_NO_TYPE_QUANTUM_GATE 8 /**< Quantum Gate of size 0 or invalid size. */ using namespace std; class DataPath; @@ -859,9 +863,17 @@ class QuantumBackend : public Component { int GetNumberofQubits () const; - void SetGateTypes(const std::vector &_gate_types, int _num_gates); + //void SetGateTypes(const std::vector &_gate_types, int _num_gates); - std::vector GetGateTypes() const; + void addGate(QuantumGate *gate); + + std::vector Get1QGates() const; + + std::vector Get2QGates() const; + + std::vector GetMQGates() const; + + std::vector GetGatesByTypes(int gate_type) const; int GetNumberofGates() const; @@ -874,7 +886,9 @@ class QuantumBackend : public Component { int num_gates; // TO-DO: make it a std::vector < QuantumGate*> - std::vector gate_types; + std::vector _1q_gates; + std::vector _2q_gates; + std::vector _mq_gates; }; class Qubit : public Component { @@ -936,20 +950,28 @@ class QuantumGate { //QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); QuantumGate(); + QuantumGate(size_t _gate_size); - void setGateProperties(); - - void setAdditionalProperties(); + void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); + void SetGateCouplingMap(std::vector > _coupling_mapping); + void SetAdditionalProperties(); + int GetGateType() const; + double GetFidelity() const; + size_t GetGateSize() const; + std::string GetUnitary() const; + std::string GetName() const; private: - std::string _name; - int _gate_size; // "No. of qubits involved" - int _gate_length; // "Time needed to execute that gate operation" - std::string _unitary; + int type; + std::string name; + size_t gate_size; // "No. of qubits involved" + int gate_length; // "Time needed to execute that gate operation" + std::string unitary; double fidelity; - std::vector> coupling_mapping; + + std::vector> coupling_mapping; std::vector qubits; /**< TODO */ - std::map _additional_properties; + std::map additional_properties; }; #endif diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index edcb516..791a1e0 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -260,14 +260,25 @@ extern "C" void QDMI_Parser::setGateSets(QuantumBackend *backend, QDMI_Device de std::cout << " [sys-sage]...............Found " << num_gates << " supported gates.\n"; } - std::vector gatesets(num_gates); + //std::vector gatesets(num_gates); for (int i = 0; i < num_gates; i++) { - gatesets[i] = gates[i].name; + + std::string name = gates[i].name; + double fidelity = gates[i].fidelity; + std::string unitary = gates[i].unitary; + size_t gate_size = gates[i].gate_size; + + // Add a destructor + QuantumGate *qgate = new QuantumGate(gate_size); + qgate->SetGateProperties(name, fidelity, unitary); + + //qgate->setAdditionalProperties(); + backend->addGate(qgate); } - backend->SetGateTypes(gatesets, num_gates); + //backend->SetGateTypes(gatesets, num_gates); // for(int num = 0; num < num_gates; ++num) // { From ce0286fa3ebd4d2246adfa5493da02414856d961 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Thu, 16 May 2024 18:12:52 +0200 Subject: [PATCH 13/34] Added gatetype for invalid gate_size --- examples/qdmi-test.cpp | 31 +++++++++++++++++++++++++------ src/Topology.cpp | 10 ++++++---- src/Topology.hpp | 4 +++- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 802af01..49f7996 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -43,34 +43,53 @@ int main() auto _1q_gates = qc->Get1QGates(); auto _2q_gates = qc->Get2QGates(); auto _mq_gates = qc->GetMQGates(); + auto _0q_gates = qc->GetInvalidTypeGates(); if(_1q_gates.size()) { int size = _1q_gates.size(); - std::cout << "Total " << size << " 1-Qubit gates\n"; + std::cout << "Total " << size << " 1-Qubit gate(s)\n"; for (int i = 0; i < size; ++i) { - std::cout << " Gate name:" << _1q_gates[i]->GetName() << "\n"; + std::cout << " Gate name:" << _1q_gates[i]->GetName() << ", "; + std::cout << "Gate size:" << _1q_gates[i]->GetGateSize() << ", "; + std::cout << "Gate fidelity:" << _1q_gates[i]->GetFidelity() << "\n"; } } if(_2q_gates.size()) { int size = _2q_gates.size(); - std::cout << "Total " << size << " 2-Qubit gates\n"; + std::cout << "Total " << size << " 2-Qubit gate(s)\n"; for (int i = 0; i < size; ++i) { - std::cout << " Gate name:" << _2q_gates[i]->GetName() << "\n"; + std::cout << " Gate name:" << _2q_gates[i]->GetName() << ", "; + std::cout << "Gate size:" << _2q_gates[i]->GetGateSize() << ", "; + std::cout << "Gate fidelity:" << _2q_gates[i]->GetFidelity() << "\n"; } } if(_mq_gates.size()) { int size = _mq_gates.size(); - std::cout << "Total " << size << " M-Qubit gates\n"; + std::cout << "Total " << size << " M-Qubit gate(s)\n"; for (int i = 0; i < size; ++i) { - std::cout << " Gate name:" << _mq_gates[i]->GetName() << "\n"; + std::cout << " Gate name:" << _mq_gates[i]->GetName() << ", "; + std::cout << "Gate size:" << _mq_gates[i]->GetGateSize() << ", "; + std::cout << "Gate fidelity:" << _mq_gates[i]->GetFidelity() << "\n"; + } + + } + if(_0q_gates.size()) + { + int size = _0q_gates.size(); + std::cout << "Total " << size << " gate(s) with no type\n"; + for (int i = 0; i < size; ++i) + { + std::cout << " Gate name:" << _0q_gates[i]->GetName() << ", "; + std::cout << "Gate size:" << _0q_gates[i]->GetGateSize() << ", "; + std::cout << "Gate fidelity:" << _0q_gates[i]->GetFidelity() << "\n"; } } diff --git a/src/Topology.cpp b/src/Topology.cpp index 90d297f..8b5c8d2 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -591,6 +591,8 @@ void QuantumBackend::addGate(QuantumGate *_gate) _2q_gates.push_back(_gate); else if(_gate->GetGateType() == SYS_SAGE_MQ_QUANTUM_GATE) _mq_gates.push_back(_gate); + else + _0q_gates.push_back(_gate); } std::vector QuantumBackend::Get1QGates() const { return _1q_gates; } @@ -598,6 +600,8 @@ std::vector QuantumBackend::Get2QGates() const { return _2q_gates; std::vector QuantumBackend::GetMQGates() const { return _mq_gates; } +std::vector QuantumBackend::GetInvalidTypeGates() const { return _0q_gates; } + std::vector QuantumBackend::GetGatesByTypes(int _gate_type) const { if(_gate_type == SYS_SAGE_1Q_QUANTUM_GATE) @@ -607,7 +611,7 @@ std::vector QuantumBackend::GetGatesByTypes(int _gate_type) const else if(_gate_type == SYS_SAGE_MQ_QUANTUM_GATE) return _mq_gates; else - return {}; + return _0q_gates; } int QuantumBackend::GetNumberofGates() const { return (_1q_gates.size() + _2q_gates.size() + _mq_gates.size()); } @@ -652,9 +656,7 @@ QuantumGate::QuantumGate(size_t _gate_size) : gate_size(_gate_size) else if(gate_size > 2) type = SYS_SAGE_MQ_QUANTUM_GATE; else - { - type = SYS_SAGE_NO_TYPE_QUANTUM_GATE; - } + type = SYS_SAGE_NO_TYPE_QUANTUM_GATE; } diff --git a/src/Topology.hpp b/src/Topology.hpp index 50f621e..b16ca87 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -873,6 +873,8 @@ class QuantumBackend : public Component { std::vector GetMQGates() const; + std::vector GetInvalidTypeGates() const; + std::vector GetGatesByTypes(int gate_type) const; int GetNumberofGates() const; @@ -885,7 +887,7 @@ class QuantumBackend : public Component { int num_qubits; int num_gates; - // TO-DO: make it a std::vector < QuantumGate*> + std::vector _0q_gates; // For gates with gate_size = 0 std::vector _1q_gates; std::vector _2q_gates; std::vector _mq_gates; From a8d6b677c25e8d26c2288975155b54469972f3d4 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Mon, 24 Jun 2024 14:47:55 +0200 Subject: [PATCH 14/34] Modified calls for retrieving gate types --- examples/qdmi-test.cpp | 3 +- src/Topology.cpp | 92 ++++++++++++++++++++++++++++++------- src/Topology.hpp | 13 +++--- src/parsers/qdmi-parser.cpp | 3 +- src/parsers/qdmi-parser.hpp | 23 +++++----- 5 files changed, 97 insertions(+), 37 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 49f7996..5d3b621 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -15,6 +15,7 @@ int main() { std::cout << std::setprecision(15); // Create an instance of the interface + // To-Do: Consider QDMI_Parser as a static class QDMI_Parser qdmi; // Use QDMI_Parser to create the topology of either all the backends or one of the backends @@ -43,7 +44,7 @@ int main() auto _1q_gates = qc->Get1QGates(); auto _2q_gates = qc->Get2QGates(); auto _mq_gates = qc->GetMQGates(); - auto _0q_gates = qc->GetInvalidTypeGates(); + auto _0q_gates = qc->GetNoTypeGates(); if(_1q_gates.size()) { diff --git a/src/Topology.cpp b/src/Topology.cpp index 8b5c8d2..a52ac67 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -575,8 +575,11 @@ Thread::Thread(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_T Thread::Thread(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_THREAD){} QuantumBackend::QuantumBackend(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} + QuantumBackend::QuantumBackend(Component * _parent, int _id, string _name):Component(_parent, _id, _name, SYS_SAGE_COMPONENT_QUANTUM_BACKEND){} + void QuantumBackend::SetNumberofQubits(int _num_qubits) { num_qubits = _num_qubits; } + int QuantumBackend::GetNumberofQubits() const { return num_qubits; } // void QuantumBackend::SetGateTypes(const std::vector &_gate_types, int _num_gates) // { @@ -585,44 +588,94 @@ int QuantumBackend::GetNumberofQubits() const { return num_qubits; } // } void QuantumBackend::addGate(QuantumGate *_gate) { - if(_gate->GetGateType() == SYS_SAGE_1Q_QUANTUM_GATE) - _1q_gates.push_back(_gate); - else if(_gate->GetGateType() == SYS_SAGE_2Q_QUANTUM_GATE) - _2q_gates.push_back(_gate); - else if(_gate->GetGateType() == SYS_SAGE_MQ_QUANTUM_GATE) - _mq_gates.push_back(_gate); - else - _0q_gates.push_back(_gate); + gate_types.push_back(_gate); +} + +std::vector QuantumBackend::Get1QGates() const +{ + std::vector gates; + gates.reserve(gate_types.size()); + for (auto gate : gate_types) + { + if(gate->GetGateType() == SYS_SAGE_1Q_QUANTUM_GATE) + { + gates.push_back(gate); + } + } + return gates; } -std::vector QuantumBackend::Get1QGates() const { return _1q_gates; } -std::vector QuantumBackend::Get2QGates() const { return _2q_gates; } +std::vector QuantumBackend::Get2QGates() const +{ + std::vector gates; + gates.reserve(gate_types.size()); + for (auto gate : gate_types) + { + if(gate->GetGateType() == SYS_SAGE_2Q_QUANTUM_GATE) + { + gates.push_back(gate); + } + } + return gates; +} -std::vector QuantumBackend::GetMQGates() const { return _mq_gates; } +std::vector QuantumBackend::GetMQGates() const +{ + std::vector gates; + gates.reserve(gate_types.size()); + for (auto gate : gate_types) + { + if(gate->GetGateType() == SYS_SAGE_MQ_QUANTUM_GATE) + { + gates.push_back(gate); + } + } + return gates; +} -std::vector QuantumBackend::GetInvalidTypeGates() const { return _0q_gates; } +std::vector QuantumBackend::GetNoTypeGates() const +{ + std::vector gates; + gates.reserve(gate_types.size()); + for (auto gate : gate_types) + { + if(gate->GetGateType() == SYS_SAGE_NO_TYPE_QUANTUM_GATE) + { + gates.push_back(gate); + } + } + return gates; +} std::vector QuantumBackend::GetGatesByTypes(int _gate_type) const { if(_gate_type == SYS_SAGE_1Q_QUANTUM_GATE) - return _1q_gates; + return this->Get1QGates(); else if(_gate_type == SYS_SAGE_2Q_QUANTUM_GATE) - return _2q_gates; + return this->Get2QGates(); else if(_gate_type == SYS_SAGE_MQ_QUANTUM_GATE) - return _mq_gates; + return this->GetMQGates(); else - return _0q_gates; + return this->GetNoTypeGates(); +} + +std::vector QuantumBackend::GetAllGateTypes() const +{ + return gate_types; } -int QuantumBackend::GetNumberofGates() const { return (_1q_gates.size() + _2q_gates.size() + _mq_gates.size()); } +int QuantumBackend::GetNumberofGates() const { return gate_types.size(); } Qubit::Qubit(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUBIT){} + Qubit::Qubit(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUBIT){} + void Qubit::SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping) { _coupling_mapping = coupling_mapping; _size_coupling_mapping = size_coupling_mapping; } + const std::vector & Qubit::GetCouplingMapping() const { return _coupling_mapping; @@ -647,6 +700,7 @@ QuantumGate::QuantumGate() gate_size = 1; type = SYS_SAGE_1Q_QUANTUM_GATE; } + QuantumGate::QuantumGate(size_t _gate_size) : gate_size(_gate_size) { if (gate_size == 1) @@ -666,6 +720,7 @@ void QuantumGate::SetGateProperties(std::string _name, double _fidelity, std::st fidelity = _fidelity; unitary = _unitary; } + int QuantumGate::GetGateType() const { return type; @@ -675,14 +730,17 @@ double QuantumGate::GetFidelity() const { return fidelity; } + size_t QuantumGate::GetGateSize() const { return gate_size; } + std::string QuantumGate::GetUnitary() const { return unitary; } + std::string QuantumGate::GetName() const { return name; diff --git a/src/Topology.hpp b/src/Topology.hpp index b16ca87..0f08e76 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -873,10 +873,12 @@ class QuantumBackend : public Component { std::vector GetMQGates() const; - std::vector GetInvalidTypeGates() const; + std::vector GetNoTypeGates() const; std::vector GetGatesByTypes(int gate_type) const; + std::vector GetAllGateTypes() const; + int GetNumberofGates() const; void RefreshTopology(); @@ -886,11 +888,8 @@ class QuantumBackend : public Component { private: int num_qubits; int num_gates; - - std::vector _0q_gates; // For gates with gate_size = 0 - std::vector _1q_gates; - std::vector _2q_gates; - std::vector _mq_gates; + // To-DO: Use only one gates memeber + std::vector gate_types; }; class Qubit : public Component { @@ -939,7 +938,7 @@ class Qubit : public Component { double _readout_length; }; - +// TO DO: May be keep this as a nested class class QuantumGate { public: diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index 791a1e0..1d23fde 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -177,12 +177,13 @@ extern "C" void QDMI_Parser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubi // QDMI_Qubit_property prop_index; QDMI_Qubit_property prop_index = new (QDMI_Qubit_property_impl_t); prop_index->name = prop[i]; - int err = QDMI_query_qubit_property_exists(dev, prop_index, qubit, &scope); + int err = QDMI_query_qubit_property_exists(dev, qubit, prop_index, &scope); if(err) { std::cout << " [sys-sage]...............Queried property doesn't exist: " << i <<"\n"; continue; } + err = QDMI_query_qubit_property_type(dev, qubit, prop_index); if(prop_index->type == QDMI_DOUBLE){ err = QDMI_query_qubit_property_d(dev, qubit, prop_index, &value); if(err) diff --git a/src/parsers/qdmi-parser.hpp b/src/parsers/qdmi-parser.hpp index a7e4078..43c2809 100644 --- a/src/parsers/qdmi-parser.hpp +++ b/src/parsers/qdmi-parser.hpp @@ -1,7 +1,7 @@ /** - * @file qdmi-parser.hpp - * @brief sys-sage's interface to QDMI. Based on MQSS's global FOMAC. - */ +* @file qdmi-parser.hpp +* @brief sys-sage's interface to QDMI. +*/ #ifndef QDMI_Parser_HPP #define QDMI_Parser_HPP @@ -22,19 +22,15 @@ extern "C" { public: QDMI_Parser(); - int initiateSession(); std::vector> get_available_backends(); int get_num_qubits(QDMI_Device dev); - /**********Maybe remove this*****************************/ - void set_qubits(QDMI_Device dev, int device_index); - /*********************************************************/ - void getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubit, std::vector &coupling_mapping, int &coupling_map_size); - void getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit); - void setQubits(QuantumBackend *backend, QDMI_Device dev); - void setGateSets(QuantumBackend *backend, QDMI_Device dev); void createQcTopo(Topology *topo); void createQcTopo(QuantumBackend *topo, QDMI_Device dev); + + /**********TODO: remove this*****************************/ + void set_qubits(QDMI_Device dev, int device_index); + /*********************************************************/ static void refreshQubitProprties(QuantumBackend *qc, Qubit *qubit) { // //auto quantum_backends = get_available_backends(); @@ -44,8 +40,13 @@ extern "C" // //QDMI_query_qubit_property(QDMI_Device dev, QDMI_Qubit_property prop, QDMI_Qubit qubit, int* coupling_map); } private: + int initiateSession(); static QInfo info; static QDMI_Session session; + void getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubit, std::vector &coupling_mapping, int &coupling_map_size); + void getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit); + void setQubits(QuantumBackend *backend, QDMI_Device dev); + void setGateSets(QuantumBackend *backend, QDMI_Device dev); //TODO: Is this needed? std::map < int, std::vector > _qubits; }; From 71d73966d63eb1a8582a5fe5e505fcb79c612568 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Tue, 9 Jul 2024 01:19:03 +0200 Subject: [PATCH 15/34] Added AtomSite as a component --- src/Topology.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Topology.hpp b/src/Topology.hpp index 0f08e76..cc5197b 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -892,6 +892,25 @@ class QuantumBackend : public Component { std::vector gate_types; }; +class AtomSite : public QuantumBackend{ +public: + struct SiteProperties { + + int nRows; + int nColumns; + int nAods; + int nAodIntermediateLevels; + int nAodCoordinates; + double interQubitDistance; + double interactionRadius; + double blockingFactor; + } properties; + + std::map shuttlingTimes; + std::map shuttlingAverageFidelities; + +}; + class Qubit : public Component { public: /** From d7e13c28325366d40241e2355b4241910bde6c31 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Sun, 14 Jul 2024 15:43:11 +0200 Subject: [PATCH 16/34] QuantumGate as a nested class --- src/Topology.hpp | 78 +++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/src/Topology.hpp b/src/Topology.hpp index cc5197b..6949d64 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -863,7 +863,41 @@ class QuantumBackend : public Component { int GetNumberofQubits () const; - //void SetGateTypes(const std::vector &_gate_types, int _num_gates); + class QuantumGate { + + public: + /** + QuantumGate constructor. + @param _qubits - An array of all qubits that the gate acts on. + @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. + \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 + */ + // QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); + + QuantumGate(); + QuantumGate(size_t _gate_size); + + void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); + void SetGateCouplingMap(std::vector > _coupling_mapping); + void SetAdditionalProperties(); + int GetGateType() const; + double GetFidelity() const; + size_t GetGateSize() const; + std::string GetUnitary() const; + std::string GetName() const; + + private: + int type; + std::string name; + size_t gate_size; // "No. of qubits involved" + int gate_length; // "Time needed to execute that gate operation" + std::string unitary; + double fidelity; + + std::vector> coupling_mapping; + std::vector qubits; /**< TODO */ + std::map additional_properties; + }; void addGate(QuantumGate *gate); @@ -892,6 +926,7 @@ class QuantumBackend : public Component { std::vector gate_types; }; +// TO-DO: Choose a better name for NA and TI systems class AtomSite : public QuantumBackend{ public: struct SiteProperties { @@ -943,6 +978,8 @@ class Qubit : public Component { const double GetReadoutLength() const; + const double GetFrequency() const; + void RefreshProperties(); ~Qubit() override = default; @@ -955,43 +992,8 @@ class Qubit : public Component { double _t2; double _readout_error; double _readout_length; -}; - -// TO DO: May be keep this as a nested class -class QuantumGate { - -public: - /** - QuantumGate constructor. - @param _qubits - An array of all qubits that the gate acts on. - @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. - \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 - */ - //QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); - - QuantumGate(); - QuantumGate(size_t _gate_size); - - void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); - void SetGateCouplingMap(std::vector > _coupling_mapping); - void SetAdditionalProperties(); - int GetGateType() const; - double GetFidelity() const; - size_t GetGateSize() const; - std::string GetUnitary() const; - std::string GetName() const; - -private: - int type; - std::string name; - size_t gate_size; // "No. of qubits involved" - int gate_length; // "Time needed to execute that gate operation" - std::string unitary; - double fidelity; - - std::vector> coupling_mapping; - std::vector qubits; /**< TODO */ - std::map additional_properties; + double _fequency; + std::string _calibration_time; }; #endif From d7bdd86e887f490526e50ee1efedcf3fe168333c Mon Sep 17 00:00:00 2001 From: Durganshu Date: Sun, 14 Jul 2024 21:31:53 +0200 Subject: [PATCH 17/34] using qdmi ibm-backend-testing branch --- cmake/Findqdmi.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Findqdmi.cmake b/cmake/Findqdmi.cmake index 4d91a76..9d80262 100644 --- a/cmake/Findqdmi.cmake +++ b/cmake/Findqdmi.cmake @@ -3,7 +3,7 @@ include(FetchContent) FetchContent_Declare( qdmi GIT_REPOSITORY git@github.com:Munich-Quantum-Software-Stack/QDMI.git - GIT_TAG testing + GIT_TAG ibm-backend-testing ) FetchContent_MakeAvailable(qdmi) From 9f14aa17b699959ee2dc415a9ef5c2f681f88036 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Mon, 15 Jul 2024 18:37:01 +0200 Subject: [PATCH 18/34] Added GetAllCouplingMaps and GetAllQubits --- examples/qdmi-test.cpp | 7 +++ src/Topology.cpp | 32 +++++++++++++- src/Topology.hpp | 97 ++++++++++++++++++++++-------------------- 3 files changed, 89 insertions(+), 47 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 5d3b621..afbccae 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -107,6 +107,13 @@ int main() std::cout << " Readout Length: " << q->GetReadoutLength() << "\n"; } + std::cout << "---------------- Printing Coupling Maps of all the Qubits----------------" << endl; + auto children = qc->GetAllCouplingMaps(); + for (auto it = children.begin(); it != children.end(); ++it) { + std::cout << "{" << it->first << ", " << it->second << "}\n"; + } + + /*******************************************Method 2**********************************************/ // auto quantum_backends = qdmi.get_available_backends(); // std::cout << "Total " << quantum_backends.size() << " devices found.\n"; diff --git a/src/Topology.cpp b/src/Topology.cpp index a52ac67..e49aa44 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -666,8 +666,38 @@ std::vector QuantumBackend::GetAllGateTypes() const int QuantumBackend::GetNumberofGates() const { return gate_types.size(); } -Qubit::Qubit(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUBIT){} +std::vector QuantumBackend::GetAllQubits() +{ + auto all_children = GetAllChildrenByType(SYS_SAGE_COMPONENT_QUBIT); + std::vector qubits; + qubits.reserve(all_children.size()); + + for (size_t i = 0; i < all_children.size(); ++i) + { + Qubit* q = dynamic_cast(all_children[i]); + qubits.push_back(q); + } + + return qubits; +} + +std::set > QuantumBackend::GetAllCouplingMaps() +{ + std::set> result; + for(auto i = 0; i < num_qubits; ++i) + { + Qubit* q = dynamic_cast(GetChild(i)); + auto coupling_map = q->GetCouplingMapping(); + for (size_t j = 0; j < coupling_map.size(); ++j) + { + result.emplace(i, coupling_map[j]); + } + } + + return result; +} +Qubit::Qubit(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUBIT){} Qubit::Qubit(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUBIT){} void Qubit::SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping) diff --git a/src/Topology.hpp b/src/Topology.hpp index 0f08e76..b53e401 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -841,6 +841,53 @@ class Thread : public Component { private: }; +class Qubit : public Component { +public: + /** + Qubit constructor (no automatic insertion in the Component Tree). Sets: + @param _id = id, default 0 + @param _name = name, default "Qubit" + @param componentType=>SYS_SAGE_COMPONENT_QUBIT + */ + Qubit(int _id = 0, string _name = "Qubit"); + /** + Qubit constructor with insertion into the Component Tree as the parent 's child (as long as parent is an existing Component). Sets: + @param parent = the parent + @param _id = id, default 0 + @param _name = name, default "Qubit0" + @param componentType=>SYS_SAGE_COMPONENT_QUBIT + */ + Qubit(Component * parent, int _id = 0, string _name = "Qubit"); + + void SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping); + + void SetProperties(double t1, double t2, double readout_error, double readout_length); + + const std::vector &GetCouplingMapping() const; + + const double GetT1() const; + + const double GetT2() const; + + const double GetReadoutError() const; + + const double GetReadoutLength() const; + + void RefreshProperties(); + + ~Qubit() override = default; + +private: + std::vector _coupling_mapping; + int _size_coupling_mapping; + double fidelity; + double _t1; + double _t2; + double _readout_error; + double _readout_length; +}; + + class QuantumBackend : public Component { public: /** @@ -881,6 +928,10 @@ class QuantumBackend : public Component { int GetNumberofGates() const; + std::vector GetAllQubits(); + + std::set > GetAllCouplingMaps(); + void RefreshTopology(); ~QuantumBackend() override = default; @@ -892,52 +943,6 @@ class QuantumBackend : public Component { std::vector gate_types; }; -class Qubit : public Component { -public: - /** - Qubit constructor (no automatic insertion in the Component Tree). Sets: - @param _id = id, default 0 - @param _name = name, default "Qubit" - @param componentType=>SYS_SAGE_COMPONENT_QUBIT - */ - Qubit(int _id = 0, string _name = "Qubit"); - /** - Qubit constructor with insertion into the Component Tree as the parent 's child (as long as parent is an existing Component). Sets: - @param parent = the parent - @param _id = id, default 0 - @param _name = name, default "Qubit0" - @param componentType=>SYS_SAGE_COMPONENT_QUBIT - */ - Qubit(Component * parent, int _id = 0, string _name = "Qubit"); - - void SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping); - - void SetProperties(double t1, double t2, double readout_error, double readout_length); - - const std::vector &GetCouplingMapping() const; - - const double GetT1() const; - - const double GetT2() const; - - const double GetReadoutError() const; - - const double GetReadoutLength() const; - - void RefreshProperties(); - - ~Qubit() override = default; - -private: - std::vector _coupling_mapping; - int _size_coupling_mapping; - double fidelity; - double _t1; - double _t2; - double _readout_error; - double _readout_length; -}; - // TO DO: May be keep this as a nested class class QuantumGate { From 9d20d06b847d93da0c3d0a6416372e92b6f3ab72 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Thu, 18 Jul 2024 23:11:44 +0200 Subject: [PATCH 19/34] Added todos --- src/Topology.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Topology.hpp b/src/Topology.hpp index 6949d64..31efbb0 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -901,12 +901,14 @@ class QuantumBackend : public Component { void addGate(QuantumGate *gate); + // TO-DO: Remove these redundant methods std::vector Get1QGates() const; std::vector Get2QGates() const; std::vector GetMQGates() const; + // TODO: This could be a 1Q Gate, generalize this std::vector GetNoTypeGates() const; std::vector GetGatesByTypes(int gate_type) const; From b697a0077424800f233c0b84115601dc022e8343 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Fri, 19 Jul 2024 17:03:59 +0200 Subject: [PATCH 20/34] Removed 1Q/2Q/3Q Gates --- examples/qdmi-test.cpp | 8 ++++---- src/Topology.hpp | 10 ---------- src/parsers/qdmi-parser.cpp | 8 +++++--- src/parsers/qdmi-parser.hpp | 3 ++- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 5d3b621..c6f044e 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -41,10 +41,10 @@ int main() std::cout << "}\n"; } cout << "---------------- Printing Supported Gate Types for IBM Backend----------------" << endl; - auto _1q_gates = qc->Get1QGates(); - auto _2q_gates = qc->Get2QGates(); - auto _mq_gates = qc->GetMQGates(); - auto _0q_gates = qc->GetNoTypeGates(); + auto _1q_gates = qc->GetGatesByTypes(SYS_SAGE_1Q_QUANTUM_GATE); + auto _2q_gates = qc->GetGatesByTypes(SYS_SAGE_2Q_QUANTUM_GATE); + auto _mq_gates = qc->GetGatesByTypes(SYS_SAGE_MQ_QUANTUM_GATE); + auto _0q_gates = qc->GetGatesByTypes(SYS_SAGE_NO_TYPE_QUANTUM_GATE); if(_1q_gates.size()) { diff --git a/src/Topology.hpp b/src/Topology.hpp index 31efbb0..f7a13bd 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -901,16 +901,6 @@ class QuantumBackend : public Component { void addGate(QuantumGate *gate); - // TO-DO: Remove these redundant methods - std::vector Get1QGates() const; - - std::vector Get2QGates() const; - - std::vector GetMQGates() const; - - // TODO: This could be a 1Q Gate, generalize this - std::vector GetNoTypeGates() const; - std::vector GetGatesByTypes(int gate_type) const; std::vector GetAllGateTypes() const; diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index 1d23fde..9a01809 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -37,11 +37,13 @@ extern "C" int QDMI_Parser::initiateSession() } // TODO: Change function name (like FOMAC_available_devices) +// This will get the list of all the available devices and check individually if that devide is up and running. + extern "C" std::vector> QDMI_Parser::get_available_backends() { - // TODO REPEAT PERIODICALLY WITH A DELAY - char **available_devices = get_qdmi_library_list_names(); + // 46-74: Replace this with newer QDMI calls + char **available_devices = get_qdmi_library_list_names(); // --> if (available_devices == NULL) { std::cout << " [sys-sage]...............Failed to get " @@ -57,7 +59,7 @@ extern "C" std::vector> QDMI_Parser::get_av QDMI_Device device = (QDMI_Device)malloc(sizeof(struct QDMI_Device_impl_d)); - QDMI_Library lib = find_library_by_name(available_devices[i]); + QDMI_Library lib = find_library_by_name(available_devices[i]); // --> if (!lib) { diff --git a/src/parsers/qdmi-parser.hpp b/src/parsers/qdmi-parser.hpp index 43c2809..f34257d 100644 --- a/src/parsers/qdmi-parser.hpp +++ b/src/parsers/qdmi-parser.hpp @@ -18,6 +18,7 @@ extern "C" { + // To-Do: Change the name of class class QDMI_Parser { public: @@ -31,7 +32,7 @@ extern "C" /**********TODO: remove this*****************************/ void set_qubits(QDMI_Device dev, int device_index); /*********************************************************/ - static void refreshQubitProprties(QuantumBackend *qc, Qubit *qubit) + static void refreshQubitProperties(QuantumBackend *qc, Qubit *qubit) { // //auto quantum_backends = get_available_backends(); From cd9d953a147b03807ccbadbc4179ab15b47d2a1a Mon Sep 17 00:00:00 2001 From: Durganshu Date: Fri, 19 Jul 2024 17:13:07 +0200 Subject: [PATCH 21/34] Renamed QDMI_Parser --- examples/qdmi-test.cpp | 8 ++++---- src/parsers/qdmi-parser.cpp | 38 ++++++++++++++++++------------------- src/parsers/qdmi-parser.hpp | 10 +++++----- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index c6f044e..8c736c7 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -15,10 +15,10 @@ int main() { std::cout << std::setprecision(15); // Create an instance of the interface - // To-Do: Consider QDMI_Parser as a static class - QDMI_Parser qdmi; + // To-Do: Consider QdmiParser as a static class + QdmiParser qdmi; - // Use QDMI_Parser to create the topology of either all the backends or one of the backends + // Use QdmiParser to create the topology of either all the backends or one of the backends /*******************************************Method 1**********************************************/ Topology* qc_topo = new Topology(); @@ -52,7 +52,7 @@ int main() std::cout << "Total " << size << " 1-Qubit gate(s)\n"; for (int i = 0; i < size; ++i) { - std::cout << " Gate name:" << _1q_gates[i]->GetName() << ", "; + std::cout << "Gate name:" << _1q_gates[i]->GetName() << ", "; std::cout << "Gate size:" << _1q_gates[i]->GetGateSize() << ", "; std::cout << "Gate fidelity:" << _1q_gates[i]->GetFidelity() << "\n"; } diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index 9a01809..510f8c1 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -1,28 +1,28 @@ /** * @file qdmi-parser.hpp - * @brief sys-sage's interface to QDMI. Based on MQSS's global FOMAC. + * @brief sys-sage's interface to QDMI. */ #include "qdmi-parser.hpp" -QInfo QDMI_Parser::info; -QDMI_Session QDMI_Parser::session; +QInfo QdmiParser::info; +QDMI_Session QdmiParser::session; -extern "C" QDMI_Parser::QDMI_Parser() +extern "C" QdmiParser::QdmiParser() { initiateSession(); } -extern "C" int QDMI_Parser::initiateSession() +extern "C" int QdmiParser::initiateSession() { int err = 0; - QDMI_Parser::info = NULL; - QDMI_Parser::session = NULL; + QdmiParser::info = NULL; + QdmiParser::session = NULL; - err = QInfo_create(&QDMI_Parser::info); + err = QInfo_create(&QdmiParser::info); CHECK_ERR(err, "QInfo_create"); - err = QDMI_session_init(QDMI_Parser::info, &QDMI_Parser::session); + err = QDMI_session_init(QdmiParser::info, &QdmiParser::session); CHECK_ERR(err, "QDMI_session_init"); if (err != QDMI_SUCCESS) { @@ -39,7 +39,7 @@ extern "C" int QDMI_Parser::initiateSession() // TODO: Change function name (like FOMAC_available_devices) // This will get the list of all the available devices and check individually if that devide is up and running. -extern "C" std::vector> QDMI_Parser::get_available_backends() +extern "C" std::vector> QdmiParser::get_available_backends() { // 46-74: Replace this with newer QDMI calls @@ -91,7 +91,7 @@ extern "C" std::vector> QDMI_Parser::get_av return registered_devices; } -extern "C" int QDMI_Parser::get_num_qubits(QDMI_Device dev) +extern "C" int QdmiParser::get_num_qubits(QDMI_Device dev) { int err, num_qubits = 0; @@ -107,7 +107,7 @@ extern "C" int QDMI_Parser::get_num_qubits(QDMI_Device dev) } -extern "C" void QDMI_Parser::set_qubits(QDMI_Device dev, int device_index) +extern "C" void QdmiParser::set_qubits(QDMI_Device dev, int device_index) { QDMI_Qubit qubits; int err, num_qubits = 0; @@ -148,7 +148,7 @@ extern "C" void QDMI_Parser::set_qubits(QDMI_Device dev, int device_index) } -extern "C" void QDMI_Parser::getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubit, std::vector &coupling_mapping, int &coupling_map_size) +extern "C" void QdmiParser::getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubit, std::vector &coupling_mapping, int &coupling_map_size) { if (qubit->size_coupling_mapping == 0) @@ -167,7 +167,7 @@ extern "C" void QDMI_Parser::getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubi //} } -extern "C" void QDMI_Parser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit) +extern "C" void QdmiParser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit) { int scope; // Declare prop as a vector @@ -201,7 +201,7 @@ extern "C" void QDMI_Parser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubi } -extern "C" void QDMI_Parser::setQubits(QuantumBackend *backend, QDMI_Device dev) +extern "C" void QdmiParser::setQubits(QuantumBackend *backend, QDMI_Device dev) { QDMI_Qubit qubits; int err, num_qubits = 0; @@ -236,7 +236,7 @@ extern "C" void QDMI_Parser::setQubits(QuantumBackend *backend, QDMI_Device dev) return; } -extern "C" void QDMI_Parser::setGateSets(QuantumBackend *backend, QDMI_Device dev) +extern "C" void QdmiParser::setGateSets(QuantumBackend *backend, QDMI_Device dev) { QDMI_Gate gates; int err, num_gates; @@ -311,7 +311,7 @@ extern "C" void QDMI_Parser::setGateSets(QuantumBackend *backend, QDMI_Device de return; } -extern "C" void QDMI_Parser::createQcTopo(Topology *topo) +extern "C" void QdmiParser::createQcTopo(Topology *topo) { auto quantum_backends = get_available_backends(); @@ -326,7 +326,7 @@ extern "C" void QDMI_Parser::createQcTopo(Topology *topo) } -extern "C" void QDMI_Parser::createQcTopo(QuantumBackend *backend, QDMI_Device dev) +extern "C" void QdmiParser::createQcTopo(QuantumBackend *backend, QDMI_Device dev) { backend->SetNumberofQubits(get_num_qubits(dev)); setQubits(backend, dev); @@ -355,6 +355,6 @@ void QuantumBackend::RefreshTopology() void Qubit::RefreshProperties() { QuantumBackend *qc = dynamic_cast (this->GetParent()); - QDMI_Parser::refreshQubitProprties(qc, this); + QdmiParser::refreshQubitProprties(qc, this); } \ No newline at end of file diff --git a/src/parsers/qdmi-parser.hpp b/src/parsers/qdmi-parser.hpp index f34257d..1b5dfff 100644 --- a/src/parsers/qdmi-parser.hpp +++ b/src/parsers/qdmi-parser.hpp @@ -3,8 +3,8 @@ * @brief sys-sage's interface to QDMI. */ -#ifndef QDMI_Parser_HPP -#define QDMI_Parser_HPP +#ifndef QDMIParser_HPP +#define QDMIParser_HPP #include #include @@ -19,10 +19,10 @@ extern "C" { // To-Do: Change the name of class - class QDMI_Parser + class QdmiParser { public: - QDMI_Parser(); + QdmiParser(); std::vector> get_available_backends(); int get_num_qubits(QDMI_Device dev); @@ -54,4 +54,4 @@ extern "C" } -#endif // QDMI_Parser_HPP \ No newline at end of file +#endif // QDMIParser_HPP \ No newline at end of file From 6d994dba9f63892be6b1161391dc7ade421ba104 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Fri, 19 Jul 2024 18:15:54 +0200 Subject: [PATCH 22/34] Added createAllQcTopo and createQcTopo overloads --- examples/qdmi-test.cpp | 2 +- src/parsers/qdmi-parser.cpp | 80 +++++++++---------------------------- src/parsers/qdmi-parser.hpp | 49 ++++++++++++++++++----- 3 files changed, 58 insertions(+), 73 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 8c736c7..13f3be8 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -22,7 +22,7 @@ int main() /*******************************************Method 1**********************************************/ Topology* qc_topo = new Topology(); - qdmi.createQcTopo(qc_topo); + qdmi.createAllQcTopo(qc_topo); cout << "---------------- Printing the configuration of IBM Backend----------------" << endl; qc_topo->PrintSubtree(); diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index 510f8c1..6d758da 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -107,66 +107,6 @@ extern "C" int QdmiParser::get_num_qubits(QDMI_Device dev) } -extern "C" void QdmiParser::set_qubits(QDMI_Device dev, int device_index) -{ - QDMI_Qubit qubits; - int err, num_qubits = 0; - - err = QDMI_query_all_qubits(dev, &qubits); - - if (err != QDMI_SUCCESS || qubits == NULL) - { - std::cout << " [sys-sage]...............Could not obtain available " - << "qubits via QDMI\n"; - return; - } - - err = QDMI_query_qubits_num(dev, &num_qubits); - - if (err != QDMI_SUCCESS || num_qubits == 0) - { - std::cout << " [sys-sage]...............Could not obtain number of " - << "available qubits via QDMI\n"; - return; - } - else - { - std::cout << " [sys-sage]...............Found " - << num_qubits << " qubits.\n"; - } - - _qubits[device_index] = std::vector (); - - for(int i = 0; i < num_qubits; ++i) - { - _qubits[device_index].push_back(qubits[i]); - } - - free(qubits); - - return; - -} - -extern "C" void QdmiParser::getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubit, std::vector &coupling_mapping, int &coupling_map_size) -{ - - if (qubit->size_coupling_mapping == 0) - { - std::cout << " [sys-sage]...............No coupling mapping for qubit\n"; - return; - } - - coupling_map_size = qubit->size_coupling_mapping; - coupling_mapping.resize(coupling_map_size); - - //for (int j = 0; j < coupling_map_size; j++) - //{ - // Copy the coupling_mapping from qubit_impl - std::copy(qubit->coupling_mapping, qubit->coupling_mapping + coupling_map_size, coupling_mapping.begin()); - //} -} - extern "C" void QdmiParser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit) { int scope; @@ -311,11 +251,10 @@ extern "C" void QdmiParser::setGateSets(QuantumBackend *backend, QDMI_Device dev return; } -extern "C" void QdmiParser::createQcTopo(Topology *topo) +extern "C" void QdmiParser::createAllQcTopo(Topology *topo) { auto quantum_backends = get_available_backends(); - int total_quantum_backends = quantum_backends.size(); for (auto i = 0; i < total_quantum_backends; ++i) @@ -326,6 +265,15 @@ extern "C" void QdmiParser::createQcTopo(Topology *topo) } +extern "C" Topology QdmiParser::createAllQcTopo() +{ + + Topology qc_topo = Topology(); + createAllQcTopo(&qc_topo); + + return qc_topo; +} + extern "C" void QdmiParser::createQcTopo(QuantumBackend *backend, QDMI_Device dev) { backend->SetNumberofQubits(get_num_qubits(dev)); @@ -333,6 +281,14 @@ extern "C" void QdmiParser::createQcTopo(QuantumBackend *backend, QDMI_Device de setGateSets(backend, dev); } +extern "C" QuantumBackend QdmiParser::createQcTopo(QDMI_Device dev, int device_index, std::string device_name) +{ + QuantumBackend qc = QuantumBackend(device_index, device_name); + createQcTopo(&qc, dev); + + return qc; +} + // extern "C" static void refreshQubitProprties(QuantumBackend *qc, Qubit *qubit) // { // //auto quantum_backends = get_available_backends(); diff --git a/src/parsers/qdmi-parser.hpp b/src/parsers/qdmi-parser.hpp index 1b5dfff..056c0ea 100644 --- a/src/parsers/qdmi-parser.hpp +++ b/src/parsers/qdmi-parser.hpp @@ -18,21 +18,51 @@ extern "C" { - // To-Do: Change the name of class + class QdmiParser { public: QdmiParser(); + + /** + * Returns all the available backends registered with QDMI. + * @return A vector of all the backends with their names and "QDMI_Device" handles + */ std::vector> get_available_backends(); int get_num_qubits(QDMI_Device dev); - void createQcTopo(Topology *topo); - void createQcTopo(QuantumBackend *topo, QDMI_Device dev); - - /**********TODO: remove this*****************************/ - void set_qubits(QDMI_Device dev, int device_index); - /*********************************************************/ - static void refreshQubitProperties(QuantumBackend *qc, Qubit *qubit) + /** + * Checks which backends are available and creates a topology with an object of type "Topology" as their parent. + * @param topo - Object of type "Topology", which will be the parent Component of all the quntum backends. + */ + void createAllQcTopo(Topology *topo); + + /** + * Checks which backends are available and creates a topology with an object of type "Topology" as their parent. + * @returns An object of type "Topology", which will be the parent Component of all the quntum backends. + * @see createAllQcTopo(Topology *topo) + */ + Topology createAllQcTopo(); + + /** + * Creates a topology of a single quantum backend corresponding to the provided "QDMI_Device". + * @param backend - Object of type "QuantumBackend", storing the topology of a quantum backend. + * @param dev - A QDMI_Device for which the topology needs to be created. + * @see createQcTopo(Topology *topo) + */ + void createQcTopo(QuantumBackend *backend, QDMI_Device dev); + + /** + * Creates a topology of a single quantum backend corresponding to the provided "QDMI_Device". + * @param dev - A QDMI_Device for which the topology needs to be created. + * @param device_index - Index of the device. + * @param device_name - Name of the device. + * @returns Object of type "QuantumBackend", storing the topology of a quantum backend. + * @see createQcTopo(QuantumBackend *backend, QDMI_Device dev) + */ + QuantumBackend createQcTopo(QDMI_Device dev, int device_index = 0, std::string device_name=""); + + static void refreshQcProperties(QuantumBackend *qc, bool single_qubit = false, int qubit_index=0) { // //auto quantum_backends = get_available_backends(); @@ -48,8 +78,7 @@ extern "C" void getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit); void setQubits(QuantumBackend *backend, QDMI_Device dev); void setGateSets(QuantumBackend *backend, QDMI_Device dev); - //TODO: Is this needed? - std::map < int, std::vector > _qubits; + }; } From 5f210b2707bd4da95342e70b5a031c89a1262b44 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Sat, 20 Jul 2024 00:16:38 +0200 Subject: [PATCH 23/34] Debugs and cleanup --- cmake/Findqdmi.cmake | 2 +- src/Topology.cpp | 72 ++-------------- src/Topology.hpp | 163 ++++++++++++++++++------------------ src/parsers/qdmi-parser.cpp | 23 ++++- 4 files changed, 111 insertions(+), 149 deletions(-) diff --git a/cmake/Findqdmi.cmake b/cmake/Findqdmi.cmake index 4d91a76..9d80262 100644 --- a/cmake/Findqdmi.cmake +++ b/cmake/Findqdmi.cmake @@ -3,7 +3,7 @@ include(FetchContent) FetchContent_Declare( qdmi GIT_REPOSITORY git@github.com:Munich-Quantum-Software-Stack/QDMI.git - GIT_TAG testing + GIT_TAG ibm-backend-testing ) FetchContent_MakeAvailable(qdmi) diff --git a/src/Topology.cpp b/src/Topology.cpp index a52ac67..845e45d 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -581,84 +581,26 @@ QuantumBackend::QuantumBackend(Component * _parent, int _id, string _name):Compo void QuantumBackend::SetNumberofQubits(int _num_qubits) { num_qubits = _num_qubits; } int QuantumBackend::GetNumberofQubits() const { return num_qubits; } -// void QuantumBackend::SetGateTypes(const std::vector &_gate_types, int _num_gates) -// { -// gate_types = _gate_types; -// num_gates = _num_gates; -// } + void QuantumBackend::addGate(QuantumGate *_gate) { gate_types.push_back(_gate); } -std::vector QuantumBackend::Get1QGates() const +std::vector QuantumBackend::GetGatesByTypes(int _gate_type) const { std::vector gates; gates.reserve(gate_types.size()); - for (auto gate : gate_types) - { - if(gate->GetGateType() == SYS_SAGE_1Q_QUANTUM_GATE) - { - gates.push_back(gate); - } - } - return gates; -} - -std::vector QuantumBackend::Get2QGates() const -{ - std::vector gates; - gates.reserve(gate_types.size()); - for (auto gate : gate_types) - { - if(gate->GetGateType() == SYS_SAGE_2Q_QUANTUM_GATE) - { - gates.push_back(gate); - } - } - return gates; -} - -std::vector QuantumBackend::GetMQGates() const -{ - std::vector gates; - gates.reserve(gate_types.size()); - for (auto gate : gate_types) + + for (QuantumGate * gate : gate_types) { - if(gate->GetGateType() == SYS_SAGE_MQ_QUANTUM_GATE) - { - gates.push_back(gate); - } + if(_gate_type == gate->GetGateType()) + gates.emplace_back(gate); } + return gates; } -std::vector QuantumBackend::GetNoTypeGates() const -{ - std::vector gates; - gates.reserve(gate_types.size()); - for (auto gate : gate_types) - { - if(gate->GetGateType() == SYS_SAGE_NO_TYPE_QUANTUM_GATE) - { - gates.push_back(gate); - } - } - return gates; -} - -std::vector QuantumBackend::GetGatesByTypes(int _gate_type) const -{ - if(_gate_type == SYS_SAGE_1Q_QUANTUM_GATE) - return this->Get1QGates(); - else if(_gate_type == SYS_SAGE_2Q_QUANTUM_GATE) - return this->Get2QGates(); - else if(_gate_type == SYS_SAGE_MQ_QUANTUM_GATE) - return this->GetMQGates(); - else - return this->GetNoTypeGates(); -} - std::vector QuantumBackend::GetAllGateTypes() const { return gate_types; diff --git a/src/Topology.hpp b/src/Topology.hpp index f7a13bd..b720828 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -841,6 +841,57 @@ class Thread : public Component { private: }; +class Qubit : public Component { +public: + /** + Qubit constructor (no automatic insertion in the Component Tree). Sets: + @param _id = id, default 0 + @param _name = name, default "Qubit" + @param componentType=>SYS_SAGE_COMPONENT_QUBIT + */ + Qubit(int _id = 0, string _name = "Qubit"); + /** + Qubit constructor with insertion into the Component Tree as the parent 's child (as long as parent is an existing Component). Sets: + @param parent = the parent + @param _id = id, default 0 + @param _name = name, default "Qubit0" + @param componentType=>SYS_SAGE_COMPONENT_QUBIT + */ + Qubit(Component * parent, int _id = 0, string _name = "Qubit"); + + void SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping); + + void SetProperties(double t1, double t2, double readout_error, double readout_length); + + const std::vector &GetCouplingMapping() const; + + const double GetT1() const; + + const double GetT2() const; + + const double GetReadoutError() const; + + const double GetReadoutLength() const; + + const double GetFrequency() const; + + void RefreshProperties(); + + ~Qubit() override = default; + +private: + std::vector _coupling_mapping; + int _size_coupling_mapping; + double fidelity; + double _t1; + double _t2; + double _readout_error; + double _readout_length; + double _fequency; + std::string _calibration_time; +}; + + class QuantumBackend : public Component { public: /** @@ -863,42 +914,6 @@ class QuantumBackend : public Component { int GetNumberofQubits () const; - class QuantumGate { - - public: - /** - QuantumGate constructor. - @param _qubits - An array of all qubits that the gate acts on. - @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. - \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 - */ - // QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); - - QuantumGate(); - QuantumGate(size_t _gate_size); - - void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); - void SetGateCouplingMap(std::vector > _coupling_mapping); - void SetAdditionalProperties(); - int GetGateType() const; - double GetFidelity() const; - size_t GetGateSize() const; - std::string GetUnitary() const; - std::string GetName() const; - - private: - int type; - std::string name; - size_t gate_size; // "No. of qubits involved" - int gate_length; // "Time needed to execute that gate operation" - std::string unitary; - double fidelity; - - std::vector> coupling_mapping; - std::vector qubits; /**< TODO */ - std::map additional_properties; - }; - void addGate(QuantumGate *gate); std::vector GetGatesByTypes(int gate_type) const; @@ -914,7 +929,7 @@ class QuantumBackend : public Component { private: int num_qubits; int num_gates; - // To-DO: Use only one gates memeber + std::vector gate_types; }; @@ -938,55 +953,41 @@ class AtomSite : public QuantumBackend{ }; -class Qubit : public Component { -public: - /** - Qubit constructor (no automatic insertion in the Component Tree). Sets: - @param _id = id, default 0 - @param _name = name, default "Qubit" - @param componentType=>SYS_SAGE_COMPONENT_QUBIT - */ - Qubit(int _id = 0, string _name = "Qubit"); - /** - Qubit constructor with insertion into the Component Tree as the parent 's child (as long as parent is an existing Component). Sets: - @param parent = the parent - @param _id = id, default 0 - @param _name = name, default "Qubit0" - @param componentType=>SYS_SAGE_COMPONENT_QUBIT - */ - Qubit(Component * parent, int _id = 0, string _name = "Qubit"); - - void SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping); - - void SetProperties(double t1, double t2, double readout_error, double readout_length); - - const std::vector &GetCouplingMapping() const; - - const double GetT1() const; - - const double GetT2() const; - - const double GetReadoutError() const; +class QuantumGate { - const double GetReadoutLength() const; + public: + /** + QuantumGate constructor. + @param _qubits - An array of all qubits that the gate acts on. + @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. + \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 + */ + // QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); - const double GetFrequency() const; + QuantumGate(); + QuantumGate(size_t _gate_size); - void RefreshProperties(); + void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); + void SetGateCouplingMap(std::vector > _coupling_mapping); + void SetAdditionalProperties(); + int GetGateType() const; + double GetFidelity() const; + size_t GetGateSize() const; + std::string GetUnitary() const; + std::string GetName() const; - ~Qubit() override = default; + private: + int type; + std::string name; + size_t gate_size; // "No. of qubits involved" + int gate_length; // "Time needed to execute that gate operation" + std::string unitary; + double fidelity; -private: - std::vector _coupling_mapping; - int _size_coupling_mapping; - double fidelity; - double _t1; - double _t2; - double _readout_error; - double _readout_length; - double _fequency; - std::string _calibration_time; -}; + std::vector> coupling_mapping; + std::vector qubits; /**< TODO */ + std::map additional_properties; + }; #endif diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index 6d758da..42b1cbf 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -107,6 +107,25 @@ extern "C" int QdmiParser::get_num_qubits(QDMI_Device dev) } +extern "C" void QdmiParser::getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubit, std::vector &coupling_mapping, int &coupling_map_size) +{ + + if (qubit->size_coupling_mapping == 0) + { + std::cout << " [sys-sage]...............No coupling mapping for qubit\n"; + return; + } + + coupling_map_size = qubit->size_coupling_mapping; + coupling_mapping.resize(coupling_map_size); + + //for (int j = 0; j < coupling_map_size; j++) + //{ + // Copy the coupling_mapping from qubit_impl + std::copy(qubit->coupling_mapping, qubit->coupling_mapping + coupling_map_size, coupling_mapping.begin()); + //} +} + extern "C" void QdmiParser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit) { int scope; @@ -310,7 +329,7 @@ void QuantumBackend::RefreshTopology() void Qubit::RefreshProperties() { - QuantumBackend *qc = dynamic_cast (this->GetParent()); - QdmiParser::refreshQubitProprties(qc, this); + // QuantumBackend *qc = dynamic_cast (this->GetParent()); + // QdmiParser::refreshQubitProprties(qc, this); } \ No newline at end of file From 7a988b707bdad867bea24f7b507e873a0d2cd72b Mon Sep 17 00:00:00 2001 From: Durganshu Date: Sat, 20 Jul 2024 14:31:49 +0200 Subject: [PATCH 24/34] Modifications in gate types --- examples/qdmi-test.cpp | 9 +++---- src/DataPath.hpp | 5 ---- src/Topology.cpp | 60 +++++++++++++++++++++++++++++++++--------- src/Topology.hpp | 21 ++++++++++++--- 4 files changed, 68 insertions(+), 27 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index 13f3be8..cce01dd 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -41,10 +41,10 @@ int main() std::cout << "}\n"; } cout << "---------------- Printing Supported Gate Types for IBM Backend----------------" << endl; - auto _1q_gates = qc->GetGatesByTypes(SYS_SAGE_1Q_QUANTUM_GATE); - auto _2q_gates = qc->GetGatesByTypes(SYS_SAGE_2Q_QUANTUM_GATE); - auto _mq_gates = qc->GetGatesByTypes(SYS_SAGE_MQ_QUANTUM_GATE); - auto _0q_gates = qc->GetGatesByTypes(SYS_SAGE_NO_TYPE_QUANTUM_GATE); + auto _1q_gates = qc->GetGatesBySize(SYS_SAGE_1Q_QUANTUM_GATE); + auto _2q_gates = qc->GetGatesBySize(SYS_SAGE_2Q_QUANTUM_GATE); + auto _mq_gates = qc->GetGatesBySize(SYS_SAGE_MQ_QUANTUM_GATE); + auto _0q_gates = qc->GetGatesBySize(SYS_SAGE_NO_TYPE_QUANTUM_GATE); if(_1q_gates.size()) { @@ -94,7 +94,6 @@ int main() } } - std::cout << "---------------- Printing Qubit Properties for IBM Backend----------------" << endl; for (int i = 0; i < total_qubits; i++) diff --git a/src/DataPath.hpp b/src/DataPath.hpp index 8369424..3464bc1 100644 --- a/src/DataPath.hpp +++ b/src/DataPath.hpp @@ -24,11 +24,6 @@ #define SYS_SAGE_DATAPATH_TYPE_DATATRANSFER 1024 /**< DataPath type describing data transfer attributes. */ #define SYS_SAGE_DATAPATH_TYPE_C2C 2048 /**< DataPath type describing cache-to-cache latencies (cccbench data source). */ -// QuantumGate type -#define SYS_SAGE_QUANTUMGATE_TYPE_ID 32 /**< Identity Gate */ -#define SYS_SAGE_QUANTUMGATE_TYPE_RZ 64 /**< RZ Gate */ -#define SYS_SAGE_QUANTUMGATE_TYPE_CNOT 128 /**< CNOT Gate */ - using namespace std; class Component; class DataPath; diff --git a/src/Topology.cpp b/src/Topology.cpp index 845e45d..ff099f0 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -587,7 +587,21 @@ void QuantumBackend::addGate(QuantumGate *_gate) gate_types.push_back(_gate); } -std::vector QuantumBackend::GetGatesByTypes(int _gate_type) const +std::vector QuantumBackend::GetGatesBySize(size_t _gate_size) const +{ + std::vector gates; + gates.reserve(gate_types.size()); + + for (QuantumGate * gate : gate_types) + { + if(_gate_size == gate->GetGateSize()) + gates.emplace_back(gate); + } + + return gates; +} + +std::vector QuantumBackend::GetGatesByType(size_t _gate_type) const { std::vector gates; gates.reserve(gate_types.size()); @@ -643,24 +657,44 @@ QuantumGate::QuantumGate() type = SYS_SAGE_1Q_QUANTUM_GATE; } -QuantumGate::QuantumGate(size_t _gate_size) : gate_size(_gate_size) -{ - if (gate_size == 1) - type = SYS_SAGE_1Q_QUANTUM_GATE; - else if (gate_size == 2) - type = SYS_SAGE_2Q_QUANTUM_GATE; - else if(gate_size > 2) - type = SYS_SAGE_MQ_QUANTUM_GATE; - else - type = SYS_SAGE_NO_TYPE_QUANTUM_GATE; - -} +QuantumGate::QuantumGate(size_t _gate_size) : gate_size(_gate_size){} void QuantumGate::SetGateProperties(std::string _name, double _fidelity, std::string _unitary) { name = _name; fidelity = _fidelity; unitary = _unitary; + SetGateType(); +} + +void QuantumGate::SetGateType() +{ + if(gate_size == 1) + { + if(name == "id") type = SYS_SAGE_QUANTUMGATE_TYPE_ID; + else if(name == "rz") type = SYS_SAGE_QUANTUMGATE_TYPE_RZ; + else if(name == "sx") type = SYS_SAGE_QUANTUMGATE_TYPE_SX; + else if(name == "x") type = SYS_SAGE_QUANTUMGATE_TYPE_X; + else type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; + } + + else if(gate_size == 2) + { + if(name == "cx") type = SYS_SAGE_QUANTUMGATE_TYPE_CNOT; + else type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; + } + + else if(gate_size > 2) + { + if(name == "toffoli") type = SYS_SAGE_QUANTUMGATE_TYPE_TOFFOLI; + else type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; + } + + else + { + type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; + } + } int QuantumGate::GetGateType() const diff --git a/src/Topology.hpp b/src/Topology.hpp index b720828..dc4877e 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -41,7 +41,17 @@ #define SYS_SAGE_1Q_QUANTUM_GATE 1 /**< Quantum Gate of size 1-Qubit. */ #define SYS_SAGE_2Q_QUANTUM_GATE 2 /**< Quantum Gate of size 2-Qubits. */ #define SYS_SAGE_MQ_QUANTUM_GATE 4 /**< Quantum Gate of size M-Qubits (where M >2). */ -#define SYS_SAGE_NO_TYPE_QUANTUM_GATE 8 /**< Quantum Gate of size 0 or invalid size. */ +#define SYS_SAGE_NO_TYPE_QUANTUM_GATE 0 /**< Quantum Gate of size 0 or invalid size. */ + + +// QuantumGate type +#define SYS_SAGE_QUANTUMGATE_TYPE_ID 32 /**< Identity Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_RZ 64 /**< RZ Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_CNOT 128 /**< CNOT Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_SX 256 /**< SX Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_X 512 /**< X Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_TOFFOLI 1024 /**< Toffoli Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN 2048 /**< Unknown Gate */ using namespace std; class DataPath; @@ -916,7 +926,9 @@ class QuantumBackend : public Component { void addGate(QuantumGate *gate); - std::vector GetGatesByTypes(int gate_type) const; + std::vector GetGatesBySize(size_t _gate_size) const; + + std::vector GetGatesByType(size_t _gate_type) const; std::vector GetAllGateTypes() const; @@ -958,7 +970,7 @@ class QuantumGate { public: /** QuantumGate constructor. - @param _qubits - An array of all qubits that the gate acts on. + @param _gate_size - No. of qubits involved in a qubit. @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 */ @@ -970,6 +982,7 @@ class QuantumGate { void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); void SetGateCouplingMap(std::vector > _coupling_mapping); void SetAdditionalProperties(); + void SetGateType(); int GetGateType() const; double GetFidelity() const; size_t GetGateSize() const; @@ -977,7 +990,7 @@ class QuantumGate { std::string GetName() const; private: - int type; + int type; // Denotes type of the QuantumGate -- helps to distinguish between different gates (ID, RZ, etc.) std::string name; size_t gate_size; // "No. of qubits involved" int gate_length; // "Time needed to execute that gate operation" From 52a183d85996bfb0efc00fc1838db5f1af20b009 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Mon, 22 Jul 2024 19:16:12 +0200 Subject: [PATCH 25/34] Update refreshQubitPropoerties --- src/Topology.cpp | 7 +++++ src/Topology.hpp | 10 +++++-- src/parsers/qdmi-parser.cpp | 15 +++++----- src/parsers/qdmi-parser.hpp | 60 +++++++++++++++++++++++++++++++++---- 4 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/Topology.cpp b/src/Topology.cpp index ff099f0..5281d12 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -622,6 +622,13 @@ std::vector QuantumBackend::GetAllGateTypes() const int QuantumBackend::GetNumberofGates() const { return gate_types.size(); } +void QuantumBackend::SetQDMIDevice(QDMI_Device dev) +{ + device = dev; +} + +QDMI_Device QuantumBackend::GetQDMIDevice(){ return device; } + Qubit::Qubit(int _id, string _name):Component(_id, _name, SYS_SAGE_COMPONENT_QUBIT){} Qubit::Qubit(Component * parent, int _id, string _name):Component(parent, _id, _name, SYS_SAGE_COMPONENT_QUBIT){} diff --git a/src/Topology.hpp b/src/Topology.hpp index dc4877e..f24ace6 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -9,6 +9,8 @@ #include "defines.hpp" #include "DataPath.hpp" #include +#include +#include #define SYS_SAGE_COMPONENT_NONE 1 /**< class Component (do not use normally)*/ @@ -922,6 +924,10 @@ class QuantumBackend : public Component { void SetNumberofQubits(int _num_qubits); + void SetQDMIDevice(QDMI_Device dev); + + QDMI_Device GetQDMIDevice(); + int GetNumberofQubits () const; void addGate(QuantumGate *gate); @@ -934,14 +940,14 @@ class QuantumBackend : public Component { int GetNumberofGates() const; - void RefreshTopology(); + void RefreshTopology(std::set qubit_indices); // qubit_indices: indices of the qubits that need to be refreshed ~QuantumBackend() override = default; private: int num_qubits; int num_gates; - + QDMI_Device device; // For refreshing the topology std::vector gate_types; }; diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index 42b1cbf..e814f4f 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -308,6 +308,7 @@ extern "C" QuantumBackend QdmiParser::createQcTopo(QDMI_Device dev, int device_i return qc; } + // extern "C" static void refreshQubitProprties(QuantumBackend *qc, Qubit *qubit) // { // //auto quantum_backends = get_available_backends(); @@ -317,19 +318,19 @@ extern "C" QuantumBackend QdmiParser::createQcTopo(QDMI_Device dev, int device_i // //QDMI_query_qubit_property(QDMI_Device dev, QDMI_Qubit_property prop, QDMI_Qubit qubit, int* coupling_map); // } -void QuantumBackend::RefreshTopology() +void QuantumBackend::RefreshTopology(std::set qubit_indices) { - for (auto child : *(this->GetChildren())) { - if (auto qubit = dynamic_cast(child)) { - qubit->RefreshProperties(); - } + for (auto q : qubit_indices) { + auto qubit = dynamic_cast(GetChild(q)); + qubit->RefreshProperties(); } } void Qubit::RefreshProperties() { - // QuantumBackend *qc = dynamic_cast (this->GetParent()); - // QdmiParser::refreshQubitProprties(qc, this); + + QuantumBackend *qc = dynamic_cast (this->GetParent()); + QdmiParser::refreshQubitProperties(qc->GetQDMIDevice(), this); } \ No newline at end of file diff --git a/src/parsers/qdmi-parser.hpp b/src/parsers/qdmi-parser.hpp index 056c0ea..e2c2c3a 100644 --- a/src/parsers/qdmi-parser.hpp +++ b/src/parsers/qdmi-parser.hpp @@ -62,13 +62,63 @@ extern "C" */ QuantumBackend createQcTopo(QDMI_Device dev, int device_index = 0, std::string device_name=""); - static void refreshQcProperties(QuantumBackend *qc, bool single_qubit = false, int qubit_index=0) + static void refreshQubitProperties(QDMI_Device dev, Qubit *q) { - // //auto quantum_backends = get_available_backends(); + //Refresh Qubit properties + QDMI_Qubit qubits; + int err; - // // Search for required QuantumBackend in the device and call these: - // //QDMI_Device dev = qc-> - // //QDMI_query_qubit_property(QDMI_Device dev, QDMI_Qubit_property prop, QDMI_Qubit qubit, int* coupling_map); + err = QDMI_query_all_qubits(dev, &qubits); + + if (err != QDMI_SUCCESS || qubits == NULL) + { + std::cout << " [sys-sage]...............Could not obtain available " + << "qubits via QDMI\n"; + return; + } + int qubit_index = q->GetId(); + + // Refreshing Qubit coupling map + int coupling_map_size; + std::vector coupling_mapping; + coupling_map_size = (&qubits[qubit_index])->size_coupling_mapping; + coupling_mapping.resize(coupling_map_size); + std::copy(qubits[qubit_index].coupling_mapping, qubits[qubit_index].coupling_mapping + coupling_map_size, coupling_mapping.begin()); + q->SetCouplingMapping(coupling_mapping, coupling_map_size); + + + // Set all the qubit properties + int scope; + // Declare prop as a vector + std::vector prop{QDMI_T1_TIME, QDMI_T2_TIME, QDMI_READOUT_ERROR, QDMI_READOUT_LENGTH}; + std::array properties{"T1", "T2", "readout_error", "readout_length"}; + double value; + for (size_t i = 0; i < 4; ++i) + { + // QDMI_Qubit_property prop_index; + QDMI_Qubit_property prop_index = new (QDMI_Qubit_property_impl_t); + prop_index->name = prop[i]; + int err = QDMI_query_qubit_property_exists(dev, &qubits[qubit_index], prop_index, &scope); + if(err) + { + std::cout << " [sys-sage]...............Queried property doesn't exist: " << i <<"\n"; + continue; + } + err = QDMI_query_qubit_property_type(dev, &qubits[qubit_index], prop_index); + if(prop_index->type == QDMI_DOUBLE){ + err = QDMI_query_qubit_property_d(dev, &qubits[qubit_index], prop_index, &value); + if(err) + { + std::cout << " [sys-sage]...............Unable to query property: " << i <<"\n"; + continue; + } + //std::cout << " [sys-sage]...............Value of " << properties[i] << ": " << value << "\n"; + } + delete prop_index; + + } + + q->SetProperties(qubits[qubit_index].t1, qubits[qubit_index].t2, qubits[qubit_index].readout_error, qubits[qubit_index].readout_length); } private: int initiateSession(); From 8457229911263f57afb76d93ecba545b6823fdcf Mon Sep 17 00:00:00 2001 From: Durganshu Date: Wed, 24 Jul 2024 23:59:44 +0200 Subject: [PATCH 26/34] Integrating with backends repo --- cmake/Findbackends.cmake | 13 +++++++ cmake/Findqdmi.cmake | 9 ----- src/CMakeLists.txt | 69 ++++++++++++++++++++----------------- src/DataPath.hpp | 1 + src/Topology.hpp | 4 +-- src/parsers/qdmi-parser.hpp | 4 +-- 6 files changed, 55 insertions(+), 45 deletions(-) create mode 100644 cmake/Findbackends.cmake delete mode 100644 cmake/Findqdmi.cmake diff --git a/cmake/Findbackends.cmake b/cmake/Findbackends.cmake new file mode 100644 index 0000000..abf9a11 --- /dev/null +++ b/cmake/Findbackends.cmake @@ -0,0 +1,13 @@ +include(FetchContent) + +FetchContent_Declare( + backends + GIT_REPOSITORY git@github.com:Munich-Quantum-Software-Stack/backends.git + GIT_TAG develop +) + +FetchContent_MakeAvailable(backends) +# FetchContent_GetProperties(qdmi) + +# set(QDMI_INCLUDE_DIRS "${qdmi_SOURCE_DIR}/include") +# set(QDMI_SRC_DIRS "${qdmi_SOURCE_DIR}/src") \ No newline at end of file diff --git a/cmake/Findqdmi.cmake b/cmake/Findqdmi.cmake deleted file mode 100644 index 9d80262..0000000 --- a/cmake/Findqdmi.cmake +++ /dev/null @@ -1,9 +0,0 @@ -include(FetchContent) - -FetchContent_Declare( - qdmi - GIT_REPOSITORY git@github.com:Munich-Quantum-Software-Stack/QDMI.git - GIT_TAG ibm-backend-testing -) - -FetchContent_MakeAvailable(qdmi) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eb35b15..b38cceb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,7 +34,7 @@ add_library(sys-sage SHARED ${SOURCES} ${HEADERS}) # For Quantum Systems # Find QDMI package -find_package(qdmi REQUIRED) +find_package(backends REQUIRED) # Find QInfo package find_package(qinfo REQUIRED) @@ -43,47 +43,52 @@ find_package(qinfo REQUIRED) find_package(nlohmann_json REQUIRED) target_link_libraries(sys-sage PRIVATE + backend_ibm qdmi qinfo nlohmann_json::nlohmann_json ) - + +# message("QDMI_INCLUDE_DIRS: ${QDMI_INCLUDE_DIRS}") +# message(${QDMI_SRC_DIRS}) + + target_include_directories(sys-sage - PRIVATE ${CMAKE_BINARY_DIR}/_deps/qdmi-src/src/include/ + PUBLIC ${CMAKE_BINARY_DIR}/_deps/qdmi-src/include/ + PUBLIC ${CMAKE_BINARY_DIR}/_deps/qdmi-src/src/ + PUBLIC ${CMAKE_BINARY_DIR}/_deps/backends-src/include/ + PUBLIC ${CMAKE_BINARY_DIR}/_deps/qinfo-src/include/ PUBLIC $ $ $ ) +# install( +# TARGETS sys-sage +# EXPORT sys-sage-targets +# RUNTIME DESTINATION bin +# LIBRARY DESTINATION lib/cmake/lib +# ARCHIVE DESTINATION lib/cmake/lib +# ) +# #for spack +# install( +# EXPORT sys-sage-targets +# FILE sys-sage-targets.cmake +# DESTINATION lib/cmake/sys-sage +# NAMESPACE sys-sage:: +# ) +# install(DIRECTORY "." +# DESTINATION lib/cmake/inc +# FILES_MATCHING PATTERN "*.hpp") - - -install( - TARGETS sys-sage - EXPORT sys-sage-targets - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib/cmake/lib - ARCHIVE DESTINATION lib/cmake/lib -) -#for spack -install( - EXPORT sys-sage-targets - FILE sys-sage-targets.cmake - DESTINATION lib/cmake/sys-sage - NAMESPACE sys-sage:: -) -install(DIRECTORY "." - DESTINATION lib/cmake/inc - FILES_MATCHING PATTERN "*.hpp") - -install( - TARGETS sys-sage - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib -) -install(DIRECTORY "." - DESTINATION inc - FILES_MATCHING PATTERN "*.hpp") +# install( +# TARGETS sys-sage +# RUNTIME DESTINATION bin +# LIBRARY DESTINATION lib +# ARCHIVE DESTINATION lib +# ) +# install(DIRECTORY "." +# DESTINATION inc +# FILES_MATCHING PATTERN "*.hpp") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) \ No newline at end of file diff --git a/src/DataPath.hpp b/src/DataPath.hpp index 3464bc1..41ab52b 100644 --- a/src/DataPath.hpp +++ b/src/DataPath.hpp @@ -1,6 +1,7 @@ #ifndef DATAPATH #define DATAPATH +#pragma once #include #include "defines.hpp" diff --git a/src/Topology.hpp b/src/Topology.hpp index f24ace6..9ee5b09 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -9,8 +9,8 @@ #include "defines.hpp" #include "DataPath.hpp" #include -#include -#include +#include +// #include #define SYS_SAGE_COMPONENT_NONE 1 /**< class Component (do not use normally)*/ diff --git a/src/parsers/qdmi-parser.hpp b/src/parsers/qdmi-parser.hpp index e2c2c3a..95e23c1 100644 --- a/src/parsers/qdmi-parser.hpp +++ b/src/parsers/qdmi-parser.hpp @@ -11,8 +11,8 @@ #include #include #include "Topology.hpp" -#include -#include +#include +// #include #define CHECK_ERR(a,b) { if (a!=QDMI_SUCCESS) { printf("\n[Error]: %i at %s",a,b); return 1; }} From c811de0b43fb24a3be3a34a30adaeeb2fd470585 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Fri, 26 Jul 2024 19:34:59 +0200 Subject: [PATCH 27/34] Working code with backends repo --- examples/qdmi-test.cpp | 8 +-- src/parsers/qdmi-parser.cpp | 105 +++++++++++++++++++++++------------- src/parsers/qdmi-parser.hpp | 2 +- 3 files changed, 73 insertions(+), 42 deletions(-) diff --git a/examples/qdmi-test.cpp b/examples/qdmi-test.cpp index cce01dd..5300270 100644 --- a/examples/qdmi-test.cpp +++ b/examples/qdmi-test.cpp @@ -1,9 +1,9 @@ /* Possible exports export CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qinfo-src/include/ export CPATH=$CPATH:/home/diogenes/sys-sage/build/_deps/qdmi-src/include -export CONF_IBM=/home/diogenes/qdmi.git/inputs/conf.json +export CONF_IBM=/home/diogenes/sys-sage/build/_deps/backends-src/tests/ibm_conf.json export QDMI_CONFIG_FILE=/home/diogenes/sys-sage/build/_deps/qdmi-src/.qdmi-config -export PROP_IBM=/home/diogenes/qdmi.git/inputs/props.json +export PROP_IBM=/home/diogenes/sys-sage/build/_deps/backends-src/tests/ibm_prob.json */ #include @@ -109,8 +109,8 @@ int main() /*******************************************Method 2**********************************************/ // auto quantum_backends = qdmi.get_available_backends(); // std::cout << "Total " << quantum_backends.size() << " devices found.\n"; - // QuantumBackend* qc_topo = new QuantumBackend(0, quantum_backends[0].first); - // qdmi.createQcTopo(qc_topo, quantum_backends[0].second); + // QuantumBackend* qc_topo = new QuantumBackend(0, ""); + // qdmi.createQcTopo(qc_topo, quantum_backends[0]); // cout << "---------------- Printing the configuration of QLM Backend ----------------" << endl; // qc_topo->PrintSubtree(); diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index e814f4f..c088ccc 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -39,54 +39,85 @@ extern "C" int QdmiParser::initiateSession() // TODO: Change function name (like FOMAC_available_devices) // This will get the list of all the available devices and check individually if that devide is up and running. -extern "C" std::vector> QdmiParser::get_available_backends() +extern "C" std::vector QdmiParser::get_available_backends() { // 46-74: Replace this with newer QDMI calls - char **available_devices = get_qdmi_library_list_names(); // --> - if (available_devices == NULL) - { - std::cout << " [sys-sage]...............Failed to get " - << "qdmi_library_list from QDMI" << std::endl; + // char **available_devices = get_qdmi_library_list_names(); // --> + // if (available_devices == NULL) + // { + // std::cout << " [sys-sage]...............Failed to get " + // << "qdmi_library_list from QDMI" << std::endl; - return std::vector>(); - } + // return std::vector>(); + // } - int i = 0, err = 0, status = 0; - std::vector> registered_devices; - while (available_devices[i] != NULL) - { - QDMI_Device device = - (QDMI_Device)malloc(sizeof(struct QDMI_Device_impl_d)); + // int i = 0, err = 0, status = 0; + // std::vector> registered_devices; + // while (available_devices[i] != NULL) + // { + // QDMI_Device device = + // (QDMI_Device)malloc(sizeof(struct QDMI_Device_impl_d)); - QDMI_Library lib = find_library_by_name(available_devices[i]); // --> + // QDMI_Library lib = find_library_by_name(available_devices[i]); // --> - if (!lib) - { - std::cout << " [sys-sage]...............A backend's library " - << "could not be found" << std::endl; + // if (!lib) + // { + // std::cout << " [sys-sage]...............A backend's library " + // << "could not be found" << std::endl; - free(available_devices[i++]); - continue; - } + // free(available_devices[i++]); + // continue; + // } - device->library = *lib; + // device->library = *lib; - // TODO HANDLE err - err = QDMI_device_status(device, device->library.info, &status); + // // TODO HANDLE err + // err = QDMI_device_status(device, device->library.info, &status); - if (status) - { - const char *device_name = strrchr(available_devices[i], '/'); - std::cout << " [sys-sage]...............Available device " - << "found: " << device_name << std::endl; + // if (status) + // { + // const char *device_name = strrchr(available_devices[i], '/'); + // std::cout << " [sys-sage]...............Available device " + // << "found: " << device_name << std::endl; - registered_devices.push_back(std::pair (device_name, device)); - } + // registered_devices.push_back(std::pair (device_name, device)); + // } + + // free(available_devices[i++]); + // } + // free(available_devices); + int count; + QDMI_core_device_count(&QdmiParser::session, &count); + + if(count == 0){ + std::cout << " [sys-sage]...............QDMI_core_device_count from QDMI returned 0." << std::endl; + return {}; + } + + else { + std::cout << " [sys-sage]...............QDMI_core_device_count returned " << count << ".\n"; + } + + std::vector registered_devices; + char **available_devices = get_qdmi_library_list_names(); // --> + if (available_devices == NULL) + { + std::cout << " [sys-sage]...............Failed to get " + << "qdmi_library_list from QDMI" << std::endl; + + return {}; + } + + for(int i = 0; i < count; i++){ + QDMI_Device device; + QDMI_core_open_device(&QdmiParser::session, i , &QdmiParser::info, &device); - free(available_devices[i++]); + // const char *device_name = strrchr(available_devices[i], '/'); + // std::cout << " [sys-sage]...............Available device " + // << "found: " << device_name << std::endl; + registered_devices.emplace_back(device); } - free(available_devices); return registered_devices; } @@ -144,7 +175,7 @@ extern "C" void QdmiParser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit std::cout << " [sys-sage]...............Queried property doesn't exist: " << i <<"\n"; continue; } - err = QDMI_query_qubit_property_type(dev, qubit, prop_index); + // err = QDMI_query_qubit_property_type(dev, qubit, prop_index); if(prop_index->type == QDMI_DOUBLE){ err = QDMI_query_qubit_property_d(dev, qubit, prop_index, &value); if(err) @@ -278,8 +309,8 @@ extern "C" void QdmiParser::createAllQcTopo(Topology *topo) for (auto i = 0; i < total_quantum_backends; ++i) { - QuantumBackend* qc = new QuantumBackend(topo, i, quantum_backends[i].first); - createQcTopo(qc, quantum_backends[i].second); + QuantumBackend* qc = new QuantumBackend(topo, i); + createQcTopo(qc, quantum_backends[i]); } } diff --git a/src/parsers/qdmi-parser.hpp b/src/parsers/qdmi-parser.hpp index 95e23c1..5a74d72 100644 --- a/src/parsers/qdmi-parser.hpp +++ b/src/parsers/qdmi-parser.hpp @@ -28,7 +28,7 @@ extern "C" * Returns all the available backends registered with QDMI. * @return A vector of all the backends with their names and "QDMI_Device" handles */ - std::vector> get_available_backends(); + std::vector get_available_backends(); int get_num_qubits(QDMI_Device dev); /** From 0bf714b969a44ff845c064fedf728fe4b751152a Mon Sep 17 00:00:00 2001 From: Durganshu Date: Fri, 26 Jul 2024 19:59:10 +0200 Subject: [PATCH 28/34] Minor changes --- src/DataPath.hpp | 1 - src/parsers/qdmi-parser.hpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/DataPath.hpp b/src/DataPath.hpp index 41ab52b..3464bc1 100644 --- a/src/DataPath.hpp +++ b/src/DataPath.hpp @@ -1,7 +1,6 @@ #ifndef DATAPATH #define DATAPATH -#pragma once #include #include "defines.hpp" diff --git a/src/parsers/qdmi-parser.hpp b/src/parsers/qdmi-parser.hpp index 5a74d72..b85e273 100644 --- a/src/parsers/qdmi-parser.hpp +++ b/src/parsers/qdmi-parser.hpp @@ -12,7 +12,6 @@ #include #include "Topology.hpp" #include -// #include #define CHECK_ERR(a,b) { if (a!=QDMI_SUCCESS) { printf("\n[Error]: %i at %s",a,b); return 1; }} From 30d5cc4d50821ff6bfd8636f072932ad1fa96aed Mon Sep 17 00:00:00 2001 From: Durganshu Date: Fri, 26 Jul 2024 20:50:56 +0200 Subject: [PATCH 29/34] Updated Cmake install instructions --- cmake/Findbackends.cmake | 2 +- src/CMakeLists.txt | 61 ++++++++++++++++++---------------------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/cmake/Findbackends.cmake b/cmake/Findbackends.cmake index abf9a11..6dc77f2 100644 --- a/cmake/Findbackends.cmake +++ b/cmake/Findbackends.cmake @@ -3,7 +3,7 @@ include(FetchContent) FetchContent_Declare( backends GIT_REPOSITORY git@github.com:Munich-Quantum-Software-Stack/backends.git - GIT_TAG develop + GIT_TAG cmake-install ) FetchContent_MakeAvailable(backends) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b38cceb..41f95f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,53 +42,46 @@ find_package(qinfo REQUIRED) # Find nlohmann_json package find_package(nlohmann_json REQUIRED) -target_link_libraries(sys-sage PRIVATE +target_link_libraries(sys-sage PUBLIC backend_ibm qdmi qinfo nlohmann_json::nlohmann_json ) -# message("QDMI_INCLUDE_DIRS: ${QDMI_INCLUDE_DIRS}") -# message(${QDMI_SRC_DIRS}) - target_include_directories(sys-sage - PUBLIC ${CMAKE_BINARY_DIR}/_deps/qdmi-src/include/ - PUBLIC ${CMAKE_BINARY_DIR}/_deps/qdmi-src/src/ - PUBLIC ${CMAKE_BINARY_DIR}/_deps/backends-src/include/ - PUBLIC ${CMAKE_BINARY_DIR}/_deps/qinfo-src/include/ PUBLIC $ $ $ ) -# install( -# TARGETS sys-sage -# EXPORT sys-sage-targets -# RUNTIME DESTINATION bin -# LIBRARY DESTINATION lib/cmake/lib -# ARCHIVE DESTINATION lib/cmake/lib -# ) -# #for spack -# install( -# EXPORT sys-sage-targets -# FILE sys-sage-targets.cmake -# DESTINATION lib/cmake/sys-sage -# NAMESPACE sys-sage:: -# ) -# install(DIRECTORY "." -# DESTINATION lib/cmake/inc -# FILES_MATCHING PATTERN "*.hpp") +install( + TARGETS sys-sage + EXPORT sys-sage-targets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib/cmake/lib + ARCHIVE DESTINATION lib/cmake/lib +) +#for spack +install( + EXPORT sys-sage-targets + FILE sys-sage-targets.cmake + DESTINATION lib/cmake/sys-sage + NAMESPACE sys-sage:: +) +install(DIRECTORY "." + DESTINATION lib/cmake/inc + FILES_MATCHING PATTERN "*.hpp") -# install( -# TARGETS sys-sage -# RUNTIME DESTINATION bin -# LIBRARY DESTINATION lib -# ARCHIVE DESTINATION lib -# ) -# install(DIRECTORY "." -# DESTINATION inc -# FILES_MATCHING PATTERN "*.hpp") +install( + TARGETS sys-sage + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) +install(DIRECTORY "." + DESTINATION inc + FILES_MATCHING PATTERN "*.hpp") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) \ No newline at end of file From fd8638cf6b74127ea325a6443b29fb2909c4ada5 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Sat, 27 Jul 2024 01:01:27 +0200 Subject: [PATCH 30/34] Reset CMAKE_MODULE_PATH --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 41f95f7..b72b497 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,5 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake" ${CMAKE_MODULE_PATH}) #defines.hpp header with #cmakedefine configure_file(${PROJECT_SOURCE_DIR}/src/defines.hpp.in ${PROJECT_SOURCE_DIR}/src/defines.hpp) From 14cb9c671cf1697e03384a80e11d9f188ead3f57 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Wed, 31 Jul 2024 15:45:04 +0200 Subject: [PATCH 31/34] Added abstract parent class called Relation --- src/DataPath.cpp | 94 ++++++++++++++++++++++++++++++++++++ src/DataPath.hpp | 96 ++++++++++++++++++++++++++++++------- src/Topology.cpp | 71 --------------------------- src/Topology.hpp | 88 ++++++++++++++-------------------- src/parsers/qdmi-parser.cpp | 2 +- 5 files changed, 212 insertions(+), 139 deletions(-) diff --git a/src/DataPath.cpp b/src/DataPath.cpp index 841a56e..449ba99 100644 --- a/src/DataPath.cpp +++ b/src/DataPath.cpp @@ -83,3 +83,97 @@ void DataPath::Print() } cout << endl; } + +void DataPath::DeleteRelation() +{ + DeleteDataPath(); +} + +QuantumGate::QuantumGate() +{ + gate_size = 1; + type = SYS_SAGE_1Q_QUANTUM_GATE; +} + +QuantumGate::QuantumGate(size_t _gate_size) : gate_size(_gate_size){} + +QuantumGate::QuantumGate(size_t _gate_size, std::string _name, double _fidelity, std::string _unitary) +: gate_size(_gate_size), name(_name), fidelity(_fidelity), unitary(_unitary){} + +QuantumGate::QuantumGate(size_t _gate_size, const std::vector & _qubits) +: gate_size(_gate_size), qubits(_qubits) {} + +QuantumGate::QuantumGate(size_t _gate_size, const std::vector & _qubits, std::string _name, double _fidelity, std::string _unitary) +: gate_size(_gate_size), qubits(_qubits), name(_name), fidelity(_fidelity), unitary(_unitary) {} + +void QuantumGate::SetGateProperties(std::string _name, double _fidelity, std::string _unitary) +{ + name = _name; + fidelity = _fidelity; + unitary = _unitary; + SetGateType(); +} + + +void QuantumGate::SetGateType() +{ + if(gate_size == 1) + { + if(name == "id") type = SYS_SAGE_QUANTUMGATE_TYPE_ID; + else if(name == "rz") type = SYS_SAGE_QUANTUMGATE_TYPE_RZ; + else if(name == "sx") type = SYS_SAGE_QUANTUMGATE_TYPE_SX; + else if(name == "x") type = SYS_SAGE_QUANTUMGATE_TYPE_X; + else type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; + } + + else if(gate_size == 2) + { + if(name == "cx") type = SYS_SAGE_QUANTUMGATE_TYPE_CNOT; + else type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; + } + + else if(gate_size > 2) + { + if(name == "toffoli") type = SYS_SAGE_QUANTUMGATE_TYPE_TOFFOLI; + else type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; + } + + else + { + type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; + } + +} + +int QuantumGate::GetGateType() const +{ + return type; +} + +double QuantumGate::GetFidelity() const +{ + return fidelity; +} + +size_t QuantumGate::GetGateSize() const +{ + return gate_size; +} + +std::string QuantumGate::GetUnitary() const +{ + return unitary; +} + +std::string QuantumGate::GetName() const +{ + return name; +} + +void QuantumGate::Print() +{ +} + +void QuantumGate::DeleteRelation() +{ +} diff --git a/src/DataPath.hpp b/src/DataPath.hpp index 3464bc1..79cc984 100644 --- a/src/DataPath.hpp +++ b/src/DataPath.hpp @@ -1,19 +1,20 @@ -#ifndef DATAPATH -#define DATAPATH +#ifndef RELATION_HPP +#define RELATION_HPP #include +#include +#include #include "defines.hpp" #include "Topology.hpp" -//Component pointing to a DataPath #define SYS_SAGE_DATAPATH_NONE 1 /**< TODO */ #define SYS_SAGE_DATAPATH_OUTGOING 2 /**< This Component is the source DataPath. */ -#define SYS_SAGE_DATAPATH_INCOMING 4 /**< This Component is the taerget DataPath. */ +#define SYS_SAGE_DATAPATH_INCOMING 4 /**< This Component is the target DataPath. */ //int oriented #define SYS_SAGE_DATAPATH_BIDIRECTIONAL 8 /**< DataPath has no direction. */ -#define SYS_SAGE_DATAPATH_ORIENTED 16 /**< DataPath is directec from the source to the target. */ +#define SYS_SAGE_DATAPATH_ORIENTED 16 /**< DataPath is directed from the source to the target. */ //dp_type #define SYS_SAGE_DATAPATH_TYPE_NONE 32 /**< Generic type of DataPath */ @@ -24,10 +25,37 @@ #define SYS_SAGE_DATAPATH_TYPE_DATATRANSFER 1024 /**< DataPath type describing data transfer attributes. */ #define SYS_SAGE_DATAPATH_TYPE_C2C 2048 /**< DataPath type describing cache-to-cache latencies (cccbench data source). */ -using namespace std; +#define SYS_SAGE_1Q_QUANTUM_GATE 1 /**< Quantum Gate of size 1-Qubit. */ +#define SYS_SAGE_2Q_QUANTUM_GATE 2 /**< Quantum Gate of size 2-Qubits. */ +#define SYS_SAGE_MQ_QUANTUM_GATE 4 /**< Quantum Gate of size M-Qubits (where M >2). */ +#define SYS_SAGE_NO_TYPE_QUANTUM_GATE 0 /**< Quantum Gate of size 0 or invalid size. */ + + +// QuantumGate type +#define SYS_SAGE_QUANTUMGATE_TYPE_ID 32 /**< Identity Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_RZ 64 /**< RZ Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_CNOT 128 /**< CNOT Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_SX 256 /**< SX Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_X 512 /**< X Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_TOFFOLI 1024 /**< Toffoli Gate */ +#define SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN 2048 /**< Unknown Gate */ class Component; -class DataPath; +class Qubit; + +/** + * Abstract class Relation representing a generic relationship or connectivity between two components. + */ +class Relation { +public: + + virtual ~Relation() = default; + + + virtual void Print() = 0; + virtual void DeleteRelation() = 0; +}; +class DataPath; /** Obsolete; use DataPath() constructors directly instead @see DataPath() @@ -49,7 +77,8 @@ Class DataPath represents Data Paths in the topology -- Data Paths represent an \n Data Paths create a Data-Path graph, which is a structure orthogonal to the Component Tree. \n Each Component contains a reference to all Data Paths going to or from this components (as well as parents and children in the Component Tree). Using these references, it is possible to navigate between the Components and to view the data stores in the Components or the Data Paths. */ -class DataPath { + +class DataPath : public Relation { public: /** @@ -120,20 +149,55 @@ class DataPath { */ void DeleteDataPath(); + void DeleteRelation() override; /** * TODO */ - map attrib; + std::map attrib; + private: - Component * source; /**< TODO */ - Component * target; /**< TODO */ + Component *source; + Component *target; + const int oriented; + const int dp_type; + double bw; + double latency; +}; - const int oriented; /**< TODO */ - const int dp_type; /**< TODO */ +class QuantumGate : public Relation { - double bw; /**< TODO */ - double latency; /**< TODO */ +public: + QuantumGate(); + QuantumGate(size_t _gate_size); + QuantumGate(size_t _gate_size, std::string _name, double _fidelity, std::string _unitary); + QuantumGate(size_t _gate_size, const std::vector & _qubits); + QuantumGate(size_t _gate_size, const std::vector & _qubits, std::string _name, double _fidelity, std::string _unitary); + + void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); + void SetGateCouplingMap(std::vector> _coupling_mapping); + void SetAdditionalProperties(); + void SetGateType(); + int GetGateType() const; + double GetFidelity() const; + size_t GetGateSize() const; + void SetGateId(int _id); + int GetGateId(); + std::string GetUnitary() const; + std::string GetName() const; + void Print() override; + void DeleteRelation() override; +private: + int id; + int type; + std::string name; + size_t gate_size; + int gate_length; + std::string unitary; + double fidelity; + std::vector> coupling_mapping; + std::vector qubits; + std::map additional_properties; }; -#endif +#endif // RELATION_HPP diff --git a/src/Topology.cpp b/src/Topology.cpp index 7ee640a..dfb4e0e 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -688,74 +688,3 @@ const double Qubit::GetT1() const { return _t1; } const double Qubit::GetT2() const { return _t2; } const double Qubit::GetReadoutError() const { return _readout_error; } const double Qubit::GetReadoutLength() const { return _readout_length; } - -QuantumGate::QuantumGate() -{ - gate_size = 1; - type = SYS_SAGE_1Q_QUANTUM_GATE; -} - -QuantumGate::QuantumGate(size_t _gate_size) : gate_size(_gate_size){} - -void QuantumGate::SetGateProperties(std::string _name, double _fidelity, std::string _unitary) -{ - name = _name; - fidelity = _fidelity; - unitary = _unitary; - SetGateType(); -} - -void QuantumGate::SetGateType() -{ - if(gate_size == 1) - { - if(name == "id") type = SYS_SAGE_QUANTUMGATE_TYPE_ID; - else if(name == "rz") type = SYS_SAGE_QUANTUMGATE_TYPE_RZ; - else if(name == "sx") type = SYS_SAGE_QUANTUMGATE_TYPE_SX; - else if(name == "x") type = SYS_SAGE_QUANTUMGATE_TYPE_X; - else type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; - } - - else if(gate_size == 2) - { - if(name == "cx") type = SYS_SAGE_QUANTUMGATE_TYPE_CNOT; - else type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; - } - - else if(gate_size > 2) - { - if(name == "toffoli") type = SYS_SAGE_QUANTUMGATE_TYPE_TOFFOLI; - else type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; - } - - else - { - type = SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN; - } - -} - -int QuantumGate::GetGateType() const -{ - return type; -} - -double QuantumGate::GetFidelity() const -{ - return fidelity; -} - -size_t QuantumGate::GetGateSize() const -{ - return gate_size; -} - -std::string QuantumGate::GetUnitary() const -{ - return unitary; -} - -std::string QuantumGate::GetName() const -{ - return name; -} \ No newline at end of file diff --git a/src/Topology.hpp b/src/Topology.hpp index cb73c73..3bfeb0d 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -40,22 +40,8 @@ #define SYS_SAGE_CHIP_TYPE_CPU_SOCKET 4 /**< Chip type used for one CPU socket. */ #define SYS_SAGE_CHIP_TYPE_GPU 8 /**< Chip type used for a GPU.*/ -#define SYS_SAGE_1Q_QUANTUM_GATE 1 /**< Quantum Gate of size 1-Qubit. */ -#define SYS_SAGE_2Q_QUANTUM_GATE 2 /**< Quantum Gate of size 2-Qubits. */ -#define SYS_SAGE_MQ_QUANTUM_GATE 4 /**< Quantum Gate of size M-Qubits (where M >2). */ -#define SYS_SAGE_NO_TYPE_QUANTUM_GATE 0 /**< Quantum Gate of size 0 or invalid size. */ - - -// QuantumGate type -#define SYS_SAGE_QUANTUMGATE_TYPE_ID 32 /**< Identity Gate */ -#define SYS_SAGE_QUANTUMGATE_TYPE_RZ 64 /**< RZ Gate */ -#define SYS_SAGE_QUANTUMGATE_TYPE_CNOT 128 /**< CNOT Gate */ -#define SYS_SAGE_QUANTUMGATE_TYPE_SX 256 /**< SX Gate */ -#define SYS_SAGE_QUANTUMGATE_TYPE_X 512 /**< X Gate */ -#define SYS_SAGE_QUANTUMGATE_TYPE_TOFFOLI 1024 /**< Toffoli Gate */ -#define SYS_SAGE_QUANTUMGATE_TYPE_UNKNOWN 2048 /**< Unknown Gate */ - using namespace std; +class Relation; class DataPath; class QuantumGate; /** @@ -975,42 +961,42 @@ class AtomSite : public QuantumBackend{ }; -class QuantumGate { - - public: - /** - QuantumGate constructor. - @param _gate_size - No. of qubits involved in a qubit. - @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. - \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 - */ - // QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); - - QuantumGate(); - QuantumGate(size_t _gate_size); - - void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); - void SetGateCouplingMap(std::vector > _coupling_mapping); - void SetAdditionalProperties(); - void SetGateType(); - int GetGateType() const; - double GetFidelity() const; - size_t GetGateSize() const; - std::string GetUnitary() const; - std::string GetName() const; - - private: - int type; // Denotes type of the QuantumGate -- helps to distinguish between different gates (ID, RZ, etc.) - std::string name; - size_t gate_size; // "No. of qubits involved" - int gate_length; // "Time needed to execute that gate operation" - std::string unitary; - double fidelity; - - std::vector> coupling_mapping; - std::vector qubits; /**< TODO */ - std::map additional_properties; - }; +// class QuantumGate { + +// public: +// /** +// QuantumGate constructor. +// @param _gate_size - No. of qubits involved in a qubit. +// @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. +// \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 +// */ +// // QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); + +// QuantumGate(); +// QuantumGate(size_t _gate_size); + +// void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); +// void SetGateCouplingMap(std::vector > _coupling_mapping); +// void SetAdditionalProperties(); +// void SetGateType(); +// int GetGateType() const; +// double GetFidelity() const; +// size_t GetGateSize() const; +// std::string GetUnitary() const; +// std::string GetName() const; + +// private: +// int type; // Denotes type of the QuantumGate -- helps to distinguish between different gates (ID, RZ, etc.) +// std::string name; +// size_t gate_size; // "No. of qubits involved" +// int gate_length; // "Time needed to execute that gate operation" +// std::string unitary; +// double fidelity; + +// std::vector> coupling_mapping; +// std::vector qubits; /**< TODO */ +// std::map additional_properties; +// }; #endif diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index c088ccc..175fb5a 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -263,7 +263,7 @@ extern "C" void QdmiParser::setGateSets(QuantumBackend *backend, QDMI_Device dev std::string unitary = gates[i].unitary; size_t gate_size = gates[i].gate_size; - // Add a destructor + // Add a constructor QuantumGate *qgate = new QuantumGate(gate_size); qgate->SetGateProperties(name, fidelity, unitary); From 0858dba07c7e1ffc9c28fb8efc6839679eba5292 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Wed, 7 Aug 2024 01:23:16 +0200 Subject: [PATCH 32/34] Replaced dp_type with type --- docs/Concept.md | 2 +- src/DataPath.cpp | 16 ++++----- src/DataPath.hpp | 34 ++++++++++++------- src/Topology.cpp | 14 ++++---- src/Topology.hpp | 8 ++--- src/xml_dump.cpp | 2 +- test/resources/schema.xml | 2 +- test/resources/sys-sage_custom_attributes.xml | 32 ++++++++--------- test/resources/sys-sage_sample_output.xml | 32 ++++++++--------- 9 files changed, 75 insertions(+), 67 deletions(-) diff --git a/docs/Concept.md b/docs/Concept.md index 510bd4c..c905610 100644 --- a/docs/Concept.md +++ b/docs/Concept.md @@ -160,7 +160,7 @@ The set of Data Paths forms a Data-path Graph. Each Data Path has a **source** and a **target Component**, but apart from that, no other rules apply. Data Paths may be oriented (differentiating between the source and the target) or bidirectional. There may also be multiple Data Paths connecting the same pair of Components, enabling the representation of multiple dependencies or relationships. -To differentiate between these, attribute ‘dp_type’ is used to easily group or tell apart different kinds of information carried by Data Paths. +To differentiate between these, attribute ‘type’ is used to easily group or tell apart different kinds of information carried by Data Paths. Analogously to Components, Data Paths have a set of default properties, such as bandwidth or latency, and an std::map **attrib**, where arbitrary information can be attached. Data Paths may carry all different kinds of information, including but not limited to performance-related or power consumption-related information, or even application-specific data diff --git a/src/DataPath.cpp b/src/DataPath.cpp index 449ba99..dc7ee23 100644 --- a/src/DataPath.cpp +++ b/src/DataPath.cpp @@ -19,12 +19,12 @@ Component * DataPath::GetSource() {return source;} Component * DataPath::GetTarget() {return target;} double DataPath::GetBw() {return bw;} double DataPath::GetLatency() {return latency;} -int DataPath::GetDpType() {return dp_type;} +int DataPath::GetDpType() {return type;} int DataPath::GetOriented() {return oriented;} DataPath::DataPath(Component* _source, Component* _target, int _oriented, int _type): DataPath(_source, _target, _oriented, _type, -1, -1) {} DataPath::DataPath(Component* _source, Component* _target, int _oriented, double _bw, double _latency): DataPath(_source, _target, _oriented, SYS_SAGE_DATAPATH_TYPE_NONE, _bw, _latency) {} -DataPath::DataPath(Component* _source, Component* _target, int _oriented, int _type, double _bw, double _latency): source(_source), target(_target), oriented(_oriented), dp_type(_type), bw(_bw), latency(_latency) +DataPath::DataPath(Component* _source, Component* _target, int _oriented, int _type, double _bw, double _latency): source(_source), target(_target), oriented(_oriented), type(_type), bw(_bw), latency(_latency) { if(_oriented == SYS_SAGE_DATAPATH_BIDIRECTIONAL) { @@ -98,24 +98,24 @@ QuantumGate::QuantumGate() QuantumGate::QuantumGate(size_t _gate_size) : gate_size(_gate_size){} QuantumGate::QuantumGate(size_t _gate_size, std::string _name, double _fidelity, std::string _unitary) -: gate_size(_gate_size), name(_name), fidelity(_fidelity), unitary(_unitary){} +: gate_size(_gate_size), fidelity(_fidelity), unitary(_unitary){ name =_name ;} QuantumGate::QuantumGate(size_t _gate_size, const std::vector & _qubits) : gate_size(_gate_size), qubits(_qubits) {} QuantumGate::QuantumGate(size_t _gate_size, const std::vector & _qubits, std::string _name, double _fidelity, std::string _unitary) -: gate_size(_gate_size), qubits(_qubits), name(_name), fidelity(_fidelity), unitary(_unitary) {} +: gate_size(_gate_size), qubits(_qubits), fidelity(_fidelity), unitary(_unitary) { name =_name ;} void QuantumGate::SetGateProperties(std::string _name, double _fidelity, std::string _unitary) { name = _name; fidelity = _fidelity; unitary = _unitary; - SetGateType(); + SetType(); } -void QuantumGate::SetGateType() +void QuantumGate::SetType() { if(gate_size == 1) { @@ -145,7 +145,7 @@ void QuantumGate::SetGateType() } -int QuantumGate::GetGateType() const +int QuantumGate::GetType() { return type; } @@ -165,7 +165,7 @@ std::string QuantumGate::GetUnitary() const return unitary; } -std::string QuantumGate::GetName() const +std::string QuantumGate::GetName() { return name; } diff --git a/src/DataPath.hpp b/src/DataPath.hpp index 79cc984..1f71afb 100644 --- a/src/DataPath.hpp +++ b/src/DataPath.hpp @@ -16,7 +16,7 @@ #define SYS_SAGE_DATAPATH_BIDIRECTIONAL 8 /**< DataPath has no direction. */ #define SYS_SAGE_DATAPATH_ORIENTED 16 /**< DataPath is directed from the source to the target. */ -//dp_type +//datapath type #define SYS_SAGE_DATAPATH_TYPE_NONE 32 /**< Generic type of DataPath */ #define SYS_SAGE_DATAPATH_TYPE_LOGICAL 64 /**< DataPath describes a logical connection/relation of two Components. */ #define SYS_SAGE_DATAPATH_TYPE_PHYSICAL 128 /**< DataPath describes a physical/hardware connection/relation of two Components. */ @@ -47,10 +47,19 @@ class Qubit; */ class Relation { public: - + + void SetType(); + int GetType(); + void SetId(); + int GetId(); + void SetName(); + std::string GetName(); + int id; + int type; + std::string name; + virtual ~Relation() = default; - virtual void Print() = 0; virtual void DeleteRelation() = 0; @@ -129,8 +138,9 @@ class DataPath : public Relation { double GetLatency(); /** @returns Type of the Data Path. - @see dp_type + @see type */ + //TO-DO: Replace this with type, no type required int GetDpType(); /** * TODO @@ -159,7 +169,7 @@ class DataPath : public Relation { Component *source; Component *target; const int oriented; - const int dp_type; + const int type; double bw; double latency; }; @@ -176,21 +186,19 @@ class QuantumGate : public Relation { void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); void SetGateCouplingMap(std::vector> _coupling_mapping); void SetAdditionalProperties(); - void SetGateType(); - int GetGateType() const; + void SetType(); + int GetType(); double GetFidelity() const; size_t GetGateSize() const; - void SetGateId(int _id); - int GetGateId(); + void SetId(int _id); + int GetId(); std::string GetUnitary() const; - std::string GetName() const; + std::string GetName(); void Print() override; void DeleteRelation() override; private: - int id; - int type; - std::string name; + size_t gate_size; int gate_length; std::string unitary; diff --git a/src/Topology.cpp b/src/Topology.cpp index dfb4e0e..9a4b7e3 100644 --- a/src/Topology.cpp +++ b/src/Topology.cpp @@ -242,33 +242,33 @@ void Component::AddDataPath(DataPath* p, int orientation) dp_incoming.push_back(p); } -DataPath* Component::GetDpByType(int dp_type, int orientation) +DataPath* Component::GetDpByType(int type, int orientation) { if(orientation & SYS_SAGE_DATAPATH_OUTGOING){ for(DataPath* dp : dp_outgoing){ - if(dp->GetDpType() == dp_type) + if(dp->GetDpType() == type) return dp; } } if(orientation & SYS_SAGE_DATAPATH_INCOMING){ for(DataPath* dp : dp_incoming){ - if(dp->GetDpType() == dp_type) + if(dp->GetDpType() == type) return dp; } } return NULL; } -void Component::GetAllDpByType(vector* outDpArr, int dp_type, int orientation) +void Component::GetAllDpByType(vector* outDpArr, int type, int orientation) { if(orientation & SYS_SAGE_DATAPATH_OUTGOING){ for(DataPath* dp : dp_outgoing){ - if(dp->GetDpType() == dp_type) + if(dp->GetDpType() == type) outDpArr->push_back(dp); } } if(orientation & SYS_SAGE_DATAPATH_INCOMING){ for(DataPath* dp : dp_incoming){ - if(dp->GetDpType() == dp_type) + if(dp->GetDpType() == type) outDpArr->push_back(dp); } } @@ -608,7 +608,7 @@ std::vector QuantumBackend::GetGatesByType(size_t _gate_type) cons for (QuantumGate * gate : gate_types) { - if(_gate_type == gate->GetGateType()) + if(_gate_type == gate->GetType()) gates.emplace_back(gate); } diff --git a/src/Topology.hpp b/src/Topology.hpp index 3bfeb0d..0170f91 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -273,21 +273,21 @@ class Component { /** Retrieves a DataPath * from the list of this component's data paths with matching type and orientation. \n The first match is returned -- first SYS_SAGE_DATAPATH_OUTGOING are searched, then SYS_SAGE_DATAPATH_INCOMING. - @param dp_type - DataPath type (dp_type) to search for + @param type - DataPath type (type) to search for @param orientation - orientation of the DataPath (SYS_SAGE_DATAPATH_OUTGOING or SYS_SAGE_DATAPATH_INCOMING or a logical or of these) @return DataPath pointer to the found data path; NULL if nothing found. */ - DataPath* GetDpByType(int dp_type, int orientation); + DataPath* GetDpByType(int type, int orientation); /** Retrieves all DataPath * from the list of this component's data paths with matching type and orientation. Results are returned in vector* outDpArr, where first the matching data paths in dp_outgoing are pushed back, then the ones in dp_incoming. - @param dp_type - DataPath type (dp_type) to search for. + @param type - DataPath type (type) to search for. @param orientation - orientation of the DataPath (SYS_SAGE_DATAPATH_OUTGOING or SYS_SAGE_DATAPATH_INCOMING or a logical or of these) @param outDpArr - output parameter (vector with results) \n An input is pointer to a std::vector, in which the data paths will be pushed. It must be allocated before the call (but does not have to be empty). \n The method pushes back the found data paths -- i.e. the data paths(pointers) can be found in this array after the method returns. (If no found, the vector is not changed.) */ - void GetAllDpByType(vector* outDpArr, int dp_type, int orientation); + void GetAllDpByType(vector* outDpArr, int type, int orientation); /** * TODO */ diff --git a/src/xml_dump.cpp b/src/xml_dump.cpp index f300e64..44f64b8 100644 --- a/src/xml_dump.cpp +++ b/src/xml_dump.cpp @@ -265,7 +265,7 @@ int exportToXml(Component* root, string path, std::functionGetOriented())).c_str()); - xmlNewProp(dp_n, (const unsigned char *)"dp_type", (const unsigned char *)(std::to_string(dpPtr->GetDpType())).c_str()); + xmlNewProp(dp_n, (const unsigned char *)"type", (const unsigned char *)(std::to_string(dpPtr->GetDpType())).c_str()); xmlNewProp(dp_n, (const unsigned char *)"bw", (const unsigned char *)(std::to_string(dpPtr->GetBw())).c_str()); xmlNewProp(dp_n, (const unsigned char *)"latency", (const unsigned char *)(std::to_string(dpPtr->GetLatency())).c_str()); xmlAddChild(data_paths_root, dp_n); diff --git a/test/resources/schema.xml b/test/resources/schema.xml index 7b99fc1..66d4f34 100644 --- a/test/resources/schema.xml +++ b/test/resources/schema.xml @@ -25,7 +25,7 @@ - + diff --git a/test/resources/sys-sage_custom_attributes.xml b/test/resources/sys-sage_custom_attributes.xml index 111b0e8..87dd9d1 100644 --- a/test/resources/sys-sage_custom_attributes.xml +++ b/test/resources/sys-sage_custom_attributes.xml @@ -269,41 +269,41 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/resources/sys-sage_sample_output.xml b/test/resources/sys-sage_sample_output.xml index 8c65ee4..e31e896 100644 --- a/test/resources/sys-sage_sample_output.xml +++ b/test/resources/sys-sage_sample_output.xml @@ -243,37 +243,37 @@ - - - - - - - - - - - - - - - - \ No newline at end of file From 0eac8cce87ce3fef486d1db79f906bd53d938fdc Mon Sep 17 00:00:00 2001 From: Durganshu Date: Sun, 11 Aug 2024 23:11:53 +0200 Subject: [PATCH 33/34] Minor changes --- src/DataPath.cpp | 9 ++++++++- src/DataPath.hpp | 25 +++++++++++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/DataPath.cpp b/src/DataPath.cpp index dc7ee23..4341e96 100644 --- a/src/DataPath.cpp +++ b/src/DataPath.cpp @@ -3,6 +3,13 @@ #include #include +void Relation::SetType(int _type) {_type = type;} +int Relation::GetType(){ return type;} +void Relation::SetId(int _id) {id = _id;} +int Relation::GetId(){ return id;} +void Relation::SetName(std::string _name) { name = _name;} +std::string Relation::GetName() {return name;} + DataPath* NewDataPath(Component* _source, Component* _target, int _oriented, int _type){ return NewDataPath(_source,_target,_oriented,_type,(double)-1,(double)-1); } @@ -19,7 +26,7 @@ Component * DataPath::GetSource() {return source;} Component * DataPath::GetTarget() {return target;} double DataPath::GetBw() {return bw;} double DataPath::GetLatency() {return latency;} -int DataPath::GetDpType() {return type;} +int DataPath::GetDpType() {return GetType();} int DataPath::GetOriented() {return oriented;} DataPath::DataPath(Component* _source, Component* _target, int _oriented, int _type): DataPath(_source, _target, _oriented, _type, -1, -1) {} diff --git a/src/DataPath.hpp b/src/DataPath.hpp index 1f71afb..26ebf7d 100644 --- a/src/DataPath.hpp +++ b/src/DataPath.hpp @@ -43,26 +43,29 @@ class Component; class Qubit; /** - * Abstract class Relation representing a generic relationship or connectivity between two components. + * class Relation representing a generic relationship or connectivity between two components. */ class Relation { public: - void SetType(); + void SetType(int _type); int GetType(); - void SetId(); + void SetId(int _id); int GetId(); - void SetName(); + void SetName(std::string _name); std::string GetName(); - int id; - int type; - std::string name; - virtual ~Relation() = default; virtual void Print() = 0; virtual void DeleteRelation() = 0; + + int id; + int type; + std::string name; + std::vector components; + + }; class DataPath; /** @@ -136,11 +139,13 @@ class DataPath : public Relation { @returns Data load latency from the source(provides the data) to the target(requests the data) */ double GetLatency(); + /** + * @private + Obsolete;use GetType() instead. @returns Type of the Data Path. @see type */ - //TO-DO: Replace this with type, no type required int GetDpType(); /** * TODO @@ -204,7 +209,7 @@ class QuantumGate : public Relation { std::string unitary; double fidelity; std::vector> coupling_mapping; - std::vector qubits; + std::vector qubits; // Remove from here. std::map additional_properties; }; From d3f83f5ac6d739a21b1bae83a7553195c6855320 Mon Sep 17 00:00:00 2001 From: Durganshu Date: Fri, 16 Aug 2024 23:50:49 +0200 Subject: [PATCH 34/34] Cleanup and documentation --- src/DataPath.hpp | 234 +++++++++++++++++++++++++++++++++++- src/Topology.hpp | 149 +++++++++++++++++------ src/parsers/qdmi-parser.cpp | 97 +-------------- 3 files changed, 341 insertions(+), 139 deletions(-) diff --git a/src/DataPath.hpp b/src/DataPath.hpp index 26ebf7d..1996823 100644 --- a/src/DataPath.hpp +++ b/src/DataPath.hpp @@ -43,30 +43,105 @@ class Component; class Qubit; /** - * class Relation representing a generic relationship or connectivity between two components. + * @class Relation + * @brief Represents a generic relationship or connectivity between two components. + * + * This class defines a generic relationship with methods to set and get + * the type, id, and name of the relationship. It also provides pure virtual + * functions for printing and deleting the relationship, making it an abstract class. */ class Relation { public: - + /** + * @brief Sets the type of the relationship. + * @param _type The type of the relationship to set. + */ void SetType(int _type); + + /** + * @brief Gets the type of the relationship. + * @return The current type of the relationship. + */ int GetType(); + + /** + * @brief Sets the id of the relationship. + * @param _id The id of the relationship to set. + */ void SetId(int _id); + + /** + * @brief Gets the id of the relationship. + * @return The current id of the relationship. + */ int GetId(); + + /** + * @brief Sets the name of the relationship. + * @param _name The name of the relationship to set. + */ void SetName(std::string _name); + + /** + * @brief Gets the name of the relationship. + * @return The current name of the relationship. + */ std::string GetName(); + + /** + * @brief Destructor for the Relation class. + * + * This is a virtual destructor to ensure proper cleanup of derived classes. + */ virtual ~Relation() = default; + /** + * @brief Pure virtual function to print the details of the relationship. + * + * Derived classes must implement this function to provide specific + * printing behavior. + */ virtual void Print() = 0; + /** + * @brief Pure virtual function to delete the relationship. + * + * Derived classes must implement this function to provide specific + * deletion behavior. + */ virtual void DeleteRelation() = 0; - + + /** + * @brief The id of the relationship. + * + * This member variable stores the unique identifier for the relationship. + */ int id; + + /** + * @brief The type of the relationship. + * + * This member variable stores the type or category of the relationship. + */ int type; + + /** + * @brief The name of the relationship. + * + * This member variable stores the name or description of the relationship. + */ std::string name; - std::vector components; - + /** + * @brief A vector of components associated with the relationship. + * + * This member variable holds pointers to components that are part of + * the relationship. + */ + std::vector components; + }; + class DataPath; /** Obsolete; use DataPath() constructors directly instead @@ -179,38 +254,185 @@ class DataPath : public Relation { double latency; }; +/** + * @class QuantumGate + * @brief Represents a quantum gate in a quantum circuit. + * + * This class extends the Relation class to model quantum gates. + * It includes various properties specific to quantum gates, such as gate size, fidelity, and unitary matrix. + * The class also handles the coupling map and additional properties related to quantum gate operations. + */ class QuantumGate : public Relation { public: + /** + * @brief Default constructor for QuantumGate. + * + * Initializes a quantum gate with default properties. + */ QuantumGate(); + + /** + * @brief Constructor that initializes a quantum gate with a specified size. + * @param _gate_size The number of qubits this gate operates on. + */ QuantumGate(size_t _gate_size); + + /** + * @brief Constructor that initializes a quantum gate with specific properties. + * @param _gate_size The number of qubits this gate operates on. + * @param _name The name of the quantum gate. + * @param _fidelity The fidelity of the quantum gate. + * @param _unitary The unitary matrix representing the quantum gate operation. + */ QuantumGate(size_t _gate_size, std::string _name, double _fidelity, std::string _unitary); + + /** + * @brief Constructor that initializes a quantum gate with a list of qubits. + * @param _gate_size The number of qubits this gate operates on. + * @param _qubits A vector of pointers to Qubit objects that the gate operates on. + */ QuantumGate(size_t _gate_size, const std::vector & _qubits); + + /** + * @brief Constructor that initializes a quantum gate with detailed properties and qubits. + * @param _gate_size The number of qubits this gate operates on. + * @param _qubits A vector of pointers to Qubit objects that the gate operates on. + * @param _name The name of the quantum gate. + * @param _fidelity The fidelity of the quantum gate. + * @param _unitary The unitary matrix representing the quantum gate operation. + */ QuantumGate(size_t _gate_size, const std::vector & _qubits, std::string _name, double _fidelity, std::string _unitary); + /** + * @brief Sets the properties of the quantum gate. + * @param _name The name of the quantum gate. + * @param _fidelity The fidelity of the quantum gate. + * @param _unitary The unitary matrix representing the quantum gate operation. + */ void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); + + /** + * @brief Sets the coupling map for the quantum gate. + * @param _coupling_mapping A vector of vectors of pointers to Qubit objects representing the coupling map. + */ void SetGateCouplingMap(std::vector> _coupling_mapping); + + /** + * @brief Sets additional properties for the quantum gate. + * + * This function allows setting properties that are not part of the core quantum gate attributes. + */ void SetAdditionalProperties(); + + /** + * @brief Sets the type of the quantum gate. + * + * Sets the specific type for quantum gates. + */ void SetType(); + + /** + * @brief Gets the type of the quantum gate. + * @return The type identifier for the quantum gate. + */ int GetType(); + + /** + * @brief Gets the fidelity of the quantum gate. + * @return The fidelity of the quantum gate. + */ double GetFidelity() const; + + /** + * @brief Gets the size of the quantum gate. + * @return The number of qubits this gate operates on. + */ size_t GetGateSize() const; + + /** + * @brief Sets the id of the quantum gate. + * @param _id The id to assign to the quantum gate. + */ void SetId(int _id); + + /** + * @brief Gets the id of the quantum gate. + * @return The id of the quantum gate. + */ int GetId(); + + /** + * @brief Gets the unitary matrix of the quantum gate. + * @return A string representing the unitary matrix of the quantum gate. + */ std::string GetUnitary() const; + + /** + * @brief Gets the name of the quantum gate. + * @return The name of the quantum gate. + */ std::string GetName(); + + /** + * @brief Prints the details of the quantum gate. + * + * This method overrides the Print function in the Relation class to provide specific printing behavior for quantum gates. + */ void Print() override; + + /** + * @brief Deletes the quantum gate relation. + * + * This method overrides the DeleteRelation function in the Relation class to handle specific deletion behavior for quantum gates. + */ void DeleteRelation() override; private: + /** + * @brief The size of the quantum gate, representing the number of qubits it operates on. + */ size_t gate_size; + + /** + * @brief The length of the quantum gate operation in terms of time or depth. + */ int gate_length; + + /** + * @brief The unitary matrix representing the quantum gate's operation. + * + * This string stores a serialized or symbolic representation of the unitary matrix. + */ std::string unitary; + + /** + * @brief The fidelity of the quantum gate, indicating its accuracy or performance. + */ double fidelity; + + /** + * @brief The coupling map for the quantum gate. + * + * This 2D vector of qubit pointers represents the coupling map, defining how qubits interact within the gate. + */ std::vector> coupling_mapping; - std::vector qubits; // Remove from here. + + /** + * @brief List of the qubits involved in a quantum gate. + * + * This vector of qubit pointers stores the list of the qubits involved in the gate. + */ + std::vector qubits; + + /** + * @brief Additional properties of the quantum gate. + * + * This map allows storing additional key-value pairs representing various other properties related to the quantum gate. + */ std::map additional_properties; }; + #endif // RELATION_HPP diff --git a/src/Topology.hpp b/src/Topology.hpp index 0170f91..51b8fe4 100644 --- a/src/Topology.hpp +++ b/src/Topology.hpp @@ -856,23 +856,69 @@ class Qubit : public Component { @param componentType=>SYS_SAGE_COMPONENT_QUBIT */ Qubit(Component * parent, int _id = 0, string _name = "Qubit"); - + + /** + * @brief Sets the coupling mapping for the qubit. + * + * @param coupling_mapping A vector of integers representing the coupling mapping. + * @param size_coupling_mapping The size of the coupling mapping. + */ void SetCouplingMapping( const std::vector &coupling_mapping, const int &size_coupling_mapping); + /** + * @brief Sets the properties of the qubit. + * + * @param t1 The T1 relaxation time. + * @param t2 The T2 dephasing time. + * @param readout_error The readout error rate. + * @param readout_length The readout length. + */ void SetProperties(double t1, double t2, double readout_error, double readout_length); + /** + * @brief Gets the coupling mapping of the qubit. + * + * @return A constant reference to a vector of integers representing the coupling mapping. + */ const std::vector &GetCouplingMapping() const; + /** + * @brief Gets the T1 relaxation time of the qubit. + * + * @return The T1 relaxation time. + */ const double GetT1() const; - + /** + * @brief Gets the T2 dephasing time of the qubit. + * + * @return The T2 dephasing time. + */ const double GetT2() const; + /** + * @brief Gets the readout error rate of the qubit. + * + * @return The readout error rate. + */ const double GetReadoutError() const; + /** + * @brief Gets the readout length of the qubit. + * + * @return The readout length. + */ const double GetReadoutLength() const; + /** + * @brief Gets the frequency of the qubit. + * + * @return The frequency of the qubit. + */ const double GetFrequency() const; + /** + * @brief Refreshes the properties of the qubit. + */ void RefreshProperties(); ~Qubit() override = default; @@ -908,28 +954,90 @@ class QuantumBackend : public Component { */ QuantumBackend(Component * parent, int _id = 0, string _name = "QuantumBackend"); + /** + * @brief Sets the number of qubits in the quantum backend. + * + * @param _num_qubits The number of qubits to set. + */ void SetNumberofQubits(int _num_qubits); + /** + * @brief Sets the QDMI device for the quantum backend. + * + * @param dev The QDMI device to set. + */ void SetQDMIDevice(QDMI_Device dev); + /** + * @brief Gets the QDMI device of the quantum backend. + * + * @return The QDMI device. + */ QDMI_Device GetQDMIDevice(); + /** + * @brief Gets the number of qubits in the quantum backend. + * + * @return The number of qubits. + */ int GetNumberofQubits () const; + /** + * @brief Adds a quantum gate to the quantum backend. + * + * @param gate The quantum gate to add. + */ void addGate(QuantumGate *gate); + /** + * @brief Gets the quantum gates by their size. + * + * @param _gate_size The size of the gates to retrieve. + * @return A vector of quantum gates with the specified size. + */ std::vector GetGatesBySize(size_t _gate_size) const; + /** + * @brief Gets the quantum gates by their type. + * + * @param _gate_type The type of the gates to retrieve. + * @return A vector of quantum gates with the specified type. + */ std::vector GetGatesByType(size_t _gate_type) const; + /** + * @brief Gets all types of quantum gates in the quantum backend. + * + * @return A vector of all quantum gate types. + */ std::vector GetAllGateTypes() const; + /** + * @brief Gets the number of quantum gates in the quantum backend. + * + * @return The number of quantum gates. + */ int GetNumberofGates() const; + /** + * @brief Gets all qubits in the quantum backend. + * + * @return A vector of pointers to all qubits. + */ std::vector GetAllQubits(); + /** + * @brief Gets all coupling maps in the quantum backend. + * + * @return A set of pairs representing the coupling maps. + */ std::set > GetAllCouplingMaps(); + /** + * @brief Refreshes the topology of the quantum backend. + * + * @param qubit_indices The indices of the qubits that need to be refreshed. + */ void RefreshTopology(std::set qubit_indices); // qubit_indices: indices of the qubits that need to be refreshed ~QuantumBackend() override = default; @@ -961,43 +1069,6 @@ class AtomSite : public QuantumBackend{ }; -// class QuantumGate { - -// public: -// /** -// QuantumGate constructor. -// @param _gate_size - No. of qubits involved in a qubit. -// @param _type - Denotes type of the QuantumGate -- helps to distinguish between different gates. -// \n Predefined types: SYS_SAGE_QUANTUMGATE_TYPE_ID, SYS_SAGE_QUANTUMGATE_TYPE_RZ, SYS_SAGE_QUANTUMGATE_TYPE_CNOT. Each user can define an arbitrary type as an integer value > 1024 -// */ -// // QuantumGate(std::vector _qubits, int _type = SYS_SAGE_QUANTUMGATE_TYPE_ID); - -// QuantumGate(); -// QuantumGate(size_t _gate_size); - -// void SetGateProperties(std::string _name, double _fidelity, std::string _unitary); -// void SetGateCouplingMap(std::vector > _coupling_mapping); -// void SetAdditionalProperties(); -// void SetGateType(); -// int GetGateType() const; -// double GetFidelity() const; -// size_t GetGateSize() const; -// std::string GetUnitary() const; -// std::string GetName() const; - -// private: -// int type; // Denotes type of the QuantumGate -- helps to distinguish between different gates (ID, RZ, etc.) -// std::string name; -// size_t gate_size; // "No. of qubits involved" -// int gate_length; // "Time needed to execute that gate operation" -// std::string unitary; -// double fidelity; - -// std::vector> coupling_mapping; -// std::vector qubits; /**< TODO */ -// std::map additional_properties; -// }; - #endif diff --git a/src/parsers/qdmi-parser.cpp b/src/parsers/qdmi-parser.cpp index 175fb5a..81427aa 100644 --- a/src/parsers/qdmi-parser.cpp +++ b/src/parsers/qdmi-parser.cpp @@ -36,57 +36,9 @@ extern "C" int QdmiParser::initiateSession() } -// TODO: Change function name (like FOMAC_available_devices) -// This will get the list of all the available devices and check individually if that devide is up and running. - extern "C" std::vector QdmiParser::get_available_backends() { - // 46-74: Replace this with newer QDMI calls - // char **available_devices = get_qdmi_library_list_names(); // --> - // if (available_devices == NULL) - // { - // std::cout << " [sys-sage]...............Failed to get " - // << "qdmi_library_list from QDMI" << std::endl; - - // return std::vector>(); - // } - - // int i = 0, err = 0, status = 0; - // std::vector> registered_devices; - // while (available_devices[i] != NULL) - // { - // QDMI_Device device = - // (QDMI_Device)malloc(sizeof(struct QDMI_Device_impl_d)); - - // QDMI_Library lib = find_library_by_name(available_devices[i]); // --> - - // if (!lib) - // { - // std::cout << " [sys-sage]...............A backend's library " - // << "could not be found" << std::endl; - - // free(available_devices[i++]); - // continue; - // } - - // device->library = *lib; - - // // TODO HANDLE err - // err = QDMI_device_status(device, device->library.info, &status); - - // if (status) - // { - // const char *device_name = strrchr(available_devices[i], '/'); - // std::cout << " [sys-sage]...............Available device " - // << "found: " << device_name << std::endl; - - // registered_devices.push_back(std::pair (device_name, device)); - // } - - // free(available_devices[i++]); - // } - // free(available_devices); int count; QDMI_core_device_count(&QdmiParser::session, &count); @@ -113,9 +65,6 @@ extern "C" std::vector QdmiParser::get_available_backends() QDMI_Device device; QDMI_core_open_device(&QdmiParser::session, i , &QdmiParser::info, &device); - // const char *device_name = strrchr(available_devices[i], '/'); - // std::cout << " [sys-sage]...............Available device " - // << "found: " << device_name << std::endl; registered_devices.emplace_back(device); } @@ -150,11 +99,7 @@ extern "C" void QdmiParser::getCouplingMapping(QDMI_Device dev, QDMI_Qubit qubit coupling_map_size = qubit->size_coupling_mapping; coupling_mapping.resize(coupling_map_size); - //for (int j = 0; j < coupling_map_size; j++) - //{ - // Copy the coupling_mapping from qubit_impl - std::copy(qubit->coupling_mapping, qubit->coupling_mapping + coupling_map_size, coupling_mapping.begin()); - //} + std::copy(qubit->coupling_mapping, qubit->coupling_mapping + coupling_map_size, coupling_mapping.begin()); } extern "C" void QdmiParser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit) @@ -175,7 +120,7 @@ extern "C" void QdmiParser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit std::cout << " [sys-sage]...............Queried property doesn't exist: " << i <<"\n"; continue; } - // err = QDMI_query_qubit_property_type(dev, qubit, prop_index); + if(prop_index->type == QDMI_DOUBLE){ err = QDMI_query_qubit_property_d(dev, qubit, prop_index, &value); if(err) @@ -183,7 +128,7 @@ extern "C" void QdmiParser::getQubitProperties(QDMI_Device dev, QDMI_Qubit qubit std::cout << " [sys-sage]...............Unable to query property: " << i <<"\n"; continue; } - //std::cout << " [sys-sage]...............Value of " << properties[i] << ": " << value << "\n"; + } delete prop_index; @@ -253,7 +198,6 @@ extern "C" void QdmiParser::setGateSets(QuantumBackend *backend, QDMI_Device dev std::cout << " [sys-sage]...............Found " << num_gates << " supported gates.\n"; } - //std::vector gatesets(num_gates); for (int i = 0; i < num_gates; i++) { @@ -267,34 +211,9 @@ extern "C" void QdmiParser::setGateSets(QuantumBackend *backend, QDMI_Device dev QuantumGate *qgate = new QuantumGate(gate_size); qgate->SetGateProperties(name, fidelity, unitary); - //qgate->setAdditionalProperties(); backend->addGate(qgate); } - //backend->SetGateTypes(gatesets, num_gates); - - // for(int num = 0; num < num_gates; ++num) - // { - // auto mapping = gates[num].coupling_mapping; - // auto size_coupling_map = gates[num].sizcde_coupling_map; - // auto gate_size = gates[num].gate_size; - // if(mapping != NULL) - // { - - // // std::cout << "[sys-sage] Coupling map of gate: " << gates[num].name <<", size_coupling_map: "<< size_coupling_map << ", gate_size: " << gate_size<< "\n"; - - // for (size_t i = 0; i < size_coupling_map; ++i) { - // std::cout << "["; - // for (size_t j = 0; j < gate_size; ++j) - // { - // std::cout << mapping[i][j] << ", "; - // } - - // printf("]\n"); - // } - // } - - // } free(gates); @@ -339,16 +258,6 @@ extern "C" QuantumBackend QdmiParser::createQcTopo(QDMI_Device dev, int device_i return qc; } - -// extern "C" static void refreshQubitProprties(QuantumBackend *qc, Qubit *qubit) -// { -// //auto quantum_backends = get_available_backends(); - -// // Search for required QuantumBackend in the device and call these: -// //QDMI_Device dev = qc-> -// //QDMI_query_qubit_property(QDMI_Device dev, QDMI_Qubit_property prop, QDMI_Qubit qubit, int* coupling_map); -// } - void QuantumBackend::RefreshTopology(std::set qubit_indices) {