Skip to content

Commit c9d0e4c

Browse files
authored
Follow-up to #2394 - handle remote REST QPU also (#2417)
1 parent 58433ca commit c9d0e4c

File tree

8 files changed

+31
-20
lines changed

8 files changed

+31
-20
lines changed

runtime/common/BaseRemoteRESTQPU.h

+6-8
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ class BaseRemoteRESTQPU : public cudaq::QPU {
657657
localShots = executionContext->shots;
658658

659659
executor->setShots(localShots);
660+
bool isObserve = executionContext && executionContext->name == "observe";
660661

661662
// If emulation requested, then just grab the function
662663
// and invoke it with the simulator
@@ -669,7 +670,7 @@ class BaseRemoteRESTQPU : public cudaq::QPU {
669670
// Launch the execution of the simulated jobs asynchronously
670671
future = cudaq::details::future(std::async(
671672
std::launch::async,
672-
[&, codes, localShots, kernelName, seed,
673+
[&, codes, localShots, kernelName, seed, isObserve,
673674
reorderIdx = executionContext->reorderIdx,
674675
localJIT = std::move(jitEngines)]() mutable -> cudaq::sample_result {
675676
std::vector<cudaq::ExecutionResult> results;
@@ -680,7 +681,7 @@ class BaseRemoteRESTQPU : public cudaq::QPU {
680681

681682
bool hasConditionals =
682683
cudaq::kernelHasConditionalFeedback(kernelName);
683-
if (hasConditionals && codes.size() > 1)
684+
if (hasConditionals && isObserve)
684685
throw std::runtime_error("error: spin_ops not yet supported with "
685686
"kernels containing conditionals");
686687
if (hasConditionals) {
@@ -710,18 +711,15 @@ class BaseRemoteRESTQPU : public cudaq::QPU {
710711
}
711712
}
712713

713-
bool isObserve =
714-
executionContext && executionContext->name == "observe";
715714
for (std::size_t i = 0; i < codes.size(); i++) {
716715
cudaq::ExecutionContext context("sample", localShots);
717716
context.reorderIdx = reorderIdx;
718717
cudaq::getExecutionManager()->setExecutionContext(&context);
719718
invokeJITKernelAndRelease(localJIT[i], kernelName);
720719
cudaq::getExecutionManager()->resetExecutionContext();
721720

722-
// If there are multiple codes, this is likely a spin_op.
723-
// If so, use the code name instead of the global register.
724-
if (isObserve || (codes.size() > 1)) {
721+
if (isObserve) {
722+
// Use the code name instead of the global register.
725723
results.emplace_back(context.result.to_map(), codes[i].name);
726724
results.back().sequentialData =
727725
context.result.sequential_data();
@@ -743,7 +741,7 @@ class BaseRemoteRESTQPU : public cudaq::QPU {
743741
// Allow developer to disable remote sending (useful for debugging IR)
744742
if (getEnvBool("DISABLE_REMOTE_SEND", false))
745743
return;
746-
future = executor->execute(codes);
744+
future = executor->execute(codes, isObserve);
747745
}
748746

749747
// Keep this asynchronous if requested

runtime/common/BraketExecutor.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ class BraketExecutor : public Executor {
7878
~BraketExecutor() = default;
7979

8080
/// @brief Execute the provided Braket task
81-
details::future
82-
execute(std::vector<KernelExecution> &codesToExecute) override;
81+
details::future execute(std::vector<KernelExecution> &codesToExecute,
82+
bool isObserve) override;
8383

8484
/// @brief Set the server helper
8585
void setServerHelper(ServerHelper *helper) override;

runtime/common/Executor.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
#include "common/Logger.h"
1111

1212
namespace cudaq {
13-
details::future
14-
Executor::execute(std::vector<KernelExecution> &codesToExecute) {
13+
details::future Executor::execute(std::vector<KernelExecution> &codesToExecute,
14+
bool isObserve) {
1515

1616
serverHelper->setShots(shots);
1717

@@ -53,7 +53,7 @@ Executor::execute(std::vector<KernelExecution> &codesToExecute) {
5353

5454
config.insert({"shots", std::to_string(shots)});
5555
std::string name = serverHelper->name();
56-
return details::future(ids, name, config);
56+
return details::future(ids, name, config, isObserve);
5757
}
5858
} // namespace cudaq
5959

runtime/common/Executor.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ class Executor : public registry::RegisteredType<Executor> {
4141

4242
/// @brief Execute the provided quantum codes and return a future object
4343
/// The caller can make this synchronous by just immediately calling .get().
44-
virtual details::future execute(std::vector<KernelExecution> &codesToExecute);
44+
virtual details::future execute(std::vector<KernelExecution> &codesToExecute,
45+
bool isObserve = false);
4546
};
4647

4748
} // namespace cudaq

runtime/common/Future.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ sample_result future::get() {
4141
}
4242
auto c = serverHelper->processResults(resultResponse, id.first);
4343

44-
// If there are multiple jobs, this is likely a spin_op.
45-
// If so, use the job name instead of the global register.
46-
if (jobs.size() > 1) {
44+
if (isObserve) {
45+
// Use the job name instead of the global register.
4746
results.emplace_back(c.to_map(), id.second);
4847
results.back().sequentialData = c.sequential_data();
4948
} else {
@@ -75,6 +74,7 @@ future &future::operator=(future &other) {
7574
jobs = other.jobs;
7675
qpuName = other.qpuName;
7776
serverConfig = other.serverConfig;
77+
isObserve = other.isObserve;
7878
if (other.wrapsFutureSampling) {
7979
wrapsFutureSampling = true;
8080
inFuture = std::move(other.inFuture);
@@ -86,6 +86,7 @@ future &future::operator=(future &&other) {
8686
jobs = other.jobs;
8787
qpuName = other.qpuName;
8888
serverConfig = other.serverConfig;
89+
isObserve = other.isObserve;
8990
if (other.wrapsFutureSampling) {
9091
wrapsFutureSampling = true;
9192
inFuture = std::move(other.inFuture);
@@ -102,6 +103,7 @@ std::ostream &operator<<(std::ostream &os, future &f) {
102103
j["jobs"] = f.jobs;
103104
j["qpu"] = f.qpuName;
104105
j["config"] = f.serverConfig;
106+
j["isObserve"] = f.isObserve;
105107
os << j.dump(4);
106108
return os;
107109
}
@@ -117,6 +119,7 @@ std::istream &operator>>(std::istream &is, future &f) {
117119
f.jobs = j["jobs"].get<std::vector<future::Job>>();
118120
f.qpuName = j["qpu"].get<std::string>();
119121
f.serverConfig = j["config"].get<std::map<std::string, std::string>>();
122+
f.isObserve = j["isObserve"].get<bool>();
120123
return is;
121124
}
122125

runtime/common/Future.h

+8
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class future {
4949
std::future<sample_result> inFuture;
5050
bool wrapsFutureSampling = false;
5151

52+
/// @brief Whether or not this is in support of an "observe" call
53+
bool isObserve = false;
54+
5255
public:
5356
/// @brief The constructor
5457
future() = default;
@@ -69,6 +72,11 @@ class future {
6972
std::map<std::string, std::string> &config)
7073
: jobs(_jobs), qpuName(qpuNameIn), serverConfig(config) {}
7174

75+
future(std::vector<Job> &_jobs, std::string &qpuNameIn,
76+
std::map<std::string, std::string> &config, bool isObserve)
77+
: jobs(_jobs), qpuName(qpuNameIn), serverConfig(config),
78+
isObserve(isObserve) {}
79+
7280
future &operator=(future &other);
7381
future &operator=(future &&other);
7482

runtime/cudaq/platform/default/rest/helpers/braket/BraketExecutor.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ void BraketExecutor::setOutputNames(const KernelExecution &codeToExecute,
173173
}
174174

175175
details::future
176-
BraketExecutor::execute(std::vector<KernelExecution> &codesToExecute) {
176+
BraketExecutor::execute(std::vector<KernelExecution> &codesToExecute,
177+
bool isObserve) {
177178
auto [dummy1, dummy2, messages] = checkHelperAndCreateJob(codesToExecute);
178179

179180
std::string const defaultBucket = defaultBucketFuture.get();

runtime/cudaq/platform/orca/OrcaExecutor.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ namespace cudaq {
1717
/// API.
1818
class OrcaExecutor : public Executor {
1919
public:
20-
details::future
21-
execute(std::vector<KernelExecution> &codesToExecute) override {
20+
details::future execute(std::vector<KernelExecution> &codesToExecute,
21+
bool isObserve) override {
2222
throw std::runtime_error(
2323
"ORCA backend does not support executing arbitrary kernels");
2424
}

0 commit comments

Comments
 (0)