diff --git a/.clang-tidy b/.clang-tidy index 7be7a6f..ee7db0b 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -30,8 +30,6 @@ Checks: | CheckOptions: - key: readability-identifier-naming.ClassCase value: CamelCase - - key: readability-identifier-naming.ClassIgnoredRegexp - value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*" - key: readability-identifier-naming.ConstantParameterCase value: camelBack - key: readability-identifier-naming.EnumCase @@ -41,7 +39,7 @@ CheckOptions: - key: readability-identifier-naming.FunctionCase value: camelBack - key: readability-identifier-naming.FunctionIgnoredRegexp - value: ".*ZX.*|.*SWAP.*|.*CEX.*|.*DD.*|.*EQ.*" + value: ".*MQSS.*" - key: readability-identifier-naming.GlobalConstantCase value: UPPER_CASE - key: readability-identifier-naming.IgnoreMainLikeFunctions diff --git a/.github/workflows/mqss_client-test.yml b/.github/workflows/mqss_client-test.yml index b1124b3..4669664 100644 --- a/.github/workflows/mqss_client-test.yml +++ b/.github/workflows/mqss_client-test.yml @@ -1,6 +1,3 @@ -# This workflow will install Python dependencies, run tests and lint with a single version of Python -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python - name: MQSS Client Testing on: @@ -15,25 +12,40 @@ permissions: jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - python: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] steps: - - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install uv - uv sync + sudo apt update -y + sudo apt-get install -y \ + software-properties-common \ + cmake \ + nlohmann-json3-dev \ + librabbitmq-dev \ + libboost-dev \ + libgtest-dev \ + libgmock-dev \ + libcurl4-openssl-dev + + python3 -m pip install --upgrade pip + pip install uv pre-commit + - name: Run pre-commit run: | - uv run pre-commit install - uv run pre-commit run --all-files - - name: Test with pytest + pre-commit install + pre-commit run --all-files + + - name: Configure project + run: | + cmake -S . -B build -DBUILD_UNIT_TESTS=ON + + - name: Build + run: | + cmake --build build --parallel + + - name: Run tests run: | - uv run nox -s test + ctest --test-dir build/tests/unit/c++/ --output-on-failure diff --git a/.gitignore b/.gitignore index 537bb38..bcf6790 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ coverage.xml .hypothesis/ .pytest_cache/ cover/ +Testing/* # Translations *.mo diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d861af..821c84e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ project( MQSS-Client VERSION 0.1 DESCRIPTION "MQSS Client" - LANGUAGES CXX) + LANGUAGES CXX C) # Generate compile_commands.json to make it easier to work with clang based tools set(CMAKE_EXPORT_COMPILE_COMMANDS @@ -33,6 +33,7 @@ option(BUILD_TESTS "Build the tests" OFF) option(BUILD_UNIT_TESTS "Build the unit tests" OFF) option(BUILD_INTEGRATION_TESTS "Build the unit tests" OFF) option(ENABLE_COVERAGE "Enabling coverage" OFF) +option(BUILD_BINDINGS "Build Python Bindings" OFF) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") diff --git a/bindings/job.cpp b/bindings/job.cpp index fb2ff81..2336b2f 100644 --- a/bindings/job.cpp +++ b/bindings/job.cpp @@ -66,10 +66,10 @@ void registerJobInterface(const py::module& m) { py::class_(m, "JobResult") .def_property_readonly("results", &mqss::client::JobResult::getResults) - .def_property_readonly("completion_timestamp", + .def_property_readonly("timestamp_completed", &mqss::client::JobResult::getTimestampCompleted) - .def_property_readonly("submission_timestamp", + .def_property_readonly("timestamp_submitted", &mqss::client::JobResult::getTimestampSubmitted) - .def_property_readonly("scheduled_timestamp", + .def_property_readonly("timestamp_scheduled", &mqss::client::JobResult::getTimestampScheduled); } diff --git a/bindings/resource.cpp b/bindings/resource.cpp index 2aedbbe..ca2d68a 100644 --- a/bindings/resource.cpp +++ b/bindings/resource.cpp @@ -34,8 +34,10 @@ void registerResourceInterface(const py::module& m) { py::class_(m, "Gate") .def_property_readonly("name", &mqss::client::Gate::getName) - .def_property_readonly("qubit_number", &mqss::client::Gate::getQubitNumber) - .def_property_readonly("parameter_number", &mqss::client::Gate::getParameterNumber) + .def_property_readonly("qubit_number", + &mqss::client::Gate::getQubitNumber) + .def_property_readonly("parameter_number", + &mqss::client::Gate::getParameterNumber) .def_property_readonly("supported_qubits", &mqss::client::Gate::getSupportedQubits); } diff --git a/include/mqss-c/client.h b/include/mqss-c/client.h new file mode 100644 index 0000000..e7c589d --- /dev/null +++ b/include/mqss-c/client.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024 - 2026 MQSS Project + * All rights reserved. + * + * Licensed under the Apache License v2.0 with LLVM Exceptions (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif +#include "job.h" +#include "resource.h" + +#include + +typedef struct MQSSOpaqueClient* MQSSClientRef; + +MQSSClientRef MQSSClientCreateClient(char* token, char* urlOrQueue, bool isHpc); + +MQSSResourceRef* MQSSClientGetAllResources(MQSSClientRef client, int* size); + +MQSSResourceRef MQSSClientGetResourceInfo(MQSSClientRef client, + const char* resourceName); + +int MQSSClientSubmitJob(MQSSClientRef client, MQSSJobRef job); + +void MQSSClientCancelJob(MQSSClientRef client, MQSSJobRef job); + +MQSSJobResultRef MQSSClientGetJobResult(MQSSClientRef client, MQSSJobRef job, + bool wait, unsigned int timeout); + +int MQSSClientGetNumberPendingJobs(MQSSClientRef client, char* resourceName); +#ifdef __cplusplus +} +#endif diff --git a/include/mqss-c/job.h b/include/mqss-c/job.h new file mode 100644 index 0000000..6b51f34 --- /dev/null +++ b/include/mqss-c/job.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 - 2026 MQSS Project + * All rights reserved. + * + * Licensed under the Apache License v2.0 with LLVM Exceptions (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#pragma once + +#include +#ifdef __cplusplus +extern "C" { +#endif +#include +typedef struct MQSSOpaqueJob* MQSSJobRef; + +typedef struct MQSSOpaqueJobResult* MQSSJobResultRef; + +MQSSJobRef MQSSClientCreateCircuitJob(char* circuit, char* circuitFormat, + char* resourceName, unsigned int shots, + bool noModify, bool queued); + +MQSSJobRef MQSSClientCreateHamiltonianJob(char* resourceName, + char* interactionStr, + char* coefficientsStr); + +int MQSSClientGetJobResultCounts(MQSSJobResultRef jobResult, char*** bitstreams, + int** counts, int* size); + +int MQSSClientGetJobResultCompletedTimestamp(MQSSJobResultRef jobResult, + uint64_t* completedTimestamp); + +int MQSSClientGetJobResultSubmittedTimestamp(MQSSJobResultRef jobResult, + uint64_t* submittedTimestamp); + +int MQSSClientGetJobResultScheduledTimestamp(MQSSJobResultRef jobResult, + uint64_t* scheduledTimestamp); + +#ifdef __cplusplus +} +#endif diff --git a/include/mqss-c/resource.h b/include/mqss-c/resource.h new file mode 100644 index 0000000..5fc7198 --- /dev/null +++ b/include/mqss-c/resource.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 - 2026 MQSS Project + * All rights reserved. + * + * Licensed under the Apache License v2.0 with LLVM Exceptions (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif +#include + +typedef struct MQSSOpaqueResource* MQSSResourceRef; + +typedef struct MQSSOpaqueGate* MQSSGateRef; + +int MQSSClientResourceGetInfo(MQSSResourceRef resource, char** name, + unsigned* qubitCount, bool* online, + int** couplingMap, unsigned int* couplingMapSize, + MQSSGateRef** nativeGateset, + unsigned int* gateCount); + +int MQSSClientResourceGetGateInfo(MQSSGateRef gate, char** name, + unsigned* qubitNumber, + unsigned* parameterNumber, + int** supportedQubits, + unsigned int* supportedQubitCount); + +#ifdef __cplusplus +} +#endif diff --git a/include/mqss/resource.h b/include/mqss/resource.h index ba6bbf8..0c41d0f 100644 --- a/include/mqss/resource.h +++ b/include/mqss/resource.h @@ -33,6 +33,12 @@ class Gate { mParameterNumber(parameterNumber), mSupportedQubits(std::move(supportedQubits)) {} + Gate(const Gate&) = default; + Gate& operator=(const Gate&) = default; + + Gate(Gate&&) = default; + Gate& operator=(Gate&&) = default; + const std::string& getName() const noexcept { return mName; } const unsigned int& getQubitNumber() const noexcept { return mQubitNumber; } @@ -69,9 +75,7 @@ class Resource { return mCouplingMap; } - const std::vector& getNativeGateset() const noexcept { - return mNativeGateset; - } + std::vector& getNativeGateset() { return mNativeGateset; } private: std::string mName; diff --git a/src/c_bindings/client.cpp b/src/c_bindings/client.cpp new file mode 100644 index 0000000..d1ac2fd --- /dev/null +++ b/src/c_bindings/client.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2024 - 2026 MQSS Project + * All rights reserved. + * + * Licensed under the Apache License v2.0 with LLVM Exceptions (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "mqss-c/client.h" + +#include "common.h" +#include "mqss/client.h" + +using namespace mqss::client; + +MQSSClientRef MQSSClientCreateClient(char* token, char* urlOrQueue, + bool isHpc) { + if (!token || !urlOrQueue) + return nullptr; + + return wrap(new MQSSClient(token, urlOrQueue, isHpc)); +} +MQSSResourceRef* MQSSClientGetAllResources(MQSSClientRef client, int* size) { + if (!client || !size) + return nullptr; + + auto resources_ = unwrap(client)->getAllResources(); + *size = static_cast(resources_.size()); + + auto resources = static_cast( + malloc(resources_.size() * sizeof(MQSSResourceRef))); + if (!resources && !resources_.empty()) + return nullptr; + + for (size_t i = 0; i < resources_.size(); ++i) { + resources[i] = wrap(new Resource(resources_[i])); + } + + return resources; +} + +MQSSResourceRef MQSSClientGetResourceInfo(MQSSClientRef client, + const char* resourceName) { + if (!client || !resourceName) + return nullptr; + + auto resource = unwrap(client)->getResourceInfo(resourceName); + if (!resource) + return nullptr; + + return wrap(new Resource(*resource)); +} +int MQSSClientSubmitJob(MQSSClientRef client, MQSSJobRef job) { + if (!client || !job) + return -1; + + auto uuid = + unwrap(client)->submitJob(*unwrap(job)); + if (!uuid.has_value()) + return -1; + + try { + return std::stoi(*uuid); + } catch (...) { + return -2; + } +} + +void MQSSClientCancelJob(MQSSClientRef client, MQSSJobRef job) { + if (!client || !job) + return; + unwrap(client)->cancelJob(*unwrap(job)); +} + +MQSSJobResultRef MQSSClientGetJobResult(MQSSClientRef client, MQSSJobRef job, + bool wait, unsigned int timeout) { + if (!client || !job) + return nullptr; + + std::unique_ptr jobResult = + unwrap(client)->getJobResult(*unwrap(job), + wait, timeout); + return wrap(jobResult.release()); +} + +int MQSSClientGetNumberPendingJobs(MQSSClientRef client, char* resourceName) { + if (!client || !resourceName) + return -1; + + return unwrap(client)->getNumberPendingJobs(resourceName); +} diff --git a/src/c_bindings/common.h b/src/c_bindings/common.h new file mode 100644 index 0000000..d752480 --- /dev/null +++ b/src/c_bindings/common.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 - 2026 MQSS Project + * All rights reserved. + * + * Licensed under the Apache License v2.0 with LLVM Exceptions (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#pragma once + +template inline T* unwrap(RefT ref) { + return reinterpret_cast(ref); +} + +template inline RefT wrap(T* ptr) { + return reinterpret_cast(ptr); +} diff --git a/src/c_bindings/job.cpp b/src/c_bindings/job.cpp new file mode 100644 index 0000000..c26f40e --- /dev/null +++ b/src/c_bindings/job.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2024 - 2026 MQSS Project + * All rights reserved. + * + * Licensed under the Apache License v2.0 with LLVM Exceptions (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "mqss-c/job.h" + +#include "common.h" +#include "mqss/job.h" + +using namespace mqss::client; + +MQSSJobRef MQSSClientCreateCircuitJob(char* circuit, char* circuitFormat, + char* resourceName, unsigned int shots, + bool noModify, bool queued) { + if (!circuit || !circuitFormat || !resourceName) + return nullptr; + return wrap(new CircuitJobRequest( + circuit, circuitFormat, resourceName, shots, noModify, queued)); +} + +MQSSJobRef MQSSClientCreateHamiltonianJob(char* resourceName, + char* interactionStr, + char* coefficientsStr) { + if (!resourceName || !interactionStr || !coefficientsStr) + return nullptr; + return wrap( + new HamiltonianJobRequest(resourceName, interactionStr, coefficientsStr)); +} + +int MQSSClientGetJobResultCounts(MQSSJobResultRef jobResult, char*** bitstreams, + int** counts, int* size) { + if (!jobResult || !bitstreams || !counts || !size) + return -1; + + auto results = unwrap(jobResult)->getResults(); + + // Count total entries across all result maps. + size_t totalEntries = 0; + for (const auto& result : results) + totalEntries += result.size(); + + *size = static_cast(totalEntries); + + if (totalEntries == 0) { + *bitstreams = nullptr; + *counts = nullptr; + return 0; + } + + *counts = static_cast(malloc(sizeof(int) * totalEntries)); + *bitstreams = static_cast(malloc(sizeof(char*) * totalEntries)); + + if (!*counts || !*bitstreams) { + free(*counts); + free(*bitstreams); + return -1; + } + + size_t index = 0; + + for (const auto& result : results) { + for (const auto& [bitstream, count] : result) { + + (*bitstreams)[index] = static_cast(malloc(bitstream.size() + 1)); + + if (!(*bitstreams)[index]) { + for (size_t i = 0; i < index; ++i) + free((*bitstreams)[i]); + free(*bitstreams); + free(*counts); + return -1; + } + + std::memcpy((*bitstreams)[index], bitstream.c_str(), + bitstream.size() + 1); + + (*counts)[index] = static_cast(count); + + ++index; + } + } + + return 0; +} + +uint64_t parseTimestamp(const std::string& s) { + + std::tm tm = {}; + std::istringstream ss(s.substr(0, 19)); // YYYY-MM-DD HH:MM:SS + + ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S"); + + auto tt = std::mktime(&tm); + + auto tp = std::chrono::system_clock::from_time_t(tt); + + // Parse microseconds + auto dot = s.find('.'); + if (dot != std::string::npos) { + int micros = std::stoi(s.substr(dot + 1)); + tp += std::chrono::microseconds(micros); + } + return std::chrono::duration_cast( + tp.time_since_epoch()) + .count(); +} +int MQSSClientGetJobResultCompletedTimestamp(MQSSJobResultRef jobResult, + uint64_t* completedTimestamp) { + if (!jobResult || !completedTimestamp) + return -1; + + try { + *completedTimestamp = + parseTimestamp(unwrap(jobResult)->getTimestampCompleted()); + } catch (...) { + return -2; + } + return 0; +} + +int MQSSClientGetJobResultSubmittedTimestamp(MQSSJobResultRef jobResult, + uint64_t* submittedTimestamp) { + if (!jobResult || !submittedTimestamp) + return -1; + + try { + *submittedTimestamp = + parseTimestamp(unwrap(jobResult)->getTimestampSubmitted()); + } catch (...) { + return -2; + } + return 0; +} + +int MQSSClientGetJobResultScheduledTimestamp(MQSSJobResultRef jobResult, + uint64_t* scheduledTimestamp) { + if (!jobResult || !scheduledTimestamp) + return -1; + + try { + *scheduledTimestamp = + parseTimestamp(unwrap(jobResult)->getTimestampScheduled()); + } catch (...) { + return -2; + } + return 0; +} diff --git a/src/c_bindings/resource.cpp b/src/c_bindings/resource.cpp new file mode 100644 index 0000000..9afb1a0 --- /dev/null +++ b/src/c_bindings/resource.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2024 - 2026 MQSS Project + * All rights reserved. + * + * Licensed under the Apache License v2.0 with LLVM Exceptions (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + * + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "mqss/resource.h" + +#include "common.h" +#include "mqss-c/resource.h" + +using namespace mqss::client; + +template +int* flatten2D(const std::vector>& input, unsigned int* count) { + if (!count) + return nullptr; + size_t total = 0; + for (const auto& row : input) + total += row.size(); + + int* result = static_cast(malloc(total * sizeof(int))); + if (!result) + return nullptr; + + size_t index = 0; + for (const auto& row : input) { + for (T value : row) { + result[index++] = static_cast(value); + } + } + *count = total; + return result; +} + +int MQSSClientResourceGetInfo(MQSSResourceRef resource, char** name, + unsigned* qubitCount, bool* online, + int** couplingMap, unsigned int* couplingMapSize, + MQSSGateRef** nativeGateset, + unsigned* gateCount) { + if (!name || !qubitCount || !online || !couplingMap || !couplingMapSize || + !nativeGateset || !gateCount) { + return -1; + } + + auto* r = unwrap(resource); + if (!r) + return -2; + + if (asprintf(name, "%s", r->getName().c_str()) < 0) + return -3; + + *qubitCount = r->getQubitCount(); + *online = r->isOnline(); + + *couplingMap = flatten2D(r->getCouplingMap(), couplingMapSize); + if (!*couplingMap) { + free(*name); + *name = nullptr; + return -4; + } + + const auto& gates = r->getNativeGateset(); + *gateCount = static_cast(gates.size()); + + *nativeGateset = + static_cast(malloc(gates.size() * sizeof(MQSSGateRef))); + + if (!*nativeGateset) { + free(*couplingMap); + *couplingMap = nullptr; + free(*name); + *name = nullptr; + return -5; + } + + for (size_t i = 0; i < gates.size(); ++i) + (*nativeGateset)[i] = wrap(new Gate(gates[i])); + + return 0; +} + +int MQSSClientResourceGetGateInfo(MQSSGateRef gate, char** name, + unsigned* qubitNumber, + unsigned* parameterNumber, + int** supportedQubits, + unsigned int* supportedQubitCount) { + if (!gate || !name || !qubitNumber || !parameterNumber || !supportedQubits || + !supportedQubitCount) { + return -1; + } + + auto* g = unwrap(gate); + if (!g) + return -1; + const auto& gateName = g->getName(); + *name = static_cast(malloc(gateName.size() + 1)); + if (!*name) + return -2; + std::memcpy(*name, gateName.c_str(), gateName.size() + 1); + + *qubitNumber = g->getQubitNumber(); + *parameterNumber = g->getParameterNumber(); + + *supportedQubits = flatten2D(g->getSupportedQubits(), supportedQubitCount); + if (!*supportedQubits) { + free(*name); + *name = nullptr; + return -2; + } + + return 0; +} diff --git a/src/client.cpp b/src/client.cpp index 36eb940..4cf6ed4 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -21,6 +21,7 @@ #include "clients/hpc_client.h" #include "clients/rest_client.h" +#include "mqss-c/client.h" #include #include diff --git a/src/job.cpp b/src/job.cpp index d5b38b0..34d8880 100644 --- a/src/job.cpp +++ b/src/job.cpp @@ -19,6 +19,16 @@ #include "mqss/job.h" +#include "mqss-c/job.h" +#include "mqss/client.h" + +#include +#include +#include +#include +#include +#include + using namespace mqss::client; nlohmann::json CircuitJobRequest::toJson() const { diff --git a/src/resource.cpp b/src/resource.cpp index e0635f4..d9414ef 100644 --- a/src/resource.cpp +++ b/src/resource.cpp @@ -19,6 +19,9 @@ #include "mqss/resource.h" +#include "mqss-c/resource.h" +#include "mqss/client.h" + #include using namespace mqss::client;