1 #ifndef DASH__ALLOCATOR__EPOCH_SYNCHRONIZED_ALLOCATOR_H__INCLUDED 2 #define DASH__ALLOCATOR__EPOCH_SYNCHRONIZED_ALLOCATOR_H__INCLUDED 7 #include <dash/Types.h> 9 #include <dash/internal/Logging.h> 11 #include <dash/GlobPtr.h> 12 #include <dash/allocator/AllocatorTraits.h> 13 #include <dash/allocator/AllocatorBase.h> 14 #include <dash/allocator/internal/Types.h> 15 #include <dash/memory/MemorySpace.h> 44 template <
class T>
class LocalAlloc = allocator::DefaultAllocator>
46 template <
class T,
class U>
47 friend bool operator==(
58 template <
class T,
class U>
59 friend bool operator!=(
74 static_assert(memory_traits::is_local::value,
"memory space must be local");
78 "currently, only the epoch_synchronized allocation policy is " 87 static constexpr
size_t const alignment =
alignof(ElementType);
89 using allocator_traits = std::allocator_traits<LocalAlloc<ElementType>>;
94 using allocation_rec_t =
95 allocator::allocation_rec<typename allocator_traits::pointer>;
98 using local_allocator_type = LocalAlloc<ElementType>;
109 using local_pointer =
typename allocator_traits::pointer;
110 using const_local_pointer =
typename allocator_traits::const_pointer;
111 using local_void_pointer =
typename allocator_traits::void_pointer;
112 using const_local_void_pointer =
113 typename allocator_traits::const_void_pointer;
115 using allocation_policy =
116 std::integral_constant<global_allocation_policy, AllocationPolicy>;
121 EpochSynchronizedAllocator<U, LMemSpace, AllocationPolicy, LocalAlloc>;
130 Team const &team, LMemSpace *r =
nullptr) noexcept;
173 return size_type(-1) /
sizeof(ElementType);
184 pointer attach(local_pointer lptr, size_type num_local_elem);
245 struct BinaryCmpLocalPointer {
246 bool operator()(
const allocation_rec_t &a,
const allocation_rec_t &b)
248 return reinterpret_cast<const uintptr_t
>(a.lptr()) <
249 reinterpret_cast<const uintptr_t>(b.lptr());
258 void clear() DASH_ASSERT_NOEXCEPT
260 DASH_LOG_DEBUG(
"EpochSynchronizedAllocator.clear()");
262 for (
auto const &segment : _segments) {
266 DASH_LOG_DEBUG(
"EpochSynchronizedAllocator.clear >");
269 template <
class ForwardIt,
class Compare>
270 ForwardIt binary_find(
273 const allocation_rec_t &value,
276 first = std::lower_bound(first, last, value, comp);
277 return first != last && !comp(value, *first) ? first : last;
280 typename std::vector<allocation_rec_t>::iterator do_local_allocate(
281 size_type num_local_elem)
283 auto lp = allocator_traits::allocate(_alloc, num_local_elem);
285 if (!lp && num_local_elem > 0) {
287 "EpochSynchronizedAllocator.allocate_local",
288 "cannot allocate local memory segment",
290 throw std::bad_alloc{};
295 auto pos = std::lower_bound(
299 BinaryCmpLocalPointer{});
301 return _segments.emplace(pos, std::move(rec));
304 typename std::vector<allocation_rec_t>::iterator lookup_segment_by_lptr(
313 BinaryCmpLocalPointer{});
316 typename std::vector<allocation_rec_t>::iterator lookup_segment_by_gptr(
322 [gptr](
const allocation_rec_t &a) {
329 std::vector<allocation_rec_t> _segments;
330 local_allocator_type _alloc;
338 typename ElementType,
341 template <
class>
class LocalAlloc>
351 : static_cast<LMemSpace *>(
354 typename memory_traits::memory_space_type_category>()))
358 "EpochSynchronizedAllocator.SymmetricAllocator(team, alloc) >");
359 _segments.reserve(1);
363 typename ElementType,
366 template <
class>
class LocalAlloc>
377 typename ElementType,
380 template <
class>
class LocalAlloc>
387 , _alloc(std::move(other._alloc))
388 , _segments(std::move(other._segments))
389 , _policy(other._policy)
395 typename ElementType,
398 template <
class>
class LocalAlloc>
408 LocalAlloc>::operator=(
self_t const &other) noexcept
410 if (&other ==
this) {
414 _alloc = other._alloc;
418 _policy = other._policy;
424 typename ElementType,
427 template <
class>
class LocalAlloc>
437 LocalAlloc>::operator=(
self_t &&other) noexcept
439 if (&other ==
this) {
443 if (_alloc == other._alloc) {
457 typename ElementType,
460 template <
class>
class LocalAlloc>
471 typename ElementType,
474 template <
class>
class LocalAlloc>
481 std::swap(_team, other._team);
482 std::swap(_alloc, other._alloc);
483 std::swap(_segments, other._segments);
484 std::swap(_policy, other._policy);
488 typename ElementType,
491 template <
class>
class LocalAlloc>
496 LocalAlloc>::local_pointer
504 "SymmetricAllocator.allocate_local(n)",
505 "number of local values:",
508 auto it = do_local_allocate(num_local_elem);
510 DASH_ASSERT_MSG(it->lptr() !=
nullptr,
"invalid pointer");
516 typename ElementType,
519 template <
class>
class LocalAlloc>
528 "EpochSynchronizedAllocator.deallocate_local(n)",
534 auto pos = lookup_segment_by_lptr(lptr);
538 "EpochSynchronizedAllocator.deallocate_local",
539 "invalid local pointer",
544 DASH_ASSERT_EQ(pos->length(), num_local_elem,
"Invalid block length");
548 "EpochSynchronizedAllocator.deallocate_local",
549 "local pointer must not be attached to global memory",
554 allocator_traits::deallocate(_alloc, pos->lptr(), pos->length());
556 _segments.erase(pos);
560 typename ElementType,
563 template <
class>
class LocalAlloc>
573 LocalAlloc>
::attach(local_pointer
const lptr, size_type num_local_elem)
576 "EpochSynchronizedAllocator.attach",
582 auto pos = lookup_segment_by_lptr(lptr);
586 "EpochSynchronizedAllocator.attach",
"Invalid local pointer", lptr);
590 DASH_ASSERT_EQ(num_local_elem, pos->length(),
"invalid block length");
592 auto gptr = _policy.do_global_attach(
593 _team->dart_id(), pos->lptr(), pos->length() *
sizeof(ElementType));
603 typename ElementType,
606 template <
class>
class LocalAlloc>
614 "EpochSynchronizedAllocator.detach",
624 auto pos = lookup_segment_by_gptr(gptr);
628 "EpochSynchronizedAllocator.detach",
"Invalid global pointer", gptr);
632 DASH_ASSERT_EQ(num_local_elem, pos->length(),
"invalid block length");
634 _policy.do_global_detach(pos->gptr());
640 typename ElementType,
643 template <
class>
class LocalAlloc>
651 "EpochSynchronizedAllocator.deallocate",
"deallocate local memory");
660 [gptr](
const allocation_rec_t &a) {
666 "EpochSynchronizedAllocator.detach",
"Invalid global pointer", gptr);
670 DASH_ASSERT_EQ(pos->length(), num_local_elem,
"invalid block length");
672 _policy.do_global_detach(pos->gptr());
674 allocator_traits::deallocate(_alloc, pos->lptr(), pos->length());
676 _segments.erase(pos);
680 typename ElementType,
683 template <
class>
class LocalAlloc>
696 "EpochSynchronizedAllocator.allocate",
700 auto it = do_local_allocate(num_local_elem);
702 DASH_ASSERT_MSG(it->lptr() !=
nullptr,
"local pointer must not be NULL");
704 auto gptr = _policy.do_global_attach(
705 _team->dart_id(), it->lptr(), num_local_elem *
sizeof(ElementType));
719 template <
class>
class LocalAlloc>
733 sizeof(T) ==
sizeof(U) && *(lhs._team) == *(rhs._team) &&
734 lhs._alloc == rhs._alloc);
742 template <
class>
class LocalAlloc>
755 return !(lhs == rhs);
760 #endif // DASH__ALLOCATOR__EPOCH_SYNCHRONIZED_ALLOCATOR_H__INCLUDED MemorySpace< MSpaceDomainCategory, MSpaceTypeCategory > * get_default_memory_space()
Forward declarations.
internal::default_unsigned_index default_size_t
Unsigned integer type used as default for size values.
constexpr auto end(RangeType &&range) -> decltype(std::forward< RangeType >(range).end())
void swap(self_t &other) noexcept
Swap two collective Allocators.
This class is a simple memory pool which holds allocates elements of size ValueType.
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
~EpochSynchronizedAllocator() noexcept
Destructor.
Encapsulates a memory allocation and deallocation strategy of global memory regions distributed acros...
local_allocator_type get_local_allocator() const noexcept
Returns a copy of the local allocator object associated with the vector.
GlobIter find_if(GlobIter first, GlobIter last, UnaryPredicate predicate)
Returns an iterator to the first element in the range [first,last) that satisfies the predicate p...
size_type max_size() const noexcept
Estimate the largest supported size.
pointer attach(local_pointer lptr, size_type num_local_elem)
Register pre-allocated local memory segment of num_local_elem elements in global memory space...
ElementType value_type
Allocator Traits.
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
#define DART_GPTR_NULL
A NULL global pointer.
A Team instance specifies a subset of all available units.
self_t & operator=(const self_t &other) noexcept
Copy Assignment operator.
all units allocate invdividually in local memory and synchronize in epochs
void detach(pointer gptr, size_type num_local_elem)
Unregister local memory segment from global memory space.
DART Global pointer type.
void deallocate(pointer gptr, size_type num_local_elem)
Deallocates a memory segment from global memory space.
#define DART_GPTR_ISNULL(gptr_)
Test for NULL global pointer.
#define DART_GPTR_EQUAL(gptr1_, gptr2_)
Compare two global pointers.
local_pointer allocate_local(size_type num_local_elem)
Allocates num_local_elem local elements in the active unit's local memory.
pointer allocate(size_type num_local_elem)
Allocates a global memory segment with at least num_local_elem bytes.
void deallocate_local(local_pointer lptr, size_type num_local_elem)
Deallocates memory segment in the active unit's local memory.
EpochSynchronizedAllocator(Team const &team, LMemSpace *r=nullptr) noexcept
Constructor.