Skip to content

Commit

Permalink
Add UniquePtr blob allocator
Browse files Browse the repository at this point in the history
  • Loading branch information
bernhardmgruber committed Nov 18, 2022
1 parent 4d79282 commit e6ea7b3
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
2 changes: 2 additions & 0 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ Blob allocators
:members:
.. doxygenstruct:: llama::bloballoc::SharedPtr
:members:
.. doxygenstruct:: llama::bloballoc::UniquePtr
:members:
.. doxygenstruct:: llama::bloballoc::Array
:members:

Expand Down
18 changes: 12 additions & 6 deletions docs/pages/blobs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,25 @@ A blob allocator is called like this:

There is a number of a built-in blob allocators:

Shared memory
^^^^^^^^^^^^^

:cpp:`llama::bloballoc::SharedPtr` is a blob allocator creating blobs of type :cpp:`std::shared_ptr<std::byte[]>`.
These blobs will be shared between each copy of the view and only destroyed then the last view is destroyed.

Vector
^^^^^^

:cpp:`llama::bloballoc::Vector` is a blob allocator creating blobs of type :cpp:`std::vector<std::byte>`.
This means every time a view is copied, the whole memory is copied too.
When the view is moved, no extra allocation or copy operation happens.

Shared pointer
^^^^^^^^^^^^^^

:cpp:`llama::bloballoc::SharedPtr` is a blob allocator creating blobs of type :cpp:`std::shared_ptr<std::byte[]>`.
These blobs will be shared between each copy of the view and only destroyed then the last view is destroyed.

Unique pointer
^^^^^^^^^^^^^^

:cpp:`llama::bloballoc::UniquePtr` is a blob allocator creating blobs of type :cpp:`std::unique_ptr<std::byte[], ...>`.
These blobs will be uniquely owned by a single view, so the view cannot be copied, only moved.

Array
^^^^^

Expand Down
19 changes: 18 additions & 1 deletion include/llama/BlobAllocators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ namespace llama::bloballoc
static_assert(BlobAllocator<Array<64>>);
#endif

/// Allocates heap memory managed by a `std::unique_ptr` for a \ref View. This memory can only be uniquely owned by
/// a single \ref View.
struct UniquePtr
{
template<std::size_t Alignment>
auto operator()(std::integral_constant<std::size_t, Alignment>, std::size_t count) const
{
auto* ptr
= static_cast<std::byte*>(::operator new[](count * sizeof(std::byte), std::align_val_t{Alignment}));
auto deleter = [](std::byte* ptr) { ::operator delete[](ptr, std::align_val_t{Alignment}); };
return std::unique_ptr<std::byte[], decltype(deleter)>{ptr, deleter};
}
};
#ifdef __cpp_lib_concepts
static_assert(BlobAllocator<UniquePtr>);
#endif

/// Allocates heap memory managed by a `std::shared_ptr` for a \ref View. This memory is shared between all copies
/// of a \ref View.
struct SharedPtr
Expand All @@ -62,7 +79,7 @@ namespace llama::bloballoc
{
auto* ptr
= static_cast<std::byte*>(::operator new[](count * sizeof(std::byte), std::align_val_t{Alignment}));
auto deleter = [=](std::byte* ptr) { ::operator delete[](ptr, std::align_val_t{Alignment}); };
auto deleter = [](std::byte* ptr) { ::operator delete[](ptr, std::align_val_t{Alignment}); };
return shared_ptr<std::byte[]>{ptr, deleter};
}
};
Expand Down
30 changes: 25 additions & 5 deletions tests/view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ TEST_CASE("view.indexing")
});
}

TEMPLATE_TEST_CASE("view.transformBlobs", "", llama::bloballoc::Vector)
TEST_CASE("view.transformBlobs")
{
auto view = llama::allocView(llama::mapping::AoS{llama::ArrayExtents{16, 16}, Particle{}});
iotaFillView(view);
Expand All @@ -320,7 +320,12 @@ TEMPLATE_TEST_CASE("view.transformBlobs", "", llama::bloballoc::Vector)
iotaCheckView(copy);
}

TEMPLATE_TEST_CASE("view.shallowCopy", "", llama::bloballoc::Vector, llama::bloballoc::SharedPtr)
TEMPLATE_TEST_CASE(
"view.shallowCopy",
"",
llama::bloballoc::Vector,
llama::bloballoc::SharedPtr,
llama::bloballoc::UniquePtr)
{
auto view = llama::allocView(llama::mapping::AoS{llama::ArrayExtents{16, 16}, Particle{}}, TestType{});
auto checkCopy = [&](const auto& copy)
Expand Down Expand Up @@ -420,7 +425,12 @@ TEST_CASE("view.withAccessor.Default.SharedPtr")
CHECK(addr == addr2);
}

TEMPLATE_TEST_CASE("view.withAccessor.shallowCopy.Default", "", llama::bloballoc::Vector, llama::bloballoc::SharedPtr)
TEMPLATE_TEST_CASE(
"view.withAccessor.shallowCopy.Default",
"",
llama::bloballoc::Vector,
llama::bloballoc::SharedPtr,
llama::bloballoc::UniquePtr)
{
auto view = llama::allocView(llama::mapping::AoS{llama::ArrayExtents{16, 16}, Particle{}}, TestType{});
auto view2 = llama::withAccessor<llama::accessor::Default>(llama::shallowCopy(view));
Expand All @@ -429,7 +439,12 @@ TEMPLATE_TEST_CASE("view.withAccessor.shallowCopy.Default", "", llama::bloballoc
}

#ifdef __cpp_lib_atomic_ref
TEMPLATE_TEST_CASE("view.withAccessor.shallowCopy.Atomic", "", llama::bloballoc::Vector, llama::bloballoc::SharedPtr)
TEMPLATE_TEST_CASE(
"view.withAccessor.shallowCopy.Atomic",
"",
llama::bloballoc::Vector,
llama::bloballoc::SharedPtr,
llama::bloballoc::UniquePtr)
{
auto view = llama::allocView(llama::mapping::AoS{llama::ArrayExtents{16, 16}, Particle{}}, TestType{});
auto view2 = llama::withAccessor<llama::accessor::Atomic>(llama::shallowCopy(view));
Expand All @@ -438,7 +453,12 @@ TEMPLATE_TEST_CASE("view.withAccessor.shallowCopy.Atomic", "", llama::bloballoc:
}
#endif

TEMPLATE_TEST_CASE("view.withAccessor.shallowCopy.Restrict", "", llama::bloballoc::Vector, llama::bloballoc::SharedPtr)
TEMPLATE_TEST_CASE(
"view.withAccessor.shallowCopy.Restrict",
"",
llama::bloballoc::Vector,
llama::bloballoc::SharedPtr,
llama::bloballoc::UniquePtr)
{
auto view = llama::allocView(llama::mapping::AoS{llama::ArrayExtents{16, 16}, Particle{}}, TestType{});
auto view2 = llama::withAccessor<llama::accessor::Restrict>(llama::shallowCopy(view));
Expand Down

0 comments on commit e6ea7b3

Please sign in to comment.