diff --git a/runtime/common/ThunkInterface.h b/runtime/common/ThunkInterface.h new file mode 100644 index 00000000000..05aeec37a3c --- /dev/null +++ b/runtime/common/ThunkInterface.h @@ -0,0 +1,44 @@ +/****************************************************************-*- C++ -*-**** + * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * + * All rights reserved. * + * * + * This source code and the accompanying materials are made available under * + * the terms of the Apache License 2.0 which accompanies this distribution. * + ******************************************************************************/ + +#pragma once + +#include + +namespace cudaq { + +/// A kernel may return results dynamically if the size of the result is not a +/// constant at compile-time. +struct KernelThunkResultType { + void *data_buffer; ///< Pointer to the first element of an array. + std::uint64_t size; ///< The size of the buffer in bytes. +}; + +/// The universal signature of a kernel thunk. +using KernelThunkType = KernelThunkResultType (*)(void *, bool); + +/// The degenerate form of a kernel call. In some launch cases, it may be +/// predetermined that the kernel can be called without a thunk. +using KernelDegenerateType = void (*)(void *); + +/// In some cases, the launcher will bypass the thunk function and call a +/// degenerate stub. That means that the extra `bool` argument will be ignored +/// by the called kernel and the kernel will not return a dynamic result. +/// +/// This is a terrible idea, generally speaking. However, if the launcher +/// neither looks for nor attempts to use the second `bool` argument at all, and +/// the launcher will drop any results returned from the kernel (regardless of +/// type) on the floor anyway, then one may be able to get away with using a +/// degenerate kernel type. +inline KernelDegenerateType +make_degenerate_kernel_type(KernelThunkType func_type) { + return reinterpret_cast( + reinterpret_cast(func_type)); +} + +} // namespace cudaq diff --git a/targettests/execution/vector_result.cpp b/targettests/execution/vector_result.cpp new file mode 100644 index 00000000000..ecc09fce5cd --- /dev/null +++ b/targettests/execution/vector_result.cpp @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. * + * All rights reserved. * + * * + * This source code and the accompanying materials are made available under * + * the terms of the Apache License 2.0 which accompanies this distribution. * + ******************************************************************************/ + +// RUN: nvq++ %cpp_std --enable-mlir %s -o %t && %t + +#include "cudaq.h" +#include + +struct VectorBoolResult { + std::vector operator()() __qpu__ { + std::vector result(3); + result[0] = true; + result[1] = false; + result[2] = true; + return result; + } +}; + +struct VectorIntResult { + std::vector operator()() __qpu__ { + std::vector result(2); + result[0] = 42; + result[1] = -23479; + return result; + } +}; + +struct VectorDoubleResult { + std::vector operator()() __qpu__ { + std::vector result(2); + result[0] = 543.0; + result[1] = -234234.0; + return result; + } +}; + +int main() { + auto retb{VectorBoolResult{}()}; + printf("%d %d %d\n", static_cast(retb[0]), static_cast(retb[1]), + static_cast(retb[2])); + auto ret = VectorIntResult{}(); + printf("%d %d\n", ret[0], ret[1]); + std::vector retd{VectorDoubleResult{}()}; + printf("%f %f\n", retd[0], retd[1]); + return !(retb[0] && !retb[1] && retb[2] && ret[0] == 42 && ret[1] == -23479 && + retd[0] == 543.0 && retd[1] == -234234.0); +}