29 ElementType*
data =
nullptr;
38 template <
class OtherElementType>
39 requires std::convertible_to<OtherElementType*, ElementType*>
55 static_assert(!std::is_const_v<ElementType>);
62 return element_ ==
nullptr ? ElementType{} : *element_;
67 if (element_ ==
nullptr)
69 assert(
value == ElementType{});
78 return *
this =
static_cast<ElementType
>(other);
82 ElementType* element_ =
nullptr;
125 auto const component_offset =
static_cast<index_type>(diagonal_index.index) * component_stride_;
126 if constexpr (std::is_const_v<element_type>)
128 return diagonal_index.present ?
handle.data[component_offset] :
value_type{};
132 return reference{diagonal_index.present ?
handle.data + component_offset :
nullptr};
150 return component_stride_;
157 return this->diagonal_index(
handle.base_offset +
offset);
162 diagonal_index(std::size_t linear)
const noexcept -> component_index_result
164 if constexpr (extents_type::rank() == 0)
170 std::array<
index_type, extents_type::rank()> indices{};
171 for (std::size_t axis = extents_type::rank(); axis > 0; --axis)
173 auto const extent =
static_cast<std::size_t
>(extents_.extent(axis - 1));
174 indices[axis - 1] =
static_cast<index_type>(linear % extent);
177 auto const first = indices[0];
178 for (std::size_t axis = 1; axis < extents_type::rank(); ++axis)
179 if (indices[axis] != first)
return {.present =
false};
180 return {.index =
static_cast<std::size_t
>(first), .present =
true};
189template <
class ElementType,
class Extents>
190 requires(!std::is_const_v<ElementType>)
197template <
class ElementType,
class Extents>
198 requires std::is_const_v<ElementType>
205template <
class ElementType,
class Extents>
206inline constexpr bool enable_accessor_in_domain<diagonal_accessor<ElementType, Extents>,
host_access_domain> =
true;
211template <
class Extents>
212[[nodiscard]]
UNI20_HOST_DEVICE constexpr auto diagonal_component_extent(Extents
const& extents)
noexcept ->
213 typename Extents::index_type
215 using index_type =
typename Extents::index_type;
216 if constexpr (Extents::rank() == 0)
223 for (std::size_t axis = 1; axis < Extents::rank(); ++axis)
224 if (extents.extent(axis) < result) result = extents.extent(axis);
229template <
class Mapping, std::size_t... Axis>
230[[nodiscard]]
constexpr auto diagonal_mapping_step(Mapping
const& mapping, std::index_sequence<Axis...>)
232 using index_type =
typename Mapping::extents_type::index_type;
250template <
class ElementType,
class Extents,
class LayoutPolicy,
class AccessorExtents>
251 requires(Extents::rank() == AccessorExtents::rank())
255 using index_type =
typename Extents::index_type;
256 using component_extents_type = stdex::dextents<index_type, 1>;
257 using component_mapping_type = stdex::layout_stride::mapping<component_extents_type>;
258 using component_mdspan_type = stdex::mdspan<ElementType, component_extents_type, stdex::layout_stride>;
259 auto const extents = component_extents_type{detail::diagonal_component_extent(
span.extents())};
261 auto* data =
span.data_handle().data;
262 if (extents.extent(0) > 0)
264 auto const origin =
span.accessor().component_index(
span.data_handle());
266 throw std::invalid_argument(
"diagonal component view does not begin on the represented diagonal");
267 data +=
static_cast<index_type>(origin.index) * component_stride;
268 if (extents.extent(0) > 1)
270 auto const step = detail::diagonal_mapping_step(
span.mapping(), std::make_index_sequence<Extents::rank()>{});
271 if constexpr (std::signed_integral<std::remove_cv_t<
decltype(step)>>)
272 if (step < 0)
throw std::invalid_argument(
"diagonal component view has a negative logical step");
273 auto const next =
span.accessor().component_index(
span.data_handle(),
static_cast<std::size_t
>(step));
274 if (!next.present || next.index < origin.index)
275 throw std::invalid_argument(
"diagonal component view does not preserve the represented diagonal");
276 component_stride *=
static_cast<index_type>(next.index - origin.index);
279 auto const mapping = component_mapping_type{extents, std::array<index_type, 1>{component_stride}};
280 return component_mdspan_type{data, mapping};
293template <
class Extents,
class Components>
294 requires RankedStridedMdspanLike<Components, 1> && DefaultAccessorMdspanLike<Components>
297 using component_type = std::remove_cvref_t<Components>;
298 using element_type =
typename component_type::element_type;
299 using index_type =
typename Extents::index_type;
300 if (
static_cast<index_type>(components.extent(0)) != detail::diagonal_component_extent(logical_extents))
302 throw std::invalid_argument(
"diagonal component extent does not match the logical tensor extents");
305 using result_type = stdex::mdspan<element_type, Extents, GeneratedLayout, accessor_type>;
306 return result_type{
typename accessor_type::data_handle_type{components.data_handle(), 0},
307 typename result_type::mapping_type{logical_extents},
308 accessor_type{std::move(logical_extents),
static_cast<index_type>(components.stride(0))}};
Mdspan accessor over a compressed rank-N generalized diagonal.
Definition diagonal_accessor.hpp:92
ElementType element_type
Definition diagonal_accessor.hpp:95
UNI20_HOST_DEVICE constexpr auto component_index(data_handle_type handle, offset_type offset=0) const noexcept -> component_index_result
Decode whether a logical offset addresses a stored component and which one.
Definition diagonal_accessor.hpp:155
UNI20_HOST_DEVICE constexpr auto extents() const noexcept -> extents_type const &
Return the extents used to decode logical offsets.
Definition diagonal_accessor.hpp:145
UNI20_HOST_DEVICE constexpr auto component_stride() const noexcept -> index_type
Return the physical offset between consecutive diagonal components.
Definition diagonal_accessor.hpp:148
UNI20_HOST_DEVICE constexpr reference access(data_handle_type handle, offset_type offset) const
Read or write the logical element represented by an encoded offset.
Definition diagonal_accessor.hpp:122
UNI20_HOST_DEVICE constexpr diagonal_accessor()=default
UNI20_HOST_DEVICE constexpr data_handle_type offset(data_handle_type handle, offset_type offset) const noexcept
Advance a logical handle without changing its original index space.
Definition diagonal_accessor.hpp:137
std::remove_cv_t< ElementType > value_type
Definition diagonal_accessor.hpp:94
typename extents_type::index_type index_type
Definition diagonal_accessor.hpp:101
std::conditional_t< std::is_const_v< element_type >, value_type, diagonal_reference< value_type > > reference
Definition diagonal_accessor.hpp:96
Extents extents_type
Definition diagonal_accessor.hpp:100
std::size_t offset_type
Definition diagonal_accessor.hpp:99
Writable proxy for one structural diagonal or off-diagonal element.
Definition diagonal_accessor.hpp:53
UNI20_HOST_DEVICE constexpr diagonal_reference() noexcept=default
UNI20_HOST_DEVICE constexpr auto operator=(ElementType const &value) noexcept -> diagonal_reference &
Definition diagonal_accessor.hpp:65
UNI20_HOST_DEVICE constexpr auto operator=(diagonal_reference const &other) noexcept -> diagonal_reference &
Definition diagonal_accessor.hpp:76
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
locale_t value
Definition data_table.cpp:49
Synthetic mdspan layout for values generated from logical indices.
constexpr stdex::default_accessor< T const > const_accessor(stdex::default_accessor< T > const &accessor_policy)
Wrap a default_accessor<T> into a const_default_accessor<T>.
Definition mdspan/concepts.hpp:160
Mdspan concept and accessor extensions for Uni20.
Definition async/async.hpp:26
std::ptrdiff_t index_type
Definition types.hpp:19
constexpr auto diagonal_components(stdex::mdspan< ElementType, Extents, LayoutPolicy, diagonal_accessor< ElementType, AccessorExtents > > const &span)
Expose the physically stored values of a generalized-diagonal mdspan.
Definition diagonal_accessor.hpp:252
constexpr auto make_diagonal_mdspan(Extents logical_extents, Components const &components)
Present rank-one strided components as a full generalized-diagonal mdspan.
Definition diagonal_accessor.hpp:295
std::size_t span
Definition presentation.cpp:2017
Decoded component coordinate for one logical mapping offset.
Definition diagonal_accessor.hpp:105
std::size_t index
Definition diagonal_accessor.hpp:106
bool present
Definition diagonal_accessor.hpp:107
Handle for one compressed generalized diagonal value sequence.
Definition diagonal_accessor.hpp:28
std::size_t base_offset
Definition diagonal_accessor.hpp:30
friend UNI20_HOST_DEVICE constexpr bool operator==(diagonal_data_handle const &, diagonal_data_handle const &)=default
ElementType * data
Definition diagonal_accessor.hpp:29
UNI20_HOST_DEVICE constexpr diagonal_data_handle() noexcept=default
UNI20_HOST_DEVICE constexpr diagonal_data_handle(diagonal_data_handle< OtherElementType > const &other) noexcept
Definition diagonal_accessor.hpp:40
Execution domain in which ordinary host code may evaluate an accessor.
Definition mdspan/concepts.hpp:74
ElementType type
Definition diagonal_accessor.hpp:314
Trait for extracting the element type from a proxy reference.
Definition types.hpp:102