Skip to content

Commit

Permalink
implement support for sub arrays of dynamic size
Browse files Browse the repository at this point in the history
  • Loading branch information
bernhardmgruber committed Jun 29, 2021
1 parent efeaec3 commit dd45ecc
Show file tree
Hide file tree
Showing 19 changed files with 720 additions and 70 deletions.
4 changes: 2 additions & 2 deletions examples/bufferguard/bufferguard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ struct GuardMapping2D
std::abort();
}

template <std::size_t... RecordCoords>
constexpr auto blobNrAndOffset(ArrayDims coord) const -> llama::NrAndOffset
template <std::size_t... RecordCoords, std::size_t N = 0>
constexpr auto blobNrAndOffset(ArrayDims coord, llama::Array<std::size_t, N> = {}) const -> llama::NrAndOffset
{
// [0][0] is at left top
const auto [row, col] = coord;
Expand Down
47 changes: 47 additions & 0 deletions include/llama/Core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ namespace llama
inline constexpr bool isAllowedFieldType
= std::is_trivially_constructible_v<T>&& 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 @@ -134,6 +143,14 @@ namespace llama
mp_push_front<typename GetTagsImpl<ChildTag, ChildType, RecordCoord<Coords...>>::type, CurrTag>;
};

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

template <typename CurrTag, typename T>
struct GetTagsImpl<CurrTag, T, RecordCoord<>>
{
Expand Down Expand Up @@ -212,6 +229,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 @@ -244,6 +271,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 @@ -565,5 +599,18 @@ namespace llama
struct is_bounded_array<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 llama
3 changes: 3 additions & 0 deletions include/llama/RecordCoord.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@

#include <array>
#include <boost/mp11.hpp>
#include <limits>
#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
37 changes: 19 additions & 18 deletions include/llama/Tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,25 @@ namespace llama
constexpr Tuple() = default;

LLAMA_FN_HOST_ACC_INLINE
constexpr Tuple(FirstElement first, Elements... rest) : first(first), rest(rest...)
constexpr Tuple(FirstElement first, Elements... rest) : first(std::move(first)), rest(std::move(rest)...)
{
}

LLAMA_FN_HOST_ACC_INLINE
constexpr Tuple(FirstElement first, Tuple<Elements...> rest) : first(first), rest(rest)
/// Converting constructor
template <typename T, typename... Ts>
LLAMA_FN_HOST_ACC_INLINE constexpr Tuple(T firstArg, Ts... restArgs)
: first(std::forward<T>(firstArg))
, rest(std::forward<Ts>(restArgs)...)
{
}

FirstElement first; ///< the first element (if existing)
RestTuple rest; ///< the remaining elements
};

template <typename T_FirstElement>
struct Tuple<T_FirstElement>
{
using FirstElement = T_FirstElement;
using RestTuple = Tuple<>;

constexpr Tuple() = default;

LLAMA_FN_HOST_ACC_INLINE
constexpr Tuple(FirstElement const first, Tuple<> const rest = Tuple<>()) : first(first)
constexpr Tuple(FirstElement first, Tuple<Elements...> rest) : first(std::move(first)), rest(std::move(rest))
{
}

FirstElement first;
FirstElement first; ///< the first element (if existing)
[[no_unique_address]] RestTuple rest; ///< the remaining elements
};

template <typename... Elements>
Expand All @@ -63,7 +55,16 @@ namespace llama
using TupleElement = boost::mp11::mp_at_c<Tuple, Pos>;

template <std::size_t Pos, typename... Elements>
LLAMA_FN_HOST_ACC_INLINE auto get(const Tuple<Elements...>& tuple)
LLAMA_FN_HOST_ACC_INLINE auto get(Tuple<Elements...>& tuple) -> auto&
{
if constexpr (Pos == 0)
return tuple.first;
else
return get<Pos - 1>(tuple.rest);
}

template <std::size_t Pos, typename... Elements>
LLAMA_FN_HOST_ACC_INLINE auto get(const Tuple<Elements...>& tuple) -> const auto&
{
if constexpr (Pos == 0)
return tuple.first;
Expand Down
29 changes: 17 additions & 12 deletions include/llama/View.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,12 @@ namespace llama
if constexpr (isRecord<RecordDim> || internal::is_bounded_array<RecordDim>::value)
{
LLAMA_FORCE_INLINE_RECURSIVE
return VirtualRecordTypeConst{arrayDims, *this};
return VirtualRecordTypeConst{*this, arrayDims};
}
else
{
LLAMA_FORCE_INLINE_RECURSIVE
return accessor(arrayDims, RecordCoord<>{});
return accessor(arrayDims, Array<size_t, 0>{}, RecordCoord<>{});
}
}

Expand All @@ -271,12 +271,12 @@ namespace llama
if constexpr (isRecord<RecordDim> || internal::is_bounded_array<RecordDim>::value)
{
LLAMA_FORCE_INLINE_RECURSIVE
return VirtualRecordType{arrayDims, *this};
return VirtualRecordType{*this, arrayDims};
}
else
{
LLAMA_FORCE_INLINE_RECURSIVE
return accessor(arrayDims, RecordCoord<>{});
return accessor(arrayDims, Array<size_t, 0>{}, RecordCoord<>{});
}
}

Expand Down Expand Up @@ -367,29 +367,34 @@ namespace llama
friend struct VirtualRecord;

LLAMA_SUPPRESS_HOST_DEVICE_WARNING
template <std::size_t... Coords>
LLAMA_FN_HOST_ACC_INLINE auto accessor(ArrayDims arrayDims, RecordCoord<Coords...> dc = {}) const
-> decltype(auto)
template <std::size_t N, std::size_t... Coords>
LLAMA_FN_HOST_ACC_INLINE auto accessor(
ArrayDims arrayDims,
Array<size_t, N> dynamicArrayExtents,
RecordCoord<Coords...> dc = {}) const -> decltype(auto)
{
if constexpr (internal::isComputed<Mapping, RecordCoord<Coords...>>::value)
return mapping.compute(arrayDims, dc, storageBlobs);
else
{
const auto [nr, offset] = mapping.template blobNrAndOffset<Coords...>(arrayDims);
const auto [nr, offset] = mapping.template blobNrAndOffset<Coords...>(arrayDims, dynamicArrayExtents);
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(ArrayDims arrayDims, RecordCoord<Coords...> dc = {}) -> decltype(auto)
template <std::size_t N, std::size_t... Coords>
LLAMA_FN_HOST_ACC_INLINE auto accessor(
ArrayDims arrayDims,
Array<size_t, N> dynamicArrayExtents,
RecordCoord<Coords...> dc = {}) -> decltype(auto)
{
if constexpr (internal::isComputed<Mapping, RecordCoord<Coords...>>::value)
return mapping.compute(arrayDims, dc, storageBlobs);
return mapping.compute(arrayDims, dynamicArrayExtents, dc, storageBlobs);
else
{
const auto [nr, offset] = mapping.template blobNrAndOffset<Coords...>(arrayDims);
const auto [nr, offset] = mapping.template blobNrAndOffset<Coords...>(arrayDims, dynamicArrayExtents);
using Type = GetType<RecordDim, RecordCoord<Coords...>>;
return reinterpret_cast<Type&>(storageBlobs[nr][offset]);
}
Expand Down
Loading

0 comments on commit dd45ecc

Please sign in to comment.