15 #include <type_traits>
20 #ifdef __cpp_lib_concepts
21 template<
typename TMapping, Blob BlobType,
typename TAccessor>
23 template<
typename TMapping,
typename BlobType,
typename TAccessor>
29 template<
typename Allocator,
typename RecordDim>
31 = decltype(std::declval<Allocator>()(std::integral_constant<std::size_t, alignOf<RecordDim>>{}, 0));
33 template<
typename Allocator,
typename Mapping, std::size_t... Is>
35 const Allocator& alloc,
36 const Mapping& mapping,
37 std::integer_sequence<std::size_t, Is...>)
40 [[maybe_unused]] constexpr
auto alignment
41 = alignOf<typename Mapping::RecordDim>;
43 return {alloc(std::integral_constant<std::size_t, alignment>{}, mapping.blobSize(Is))...};
50 #ifdef __cpp_lib_concepts
51 template<
typename Mapping, BlobAllocator Allocator = bloballoc::Vector,
typename Accessor = accessor::Default>
53 template<
typename Mapping,
typename Allocator = bloballoc::Vector,
typename Accessor = accessor::Default>
57 const Allocator& alloc = {},
58 Accessor accessor = {})
61 return View<Mapping, internal::AllocatorBlobType<Allocator, typename Mapping::RecordDim>, Accessor>{
69 template<
typename Mapping,
typename RecordCoord,
typename =
void>
74 template<
typename Mapping,
typename RecordCoord>
76 : std::bool_constant<Mapping::isComputed(RecordCoord{})>
83 template<
typename Mapping,
typename RecordCoord>
89 template<
typename Mapping>
92 mp_bind_front<internal::IsComputed, Mapping>::template fn>::value;
95 template<
typename Mapping,
typename BlobType,
typename Accessor, std::size_t... RCs>
98 typename Mapping::ArrayExtents::Index ai,
104 using RefType = decltype(ref);
110 std::is_lvalue_reference_v<RefType> && !std::is_const_v<std::remove_reference_t<RefType>>)
112 new(&ref) FieldType{};
117 if constexpr(
sizeof...(RCs) == 0)
131 template<
typename Mapping,
typename BlobType,
typename Accessor>
139 { forEachLeafCoord<RecordDim>([&](auto rc) LLAMA_LAMBDA_INLINE { constructField(view, ai, rc); }); });
148 #ifdef __cpp_lib_concepts
149 template<
typename Mapping, BlobAllocator Allocator = bloballoc::Vector,
typename Accessor = accessor::Default>
151 template<
typename Mapping,
typename Allocator = bloballoc::Vector,
typename Accessor = accessor::Default>
154 -> View<Mapping, internal::AllocatorBlobType<Allocator, typename Mapping::RecordDim>, Accessor>
163 template<std::
size_t Dim,
typename RecordDim>
173 template<std::
size_t Dim,
typename RecordDim>
176 auto view = allocScalarViewUninitialized<Dim, RecordDim>();
182 template<
typename View,
typename BoundRecordCoord = RecordCoord<>,
bool OwnView = false>
187 template<
typename RecordDim>
193 inline constexpr
bool isOne =
false;
196 template<
typename View,
typename BoundRecordCoord>
197 inline constexpr
bool isOne<RecordRef<View, BoundRecordCoord, true>> =
true;
204 template<
typename View>
218 : arrayIndex(arrayIndex)
256 return (*view)(*arrayIndex);
308 assert(a.view == b.view);
309 return static_cast<std::ptrdiff_t
>(a.arrayIndex - b.arrayIndex);
315 assert(a.view == b.view);
316 return a.arrayIndex == b.arrayIndex;
328 assert(a.view == b.view);
329 return a.arrayIndex < b.arrayIndex;
358 template<
typename Mapping,
typename RecordCoord,
typename Blobs>
361 typename Mapping::ArrayExtents::Index ai,
363 Blobs& blobs) -> decltype(
auto)
365 if constexpr(llama::isComputed<Mapping, RecordCoord>)
366 return mapping.compute(ai, rc, blobs);
369 const auto [nr, offset] = mapping.blobNrAndOffset(ai, rc);
372 return reinterpret_cast<CopyConst<std::remove_reference_t<decltype(blobs[nr][offset])
>, Type>&>(
383 #ifdef __cpp_lib_concepts
384 template<
typename TMapping, Blob TBlobType,
typename TAccessor = accessor::Default>
386 template<
typename TMapping,
typename TBlobType,
typename TAccessor = accessor::Default>
392 , std::ranges::view_base
395 static_assert(!std::is_const_v<TMapping>);
410 std::is_same_v<
Mapping, std::decay_t<Mapping>>,
411 "Mapping must not be const qualified or a reference. Are you using decltype(...) as View template "
414 std::is_same_v<
ArrayExtents, std::decay_t<ArrayExtents>>,
415 "Mapping::ArrayExtents must not be const qualified or a reference. Are you using decltype(...) as "
417 "template argument?");
430 : Mapping(std::move(mapping))
431 , Accessor(std::move(accessor))
432 , m_blobs(std::move(blobs))
438 return static_cast<Mapping&
>(*this);
443 return static_cast<const Mapping&
>(*this);
448 return static_cast<Accessor&
>(*this);
453 return static_cast<const Accessor&
>(*this);
458 return mapping().extents();
461 #if !(defined(_MSC_VER) && defined(__NVCC__))
465 static_assert(!
sizeof(V),
"Passed ArrayIndex with SizeType different than Mapping::ArrayExtent");
472 if constexpr(isRecordDim<RecordDim>)
480 if constexpr(isRecordDim<RecordDim>)
490 std::enable_if_t<std::conjunction_v<std::is_convertible<Indices, size_type>...>,
int> = 0>
494 sizeof...(Indices) == ArrayIndex::rank,
495 "Please specify as many indices as you have array dimensions");
501 std::enable_if_t<std::conjunction_v<std::is_convertible<Indices, size_type>...>,
int> = 0>
505 sizeof...(Indices) == ArrayIndex::rank,
506 "Please specify as many indices as you have array dimensions");
522 #if !(defined(_MSC_VER) && defined(__NVCC__))
526 static_assert(!
sizeof(V),
"Passed ArrayIndex with SizeType different than Mapping::ArrayExtent");
533 return (*
this)(index);
538 return (*
this)(index);
576 template<
typename TView,
typename TBoundRecordCoord,
bool OwnView>
579 template<std::size_t... Coords>
582 return accessor()(
mapToMemory(mapping(), ai, rc, m_blobs));
585 template<std::size_t... Coords>
588 return accessor()(
mapToMemory(mapping(), ai, rc, m_blobs));
591 Array<BlobType, Mapping::blobCount> m_blobs;
595 #ifdef __cpp_lib_concepts
596 template<
typename View>
597 inline constexpr
auto isView = AnyView<View>;
599 template<
typename View>
604 template<
typename Mapping,
typename BlobType,
typename Accessor>
605 inline constexpr
auto isView<View<Mapping, BlobType, Accessor>> =
true;
612 template<
class T,
class U>
615 constexpr
bool is_adding_const = std::is_const_v<std::remove_reference_t<T>>;
616 if constexpr(std::is_lvalue_reference_v<T&&>)
618 if constexpr(is_adding_const)
619 return std::as_const(x);
621 return static_cast<U&
>(x);
625 if constexpr(is_adding_const)
626 return std::move(std::as_const(x));
633 template<
typename Blobs,
typename TransformBlobFunc, std::size_t... Is>
636 const TransformBlobFunc& transformBlob,
637 std::integer_sequence<std::size_t, Is...>)
639 return llama::Array{transformBlob(forward_like<Blobs>(blobs[Is]))...};
646 template<
typename ViewFwd,
typename TransformBlobFunc,
typename = std::enable_if_t<isView<std::decay_t<ViewFwd>>>>
649 using View = std::decay_t<ViewFwd>;
650 constexpr
auto blobCount = View::Mapping::blobCount;
653 internal::forward_like<ViewFwd>(view.blobs()),
655 std::make_index_sequence<blobCount>{});
668 typename NewBlobType = CopyConst<std::remove_reference_t<View>, std::byte>*,
669 typename = std::enable_if_t<isView<std::decay_t<View>>>>
672 if constexpr(std::is_same_v<
typename std::decay_t<View>::BlobType, NewBlobType>)
676 std::forward<View>(view),
680 return static_cast<NewBlobType
>(&blob[0]);
688 template<
typename NewAccessor,
typename ViewFwd,
typename = std::enable_if_t<isView<std::decay_t<ViewFwd>>>>
691 using OldView = std::decay_t<ViewFwd>;
692 return View<typename OldView::Mapping, typename OldView::BlobType, NewAccessor>{
693 internal::forward_like<ViewFwd>(view.mapping()),
694 internal::forward_like<ViewFwd>(view.blobs()),
695 std::move(newAccessor)};
701 template<
typename NewMapping,
typename ViewFwd,
typename = std::enable_if_t<isView<std::decay_t<ViewFwd>>>>
704 using OldView = std::decay_t<ViewFwd>;
705 static_assert(OldView::Mapping::blobCount == NewMapping::blobCount);
706 for(std::size_t i = 0; i < NewMapping::blobCount; i++)
708 assert(view.mapping().blobSize(i) == newMapping.blobSize(i));
711 return View<NewMapping, typename OldView::BlobType, typename OldView::Accessor>{
712 std::move(newMapping),
713 internal::forward_like<ViewFwd>(view.blobs()),
714 internal::forward_like<ViewFwd>(view.accessor())};
720 template<
typename TStoredParentView>
724 using ParentView = std::remove_const_t<std::remove_reference_t<StoredParentView>>;
745 template<
typename StoredParentViewFwd>
747 : parentView(std::forward<StoredParentViewFwd>(parentView))
754 return parentView.mapping();
759 return parentView.mapping();
764 return parentView.accessor();
769 return parentView.accessor();
774 return parentView.extents();
789 template<
typename... Indices>
793 sizeof...(Indices) == ArrayIndex::rank,
794 "Please specify as many indices as you have array dimensions");
796 std::conjunction_v<std::is_convertible<Indices, size_type>...>,
797 "Indices must be convertible to ArrayExtents::size_type");
802 template<
typename... Indices>
806 sizeof...(Indices) == ArrayIndex::rank,
807 "Please specify as many indices as you have array dimensions");
809 std::conjunction_v<std::is_convertible<Indices, size_type>...>,
810 "Indices must be convertible to ArrayExtents::size_type");
815 template<std::size_t... Coords>
821 template<std::size_t... Coords>
832 return parentView.blobs();
837 return parentView.blobs();
848 template<
typename TStoredParentView>
849 SubView(TStoredParentView&&,
typename std::remove_reference_t<TStoredParentView>::Mapping::ArrayExtents::Index)
#define LLAMA_DECLSPEC_EMPTY_BASES
#define LLAMA_LAMBDA_INLINE
Gives strong indication to the compiler to inline the attributed lambda.
#define LLAMA_BEGIN_SUPPRESS_HOST_DEVICE_WARNING
#define LLAMA_FN_HOST_ACC_INLINE
#define LLAMA_END_SUPPRESS_HOST_DEVICE_WARNING
auto makeBlobArray(const Allocator &alloc, const Mapping &mapping, std::integer_sequence< std::size_t, Is... >) -> Array< AllocatorBlobType< Allocator, typename Mapping::RecordDim >, Mapping::blobCount >
decltype(std::declval< Allocator >()(std::integral_constant< std::size_t, alignOf< RecordDim > >{}, 0)) AllocatorBlobType
auto makeTransformedBlobArray(Blobs &&blobs, const TransformBlobFunc &transformBlob, std::integer_sequence< std::size_t, Is... >)
constexpr auto && forward_like(U &&x) noexcept
void constructField(View< Mapping, BlobType, Accessor > &view, typename Mapping::ArrayExtents::Index ai, RecordCoord< RCs... > rc)
constexpr bool isProxyReference
SubView(TStoredParentView &&, typename std::remove_reference_t< TStoredParentView >::Mapping::ArrayExtents::Index) -> SubView< TStoredParentView >
ArrayIndex(Args...) -> ArrayIndex< typename internal::IndexTypeFromArgs< std::size_t, Args... >::type, sizeof...(Args)>
constexpr bool hasAnyComputedField
Returns true if any field accessed via the given mapping is a computed value.
auto transformBlobs(ViewFwd &&view, const TransformBlobFunc &transformBlob)
auto allocViewUninitialized(Mapping mapping={}, const Allocator &alloc={}, Accessor accessor={})
Same as allocView but does not run field constructors.
void forEachArrayIndex([[maybe_unused]] const ArrayIndex< SizeType, Dim > &extents, Func &&func, OuterIndices... outerIndices)
auto allocScalarView() -> decltype(auto)
ArrayExtents(Args...) -> ArrayExtents< typename internal::IndexTypeFromArgs< std::size_t, Args... >::type,(Args{}, dyn)... >
auto shallowCopy(View &&view)
auto withAccessor(ViewFwd &&view, NewAccessor newAccessor={})
auto withMapping(ViewFwd &&view, NewMapping newMapping={})
auto allocView(Mapping mapping={}, const Allocator &alloc={}, Accessor accessor={}) -> View< Mapping, internal::AllocatorBlobType< Allocator, typename Mapping::RecordDim >, Accessor >
constexpr bool isComputed
Returns true if the field accessed via the given mapping and record coordinate is a computed value.
std::conditional_t< std::is_const_v< FromT >, const ToT, ToT > CopyConst
Alias for ToT, adding const if FromT is const qualified.
typename internal::LeafRecordCoordsImpl< RecordDim, RecordCoord<> >::type LeafRecordCoords
Returns a flat type list containing all record coordinates to all leaves of the given record dimensio...
auto allocScalarViewUninitialized() -> decltype(auto)
Same as allocScalarView but does not run field constructors.
typename internal::GetTypeImpl< RecordDim, RecordCoordOrTags... >::type GetType
auto mapToMemory(Mapping &mapping, typename Mapping::ArrayExtents::Index ai, RecordCoord rc, Blobs &blobs) -> decltype(auto)
constexpr bool isOne
Is true, if T is an instance of One.
void constructFields(View< Mapping, BlobType, Accessor > &view)
std::ptrdiff_t difference_type
Range allowing to iterate over all indices in an ArrayExtents.
constexpr auto end() const noexcept -> ArrayIndexIterator< ArrayExtents >
constexpr auto begin() const noexcept -> ArrayIndexIterator< ArrayExtents >
constexpr friend auto operator<=(const Iterator &a, const Iterator &b) -> bool
constexpr auto operator-=(difference_type n) -> Iterator &
constexpr friend auto operator-(Iterator it, difference_type n) -> Iterator
typename ArrayIndexIterator::difference_type difference_type
constexpr auto operator[](difference_type i) const -> reference
constexpr friend auto operator>=(const Iterator &a, const Iterator &b) -> bool
constexpr friend auto operator+(difference_type n, Iterator it) -> Iterator
constexpr friend auto operator!=(const Iterator &a, const Iterator &b) -> bool
constexpr friend auto operator>(const Iterator &a, const Iterator &b) -> bool
constexpr auto operator++(int) -> Iterator
constexpr Iterator(ArrayIndexIterator arrayIndex, View *view)
constexpr auto operator--() -> Iterator &
constexpr friend auto operator==(const Iterator &a, const Iterator &b) -> bool
std::random_access_iterator_tag iterator_category
constexpr friend auto operator+(Iterator it, difference_type n) -> Iterator
constexpr auto operator+=(difference_type n) -> Iterator &
constexpr auto operator->() const -> pointer
constexpr friend auto operator<(const Iterator &a, const Iterator &b) -> bool
constexpr auto operator*() const -> reference
constexpr friend auto operator-(const Iterator &a, const Iterator &b) -> difference_type
constexpr auto operator++() -> Iterator &
constexpr auto operator--(int) -> Iterator
constexpr Iterator()=default
ArrayIndexIterator arrayIndex
StoredParentView parentView
auto mapping() const -> const Mapping &
auto blobs() const -> const Array< BlobType, Mapping::blobCount > &
auto accessor() const -> const Accessor &
auto mapping() -> Mapping &
typename ParentView::ArrayIndex ArrayIndex
typename ParentView::ArrayExtents ArrayExtents
auto operator()(ArrayIndex ai) -> decltype(auto)
auto operator()(RecordCoord< Coords... > rc={}) -> decltype(auto)
typename ParentView::RecordDim RecordDim
auto operator()(ArrayIndex ai) const -> decltype(auto)
Same as View::operator()(ArrayIndex), but shifted by the offset of this SubView.
std::remove_const_t< std::remove_reference_t< StoredParentView > > ParentView
type of the parent view
typename ParentView::iterator iterator
auto operator()(RecordCoord< Coords... > rc={}) const -> decltype(auto)
auto operator()(Indices... indices) const -> decltype(auto)
Same as corresponding operator in View, but shifted by the offset of this SubView.
auto accessor() -> Accessor &
typename ParentView::Accessor Accessor
SubView(ArrayIndex offset)
Creates a SubView given an offset. The parent view is default constructed.
auto operator()(Indices... indices) -> decltype(auto)
typename ParentView::BlobType BlobType
auto blobs() -> Array< BlobType, Mapping::blobCount > &
typename ParentView::Mapping Mapping
typename ParentView::const_iterator const_iterator
SubView(StoredParentViewFwd &&parentView, ArrayIndex offset)
Creates a SubView given a parent View and offset.
auto extents() const -> ArrayExtents
TStoredParentView StoredParentView
auto mapping() -> Mapping &
typename ArrayExtents::Index ArrayIndex
typename Mapping::RecordDim RecordDim
auto operator[](ArrayIndex ai) const -> decltype(auto)
auto mapping() const -> const Mapping &
typename Mapping::ArrayExtents ArrayExtents
View(Mapping mapping, Array< BlobType, Mapping::blobCount > blobs={}, Accessor accessor={})
auto blobs() -> Array< BlobType, Mapping::blobCount > &
auto blobs() const -> const Array< BlobType, Mapping::blobCount > &
auto operator[](ArrayIndex ai) -> decltype(auto)
auto operator[](llama::ArrayIndex< V, ArrayIndex::rank >) const
auto operator()(Indices... indices) -> decltype(auto)
auto begin() const -> const_iterator
auto operator()(ArrayIndex ai) const -> decltype(auto)
Retrieves the RecordRef at the given ArrayIndex index.
auto operator()(ArrayIndex ai) -> decltype(auto)
auto accessor() const -> const Accessor &
auto end() const -> const_iterator
auto accessor() -> Accessor &
auto operator()(Indices... indices) const -> decltype(auto)
View()=default
Performs default initialization of the blob array.
auto operator[](size_type index) -> decltype(auto)
auto extents() const -> ArrayExtents
auto operator[](size_type index) const -> decltype(auto)
Retrieves the RecordRef at the 1D ArrayIndex index constructed from the passed index.
auto operator()(llama::ArrayIndex< V, ArrayIndex::rank >) const