@brief Run `cudaq::run_async` on the provided kernel.
| 151 | |
| 152 | /// @brief Run `cudaq::run_async` on the provided kernel. |
| 153 | static async_run_result |
| 154 | run_async_impl(const std::string &shortName, MlirModule module, |
| 155 | std::size_t shots_count, std::optional<noise_model> noise_model, |
| 156 | std::size_t qpu_id, nanobind::args runtimeArgs) { |
| 157 | auto &platform = get_platform(); |
| 158 | auto numQPUs = platform.num_qpus(); |
| 159 | if (qpu_id >= numQPUs) |
| 160 | throw std::runtime_error("qpu_id (" + std::to_string(qpu_id) + |
| 161 | ") exceeds the number of available QPUs (" + |
| 162 | std::to_string(numQPUs) + ")"); |
| 163 | |
| 164 | auto mod = unwrap(module); |
| 165 | // Set the `run` attribute on the module to indicate this is a run context |
| 166 | // (for result handling). |
| 167 | mod->setAttr(runtime::enableCudaqRun, mlir::UnitAttr::get(mod->getContext())); |
| 168 | if (noise_model.has_value() && platform.is_remote()) |
| 169 | throw std::runtime_error( |
| 170 | "Noise model is not supported on remote platforms."); |
| 171 | |
| 172 | async_run_result result; |
| 173 | result.results = std::make_unique<std::vector<nanobind::object>>(); |
| 174 | result.error = std::make_unique<std::string>(); |
| 175 | |
| 176 | if (shots_count == 0) { |
| 177 | std::promise<void> promise; |
| 178 | result.ready = promise.get_future(); |
| 179 | promise.set_value(); |
| 180 | return result; |
| 181 | } |
| 182 | |
| 183 | std::promise<detail::RunResultSpan> spanPromise; |
| 184 | auto spanFuture = spanPromise.get_future(); |
| 185 | |
| 186 | std::promise<std::string> errorPromise; |
| 187 | auto errorFuture = errorPromise.get_future(); |
| 188 | |
| 189 | auto fnOp = getFuncOpAndCheckResult(mod, shortName); |
| 190 | auto opaques = marshal_arguments_for_module_launch(mod, runtimeArgs, fnOp); |
| 191 | // Run the kernel and compute results span. |
| 192 | { |
| 193 | // Release GIL to allow c++ threads, all code inside the scope is c++, so |
| 194 | // there is no need to re-acquire the GIL inside the thread. |
| 195 | nanobind::gil_scoped_release gil_release{}; |
| 196 | QuantumTask wrapped = detail::make_copyable_function( |
| 197 | [sp = std::move(spanPromise), ep = std::move(errorPromise), |
| 198 | noise_model = std::move(noise_model), qpu_id, name = shortName, |
| 199 | opaques = std::move(opaques), shots_count, |
| 200 | mod = mod.clone()]() mutable { |
| 201 | auto &platform = get_platform(); |
| 202 | |
| 203 | // Launch the kernel in the appropriate context. |
| 204 | if (noise_model.has_value()) |
| 205 | platform.set_noise(&noise_model.value()); |
| 206 | try { |
| 207 | auto span = pyRunTheKernel(name, platform, mod, nullptr, |
| 208 | shots_count, qpu_id, opaques, false); |
| 209 | sp.set_value(span); |
| 210 | ep.set_value(""); |
nothing calls this directly
no test coverage detected