From 09c29ac5e3dcec91a8931357edb9e447f1ad3e32 Mon Sep 17 00:00:00 2001 From: Jun Doi Date: Tue, 9 Dec 2025 11:12:41 +0900 Subject: [PATCH] restructure runtime services --- samples/sampler_test.cpp | 2 +- samples/transpile_test.cpp | 2 +- src/service/qiskit_runtime_service.hpp | 132 +---------------- src/service/qiskit_runtime_service_c.hpp | 140 ++++++++++++++++++ ...mi.hpp => qiskit_runtime_service_qrmi.hpp} | 0 5 files changed, 147 insertions(+), 129 deletions(-) create mode 100644 src/service/qiskit_runtime_service_c.hpp rename src/service/{qiskit_runtime_service qrmi.hpp => qiskit_runtime_service_qrmi.hpp} (100%) diff --git a/samples/sampler_test.cpp b/samples/sampler_test.cpp index 017a69d..387f431 100644 --- a/samples/sampler_test.cpp +++ b/samples/sampler_test.cpp @@ -22,7 +22,7 @@ #include "circuit/quantumcircuit.hpp" #include "primitives/backend_sampler_v2.hpp" -#include "service/qiskit_runtime_service.hpp" +#include "service/qiskit_runtime_service_qrmi.hpp" #include "compiler/transpiler.hpp" using namespace Qiskit; diff --git a/samples/transpile_test.cpp b/samples/transpile_test.cpp index 03c5eb5..c41487a 100644 --- a/samples/transpile_test.cpp +++ b/samples/transpile_test.cpp @@ -23,7 +23,7 @@ #include "circuit/quantumcircuit.hpp" #include "primitives/backend_sampler_v2.hpp" -#include "service/qiskit_runtime_service.hpp" +#include "service/qiskit_runtime_service_qrmi.hpp" #include "compiler/transpiler.hpp" using namespace Qiskit::circuit; diff --git a/src/service/qiskit_runtime_service.hpp b/src/service/qiskit_runtime_service.hpp index 185b85c..a82d1fe 100644 --- a/src/service/qiskit_runtime_service.hpp +++ b/src/service/qiskit_runtime_service.hpp @@ -1,7 +1,7 @@ /* # This code is part of Qiskit. # -# (C) Copyright IBM 2017, 2024. +# (C) Copyright IBM 2017, 2025. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory @@ -12,134 +12,12 @@ # that they have been altered from the originals. */ -// Qiskit Runtime Service +// Qiskit Runtime Service wrapper for backward compatibility +// use one of "service/qiskit_runtime_service_qrmi.hpp" or "service/qiskit_runtime_service_c.hpp" directly #ifdef QRMI_ROOT -#include "service/qiskit_runtime_service qrmi.hpp" +#include "service/qiskit_runtime_service_qrmi.hpp" #else // otherwise use Qiskit IBM runtime C-API - -#ifndef __qiskitcpp_providers_qiskit_runtime_service_def_hpp__ -#define __qiskitcpp_providers_qiskit_runtime_service_def_hpp__ - -#include - -#include "utils/types.hpp" -#include "providers/qkrt_backend.hpp" - -#ifdef _MSC_VER -#include -#else -#include -#include -#endif - -extern "C" { -#include "qiskit_ibm_runtime/qiskit_ibm_runtime.h" -} - -using qkrt_Backend = Backend; - -namespace Qiskit { -namespace service { - -/// @class QiskitRuntimeService -/// @brief runtime service using Qiskit IBM runtime Rust C-API. -class QiskitRuntimeService { -protected: - std::shared_ptr service_ = nullptr; - BackendSearchResults* backend_results_ = nullptr; - std::unordered_map backends_; -public: - /// @brief Create a new runtime service class - /// This constructor initializes runtime service from saved account configuration - /// in ~/.qiskit/qiskit-ibm.json - QiskitRuntimeService() - { - Service* service; - int ret = qkrt_service_new(&service); - if (ret != 0) { - std::cerr << "ERROR: Qiskit IBM runtime serivce initialization failed with code " << ret << std::endl; - } else { - service_ = std::shared_ptr(service, qkrt_service_free); - } - } - - ~QiskitRuntimeService() - { - if (service_) { - service_.reset(); - } - if (backend_results_) { - qkrt_backend_search_results_free(backend_results_); - } - } - - /// @brief get list of backends - /// @return a list of backends provided in this service - std::vector backends(void) - { - get_backends(); - - std::vector keys; - for (auto b : backends_) { - keys.push_back(b.first); - } - return keys; - } - - /// @brief create a new backend object - /// @param name the name of the backend resource - /// @return a new QkrtBackend class - Qiskit::providers::QkrtBackend backend(std::string name) - { - get_backends(); - - qkrt_Backend* backend = backends_[name]; - if (backend == nullptr) { - std::cerr << "ERROR: backend " << name << " is not provided in this service" << std::endl; - return Qiskit::providers::QkrtBackend(); - } - - return Qiskit::providers::QkrtBackend(service_, backend); - } - - /// @brief find the least busy backend - /// @return a new QkrtBackend class - Qiskit::providers::QkrtBackend least_busy(void) - { - get_backends(); - qkrt_Backend *least_busy = qkrt_backend_search_results_least_busy(backend_results_); - - return Qiskit::providers::QkrtBackend(service_, least_busy); - } - -protected: - bool get_backends(void) - { - if (backend_results_ != nullptr) - return true; - - int ret = qkrt_backend_search(&backend_results_, service_.get()); - if (ret != 0) { - std::cerr << "ERROR : qkrt_backend_search fails with code " << ret << std::endl; - return false; - } - uint_t count = qkrt_backend_search_results_length(backend_results_); - - // make map of backend name and pointer - qkrt_Backend **backends = qkrt_backend_search_results_data(backend_results_); - for (uint_t i = 0; i < count; i++) { - std::string name = qkrt_backend_name(backends[i]); - backends_[name] = backends[i]; - } - return true; - } -}; - -} // namespace service -} // namespace Qiskit - -#endif //__qiskitcpp_providers_qiskit_runtime_service_def_hpp__ - +#include "service/qiskit_runtime_service_c.hpp" #endif diff --git a/src/service/qiskit_runtime_service_c.hpp b/src/service/qiskit_runtime_service_c.hpp new file mode 100644 index 0000000..8bf37de --- /dev/null +++ b/src/service/qiskit_runtime_service_c.hpp @@ -0,0 +1,140 @@ +/* +# This code is part of Qiskit. +# +# (C) Copyright IBM 2017, 2024. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. +*/ + +// Qiskit Runtime Service using Qiskit IBM Runtime C + +#ifndef __qiskitcpp_providers_qiskit_runtime_service_c_def_hpp__ +#define __qiskitcpp_providers_qiskit_runtime_service_c_def_hpp__ + +#include + +#include "utils/types.hpp" +#include "providers/qkrt_backend.hpp" + +#ifdef _MSC_VER +#include +#else +#include +#include +#endif + +extern "C" { +#include "qiskit_ibm_runtime/qiskit_ibm_runtime.h" +} + +using qkrt_Backend = Backend; + +namespace Qiskit { +namespace service { + +/// @class QiskitRuntimeService +/// @brief runtime service using Qiskit IBM runtime Rust C-API. +class QiskitRuntimeService { +protected: + std::shared_ptr service_ = nullptr; + BackendSearchResults* backend_results_ = nullptr; + std::unordered_map backends_; +public: + /// @brief Create a new runtime service class + /// This constructor initializes runtime service from saved account configuration + /// in ~/.qiskit/qiskit-ibm.json + QiskitRuntimeService() + { + Service* service; + int ret = qkrt_service_new(&service); + if (ret != 0) { + std::cerr << "ERROR: Qiskit IBM runtime serivce initialization failed with code " << ret << std::endl; + } else { + service_ = std::shared_ptr(service, qkrt_service_free); + } + } + + ~QiskitRuntimeService() + { + if (service_) { + service_.reset(); + } + if (backend_results_) { + qkrt_backend_search_results_free(backend_results_); + } + } + + /// @brief get list of backends + /// @return a list of backends provided in this service + std::vector backends(void) + { + get_backends(); + + std::vector keys; + for (auto b : backends_) { + keys.push_back(b.first); + } + return keys; + } + + /// @brief create a new backend object + /// @param name the name of the backend resource + /// @return a new QkrtBackend class + Qiskit::providers::QkrtBackend backend(std::string name) + { + get_backends(); + + qkrt_Backend* backend = backends_[name]; + if (backend == nullptr) { + std::cerr << "ERROR: backend " << name << " is not provided in this service" << std::endl; + return Qiskit::providers::QkrtBackend(); + } + + return Qiskit::providers::QkrtBackend(service_, backend); + } + + /// @brief find the least busy backend + /// @return a new QkrtBackend class + Qiskit::providers::QkrtBackend least_busy(void) + { + get_backends(); + qkrt_Backend *least_busy = qkrt_backend_search_results_least_busy(backend_results_); + + return Qiskit::providers::QkrtBackend(service_, least_busy); + } + +protected: + bool get_backends(void) + { + if (backend_results_ != nullptr) + return true; + + int ret = qkrt_backend_search(&backend_results_, service_.get()); + if (ret != 0) { + std::cerr << "ERROR : qkrt_backend_search fails with code " << ret << std::endl; + return false; + } + uint_t count = qkrt_backend_search_results_length(backend_results_); + + // make map of backend name and pointer + qkrt_Backend **backends = qkrt_backend_search_results_data(backend_results_); + for (uint_t i = 0; i < count; i++) { + std::string name = qkrt_backend_name(backends[i]); + backends_[name] = backends[i]; + } + return true; + } +}; + +} // namespace service +} // namespace Qiskit + +#endif //__qiskitcpp_providers_qiskit_runtime_service_c_def_hpp__ + + diff --git a/src/service/qiskit_runtime_service qrmi.hpp b/src/service/qiskit_runtime_service_qrmi.hpp similarity index 100% rename from src/service/qiskit_runtime_service qrmi.hpp rename to src/service/qiskit_runtime_service_qrmi.hpp