Skip to content

Commit

Permalink
C++17 fallback. (#973)
Browse files Browse the repository at this point in the history
These changes modify the CUDAQ headers such that they can be compiled by
a C++ compiler in C++17 mode.

Simplify the diffs in observe.h, sample.h

Fix #971. Do perfect forwarding into the lambda captures instead of
passing references. This is required for asynchronous calls.

Augment the tests in NVQPP to use the -std=c++17 command line option.
Not all of these will execute the resulting c++17 executable in order
to keep the test time down.
  • Loading branch information
schweitzpgi authored Dec 5, 2023
1 parent 4ca0bc1 commit 4343201
Show file tree
Hide file tree
Showing 71 changed files with 1,050 additions and 345 deletions.
2 changes: 1 addition & 1 deletion runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ install (FILES nvqir/CircuitSimulator.h
nvqir/QIRTypes.h
nvqir/Gates.h
DESTINATION include/nvqir)
install (FILES cudaq.h DESTINATION include)
install (FILES cudaq.h host_config.h DESTINATION include)
18 changes: 15 additions & 3 deletions runtime/cudaq.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

#include "common/NoiseModel.h"
#include "cudaq/qis/qubit_qis.h"

#include "host_config.h"
#include <string>
#include <type_traits>

Expand Down Expand Up @@ -118,9 +118,16 @@ std::string get_kernel_template_function_name(const std::string &funcName) {

/// These get_quake overloads can be used for introspection, to look up the
/// Quake IR for a specific kernel by providing an instance of the kernel, etc.
#if CUDAQ_USE_STD20
template <typename MemberArg0, typename... MemberArgs, typename QuantumKernel,
std::enable_if_t<std::is_class_v<std::remove_cvref_t<QuantumKernel>>,
bool> = true>
#else
template <typename MemberArg0, typename... MemberArgs, typename QuantumKernel,
std::enable_if_t<std::is_class_v<std::remove_cv_t<
std::remove_reference_t<QuantumKernel>>>,
bool> = true>
#endif
std::string get_quake(QuantumKernel &&kernel) {
// See comment below.
if (__internal__::globalFalse) {
Expand All @@ -135,9 +142,16 @@ std::string get_quake(QuantumKernel &&kernel) {
MemberArgs...>());
}

#if CUDAQ_USE_STD20
template <typename QuantumKernel,
std::enable_if_t<std::is_class_v<std::remove_cvref_t<QuantumKernel>>,
bool> = true>
#else
template <typename QuantumKernel,
std::enable_if_t<std::is_class_v<std::remove_cv_t<
std::remove_reference_t<QuantumKernel>>>,
bool> = true>
#endif
std::string get_quake(QuantumKernel &&kernel) {
if constexpr (hasToQuakeMethod<QuantumKernel>::value) {
return kernel.to_quake();
Expand Down Expand Up @@ -172,8 +186,6 @@ inline std::string get_quake(std::string &&functionName) {
typedef std::size_t (*KernelArgsCreator)(void **, void **);
KernelArgsCreator getArgsCreator(const std::string &kernelName);

/// @brief
/// @return
bool kernelHasConditionalFeedback(const std::string &kernelName);

/// @brief Provide a hook to set the target backend.
Expand Down
36 changes: 23 additions & 13 deletions runtime/cudaq/algorithms/broadcast.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@
#pragma once

#include "cudaq/platform.h"
#include "host_config.h"

namespace cudaq {

void set_random_seed(std::size_t);
std::size_t get_random_seed();

/// @brief An ArgumentSet is a tuple of vectors of general
/// arguments to a CUDA Quantum kernel. The ith vector of the tuple
/// corresponds to the ith argument of the kernel. The jth element of
/// the ith vector corresponds to the jth batch of arguments to evaluate
/// the kernel at.
/// @brief An ArgumentSet is a tuple of vectors of general arguments to a CUDA
/// Quantum kernel. The `i-th` vector of the tuple corresponds to the `i-th`
/// argument of the kernel. The `j-th` element of the `i-th` vector corresponds
/// to the `j-th` batch of arguments to evaluate the kernel at.
template <typename... Args>
using ArgumentSet = std::tuple<std::vector<Args>...>;

/// @brief Create a new ArgumentSet from a variadic list of
/// vectors of general args.
/// @brief Create a new ArgumentSet from a variadic list of vectors of general
/// arguments.
template <typename... Args>
auto make_argset(const std::vector<Args> &...args) {
return std::make_tuple(args...);
Expand All @@ -35,9 +35,9 @@ template <typename ReturnType, typename... Args>
using BroadcastFunctorType = const std::function<ReturnType(
std::size_t, std::size_t, std::size_t, Args &...)>;

/// @brief Given the input BroadcastFunctorType, apply it to all
/// argument sets in the provided ArgumentSet `params`. Distribute the
/// work over the provided number of QPUs.
/// @brief Given the input BroadcastFunctorType, apply it to all argument sets
/// in the provided ArgumentSet `params`. Distribute the work over the provided
/// number of QPUs.
template <typename ResType, typename... Args>
std::vector<ResType>
broadcastFunctionOverArguments(std::size_t numQpus, quantum_platform &platform,
Expand Down Expand Up @@ -97,9 +97,19 @@ broadcastFunctionOverArguments(std::size_t numQpus, quantum_platform &platform,

// Fill the argument tuple with the actual arguments.
cudaq::tuple_for_each_with_idx(
params, [&]<typename IDX_TYPE>(auto &&element, IDX_TYPE &&idx) {
params,
#if CUDAQ_USE_STD20
[&]<typename IDX_TYPE>(auto &&element, IDX_TYPE &&idx) {
std::get<IDX_TYPE::value + 3>(currentArgs) = element[i];
});
}
#else
[&](auto &&element, auto &&idx) {
std::get<std::remove_cv_t<
std::remove_reference_t<decltype(idx)>>::value +
3>(currentArgs) = element[i];
}
#endif
);

// Call observe/sample with the current set of arguments
// (provided as a tuple)
Expand All @@ -126,4 +136,4 @@ broadcastFunctionOverArguments(std::size_t numQpus, quantum_platform &platform,
return allResults;
}
} // namespace details
} // namespace cudaq
} // namespace cudaq
Loading

0 comments on commit 4343201

Please sign in to comment.