Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[on hold] Support for sub arrays of dynamic size (jagged arrays) #305

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
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
8 changes: 5 additions & 3 deletions examples/bufferguard/bufferguard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,11 @@ struct GuardMapping2D : llama::ArrayExtentsDynamic<2>
std::abort();
}

template<std::size_t... RecordCoords>
constexpr auto blobNrAndOffset(ArrayIndex ai, llama::RecordCoord<RecordCoords...> rc = {}) const
-> llama::NrAndOffset
template<std::size_t... RecordCoords, std::size_t N = 0>
constexpr auto blobNrAndOffset(
ArrayIndex ai,
llama::Array<std::size_t, N> = {},
llama::RecordCoord<RecordCoords...> rc = {}) const -> llama::NrAndOffset
{
// [0][0] is at left top
const auto [row, col] = ai;
Expand Down
2 changes: 1 addition & 1 deletion include/llama/Concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace llama
{ m.blobSize(std::size_t{}) } -> std::same_as<std::size_t>;
{ m.blobNrAndOffset(typename M::ArrayIndex{}) } -> std::same_as<NrAndOffset>;
{ m.template blobNrAndOffset<0>(typename M::ArrayIndex{}) } -> std::same_as<NrAndOffset>;
{ m.blobNrAndOffset(typename M::ArrayIndex{}, llama::RecordCoord<0>{}) } -> std::same_as<NrAndOffset>;
{ m.blobNrAndOffset(typename M::ArrayIndex{}, {}, llama::RecordCoord<0>{}) } -> std::same_as<NrAndOffset>;
};
// clang-format on

Expand Down
53 changes: 53 additions & 0 deletions include/llama/Core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ namespace llama
template<typename T>
inline constexpr bool isAllowedFieldType = std::is_trivially_destructible_v<T>;

template<typename... Fields>
inline constexpr bool isAllowedFieldType<Record<Fields...>> = true;

template<typename T, std::size_t N>
inline constexpr bool isAllowedFieldType<T[N]> = isAllowedFieldType<T>;

template<typename T>
inline constexpr bool isAllowedFieldType<T[]> = isAllowedFieldType<T>;

/// Record dimension tree node which may either be a leaf or refer to a child tree presented as another \ref
/// Record.
/// \tparam Tag Name of the node. May be any type (struct, class).
Expand Down Expand Up @@ -101,6 +110,14 @@ namespace llama
= boost::mp11::mp_push_front<typename GetTagsImpl<ChildType, RecordCoord<Coords...>>::type, ChildTag>;
};

template<typename ChildType, std::size_t... Coords>
struct GetTagsImpl<ChildType[], RecordCoord<dynamic, Coords...>>
{
using ChildTag = RecordCoord<dynamic>;
using type
= boost::mp11::mp_push_front<typename GetTagsImpl<ChildType, RecordCoord<Coords...>>::type, ChildTag>;
};

template<typename T>
struct GetTagsImpl<T, RecordCoord<>>
{
Expand Down Expand Up @@ -198,6 +215,16 @@ namespace llama
typename GetCoordFromTagsImpl<ChildType, RecordCoord<ResultCoords..., FirstTag::front>, Tags...>::type;
};

template<typename ChildType, std::size_t... ResultCoords, typename FirstTag, typename... Tags>
struct GetCoordFromTagsImpl<ChildType[], RecordCoord<ResultCoords...>, FirstTag, Tags...>
{
static_assert(
std::is_same_v<FirstTag, RecordCoord<dynamic>>,
"Please use a RecordCoord<dynamic> to index into dynamic arrays");
using type =
typename GetCoordFromTagsImpl<ChildType, RecordCoord<ResultCoords..., FirstTag::front>, Tags...>::type;
};

template<typename RecordDim, typename RecordCoord>
struct GetCoordFromTagsImpl<RecordDim, RecordCoord>
{
Expand Down Expand Up @@ -242,6 +269,13 @@ namespace llama
using type = typename GetTypeImpl<ChildType, RecordCoord<TailCoords...>>::type;
};

template<typename ChildType, std::size_t HeadCoord, std::size_t... TailCoords>
struct GetTypeImpl<ChildType[], RecordCoord<HeadCoord, TailCoords...>>
{
static_assert(HeadCoord == dynamic, "Record coord at a dynamic array must be llama::dynamic");
using type = typename GetTypeImpl<ChildType, RecordCoord<TailCoords...>>::type;
};

template<typename T>
struct GetTypeImpl<T, RecordCoord<>>
{
Expand Down Expand Up @@ -289,6 +323,12 @@ namespace llama
}
using type = decltype(help(std::make_index_sequence<N>{}));
};

template<typename Child, std::size_t... RCs>
struct LeafRecordCoordsImpl<Child[], RecordCoord<RCs...>>
{
using type = typename LeafRecordCoordsImpl<Child, RecordCoord<RCs..., dynamic>>::type;
};
} // namespace internal

/// Returns a flat type list containing all record coordinates to all leaves of the given record dimension.
Expand Down Expand Up @@ -557,6 +597,19 @@ namespace llama
struct IsBoundedArray<T[N]> : std::true_type
{
};

template<class T>
struct is_unbounded_array : std::false_type
{
};

template<class T>
struct is_unbounded_array<T[]> : std::true_type
{
};

template<typename T>
inline constexpr bool is_unbounded_array_v = is_unbounded_array<T>::value;
} // namespace internal

namespace internal
Expand Down
22 changes: 21 additions & 1 deletion include/llama/DumpMapping.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "ArrayIndexRange.hpp"
#include "Core.hpp"
#include "mapping/OffsetTable.hpp"

#include <boost/functional/hash.hpp>
#include <fmt/format.h>
Expand Down Expand Up @@ -75,14 +76,33 @@ namespace llama
{ai,
internal::toVec(rc),
recordCoordTags<RecordDim>(rc),
mapping.blobNrAndOffset(ai, rc),
mapping.blobNrAndOffset(ai, {}, rc),
sizeof(GetType<RecordDim, decltype(rc)>)});
});
}

return infos;
}

template<typename ArrayExtents, typename RecordDim, typename SubMappings>
auto boxesFromMapping(const mapping::OffsetTable<ArrayExtents, RecordDim, SubMappings>& mapping)
-> std::vector<FieldBox<ArrayExtents::rank>>
{
std::size_t previousBlobs = 0;
std::vector<FieldBox<ArrayExtents::rank>> infos;
boost::mp11::mp_for_each<boost::mp11::mp_iota<boost::mp11::mp_size<decltype(mapping.subMappings)>>>(
[&](auto ic)
{
const auto& subMapping = get<decltype(ic)::value>(mapping.subMappings);
auto subBoxes = boxesFromMapping(subMapping);
for(auto& box : subBoxes)
box.nrAndOffset.nr += previousBlobs;
infos.insert(infos.end(), subBoxes.begin(), subBoxes.end());
previousBlobs += std::decay_t<decltype(subMapping)>::blobCount;
});
return infos;
}

template<std::size_t Dim>
auto breakBoxes(std::vector<FieldBox<Dim>> boxes, std::size_t wrapByteCount) -> std::vector<FieldBox<Dim>>
{
Expand Down
6 changes: 4 additions & 2 deletions include/llama/Proofs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ namespace llama
{
using Type
= GetType<typename Mapping::RecordDim, decltype(rc)>;
const auto [blob, offset] = m.blobNrAndOffset(ai, rc);
const auto [blob, offset]
= m.blobNrAndOffset(ai, {}, rc);
for(std::size_t b = 0; b < sizeof(Type); b++)
if(testAndSet(blob, offset + b))
{
Expand Down Expand Up @@ -105,7 +106,8 @@ namespace llama
{
using Type
= GetType<typename Mapping::RecordDim, decltype(rc)>;
const auto [blob, offset] = m.blobNrAndOffset(ai, rc);
const auto [blob, offset]
= m.blobNrAndOffset(ai, {}, rc);
if(flatIndex % PieceLength != 0
&& (lastBlob != blob
|| lastOffset + sizeof(Type) != offset))
Expand Down
3 changes: 3 additions & 0 deletions include/llama/RecordCoord.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
#include "Meta.hpp"

#include <array>
#include <limits>
#include <ostream>
#include <type_traits>

namespace llama
{
inline constexpr auto dynamic = std::numeric_limits<std::size_t>::max();

/// Represents a coordinate for a record inside the record dimension tree.
/// \tparam Coords... the compile time coordinate.
template<std::size_t... Coords>
Expand Down
28 changes: 17 additions & 11 deletions include/llama/View.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,12 +342,12 @@ namespace llama
if constexpr(isRecord<RecordDim> || internal::IsBoundedArray<RecordDim>::value)
{
LLAMA_FORCE_INLINE_RECURSIVE
return VirtualRecord<const View>{ai, *this};
return VirtualRecord<const View>{*this, ai};
}
else
{
LLAMA_FORCE_INLINE_RECURSIVE
return accessor(ai, RecordCoord<>{});
return accessor(ai, Array<size_t, 0>{}, RecordCoord<>{});
}
}

Expand All @@ -356,12 +356,12 @@ namespace llama
if constexpr(isRecord<RecordDim> || internal::IsBoundedArray<RecordDim>::value)
{
LLAMA_FORCE_INLINE_RECURSIVE
return VirtualRecord<View>{ai, *this};
return VirtualRecord<View>{*this, ai};
}
else
{
LLAMA_FORCE_INLINE_RECURSIVE
return accessor(ai, RecordCoord<>{});
return accessor(ai, Array<size_t, 0>{}, RecordCoord<>{});
}
}

Expand Down Expand Up @@ -451,28 +451,34 @@ namespace llama
friend struct VirtualRecord;

LLAMA_SUPPRESS_HOST_DEVICE_WARNING
template<std::size_t... Coords>
LLAMA_FN_HOST_ACC_INLINE auto accessor(ArrayIndex ai, RecordCoord<Coords...> rc = {}) const -> decltype(auto)
template<std::size_t N, std::size_t... Coords>
LLAMA_FN_HOST_ACC_INLINE auto accessor(
ArrayIndex ai,
Array<size_t, N> dynamicArrayExtents,
RecordCoord<Coords...> rc = {}) const -> decltype(auto)
{
if constexpr(llama::isComputed<Mapping, RecordCoord<Coords...>>)
return mapping().compute(ai, rc, storageBlobs);
else
{
const auto [nr, offset] = mapping().blobNrAndOffset(ai, rc);
const auto [nr, offset] = mapping().blobNrAndOffset(ai, dynamicArrayExtents, rc);
using Type = GetType<RecordDim, RecordCoord<Coords...>>;
return reinterpret_cast<const Type&>(storageBlobs[nr][offset]);
}
}

LLAMA_SUPPRESS_HOST_DEVICE_WARNING
template<std::size_t... Coords>
LLAMA_FN_HOST_ACC_INLINE auto accessor(ArrayIndex ai, RecordCoord<Coords...> rc = {}) -> decltype(auto)
template<std::size_t N, std::size_t... Coords>
LLAMA_FN_HOST_ACC_INLINE auto accessor(
ArrayIndex ai,
Array<size_t, N> dynamicArrayExtents,
RecordCoord<Coords...> rc = {}) -> decltype(auto)
{
if constexpr(llama::isComputed<Mapping, RecordCoord<Coords...>>)
return mapping().compute(ai, rc, storageBlobs);
return mapping().compute(ai, dynamicArrayExtents, rc, storageBlobs);
else
{
const auto [nr, offset] = mapping().blobNrAndOffset(ai, rc);
const auto [nr, offset] = mapping().blobNrAndOffset(ai, dynamicArrayExtents, rc);
using Type = GetType<RecordDim, RecordCoord<Coords...>>;
using QualifiedType = std::conditional_t<
std::is_const_v<std::remove_reference_t<decltype(storageBlobs[nr][offset])>>,
Expand Down
Loading