33 BumpAllocator(T* data,
size_t byte_size): data(data), byte_size(byte_size){}
61 throw batchlas::api_misuse(
"BumpAllocator::required_bytes() on a real pool; use BumpAllocator::measuring().");
63 if (align_quantum_ == 0)
return high_water_;
64 return (high_water_ + align_quantum_ - 1) & ~(align_quantum_ - 1);
72 return std::max(device_align_bytes,
static_cast<std::uintptr_t
>(
alignof(T)));
78 if (size == 0)
return 0;
79 std::uintptr_t total_size = size *
sizeof(T);
95 if (size == 0)
return {};
97 if (alloc_size > byte_size){
98 throw batchlas::workspace_error(
"Attempted to allocate " + std::to_string(alloc_size) +
" bytes from a BumpAllocator with only " + std::to_string(byte_size) +
" bytes remaining.");
101 void* aligned = data;
110 const auto base =
static_cast<std::byte*
>(measure_base_);
111 const size_t need_for_check =
static_cast<size_t>(
static_cast<std::byte*
>(data) - base) + alloc_size;
112 const size_t need_for_data =
static_cast<size_t>(
static_cast<std::byte*
>(aligned) - base) + size *
sizeof(T);
113 high_water_ = std::max(high_water_, std::max(need_for_check, need_for_data));
117 auto* next =
static_cast<std::byte*
>(aligned) + size *
sizeof(T);
118 T* ptr =
static_cast<T*
>(aligned);
119 byte_size -=
static_cast<size_t>(next -
static_cast<std::byte*
>(data));
122 return Span(ptr, size);
146 if (bytes > byte_size) {
149 data =
static_cast<std::byte*
>(data) + bytes;
155 struct measure_tag {};
158 static constexpr std::uintptr_t kMeasureBase = std::uintptr_t(1) << 32;
161 : data(reinterpret_cast<void*>(kMeasureBase)),
163 byte_size(std::numeric_limits<size_t>::max() / 4),
165 measure_base_(reinterpret_cast<void*>(kMeasureBase)) {}
169 bool measuring_ =
false;
170 void* measure_base_ =
nullptr;
171 size_t high_water_ = 0;
172 size_t align_quantum_ = 0;
191template <
typename Fn>
195 return sizer.required_bytes();
202#ifndef BATCHLAS_NO_GLOBAL_NAMES
A well-formed call arrived in a state, order or thread where it is not valid.
The scratch the operation was handed is too small, or the allocator ran out of it.
@ MEM_BASE_ADDR_ALIGN
Base address alignment (bits).
size_t workspace_bytes(Fn &&layout)
Bytes a workspace layout needs, obtained by replaying it against a sizing pool.
Span(T *, typename Span< T >::size_t) -> Span< T >
Linear (bump) sub-allocator over a caller-supplied workspace buffer.
size_t required_bytes() const
Bytes a real pool must be given for the call sequence so far to succeed.
static constexpr size_t allocation_size(Queue &ctx, size_t size)
allocation_size() for the Queue's device.
constexpr Span< T > allocate(Queue &ctx, size_t size)
allocate() with the Queue's device.
bool is_measuring() const
True for a pool made by measuring().
BumpAllocator(T *data, size_t byte_size)
A pool over byte_size bytes starting at data.
static constexpr size_t allocation_size(const Device &device, size_t size)
Bytes size elements of T occupy, rounded up to alignment<T>(); 0 for size == 0.
BumpAllocator(Span< T > span)
A pool over the bytes of span.
Span< std::byte > remaining() const
The still-unclaimed tail of the pool.
void consume(size_t bytes)
Advance the pool by bytes (after a callee used remaining()).
static constexpr auto alignment(const Device &device)
Alignment in bytes of an allocation of T on device.
constexpr Span< T > allocate(const Device &device, size_t size)
Carve size elements of T, aligned to alignment<T>(), off the front of the pool.
static BumpAllocator measuring()
A sizing pool: an effectively unbounded, maximally aligned fictitious region.
A handle to one SYCL device: its type and its index among devices of that type.
Where BatchLAS work runs: a device, a backend, an ordered SYCL queue and a workspace arena.
Device device() const
The device this Queue runs on.
Non-owning view of size() contiguous elements of type T.
constexpr Span()
An empty span (null data, size 0).
batchlas::Device, batchlas::Event and batchlas::Queue: where work runs and how it is ordered.
batchlas::Span, the non-owning pointer + length every entry point takes for 1-D data.