29namespace detail::cuda_reference
32template <
class Mdspec>
using conjugate_scalar_t = std::remove_cv_t<typename std::remove_cvref_t<Mdspec>::element_type>;
34template <
class Mdspec>
37 (uni20::has_trivial_conj<conjugate_scalar_t<Mdspec>> ||
39 supports_elementwise_conjugate<conjugate_scalar_t<Mdspec>>));
41template <
class Scalar>
struct ConjugatePlan
45 std::size_t element_offset = 0;
46 std::size_t required_span_size = 0;
47 LoweredElementwiseConjugatePlan elementwise_plan;
48 bool has_work =
false;
51template <uni20::MdspecLike Mdspec>
53[[nodiscard]]
bool try_make_elementwise_conjugate_plan(Mdspec
const& mdspec, LoweredElementwiseConjugatePlan& plan)
56 return try_lower_strided_elementwise_plan<elementwise_conjugate_maximum_rank>(host_plan, plan);
59template <
class Mdspec>
60 requires SupportedConjugateMdspec<Mdspec>
61[[nodiscard]]
auto prepare_conjugate_inplace(Mdspec& mdspec)
63 using scalar_type = conjugate_scalar_t<Mdspec>;
64 ConjugatePlan<scalar_type> plan;
66 if constexpr (uni20::has_trivial_conj<scalar_type>)
75 if (!mdspec.mapping().is_unique() || !try_make_elementwise_conjugate_plan(mdspec, plan.elementwise_plan))
81 plan.has_work = plan.elementwise_plan.element_count() != 0;
88 auto const required = mdspec.mapping().required_span_size();
89 if (std::cmp_less(required, 0) || std::cmp_greater(required, std::numeric_limits<std::size_t>::max()))
94 plan.required_span_size =
static_cast<std::size_t
>(required);
96 auto descriptor = mdspec.data_descriptor();
97 plan.buffer = std::addressof(descriptor.buffer());
98 plan.element_offset = descriptor.element_offset();
99 CHECK(plan.element_offset <= plan.buffer->size() &&
100 plan.required_span_size <= plan.buffer->size() - plan.element_offset,
101 plan.element_offset, plan.required_span_size, plan.buffer->size());
108template <
class Scalar>
void execute_conjugate_inplace(ConjugatePlan<Scalar>
const& plan)
111 if (!plan.has_work)
return;
112 CHECK(plan.buffer !=
nullptr);
114 auto stream = plan.buffer->resources().streams().acquire();
115 int const device = plan.buffer->device().ordinal();
118 auto access = plan.buffer->write_synchronized_with(stream);
119 auto* output = access.data() + plan.element_offset;
121 if constexpr (supports_elementwise_conjugate<Scalar>)
123 plan.elementwise_plan.visit([&](
auto const& elementwise_plan) {
124 enqueue_elementwise_conjugate(output, elementwise_plan,
stream.native_handle(), device);
129 PANIC(
"unsupported scalar reached CUDA reference elementwise conjugation");
134template <uni20::MutableMdspecLike Mdspec>
consteval auto conjugate_acceptance()
136 if constexpr (SupportedConjugateMdspec<Mdspec>)
143template <
class Mdspec>
144 requires SupportedConjugateMdspec<Mdspec>
147 auto preparation = prepare_conjugate_inplace(mdspec);
149 execute_conjugate_inplace(preparation);
156template <uni20::MutableMdspecLike Mdspec>
159 constexpr auto acceptance = detail::cuda_reference::conjugate_acceptance<Mdspec>();
167template <
class Mdspec>
168 requires detail::cuda_reference::SupportedConjugateMdspec<Mdspec>
171 return detail::cuda_reference::conjugate_inplace(
mdspec);
Typed CUDA device buffers and scoped stream access guards.
Move-only logical CUDA buffer and completion state.
Definition buffer.hpp:222
Temporarily select one CUDA device and restore the previous device on destruction.
Definition runtime.hpp:44
Store a data descriptor with the mapping and accessor for an eventual mdspan.
Definition mdspec.hpp:31
MdspecLike types whose eventual storage supports writes.
Definition mdspan/concepts.hpp:398
Concept for numeric scalar types (integer, real, or complex).
Definition scalar_concepts.hpp:81
An mdspec-like type whose mapping exposes multidimensional strides.
Definition mdspan/concepts.hpp:427
CUDA Tensor storage with deferred device-memory data descriptors.
Operation-tag backend dispatch over tensor-view operands.
Typed launch boundary for CUDA accessor-respecting in-place conjugation.
auto make_multi_iteration_plan(std::tuple< Mappings... > const &mappings)
Build a merged iteration plan for multiple tensors sharing the same extents.
Definition iteration_plan.hpp:263
Helpers for constructing merged iteration plans over strided tensors.
Scalar math helper utilities.
Mdspan concept and accessor extensions for Uni20.
Shared CUDA reference-backend traits for raw buffer mdspecs.
stream
Selects the ordinary display stream for a message.
Definition display.hpp:25
Definition linalg/async.hpp:28
constexpr bool kernel_attempt_succeeded(KernelAttempt attempt) noexcept
Return whether a backend performed the operation.
Definition kernel_attempt.hpp:40
KernelAttempt try_kernel(BlasBackend, gemm_op const &, C &c, S const &alpha, A &a, B &b, S const &beta)
Pack logical host values and execute GEMM through value-preserving provider conversion.
Definition linalg/backends/blas/binary80.hpp:30
KernelAttempt
Result of one runtime kernel backend attempt.
Definition kernel_attempt.hpp:27
constexpr KernelAcceptance< KernelTypeAcceptance::no > kernel_types_no
Report that a backend rejects the argument types.
Definition dispatch_error.hpp:34
consteval auto kernel_accepts_types(BlasBackend, gemm_op const &, C &, S const &, A &, B &, S const &)
Accept host-readable native binary80 operands, including transforming accessors.
Definition linalg/backends/blas/binary80.hpp:19
constexpr KernelAcceptance< KernelTypeAcceptance::maybe > kernel_types_maybe
Report that runtime operand values determine backend acceptance.
Definition dispatch_error.hpp:37
void conjugate_inplace(BackendSelector selector, async::Async< Tensor > &tensor)
Schedule eager in-place conjugation through an explicit selector.
Definition linalg/async/conjugate_inplace.hpp:44
Backend value for generic CUDA runtime kernels and transfers.
Definition backend_selector.hpp:48
Accessor-respecting in-place scalar conjugation operation tag.
Definition operation_tags.hpp:39
#define CHECK(cond,...)
Definition trace.hpp:299
#define PANIC(...)
Definition trace.hpp:382
#define CHECK_EQUAL(a, b,...)
Definition trace.hpp:309