| 13 | #include "cudaq/simulators.h" |
| 14 | |
| 15 | cudaq::detail::RunResultSpan cudaq::detail::runTheKernel( |
| 16 | std::function<void()> &&kernel, quantum_platform &platform, |
| 17 | const std::string &kernel_name, const std::string &original_name, |
| 18 | std::size_t shots, |
| 19 | const cudaq_internal::compiler::LayoutInfoType &layoutInfo, |
| 20 | std::size_t qpu_id, bool allowCaching) { |
| 21 | ScopedTraceWithContext(cudaq::TIMING_RUN, "runTheKernel"); |
| 22 | // 1. Clear the outputLog. |
| 23 | auto *circuitSimulator = nvqir::getCircuitSimulatorInternal(); |
| 24 | circuitSimulator->outputLog.clear(); |
| 25 | |
| 26 | // Some platforms do not support run yet, emit error. |
| 27 | if (!platform.get_codegen_config().outputLog) |
| 28 | throw std::runtime_error("`run` is not yet supported on this target."); |
| 29 | |
| 30 | // 2. Launch the kernel on the QPU. |
| 31 | if (platform.is_remote() || platform.is_emulated()) { |
| 32 | // In a remote simulator execution or hardware emulation environment, set |
| 33 | // the `run` context name and number of iterations (shots) |
| 34 | cudaq::ExecutionContext ctx("run", shots, qpu_id); |
| 35 | ctx.allowCompiledModuleCaching = allowCaching; |
| 36 | // Launch the kernel a single time to post the 'run' request to the remote |
| 37 | // server or emulation executor. |
| 38 | platform.with_execution_context(ctx, std::move(kernel)); |
| 39 | // Retrieve the result output log. |
| 40 | // FIXME: this currently assumes all the shots are good. |
| 41 | std::string remoteOutputLog(ctx.invocationResultBuffer.begin(), |
| 42 | ctx.invocationResultBuffer.end()); |
| 43 | circuitSimulator->outputLog.swap(remoteOutputLog); |
| 44 | } else { |
| 45 | cudaq::ExecutionContext ctx("run", 1, qpu_id); |
| 46 | ctx.allowCompiledModuleCaching = allowCaching; |
| 47 | for (std::size_t i = 0; i < shots; ++i) { |
| 48 | // Set the execution context since as noise model is attached to this |
| 49 | // context. |
| 50 | platform.with_execution_context(ctx, std::move(kernel)); |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | // 3. Pass the outputLog to the parser (target-specific?) |
| 55 | cudaq::RecordLogParser parser(layoutInfo); |
| 56 | parser.parse(circuitSimulator->outputLog); |
| 57 | |
| 58 | // 4. Get the buffer and length of buffer (in bytes) from the parser. |
| 59 | auto *origBuffer = parser.getBufferPtr(); |
| 60 | std::size_t bufferSize = parser.getBufferSize(); |
| 61 | char *buffer = static_cast<char *>(malloc(bufferSize)); |
| 62 | std::memcpy(buffer, origBuffer, bufferSize); |
| 63 | |
| 64 | // 5. Clear the outputLog (?) |
| 65 | circuitSimulator->outputLog.clear(); |
| 66 | |
| 67 | // 6. Pass the span back as a RunResultSpan. NB: it is the responsibility of |
| 68 | // the caller to free the buffer. |
| 69 | return {buffer, bufferSize}; |
| 70 | } |
nothing calls this directly
no test coverage detected