25template <
class Function,
class... Arguments>
26concept ConstDirectlyCallable =
requires(Function
const& function) { function(std::declval<Arguments>()...); };
28template <
class Function,
class... Arguments>
29using direct_call_result_t =
decltype(std::declval<Function const&>()(std::declval<Arguments>()...));
31template <
class Function, MdspanLike Span>
class unary_transform_accessor {
33 using function_type = Function;
34 using span_type = Span;
35 using wrapped_accessor_type =
typename span_type::accessor_type;
36 using data_handle_type =
typename span_type::data_handle_type;
37 using offset_type = span_offset_t<wrapped_accessor_type>;
38 using reference = direct_call_result_t<function_type, typename span_type::reference>;
39 using element_type = logical_value_t<remove_proxy_reference_t<reference>>
const;
40 using offset_policy = unary_transform_accessor;
42 template <
class FwdFunction>
44 : function_(
std::forward<FwdFunction>(function)), accessor_(
span.accessor())
48 offset_type
const& offset)
const -> data_handle_type
50 return accessor_.offset(
handle, offset);
54 offset_type
const& offset)
const -> reference
56 return function_(accessor_.access(
handle, offset));
60 [[no_unique_address]] function_type function_;
61 [[no_unique_address]] wrapped_accessor_type accessor_;
64template <
class Function, MdspanLike... Spans>
class transform_accessor {
66 static_assert(
sizeof...(Spans) >= 2);
68 using function_type = Function;
69 using accessor_tuple = std::tuple<
typename Spans::accessor_type...>;
70 using data_handle_type = std::tuple<
typename Spans::data_handle_type...>;
71 using offset_type = std::tuple<span_offset_t<typename Spans::accessor_type>...>;
72 using reference = direct_call_result_t<function_type,
typename Spans::reference...>;
73 using element_type = logical_value_t<remove_proxy_reference_t<reference>>
const;
74 using offset_policy = transform_accessor;
76 template <
class FwdFunction>
77 UNI20_HOST_DEVICE constexpr transform_accessor(FwdFunction&& function, Spans
const&... spans)
78 : function_(
std::forward<FwdFunction>(function)), accessors_(spans.accessor()...)
81 [[nodiscard]]
UNI20_HOST_DEVICE constexpr auto offset(data_handle_type
const& handles,
82 offset_type
const& offsets)
const -> data_handle_type
84 return offset_impl(handles, offsets, std::index_sequence_for<Spans...>{});
87 [[nodiscard]]
UNI20_HOST_DEVICE constexpr auto access(data_handle_type
const& handles,
88 offset_type
const& offsets)
const -> reference
90 return access_impl(handles, offsets, std::index_sequence_for<Spans...>{});
94 template <std::size_t... Index>
95 [[nodiscard]]
UNI20_HOST_DEVICE constexpr auto offset_impl(data_handle_type
const& handles,
96 offset_type
const& offsets,
97 std::index_sequence<Index...>)
const -> data_handle_type
99 return {std::get<Index>(accessors_).offset(std::get<Index>(handles), std::get<Index>(offsets))...};
102 template <std::size_t... Index>
103 [[nodiscard]]
UNI20_HOST_DEVICE constexpr auto access_impl(data_handle_type
const& handles,
104 offset_type
const& offsets,
105 std::index_sequence<Index...>)
const -> reference
107 return function_(std::get<Index>(accessors_).access(std::get<Index>(handles), std::get<Index>(offsets))...);
110 [[no_unique_address]] function_type function_;
111 [[no_unique_address]] accessor_tuple accessors_;
117template <
class Function, MdspanLike Span,
class Domain>
118inline constexpr bool enable_accessor_in_domain<detail::unary_transform_accessor<Function, Span>,
Domain> =
119 enable_accessor_in_domain<typename Span::accessor_type, Domain>;
122template <
class Function, MdspanLike... Spans>
124 (enable_accessor_in_domain<typename Spans::accessor_type, host_access_domain> && ...);
127template <
class Function, MdspanLike... Spans>
129 (enable_accessor_in_domain<typename Spans::accessor_type, cuda_access_domain> && ...);
132template <
class Function, MdspanLike Span>
133 requires detail::ConstDirectlyCallable<std::decay_t<Function>,
typename Span::reference>
136 using function_type = std::decay_t<Function>;
137 using accessor_type = detail::unary_transform_accessor<function_type, Span>;
138 using element_type =
typename accessor_type::element_type;
139 using extents_type =
typename Span::extents_type;
140 using layout_type =
typename Span::layout_type;
142 return stdex::mdspan<element_type, extents_type, layout_type, accessor_type>{
143 span.data_handle(),
span.mapping(), accessor_type(std::forward<Function>(function),
span)};
148template <
class Function, MdspanLike First, MdspanLike Second, MdspanLike... Rest>
149 requires detail::ConstDirectlyCallable<std::decay_t<Function>,
typename First::reference,
typename Second::reference,
150 typename Rest::reference...>
151[[nodiscard]]
constexpr auto transform_view(Function&& function, First
const& first, Second
const& second,
154 static_assert(First::rank() == Second::rank() && ((First::rank() == Rest::rank()) && ...));
156 using function_type = std::decay_t<Function>;
158 using layout_type =
zip_layout_t<First, Second, Rest...>;
159 using mapping_type =
typename layout_type::template mapping<extents_type>;
160 using accessor_type = detail::transform_accessor<function_type, First, Second, Rest...>;
161 using element_type =
typename accessor_type::element_type;
164 return stdex::mdspan<element_type, extents_type, layout_type, accessor_type>{
165 std::tuple{first.data_handle(), second.data_handle(), rest.data_handle()...},
166 mapping_type{extents, first.mapping(), second.mapping(), rest.mapping()...},
167 accessor_type(std::forward<Function>(function), first, second, rest...)};
Project compiler annotations shared by host and device code.
#define UNI20_HOST_DEVICE
Definition compiler_attributes.hpp:12
cuda::ResourceLease< HandleSlot > handle
Definition cublas/execution.cpp:33
Domain
MKL computation domains accepted by domain-specific thread controls.
Definition backend_mkl.hpp:35
auto make_common_extents(Spans... spans)
Build an extents object representing the common shape of the given spans.
Definition zip_layout.hpp:127
typename detail::common_extents< Spans... >::type common_extents_t
Convenience alias that represents the common extents of a set of mdspans.
Definition zip_layout.hpp:120
typename zip_layout_selector< Spans... >::type zip_layout_t
Alias to extract the chosen layout policy for the given spans.
Definition zip_layout.hpp:520
Mdspan concept and accessor extensions for Uni20.
Configured gateway to Uni20's mdspan implementation.
Definition async/async.hpp:26
constexpr auto transform_view(Function &&function, Span const &span)
Create a lazy read-only unary transform view while preserving the input mapping.
Definition transform_view.hpp:134
constexpr bool enable_accessor_in_domain
Opt-in customization for the execution domains supported by an accessor.
Definition mdspan/concepts.hpp:85
std::size_t span
Definition presentation.cpp:2017
Additional layout helpers and policies for zipped mdspan views.