Skip to content

Commit

Permalink
use custom implementation of aligned sizeOf<> and offsetOf<>
Browse files Browse the repository at this point in the history
  • Loading branch information
bernhardmgruber committed Mar 2, 2021
1 parent e593867 commit 9a284db
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 19 deletions.
56 changes: 43 additions & 13 deletions include/llama/Core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,14 @@ namespace llama
namespace internal
{
template <typename T, std::size_t... Coords, typename Functor>
LLAMA_FN_HOST_ACC_INLINE constexpr void forEachLeaveImpl(T, DatumCoord<Coords...> coord, Functor&& functor)
LLAMA_FN_HOST_ACC_INLINE constexpr void forEachLeaveImpl(T*, DatumCoord<Coords...> coord, Functor&& functor)
{
functor(coord);
};

template <typename... Children, std::size_t... Coords, typename Functor>
LLAMA_FN_HOST_ACC_INLINE constexpr void forEachLeaveImpl(
DatumStruct<Children...>,
DatumStruct<Children...>*,
DatumCoord<Coords...>,
Functor&& functor)
{
Expand All @@ -290,7 +290,7 @@ namespace llama

LLAMA_FORCE_INLINE_RECURSIVE
forEachLeaveImpl(
GetDatumElementType<DatumElement>{},
static_cast<GetDatumElementType<DatumElement>*>(nullptr),
llama::DatumCoord<Coords..., childIndex>{},
std::forward<Functor>(functor));
});
Expand All @@ -308,7 +308,7 @@ namespace llama
{
LLAMA_FORCE_INLINE_RECURSIVE
internal::forEachLeaveImpl(
GetType<DatumDomain, DatumCoord<Coords...>>{},
static_cast<GetType<DatumDomain, DatumCoord<Coords...>>*>(nullptr),
baseCoord,
std::forward<Functor>(functor));
}
Expand Down Expand Up @@ -357,17 +357,39 @@ namespace llama
}
();

namespace internal
{
constexpr void roundUpToMultiple(std::size_t& value, std::size_t multiple)
{
value = ((value + multiple - 1) / multiple) * multiple;
}
} // namespace internal

template <typename T, bool Align = false>
static constexpr auto sizeOf = sizeof(T);
inline constexpr std::size_t sizeOf = sizeof(T);

/// The size a datum domain if it would be a normal struct.
template <typename... DatumElements, bool Align>
static constexpr auto sizeOf<DatumStruct<DatumElements...>, Align> = []() constexpr
inline constexpr std::size_t sizeOf<DatumStruct<DatumElements...>, Align> = []() constexpr
{
if constexpr (Align)
return sizeof(boost::mp11::mp_rename<
boost::mp11::mp_reverse<FlattenDatumDomain<DatumStruct<DatumElements...>>>,
std::tuple>{});
{
using namespace boost::mp11;

std::size_t size;
size = 0; // if we join this assignment with the previous line, MSVC crashes :(
using FlatDD = FlattenDatumDomain<DatumStruct<DatumElements...>>;
mp_for_each<mp_iota<mp_size<FlatDD>>>([&](auto i) constexpr {
using T = mp_at<FlatDD, decltype(i)>;
internal::roundUpToMultiple(size, alignof(T));
size += sizeof(T);
});

// final padding, so next struct can start right away
using FirstType = mp_first<FlatDD>;
internal::roundUpToMultiple(size, alignof(FirstType));
return size;
}
else
return (sizeOf<GetDatumElementType<DatumElements>, Align> + ...);
}
Expand Down Expand Up @@ -404,11 +426,19 @@ namespace llama
{
if constexpr (Align)
{
using namespace boost::mp11;

constexpr auto i = flatDatumCoord<DatumDomain, DatumCoord>;
using Tuple = boost::mp11::mp_rename<boost::mp11::mp_reverse<FlattenDatumDomain<DatumDomain>>, std::tuple>;
constexpr auto n = boost::mp11::mp_size<Tuple>::value;
Tuple t;
return (std::intptr_t) std::addressof(std::get<n - 1 - i>(t)) - (std::intptr_t) std::addressof(t);

std::size_t offset = 0;
using FlatDD = FlattenDatumDomain<DatumDomain>;
mp_for_each<mp_iota_c<i>>([&](auto i) constexpr {
using T = mp_at<FlatDD, decltype(i)>;
internal::roundUpToMultiple(offset, alignof(T));
offset += sizeof(T);
});
internal::roundUpToMultiple(offset, alignof(boost::mp11::mp_at_c<FlatDD, i>));
return offset;
}
else
return internal::offsetOfImpl<Align>((DatumDomain*) nullptr, DatumCoord{});
Expand Down
20 changes: 14 additions & 6 deletions tests/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ namespace tag
struct Weight {};
}

using XYZ = llama::DS<
llama::DE<tag::X, double>,
llama::DE<tag::Y, double>,
llama::DE<tag::Z, double>
>;
using Particle = llama::DS<
llama::DE<tag::Pos, llama::DS<
llama::DE<tag::X, double>,
llama::DE<tag::Y, double>,
llama::DE<tag::Z, double>
>>,
llama::DE<tag::Pos, XYZ>,
llama::DE<tag::Weight, float>,
llama::DE<llama::NoName, int>,
llama::DE<tag::Vel,llama::DS<
Expand Down Expand Up @@ -117,11 +118,15 @@ TEST_CASE("prettyPrintType")

TEST_CASE("sizeOf")
{
STATIC_REQUIRE(llama::sizeOf<float> == 4);
STATIC_REQUIRE(llama::sizeOf<XYZ> == 24);
STATIC_REQUIRE(llama::sizeOf<Particle> == 52);
}

TEST_CASE("sizeOf.Align")
{
STATIC_REQUIRE(llama::sizeOf<float, true> == 4);
STATIC_REQUIRE(llama::sizeOf<XYZ, true> == 24);
STATIC_REQUIRE(llama::sizeOf<Particle, true> == 56);
}

Expand Down Expand Up @@ -163,6 +168,9 @@ TEST_CASE("offsetOf.Align")
STATIC_REQUIRE(llama::offsetOf<Particle, llama::DatumCoord<4, 3>, true> == 51);
}

template <int i>
struct S;

TEST_CASE("alignment")
{
using DD = llama::DS<
Expand All @@ -183,7 +191,7 @@ TEST_CASE("alignment")
STATIC_REQUIRE(llama::offsetOf<DD, llama::DatumCoord<1>, true> == 8); // aligned
STATIC_REQUIRE(llama::offsetOf<DD, llama::DatumCoord<2>, true> == 16);
STATIC_REQUIRE(llama::offsetOf<DD, llama::DatumCoord<3>, true> == 18); // aligned
STATIC_REQUIRE(llama::sizeOf<DD, true> == 24);
STATIC_REQUIRE(llama::sizeOf<DD, true> == 20);
}

TEST_CASE("GetCoordFromTags")
Expand Down

0 comments on commit 9a284db

Please sign in to comment.