Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions runtime/cudaq/qis/qubit_qis.h
Original file line number Diff line number Diff line change
Expand Up @@ -1276,11 +1276,28 @@ template <typename... Args>
constexpr bool any_float = std::disjunction_v<
std::is_floating_point<std::remove_cv_t<std::remove_reference_t<Args>>>...>;

#if CUDAQ_USE_STD20
#ifdef CUDAQ_REMOTE_SIM
#define TARGET_OK_FOR_APPLY_NOISE false
#else
#define TARGET_OK_FOR_APPLY_NOISE true
#endif
#else
#ifdef CUDAQ_REMOTE_SIM
#define TARGET_OK_FOR_APPLY_NOISE \
typename = std::enable_if_t<std::is_same_v<T, int>>
#else
#define TARGET_OK_FOR_APPLY_NOISE \
typename = std::enable_if_t<std::is_same_v<T, T>>
#endif
#endif

#if CUDAQ_USE_STD20
template <typename T, typename... Q>
requires(std::derived_from<T, cudaq::kraus_channel> && !any_float<Q...>)
requires(std::derived_from<T, cudaq::kraus_channel> && !any_float<Q...> &&
TARGET_OK_FOR_APPLY_NOISE)
#else
template <typename T, typename... Q,
template <typename T, typename... Q, TARGET_OK_FOR_APPLY_NOISE,
typename = std::enable_if_t<
std::is_base_of_v<cudaq::kraus_channel, T> &&
std::is_convertible_v<const volatile T *,
Expand Down Expand Up @@ -1338,22 +1355,22 @@ constexpr bool any_vector_of_float = std::disjunction_v<std::is_same<
std::vector<double>, std::remove_cv_t<std::remove_reference_t<Args>>>...>;

#if CUDAQ_USE_STD20
template <typename KrausChannelT, typename... Args>
requires(std::derived_from<KrausChannelT, cudaq::kraus_channel> &&
!any_vector_of_float<Args...>)
template <typename T, typename... Args>
requires(std::derived_from<T, cudaq::kraus_channel> &&
!any_vector_of_float<Args...> && TARGET_OK_FOR_APPLY_NOISE)
#else
template <typename KrausChannelT, typename... Args,
template <typename T, typename... Args, TARGET_OK_FOR_APPLY_NOISE,
typename = std::enable_if_t<
std::is_base_of_v<cudaq::kraus_channel, KrausChannelT> &&
std::is_convertible_v<const volatile KrausChannelT *,
std::is_base_of_v<cudaq::kraus_channel, T> &&
std::is_convertible_v<const volatile T *,
const volatile cudaq::kraus_channel *> &&
!any_vector_of_float<Args...>>>
#endif
void apply_noise(Args &&...args) {
constexpr auto ctor_arity = count_leading_floats<0, Args...>();
constexpr auto qubit_arity = sizeof...(args) - ctor_arity;

details::applyNoiseImpl<KrausChannelT>(
details::applyNoiseImpl<T>(
details::tuple_slice<ctor_arity>(std::forward_as_tuple(args...)),
details::tuple_slice_last<qubit_arity>(std::forward_as_tuple(args...)));
}
Expand Down
27 changes: 27 additions & 0 deletions test/AST-error/apply_noise.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2022 - 2025 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: cudaq-quake %cpp_std -verify -D CUDAQ_REMOTE_SIM=1 %s

#include <cudaq.h>

struct SantaKraus : public cudaq::kraus_channel {
constexpr static std::size_t num_parameters = 0;
constexpr static std::size_t num_targets = 2;
static std::size_t get_key() { return (std::size_t)&get_key; }
SantaKraus() {}
};

struct testApplyNoise {
void operator()() __qpu__ {
cudaq::qubit q0, q1;
// expected-error@+1{{no matching function for call to 'apply_noise'}}
cudaq::apply_noise<SantaKraus>(q0, q1);
// expected-note@* 2-3 {{}}
}
};
3 changes: 2 additions & 1 deletion test/AST-error/negation_error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
struct NegationOperatorTest {
void operator()() __qpu__ {
cudaq::qvector qr(3);
x<cudaq::ctrl>(qr[0], qr[1], !qr[2]); // expected-error{{target qubit cannot be negated}}
// expected-error@+1{{target qubit cannot be negated}}
x<cudaq::ctrl>(qr[0], qr[1], !qr[2]);
rz(2.0, !qr[0]); // expected-error{{target qubit cannot be negated}}
}
};
Loading