20
21
22
23
27#include "./allocators.hpp"
28#include "./memcpy.hpp"
29#include "../concepts.hpp"
30#include "../macros.hpp"
40
41
42
48
49
50
51
52
53 template <
typename T,
int Al>
80
81
82
91
92
93
94
95
96
97
98 template <
typename T, Allocator A =
mallocator<>>
100 static_assert(std::is_nothrow_destructible_v<T>,
"nda::mem::handle_heap requires the value_type to have a non-throwing destructor");
110#ifndef NDA_DEBUG_LEAK_CHECK
111 static inline A allocator;
117 mutable std::shared_ptr<
void> sptr;
120 using blk_T_t = std::pair<T *, size_t>;
123 static void destruct(blk_T_t b)
noexcept {
124 auto [data, size] = b;
127 if (data ==
nullptr)
return;
130 if constexpr (A::address_space == Host
and !(std::is_trivial_v<T>
or nda::is_complex_v<T>)) {
131 for (size_t i = 0; i < size; ++i) data[i].~T();
135 allocator.deallocate({(
char *)data, size *
sizeof(T)});
139 static void deleter(
void *p)
noexcept { destruct(*((blk_T_t *)p)); }
143 using value_type = T;
146 using allocator_type = A;
152
153
154
156 if (
not sptr) sptr.reset(
new blk_T_t{_data, _size}, deleter);
161
162
163
164
166 if (
not sptr
and not(
is_null())) destruct({_data, _size});
173
174
175
182
183
184
185
186
189 if (
not sptr
and not(
is_null())) destruct({_data, _size});
194 sptr = std::move(h.sptr);
203
204
205
208 if constexpr (std::is_trivially_copyable_v<T>) {
211 for (size_t i = 0; i < _size; ++i)
new (_data + i) T(h[i]);
216
217
218
219
220
227
228
229
230
231
232 template <OwningHandle<value_type> H>
235 if constexpr (std::is_trivially_copyable_v<T>) {
236 memcpy<
address_space, H::address_space>((
void *)_data, (
void *)h.data(), _size *
sizeof(T));
239 "Constructing an nda::mem::handle_heap from a handle of a different address space requires a trivially copyable value_type");
240 for (size_t i = 0; i < _size; ++i)
new (_data + i) T(h[i]);
245
246
247
248
249
250
251 template <Allocator AS>
258
259
260
262 if (size == 0)
return;
263 auto b = allocator.allocate(size *
sizeof(T));
264 if (
not b.ptr)
throw std::bad_alloc{};
270
271
272
274 if (size == 0)
return;
275 auto b = allocator.allocate_zero(size *
sizeof(T));
276 if (
not b.ptr)
throw std::bad_alloc{};
282
283
284
285
286
287
288
289
290
291
293 if (size == 0)
return;
296 b = allocator.allocate_zero(size *
sizeof(T));
298 b = allocator.allocate(size *
sizeof(T));
299 if (
not b
.ptr)
throw std::bad_alloc{};
304 if constexpr (!std::is_trivial_v<T>
and !is_complex_v<T>) {
305 for (size_t i = 0; i < size; ++i)
new (_data + i) T();
310
311
312
313
314
318
319
320
321
322
326
327
328
332 EXPECTS((_data ==
nullptr) == (_size == 0));
334 return _data ==
nullptr;
338
339
340
344
345
346
351
352
353
354
355
356
357
358 template <
typename T, size_t Size>
360 static_assert(std::is_copy_constructible_v<T>,
"nda::mem::handle_stack requires the value_type to be copy constructible");
361 static_assert(std::is_nothrow_destructible_v<T>,
"nda::mem::handle_stack requires the value_type to have a non-throwing destructor");
365 std::array<
char,
sizeof(T) * Size> buffer;
369 using value_type = T;
375
376
377
379 if constexpr (!std::is_trivial_v<T>) {
381 for (size_t i = 0; i < Size; ++i)
data()[i].~T();
389
390
391
392
396
397
398
399
406
407
408
409
413
414
415
417 for (size_t i = 0; i < Size; ++i)
new (
data() + i) T(h[i]);
426 static_assert(std::is_scalar_v<T>
or is_complex_v<T>,
"nda::mem::handle_stack can only be initialized to zero for scalar and complex types");
427 for (size_t i = 0; i < Size; ++i)
data()[i] = 0;
431
432
433
434
435
436
438 if constexpr (!std::is_trivial_v<T>
and !is_complex_v<T>) {
439 for (size_t i = 0; i < Size; ++i)
new (
data() + i) T();
444
445
446
447
448
452
453
454
455
456
460
461
462
463 static constexpr bool is_null()
noexcept {
return false; }
466
467
468
472
473
474
475 static constexpr long size()
noexcept {
return Size; }
479
480
481
482
483
484
485
486
487
488
489
490
491 template <
typename T, size_t Size>
493 static_assert(Size > 0,
"Size == 0 makes no sense in nda::mem::handle_sso");
494 static_assert(std::is_copy_constructible_v<T>,
"nda::mem::handle_sso requires the value_type to be copy constructible");
495 static_assert(std::is_nothrow_destructible_v<T>,
"nda::mem::handle_sso requires the value_type to have a non-throwing destructor");
499 std::array<
char,
sizeof(T) * Size> buffer;
508 void clean()
noexcept {
510 if constexpr (!std::is_trivial_v<T>) {
512 for (size_t i = 0; i < _size; ++i)
data()[i].~T();
521 using value_type = T;
530
531
532
533
534
538
539
540
541
547 _data = (T *)buffer.data();
548 for (size_t i = 0; i < _size; ++i)
new (
data() + i) T(h[i]);
556
557
558
559
560
561
562
570 _data = (T *)buffer.data();
571 for (size_t i = 0; i < _size; ++i)
new (_data + i) T(h[i]);
580
581
582
585 if constexpr (std::is_trivially_copyable_v<T>) {
588 for (size_t i = 0; i < _size; ++i)
new (_data + i) T(h[i]);
593
594
595
596
597
599 if (
this == &h)
return *
this;
602 if (_size == 0)
return *
this;
605 if (
not b
.ptr)
throw std::bad_alloc{};
608 _data = (T *)buffer.data();
610 for (size_t i = 0; i < _size; ++i)
new (_data + i) T(h[i]);
615
616
617
618
619 template <OwningHandle<value_type> H>
622 if constexpr (std::is_trivially_copyable_v<T>) {
623 memcpy<
address_space, H::address_space>((
void *)_data, (
void *)h.data(), _size *
sizeof(T));
626 "Constructing an nda::mem::handle_sso from a handle of a different address space requires a trivially copyable value_type");
627 for (size_t i = 0; i < _size; ++i)
new (_data + i) T(h[i]);
632
633
634
635
637 if (size == 0)
return;
640 _data = (T *)buffer.data();
643 if (
not b
.ptr)
throw std::bad_alloc{};
649
650
651
652
653
654
655
657 static_assert(std::is_scalar_v<T>
or is_complex_v<T>,
"nda::mem::handle_sso can only be initialized to zero for scalar and complex types");
658 if (size == 0)
return;
661 _data = (T *)buffer.data();
662 for (size_t i = 0; i < _size; ++i)
data()[i] = 0;
665 if (
not b
.ptr)
throw std::bad_alloc{};
671
672
673
674
675
676
677
678
679
681 if (size == 0)
return;
684 _data = (T *)buffer.data();
691 if (
not b
.ptr)
throw std::bad_alloc{};
696 if constexpr (!std::is_trivial_v<T>
and !is_complex_v<T>) {
697 for (size_t i = 0; i < size; ++i)
new (_data + i) T();
702
703
704
705
706
710
711
712
713
714
718
719
720
724
725
726
729 EXPECTS((_data ==
nullptr) == (_size == 0));
731 return _data ==
nullptr;
735
736
737
741
742
743
748
749
750
751
752
755 static_assert(std::is_nothrow_destructible_v<T>,
"nda::mem::handle_shared requires the value_type to have a non-throwing destructor");
765 using blk_t = std::pair<T *, size_t>;
768 std::shared_ptr<
void> sptr;
772 using value_type = T;
781
782
783
784
785
786
787
788 handle_shared(T *data, size_t size,
void *foreign_handle,
void (*foreign_decref)(
void *))
noexcept
789 : _data(data), _size(size), sptr{foreign_handle, foreign_decref} {}
792
793
794
795
796
797 template <Allocator A>
800 : _data(h.data()), _size(h.size()) {
801 if (
not h.is_null()) sptr = h.get_sptr();
805
806
807
808
809
813
814
815
816
817
821
822
823
827 EXPECTS((_data ==
nullptr) == (_size == 0));
829 return _data ==
nullptr;
833
834
835
839
840
841
845
846
847
852
853
854
855
856
861 using T0 = std::remove_const_t<T>;
871 using value_type = T;
889
890
891
895
896
897
898
899
900
902 requires(
address_space == H::address_space
and (std::is_const_v<value_type>
or !std::is_const_v<
typename H::value_type>)
903 and std::is_same_v<
const value_type,
const typename H::value_type>)
905 if constexpr (std::is_same_v<H,
handle_heap<T0>>) _parent = &h;
909
910
911
912
913
917
918
919
920
921
925
926
927
931
932
933
937
938
939
void swap(nda::basic_array_view< V1, R1, LP1, A1, AP1, OP1 > &a, nda::basic_array_view< V2, R2, LP2, A2, AP2, OP2 > &b)=delete
std::swap is deleted for nda::basic_array_view.
Iterator for nda::basic_array and nda::basic_array_view types.
A generic view of a multi-dimensional array.
basic_array_view(A &&a) noexcept
Generic constructor from any nda::MemoryArray type.
const_iterator end() const noexcept
Get a const iterator to the end of the view/array.
ValueType const * data() const noexcept
Get a pointer to the actual data (in general this is not the beginning of the memory block for a view...
auto as_array_view() const
static constexpr bool is_stride_order_C() noexcept
Is the stride order of the view/array in C-order?
iterator begin() noexcept
Get an iterator to the beginning of the view/array.
ValueType * data() noexcept
Get a pointer to the actual data (in general this is not the beginning of thr memory block for a view...
basic_array_view & operator=(RHS const &rhs) noexcept
Assignment operator makes a deep copy of the contents of an nda::ArrayOfRank object.
auto & operator/=(RHS const &rhs) noexcept
Division assignment operator.
static constexpr int rank
Number of dimensions of the view.
decltype(auto) operator[](T const &idx) const &noexcept(has_no_boundcheck)
Subscript operator to access the 1-dimensional view/array.
auto const & shape() const noexcept
Get the shape of the view/array.
static __inline__ decltype(auto) call(Self &&self, Ts const &...idxs) noexcept(has_no_boundcheck)
Implementation of the function call operator.
basic_array_view(layout_t const &idxm, ValueType *p) noexcept
Construct a view from a bare pointer to some contiguous data and a memory layout.
__inline__ decltype(auto) operator()(Ts const &...idxs) &noexcept(has_no_boundcheck)
Non-const overload of nda::basic_array_view::operator()(Ts const &...) const &.
decltype(auto) operator[](T const &x) &&noexcept(has_no_boundcheck)
Rvalue overload of nda::basic_array_view::operator[](T const &) const &.
basic_array_view(R &rg) noexcept
Construct a 1-dimensional view of a general contiguous range.
basic_array_view & operator=(basic_array_view const &rhs) noexcept
Copy assignment operator makes a deep copy of the contents of the view.
basic_array_view(std::array< ValueType, N > &a) noexcept
Construct a 1-dimensional view of a std::array.
auto const & strides() const noexcept
Get the strides of the view/array (see nda::idx_map for more details on how we define strides).
long shape(int i) const noexcept
storage_t storage() &&noexcept
Get the data storage of the view/array.
decltype(auto) operator[](T const &x) &noexcept(has_no_boundcheck)
Non-const overload of nda::basic_array_view::operator[](T const &) const &.
decltype(auto) operator()(_linear_index_t idx) noexcept
Non-const overload of nda::basic_array_view::operator()(_linear_index_t) const.
auto & operator+=(RHS const &rhs) noexcept
Addition assignment operator.
auto indices() const noexcept
Get a range that generates all valid index tuples.
basic_array_view()=default
Default constructor constructs an empty view with a default constructed memory handle and layout.
long is_contiguous() const noexcept
Is the memory layout of the view/array contiguous?
auto & operator=(R const &rhs) noexcept
Assignment operator makes a deep copy of a general contiguous range and assigns it to the 1-dimension...
storage_t & storage() &noexcept
Get the data storage of the view/array.
static constexpr bool is_stride_order_Fortran() noexcept
Is the stride order of the view/array in Fortran-order?
decltype(auto) operator()(_linear_index_t idx) const noexcept
Access the element of the view/array at the given nda::_linear_index_t.
__inline__ decltype(auto) operator()(Ts const &...idxs) const &noexcept(has_no_boundcheck)
Function call operator to access the view/array.
auto & operator*=(RHS const &rhs) noexcept
Multiplication assignment operator.
basic_array_view(std::array< std::remove_const_t< ValueType >, N > const &a) noexcept
Construct a 1-dimensional view of a std::array.
friend void deep_swap(basic_array_view a, basic_array_view b) noexcept
Swap two views by swapping their data.
iterator end() noexcept
Get an iterator to the end of the view/array.
long size() const noexcept
Get the total size of the view/array.
auto & operator-=(RHS const &rhs) noexcept
Subtraction assignment operator.
bool empty() const
Is the view/array empty?
basic_array_view(std::array< long, Rank > const &shape, ValueType *p) noexcept
Construct a view from a bare pointer to some contiguous data and a shape.
bool is_empty() const noexcept
friend void swap(basic_array_view &a, basic_array_view &b) noexcept
Swap two views by swapping their memory handles and layouts.
constexpr auto stride_order() const noexcept
Get the stride order of the memory layout of the view/array (see nda::idx_map for more details on how...
const_iterator cbegin() const noexcept
Get a const iterator to the beginning of the view/array.
basic_array_view(layout_t const &idxm, storage_t st)
Construct a view from a given layout and memory handle.
static constexpr int iterator_rank
Rank of the nda::array_iterator for the view/array.
basic_array_view(basic_array_view &&)=default
Default move constructor moves the memory handle and layout.
void rebind(basic_array_view< T, R, LP, A, AP, OP > v) noexcept
Rebind the current view to another view.
basic_array_view(basic_array_view const &)=default
Default copy constructor copies the memory handle and layout.
__inline__ decltype(auto) operator()(Ts const &...idxs) &&noexcept(has_no_boundcheck)
Rvalue overload of nda::basic_array_view::operator()(Ts const &...) const &.
long extent(int i) const noexcept
Get the extent of the ith dimension.
constexpr auto const & indexmap() const noexcept
Get the memory layout of the view/array.
const_iterator begin() const noexcept
Get a const iterator to the beginning of the view/array.
const_iterator cend() const noexcept
Get a const iterator to the end of the view/array.
storage_t const & storage() const &noexcept
Get the data storage of the view/array.
A generic multi-dimensional array.
auto & operator+=(RHS const &rhs) noexcept
Addition assignment operator.
decltype(auto) operator[](T const &idx) const &noexcept(has_no_boundcheck)
Subscript operator to access the 1-dimensional view/array.
basic_array(basic_array< ValueType, 2, LayoutPolicy, A2, ContainerPolicy > &&a) noexcept
Construct a 2-dimensional array from another 2-dimensional array with a different algebra.
basic_array & operator=(RHS const &rhs)
Assignment operator makes a deep copy of an nda::ArrayOfRank object.
static constexpr bool is_stride_order_Fortran() noexcept
Is the stride order of the view/array in Fortran-order?
ValueType const * data() const noexcept
Get a pointer to the actual data (in general this is not the beginning of the memory block for a view...
ValueType * data() noexcept
Get a pointer to the actual data (in general this is not the beginning of thr memory block for a view...
long shape(int i) const noexcept
const_iterator cbegin() const noexcept
Get a const iterator to the beginning of the view/array.
static constexpr int rank
Number of dimensions of the array.
static constexpr bool is_stride_order_C() noexcept
Is the stride order of the view/array in C-order?
storage_t & storage() &noexcept
Get the data storage of the view/array.
basic_array(basic_array< ValueType, Rank, LayoutPolicy, A, CP > a) noexcept
Construct an array from another array with a different algebra and/or container policy.
auto const & strides() const noexcept
Get the strides of the view/array (see nda::idx_map for more details on how we define strides).
basic_array(Ints... is)
Construct an array with the given dimensions.
static basic_array ones(Ints... is)
Make a one-initialized array with the given dimensions.
const_iterator begin() const noexcept
Get a const iterator to the beginning of the view/array.
auto as_array_view() const
Convert the current array to a view with an 'A' (array) algebra.
long extent(int i) const noexcept
Get the extent of the ith dimension.
basic_array(std::initializer_list< ValueType > const &l)
Construct a 1-dimensional array from an initializer list.
decltype(auto) operator[](T const &x) &&noexcept(has_no_boundcheck)
Rvalue overload of nda::basic_array_view::operator[](T const &) const &.
long is_contiguous() const noexcept
Is the memory layout of the view/array contiguous?
basic_array(std::initializer_list< std::initializer_list< ValueType > > const &l2)
Construct a 2-dimensional array from a double nested initializer list.
decltype(auto) operator()(_linear_index_t idx) noexcept
Non-const overload of nda::basic_array_view::operator()(_linear_index_t) const.
__inline__ decltype(auto) operator()(Ts const &...idxs) &noexcept(has_no_boundcheck)
Non-const overload of nda::basic_array_view::operator()(Ts const &...) const &.
bool empty() const
Is the view/array empty?
void resize(std::array< long, Rank > const &shape)
Resize the array to a new shape.
basic_array(Int sz, RHS const &val)
Construct a 1-dimensional array with the given size and initialize each element to the given scalar v...
static basic_array ones(std::array< Int, Rank > const &shape)
Make a one-initialized array with the given shape.
constexpr auto stride_order() const noexcept
Get the stride order of the memory layout of the view/array (see nda::idx_map for more details on how...
auto & operator/=(RHS const &rhs) noexcept
Division assignment operator.
auto as_array_view()
Convert the current array to a view with an 'A' (array) algebra.
basic_array(A const &a)
Construct an array from an nda::ArrayOfRank object with the same rank by copying each element.
static basic_array zeros(Ints... is)
Make a zero-initialized array with the given dimensions.
auto indices() const noexcept
Get a range that generates all valid index tuples.
static __inline__ decltype(auto) call(Self &&self, Ts const &...idxs) noexcept(has_no_boundcheck)
Implementation of the function call operator.
void resize(Ints const &...is)
Resize the array to a new shape.
storage_t storage() &&noexcept
Get the data storage of the view/array.
basic_array()
Default constructor constructs an empty array with a default constructed memory handle and layout.
bool is_empty() const noexcept
auto & operator=(R const &rhs) noexcept
Assignment operator makes a deep copy of a general contiguous range and assigns it to the 1-dimension...
storage_t const & storage() const &noexcept
Get the data storage of the view/array.
basic_array & operator=(basic_array const &)=default
Default copy assignment copies the memory handle and layout from the right hand side array.
basic_array & operator=(basic_array< ValueType, Rank, LayoutPolicy, A, CP > const &rhs)
Assignment operator makes a deep copy of another array with a different algebra and/or container poli...
basic_array(basic_array const &a)=default
Default copy constructor copies the memory handle and layout.
basic_array(std::initializer_list< std::initializer_list< std::initializer_list< ValueType > > > const &l3)
Construct a 3-dimensional array from a triple nested initializer list.
iterator begin() noexcept
Get an iterator to the beginning of the view/array.
basic_array(layout_t const &layout)
Construct an array with the given memory layout.
static basic_array rand(Ints... is)
Make a random-initialized array with the given dimensions.
basic_array(layout_t const &layout, storage_t &&storage) noexcept
Construct an array with the given memory layout and with an existing memory handle/storage.
static constexpr int iterator_rank
Rank of the nda::array_iterator for the view/array.
auto & operator-=(RHS const &rhs) noexcept
Subtraction assignment operator.
const_iterator end() const noexcept
Get a const iterator to the end of the view/array.
basic_array(basic_array &&)=default
Default move constructor moves the memory handle and layout.
__inline__ decltype(auto) operator()(Ts const &...idxs) &&noexcept(has_no_boundcheck)
Rvalue overload of nda::basic_array_view::operator()(Ts const &...) const &.
basic_array(std::array< Int, Rank > const &shape)
Construct an array with the given shape.
const_iterator cend() const noexcept
Get a const iterator to the end of the view/array.
auto const & shape() const noexcept
Get the shape of the view/array.
long size() const noexcept
Get the total size of the view/array.
decltype(auto) operator[](T const &x) &noexcept(has_no_boundcheck)
Non-const overload of nda::basic_array_view::operator[](T const &) const &.
auto & operator*=(RHS const &rhs) noexcept
Multiplication assignment operator.
basic_array & operator=(basic_array &&)=default
Default move assignment moves the memory handle and layout from the right hand side array.
static basic_array zeros(std::array< Int, Rank > const &shape)
Make a zero-initialized array with the given shape.
__inline__ decltype(auto) operator()(Ts const &...idxs) const &noexcept(has_no_boundcheck)
Function call operator to access the view/array.
constexpr auto const & indexmap() const noexcept
Get the memory layout of the view/array.
iterator end() noexcept
Get an iterator to the end of the view/array.
decltype(auto) operator()(_linear_index_t idx) const noexcept
Access the element of the view/array at the given nda::_linear_index_t.
static basic_array rand(std::array< Int, Rank > const &shape)
Make a random-initialized array with the given shape.
Layout that specifies how to map multi-dimensional indices to a linear/flat index.
__inline__ long operator()(Args const &...args) const noexcept(true)
Function call operator to map a given multi-dimensional index to a linear index.
static constexpr std::array< int, Rank > stride_order
Decoded stride order.
idx_map(idx_map< Rank, StaticExtents, StrideOrder, LP > const &idxm) noexcept
Construct a new map from an existing map with different layout properties.
static bool is_stride_order_valid(Int *lenptr, Int *strptr)
Check if a given shape and strides are compatible with the stride order.
static constexpr layout_info_t layout_info
Compile-time information about the layout (stride order and layout properties).
idx_map(idx_map &&)=default
Default move constructor.
long size() const noexcept
Get the total number of elements.
long min_stride() const noexcept
Get the value of the smallest stride.
idx_map(std::array< long, n_dynamic_extents > const &shape) noexcept
Construct a new map from an array with its dynamic extents.
auto transpose() const
Create a new map by permuting the indices/dimensions of the current map with a given permutation.
std::array< long, Rank > to_idx(long lin_idx) const
Calculate the multi-dimensional index from a given linear index.
bool is_stride_order_valid() const
Check if the shape and strides of the current map are compatible with its stride order.
idx_map(idx_map< Rank, SE, SO, LP > const &)
Construct a new map from an existing map with a different stride order.
bool operator==(idx_map< R, SE, SO, LP > const &rhs) const
Equal-to operator for two nda::idx_map objects.
static constexpr bool is_stride_order_C()
Is the stride order equal to C-order?
static constexpr int n_dynamic_extents
Number of dynamic dimensions/extents.
static constexpr uint64_t stride_order_encoded
Encoded stride order.
static constexpr int rank() noexcept
Get the rank of the map.
static constexpr std::array< int, Rank > static_extents
Decoded static extents.
bool is_strided_1d() const noexcept
Is the data strided in memory with a constant stride?
static constexpr int argument_is_allowed_for_call_or_slice
Alias template to check if type T can be used to either access a single element or a slice of element...
idx_map(std::array< Int, Rank > const &shape) noexcept
Construct a new map from a given shape and with contiguous strides.
std::array< long, Rank > const & lengths() const noexcept
Get the extents of all dimensions.
auto slice(Args const &...args) const
Get a new nda::idx_map by taking a slice of the current one.
static constexpr bool is_stride_order_Fortran()
Is the stride order equal to Fortran-order?
idx_map(idx_map const &)=default
Default copy constructor.
static constexpr int argument_is_allowed_for_call
Alias template to check if type T can be used to access a single element.
static constexpr long ce_size() noexcept
Get the size known at compile-time.
bool is_contiguous() const noexcept
Is the data contiguous in memory?
idx_map(idx_map< Rank, SE, StrideOrder, LP > const &idxm) noexcept(false)
Construct a new map from an existing map with different layout properties and different static extent...
idx_map(std::array< long, Rank > const &shape, std::array< long, Rank > const &strides) noexcept(!check_stride_order)
Construct a new map from a given shape and strides.
idx_map()
Default constructor.
std::array< long, Rank > const & strides() const noexcept
Get the strides of all dimensions.
idx_map & operator=(idx_map const &)=default
Default copy assignment operator.
static constexpr layout_prop_e layout_prop
Compile-time memory layout properties.
static constexpr uint64_t static_extents_encoded
Encoded static extents.
idx_map & operator=(idx_map &&)=default
Default move assignment operator.
idx_map(std::array< long, R > const &)
Construct a new map with a shape of a different rank.
Custom allocator that allocates a bucket of memory on the heap consisting of 64 chunks.
bucket(bucket &&)=default
Default move constructor.
bool empty() const noexcept
Check if the bucket is empty.
bucket()=default
Default constructor.
bool owns(blk_t b) const noexcept
Check if a given nda::mem::blk_t memory block is owned by the bucket.
void deallocate(blk_t b) noexcept
Deallocate a chunk of memory from the bucket by simply resetting the bitmask.
bool is_full() const noexcept
Check if the bucket is full.
auto mask() const noexcept
Get the bitmask of the bucket.
const char * data() const noexcept
Get a pointer to the start of the bucket.
static constexpr auto address_space
Only Host nda::mem::AddressSpace is supported for this allocator.
bucket(bucket const &)=delete
Deleted copy constructor.
bucket & operator=(bucket const &)=delete
Deleted copy assignment operator.
bucket & operator=(bucket &&)=default
Default move assignment operator.
blk_t allocate(size_t s) noexcept
Allocate a chunk of memory in the bucket and update the bitmask.
static constexpr int TotalChunkSize
Total size of the bucket in bytes.
blk_t allocate_zero(size_t s) noexcept
Allocate a chunk of memory in the bucket, set it to zero and update the bitmask.
Wrap an allocator to check for memory leaks.
bool empty() const
Check if the base allocator is empty.
long get_memory_used() const noexcept
Get the total memory used by the base allocator.
bool owns(blk_t b) const noexcept
Check if a given nda::mem::blk_t memory block is owned by the base allocator.
leak_check & operator=(leak_check &&)=default
Default move assignment operator.
static constexpr auto address_space
nda::mem::AddressSpace in which the memory is allocated.
leak_check(leak_check const &)=delete
Deleted copy constructor.
~leak_check()
Destructor that checks for memory leaks.
blk_t allocate_zero(size_t s)
Allocate memory, set it to zero and update the total memory used.
leak_check()=default
Default constructor.
blk_t allocate(size_t s)
Allocate memory and update the total memory used.
leak_check & operator=(leak_check const &)=delete
Deleted copy assignment operator.
void deallocate(blk_t b) noexcept
Deallocate memory and update the total memory used.
leak_check(leak_check &&)=default
Default move constructor.
Custom allocator that uses nda::mem::malloc to allocate memory.
mallocator & operator=(mallocator const &)=delete
Deleted copy assignment operator.
static void deallocate(blk_t b) noexcept
Deallocate memory using nda::mem::free.
mallocator & operator=(mallocator &&)=default
Default move assignment operator.
mallocator()=default
Default constructor.
mallocator(mallocator const &)=delete
Deleted copy constructor.
static blk_t allocate_zero(size_t s) noexcept
Allocate memory and set it to zero.
static blk_t allocate(size_t s) noexcept
Allocate memory using nda::mem::malloc.
static constexpr auto address_space
nda::mem::AddressSpace in which the memory is allocated.
mallocator(mallocator &&)=default
Default move constructor.
Custom allocator that uses multiple nda::mem::bucket allocators.
multi_bucket(multi_bucket &&)=default
Default move constructor.
bool owns(blk_t b) const noexcept
Check if a given nda::mem::blk_t memory block is owned by allocator.
blk_t allocate_zero(size_t s) noexcept
Allocate a chunk of memory in the current bucket or find a new one if the current one is full and set...
void deallocate(blk_t b) noexcept
Deallocate a chunk of memory from the bucket to which it belongs.
multi_bucket()
Default constructor.
bool empty() const noexcept
Check if the current allocator is empty.
static constexpr auto address_space
Only Host nda::mem::AddressSpace is supported for this allocator.
multi_bucket & operator=(multi_bucket &&)=default
Default move assignment operator.
auto const & buckets() const noexcept
Get the bucket vector.
blk_t allocate(size_t s) noexcept
Allocate a chunk of memory in the current bucket or find a new one if the current one is full.
multi_bucket(multi_bucket const &)=delete
Deleted copy constructor.
multi_bucket & operator=(multi_bucket const &)=delete
Deleted copy assignment operator.
Custom allocator that dispatches memory allocation to one of two allocators based on the size of the ...
blk_t allocate_zero(size_t s) noexcept
Allocate memory and set the memory to zero using the small allocator if the size is less than or equa...
segregator()=default
Default constructor.
segregator(segregator const &)=delete
Deleted copy constructor.
void deallocate(blk_t b) noexcept
Deallocate memory using the small allocator if the size is less than or equal to the Threshold,...
bool owns(blk_t b) const noexcept
Check if a given nda::mem::blk_t memory block is owned by the allocator.
segregator & operator=(segregator &&)=default
Default move assignment operator.
segregator(segregator &&)=default
Default move constructor.
static constexpr auto address_space
nda::mem::AddressSpace in which the memory is allocated.
segregator & operator=(segregator const &)=delete
Deleted copy assignment operator.
blk_t allocate(size_t s) noexcept
Allocate memory using the small allocator if the size is less than or equal to the Threshold,...
Wrap an allocator to gather statistics about memory allocation.
stats & operator=(stats &&)=default
Default move assignment operator.
static constexpr auto address_space
nda::mem::AddressSpace in which the memory is allocated.
blk_t allocate(uint64_t s)
Allocate memory and update the histogram.
auto const & histogram() const noexcept
Get the histogram of the allocation sizes.
void print_histogram(std::ostream &os) const
Print the histogram to a std::ostream.
blk_t allocate_zero(uint64_t s)
Allocate memory, set it to zero and update the histogram.
~stats()
Destructor that outputs the statistics about the memory allocation in debug mode.
stats & operator=(stats const &)=delete
Deleted copy assignment operator.
bool owns(blk_t b) const noexcept
Check if a given nda::mem::blk_t memory block is owned by the base allocator.
stats(stats const &)=delete
Deleted copy constructor.
void deallocate(blk_t b) noexcept
Deallocate memory.
stats(stats &&)=default
Default move constructor.
stats()=default
Default constructor.
#define CUSOLVER_CHECK(X, info,...)
#define NDA_RUNTIME_ERROR
auto rand(std::array< Int, Rank > const &shape)
Make an array of the given shape and initialize it with random values from the uniform distribution o...
decltype(auto) make_regular(A &&a)
Make a given object regular.
void resize_or_check_if_view(A &a, std::array< long, A::rank > const &sha)
Resize a given regular array to the given shape or check if a given view as the correct shape.
decltype(auto) to_unified(A &&a)
Convert an nda::MemoryArray to its regular type on unified memory.
auto make_const_view(basic_array< T, R, LP, A, CP > const &a)
Make an nda::basic_array_view with a const value type from a given nda::basic_array.
auto zeros(Ints... is)
Make an array of the given shape on the given address space and zero-initialize it.
auto zeros(std::array< Int, Rank > const &shape)
Make an array of the given shape on the given address space and zero-initialize it.
auto rand(Ints... is)
Make an array of the given dimensions and initialize it with random values from the uniform distribut...
auto arange(long first, long last, long step=1)
Make a 1-dimensional integer array and initialize it with values of a given nda::range.
decltype(auto) to_host(A &&a)
Convert an nda::MemoryArray to its regular type on host memory.
auto make_matrix_view(basic_array_view< T, R, LP, A, AP, OP > const &a)
Make an nda::matrix_view of a given nda::basic_array_view.
auto arange(long last)
Make a 1-dimensional integer array and initialize it with values of a given nda::range with a step si...
auto make_matrix_view(basic_array< T, R, LP, A, CP > const &a)
Make an nda::matrix_view of a given nda::basic_array.
auto ones(Ints... is)
Make an array with the given dimensions and one-initialize it.
auto make_const_view(basic_array_view< T, R, LP, A, AP, OP > const &a)
Make an nda::basic_array_view with a const value type from a given nda::basic_array_view.
decltype(auto) to_device(A &&a)
Convert an nda::MemoryArray to its regular type on device memory.
auto make_array_view(basic_array< T, R, LP, A, CP > const &a)
Make an nda::array_view of a given nda::basic_array.
auto make_array_const_view(basic_array< T, R, LP, A, CP > const &a)
Make an nda::array_const_view of a given nda::basic_array.
auto ones(std::array< Int, Rank > const &shape)
Make an array of the given shape and one-initialize it.
auto make_array_const_view(basic_array_view< T, R, LP, A, AP, OP > const &a)
Make an nda::array_const_view of a given nda::basic_array_view.
auto make_array_view(basic_array_view< T, R, LP, A, AP, OP > const &a)
Make an nda::array_view of a given nda::basic_array_view.
auto concatenate(A0 const &a0, As const &...as)
Join a sequence of nda::Array types along an existing axis.
long first_dim(A const &a)
Get the extent of the first dimension of the array.
constexpr bool is_view_v< basic_array_view< ValueType, Rank, Layout, Algebra, AccessorPolicy, OwningPolicy > >
Specialization of nda::is_view_v for nda::basic_array_view.
constexpr bool is_regular_v< basic_array< ValueType, Rank, Layout, Algebra, ContainerPolicy > >
Specialization of nda::is_regular_v for nda::basic_array.
constexpr char get_algebra< basic_array_view< ValueType, Rank, Layout, Algebra, AccessorPolicy, OwningPolicy > >
Specialization of nda::get_algebra for nda::basic_array_view types.
constexpr char get_algebra< basic_array< ValueType, Rank, Layout, Algebra, ContainerPolicy > >
Specialization of nda::get_algebra for nda::basic_array types.
constexpr uint64_t static_extents(int i0, Is... is)
Encode the given shape into a single integer using the nda::encode function.
constexpr char get_algebra< expr_unary< OP, A > >
Specialization of nda::get_algebra for nda::expr_unary types.
bool operator==(LHS const &lhs, RHS const &rhs)
Equal-to comparison operator for two nda::Array objects.
long second_dim(A const &a)
Get the extent of the second dimension of the array.
constexpr char get_algebra< expr< OP, L, R > >
Specialization of nda::get_algebra for nda::expr types.
__inline__ void clef_auto_assign(expr< tags::terminal, T > const &ex, RHS &&rhs)
Overload of clef_auto_assign function for terminal expressions.
__inline__ void clef_auto_assign(std::reference_wrapper< T > wrapper, RHS &&rhs)
Overload of clef_auto_assign function for std::reference_wrapper objects.
__inline__ void operator<<(expr< tags::function, F, placeholder< Is >... > const &ex, RHS &&rhs)
Assign values to the underlying object of a lazy function call expression.
__inline__ void clef_auto_assign_subscript(std::reference_wrapper< T > wrapper, RHS &&rhs)
Overload of clef_auto_assign_subscript function for std::reference_wrapper objects.
__inline__ void clef_auto_assign_subscript(expr< Tag, Childs... > const &ex, RHS const &rhs)
Overload of clef_auto_assign_subscript function for generic expressions.
__inline__ void clef_auto_assign_subscript(expr< tags::terminal, T > const &ex, RHS &&rhs)
Overload of clef_auto_assign_subscript function for terminal expressions.
__inline__ void clef_auto_assign(expr< Tag, Childs... > const &ex, RHS const &rhs)
Overload of clef_auto_assign function for generic expressions.
void clef_auto_assign(A &&a, F &&f)
Overload of nda::clef::clef_auto_assign function for nda::Array objects.
__inline__ void operator<<(expr< tags::subscript, T, placeholder< Is >... > const &ex, RHS &&rhs)
Assign values to the underlying object of a lazy subscript expression.
__inline__ decltype(auto) eval(T const &obj, Pairs &&...pairs)
Generic function to evaluate expressions and other types.
__inline__ auto make_function(T &&obj, Phs...)
Factory function for nda::clef::make_fun_impl objects.
__inline__ auto if_else(C &&c, A &&a, B &&b)
Create a lazy ternary (if-else) expression.
#define CLEF_OPERATION(TAG, OP)
auto make_expr(T &&t)
Create a terminal expression node of an object.
__inline__ auto op_dispatch(std::true_type, Args &&...args)
Dispatch operations containing at least one lazy operand.
__inline__ decltype(auto) op_dispatch(std::false_type, Args &&...args)
Dispatch operations containing only non-lazy operands.
auto make_expr_subscript(T &&t, Args &&...args)
Create a subscript expression from an object and a list of arguments.
auto make_expr_call(F &&f, Args &&...args)
Create a function call expression from a callable object and a list of arguments.
auto make_expr_from_clone(T &&t)
Create a terminal expression node of an object.
constexpr bool is_clef_expression
Alias template for nda::clef::is_any_lazy.
constexpr bool is_lazy
Constexpr variable that is true if the type T is a lazy type.
constexpr bool force_copy_in_expr
Constexpr variable that is true if objects of type T should be forced to be copied into an expression...
constexpr bool is_function
Constexpr variable that is true if the type T is an nda::clef::make_fun_impl type.
constexpr bool is_any_lazy
Constexpr variable that is true if any of the given types is lazy.
constexpr uint64_t C_stride_order
C/Row-major stride order.
constexpr uint64_t Fortran_stride_order
Fortran/Column-major stride order.
__inline__ decltype(auto) slice_idx_map(idx_map< R, SE, SO, LP > const &idxm, Args const &...args)
Determine the resulting nda::idx_map when taking a slice of a given nda::idx_map.
constexpr bool layout_property_compatible(layout_prop_e from, layout_prop_e to)
Checks if two layout properties are compatible with each other.
constexpr bool has_contiguous(layout_prop_e lp)
Checks if a layout property has the contiguous property.
constexpr bool has_strided_1d(layout_prop_e lp)
Checks if a layout property has the strided_1d property.
auto get_block_layout(A const &a)
Check if a given nda::MemoryArray has a block-strided layout.
constexpr bool has_smallest_stride_is_one(layout_prop_e lp)
Checks if a layout property has the smallest_stride_is_one property.
layout_prop_e
Compile-time guarantees of the memory layout of an array/view.
AddressSpace
Enum providing identifiers for the different memory address spaces.
static constexpr bool have_host_compatible_addr_space
Constexpr variable that is true if all given types have an address space compatible with Host.
static constexpr bool have_compatible_addr_space
Constexpr variable that is true if all given types have compatible address spaces.
constexpr AddressSpace combine
Promotion rules for nda::mem::AddressSpace values.
static constexpr bool have_device_compatible_addr_space
Constexpr variable that is true if all given types have an address space compatible with Device.
static constexpr bool on_device
Constexpr variable that is true if all given types have a Device address space.
static constexpr bool on_unified
Constexpr variable that is true if all given types have a Unified address space.
static constexpr AddressSpace get_addr_space
Variable template providing the address space for different types.
static constexpr bool on_host
Constexpr variable that is true if all given types have a Host address space.
constexpr AddressSpace common_addr_space
Get common address space for a number of given nda::MemoryArray types.
static const auto check_adr_sp_valid
Check validity of a set of nda::mem::AddressSpace values.
static constexpr bool have_same_addr_space
Constexpr variable that is true if all given types have the same address space.
static constexpr bool have_cuda
Constexpr variable that is true if the project is configured with CUDA support.
void memset2D(void *ptr, size_t pitch, int value, size_t width, size_t height)
Call CUDA's cudaMemset2D function or simulate its behavior on the Host based on the given address spa...
#define device_error_check(ARG1, ARG2)
Trigger a compilation error every time the nda::device_error_check function is called.
static constexpr bool have_device
Constexpr variable that is true if the project is configured with GPU support.
static constexpr bool init_dcmplx
Should we initialize memory for complex double types to zero.
void * malloc(size_t size)
Call the correct malloc function based on the given address space.
static constexpr do_not_initialize_t do_not_initialize
Instance of nda::mem::do_not_initialize_t.
void memset(void *p, int value, size_t count)
Call the correct memset function based on the given address space.
void memcpy(void *dest, void const *src, size_t count)
Call the correct memcpy function based on the given address spaces.
static constexpr init_zero_t init_zero
Instance of nda::mem::init_zero_t.
void free(void *p)
Call the correct free function based on the given address space.
constexpr std::array< int, N > transposition(int i, int j)
Get the permutation representing a single given transposition.
constexpr std::array< Int, N > inverse(std::array< Int, N > const &p)
Inverse of a permutation.
constexpr std::array< int, N > decode(uint64_t binary_representation)
Decode a uint64_t into a std::array<int, N>.
constexpr bool is_valid(std::array< Int, N > const &p)
Check if a given array is a valid permutation.
constexpr std::array< T, N > apply_inverse(std::array< Int, N > const &p, std::array< T, N > const &a)
Apply the inverse of a permutation to a std::array.
constexpr std::array< int, N > identity()
Get the identity permutation.
constexpr uint64_t encode(std::array< int, N > const &a)
Encode a std::array<int, N> in a uint64_t.
constexpr std::array< int, N > reverse_identity()
Get the reverse identity permutation.
constexpr std::array< int, N > cycle(int p, int pos=N)
Perform a forward (partial) cyclic permutation of the identity p times.
constexpr std::array< Int, N > compose(std::array< Int, N > const &p1, std::array< Int, N > const &p2)
Composition of two permutations.
constexpr std::array< T, N > apply(std::array< Int, N > const &p, std::array< T, N > const &a)
Apply a permutation to a std::array.
constexpr std::array< T, R > operator*(std::array< T, R > const &lhs, std::array< T, R > const &rhs)
Multiply two std::array objects element-wise.
constexpr std::array< T, R - N > front_mpop(std::array< T, R > const &a)
Make a new std::array by popping the first N elements of an existing std::array.
constexpr std::array< T, R+1 > append(std::array< T, R > const &a, U const &x)
Make a new std::array by appending one element at the end to an existing std::array.
constexpr std::array< T, R+1 > front_append(std::array< T, R > const &a, U const &x)
Make a new std::array by prepending one element at the front to an existing std::array.
constexpr std::array< T, R - 1 > pop(std::array< T, R > const &a)
Make a new std::array by popping the last element of an existing std::array.
constexpr std::array< T, R > operator+(std::array< T, R > const &lhs, std::array< T, R > const &rhs)
Add two std::array objects element-wise.
constexpr std::array< T, R > operator-(std::array< T, R > const &a)
Negate a std::array element-wise (unary minus).
constexpr std::array< T, R1+R2 > join(std::array< T, R1 > const &a1, std::array< T, R2 > const &a2)
Make a new std::array by joining two existing std::array objects.
constexpr std::array< T, R > operator*(T s, std::array< T, R > const &a)
Multiply a scalar and a std::array element-wise.
constexpr std::vector< T > to_vector(std::array< T, R > const &a)
Convert a std::array to a std::vector.
constexpr std::array< T, R > make_initialized_array(T v)
Create a new std::array object initialized with a specific value.
constexpr auto sum(std::array< T, R > const &a)
Calculate the sum of all elements in a std::array.
std::string to_string(std::array< T, R > const &a)
Get a string representation of a std::array.
constexpr std::array< T, R > operator-(std::array< T, R > const &lhs, std::array< T, R > const &rhs)
Subtract two std::array objects element-wise.
constexpr std::array< T, R > make_std_array(std::array< U, R > const &a)
Convert a std::array with value type U to a std::array with value type T.
constexpr std::array< T, R - 1 > front_pop(std::array< T, R > const &a)
Make a new std::array by popping the first element of an existing std::array.
constexpr auto product(std::array< T, R > const &a)
Calculate the product of all elements in a std::array.
constexpr auto dot_product(std::array< T, R > const &a1, std::array< U, R > const &a2)
Calculate the dot product of two std::array objects.
constexpr std::array< T, R - N > mpop(std::array< T, R > const &a)
Make a new std::array by popping the last N elements of an existing std::array.
#define EXPECTS_WITH_MESSAGE(X,...)
Contiguous layout policy with C-order (row-major order).
Strided (non-contiguous) layout policy with C-order (row-major order).
Contiguous layout policy with Fortran-order (column-major order).
Strided (non-contiguous) layout policy with Fortran-order (column-major order).
A small wrapper around a single long integer to be used as a linear index.
Generic layout policy with arbitrary order.
Memory policy using an nda::mem::handle_borrowed.
static constexpr bool is_lazy
Constexpr variable that is true if any of the evaluators of the child nodes is lazy.
__inline__ decltype(auto) operator()(expr< Tag, Childs... > const &ex, Pairs &...pairs) const
Evaluate the given expression by applying the given nda::clef::pair objects.
__inline__ decltype(auto) operator()(make_fun_impl< T, Is... > const &f, Pairs &...pairs) const
Evaluate the nda::clef::make_fun_impl object.
static constexpr bool is_lazy
Constexpr variable that is true if all the placeholders are assigned a value.
static constexpr bool is_lazy
Constexpr variable that is true if the there is no nda::clef::pair containing an nda::clef::placehold...
__inline__ decltype(auto) operator()(placeholder< N >, pair< Is, Ts > &...pairs) const
Evaluate the placeholder.
static constexpr bool is_lazy
Constexpr variable that is always false.
__inline__ decltype(auto) operator()(std::reference_wrapper< T > const &wrapper, Pairs const &...pairs) const
Evaluate the std::reference_wrapper by redirecting the evaluation to the object contained in the wrap...
Generic evaluator for types which do not have a specialized evaluator.
__inline__ T const & operator()(T const &t, Pairs &...) const
Evaluate the object and ignore all given nda::clef::pair objects.
static constexpr bool is_lazy
Constexpr variable that is true if the type T is lazy.
Single node of the expression tree.
expr & operator=(expr const &)=delete
Copy assignment operator is deleted.
expr(expr &&ex) noexcept
Move constructor simply moves the child nodes from the source expression.
auto operator[](Args &&...args) const
Subscript operator.
expr & operator=(expr &&)=default
Default move assignment operator.
expr(expr const &)=default
Default copy constructor.
expr(Tag, Us &&...us)
Construct an expression node with a given tag and child nodes.
childs_t childs
Child nodes of the current expression node.
auto operator()(Args &&...args) const
Function call operator.
Helper struct to simplify calls to nda::clef::eval.
T obj
Object to be evaluated.
__inline__ decltype(auto) operator()(Args &&...args) const
Function call operator.
A pair consisting of a placeholder and its assigned value.
T rhs
Value assigned to the placeholder (can be an lvalue reference).
static constexpr int p
Integer label of the placeholder.
A placeholder is an empty struct, labelled by an int.
static constexpr int index
Integer label.
auto operator[](T &&t) const
Subscript operator.
pair< N, RHS > operator=(RHS &&rhs) const
Assign a value to the placeholder.
auto operator()(Args &&...args) const
Function call operator.
Accessor type of the nda::default_accessor.
static __inline__ T * offset(pointer p, std::ptrdiff_t i) noexcept
Offset the pointer by a certain number of elements.
static __inline__ reference access(pointer p, std::ptrdiff_t i) noexcept
Access a specific element of the data.
Default accessor for various array and view types.
Mimics Python's ... syntax.
A lazy function call expression on arrays/views.
Lazy unary expression for nda::Array types.
Lazy binary expression for nda::ArrayOrScalar types.
Memory policy using an nda::mem::handle_heap.
Stores information about the memory layout and the stride order of an array/view.
Wraps an arbitrary type to have a specified alignment.
T & get() noexcept
Get reference to the wrapped object.
T const & get() const noexcept
Get const reference to the wrapped object.
T x
Wrapped object of type T.
Memory block consisting of a pointer and its size.
char * ptr
Pointer to the memory block.
size_t s
Size of the memory block in bytes.
Tag used in constructors to indicate that the memory should not be initialized.
A non-owning handle for a memory block on the heap.
handle_borrowed(T *ptr) noexcept
Construct a borrowed handle from a pointer to the data.
handle_heap< T0 > const * parent() const
Get a pointer to the parent handle.
handle_borrowed(H const &h, long offset=0) noexcept
Construct a borrowed handle from a another handle.
static constexpr auto address_space
nda::mem::AddressSpace in which the memory is allocated.
handle_borrowed & operator=(handle_borrowed &&)=default
Default move assignment operator.
handle_borrowed & operator=(handle_borrowed const &)=default
Default copy assignment operator.
handle_borrowed()=default
Default constructor leaves the handle in a null state (nullptr).
T & operator[](long i) noexcept
Subscript operator to access the data.
bool is_null() const noexcept
Check if the handle is in a null state.
T const & operator[](long i) const noexcept
Subscript operator to access the data.
handle_borrowed(handle_borrowed const &)=default
Default copy constructor.
T * data() const noexcept
Get a pointer to the stored data.
A handle for a memory block on the heap.
long size() const noexcept
Get the size of the handle.
~handle_heap() noexcept
Destructor for the handle.
handle_heap & operator=(handle_heap const &h)
Copy assignment operator utilizes the copy constructor and move assignment operator to make a deep co...
T const & operator[](long i) const noexcept
Subscript operator to access the data.
handle_heap(handle_heap &&h) noexcept
Move constructor simply copies the pointers and size and resets the source handle to a null state.
handle_heap(long size, init_zero_t)
Construct a handle by allocating memory for the data of a given size and initializing it to zero.
T * data() const noexcept
Get a pointer to the stored data.
handle_heap(long size)
Construct a handle by allocating memory for the data of a given size and initializing it depending on...
handle_heap & operator=(handle_heap< T, AS > const &h)
Assignment operator utilizes another constructor and move assignment to make a deep copy of the data ...
handle_heap(long size, do_not_initialize_t)
Construct a handle by allocating memory for the data of a given size but without initializing it.
bool is_null() const noexcept
Check if the handle is in a null state.
handle_heap(handle_heap const &h)
Copy constructor makes a deep copy of the data from another handle.
T & operator[](long i) noexcept
Subscript operator to access the data.
static constexpr auto address_space
nda::mem::AddressSpace in which the memory is allocated.
handle_heap & operator=(handle_heap &&h) noexcept
Move assignment operator first releases the resources held by the current handle and then moves the r...
handle_heap()=default
Default constructor leaves the handle in a null state (nullptr and size 0).
std::shared_ptr< void > get_sptr() const
Get a shared pointer to the memory block.
handle_heap(H const &h)
Construct a handle by making a deep copy of the data from another handle.
A handle for a memory block on the heap with shared ownership.
handle_shared(handle_heap< T, A > const &h) noexcept
Construct a shared handle from an nda::mem::handle_heap.
handle_shared()=default
Default constructor leaves the handle in a null state (nullptr and size 0).
T & operator[](long i) noexcept
Subscript operator to access the data.
static constexpr auto address_space
nda::mem::AddressSpace in which the memory is allocated.
long refcount() const noexcept
Get the reference count of the shared object.
bool is_null() const noexcept
Check if the handle is in a null state.
T const & operator[](long i) const noexcept
Subscript operator to access the data.
handle_shared(T *data, size_t size, void *foreign_handle, void(*foreign_decref)(void *)) noexcept
Construct a handle from a shared object from a foreign library.
T * data() const noexcept
Get a pointer to the stored data.
long size() const noexcept
Get the size of the handle.
A handle for a memory block on the heap or stack depending on the size of the data.
static constexpr auto address_space
nda::mem::AddressSpace in which the memory is allocated.
handle_sso()
Default constructor.
long size() const noexcept
Get the size of the handle.
~handle_sso() noexcept
Destructor for the handle.
T & operator[](long i) noexcept
Subscript operator to access the data.
bool is_null() const noexcept
Check if the handle is in a null state.
handle_sso & operator=(handle_sso const &h) noexcept
Copy assignment operator first cleans up the current handle and then makes a deep copy of the data fr...
handle_sso & operator=(handle_sso &&h) noexcept
Move assignment operator first releases the resources held by the current handle and then either copi...
handle_sso(long size)
Construct a handle for the data of a given size and initialize it depending on the value type.
handle_sso(handle_sso const &h)
Copy construct a handle by making a deep copy of the data from the source handle.
T * data() const noexcept
Get a pointer to the stored data.
bool on_heap() const
Check if the data is/should be stored on the heap.
handle_sso(long size, do_not_initialize_t)
Construct a handle for the data of a given size and do not initialize it.
handle_sso(long size, init_zero_t)
Construct a handle for the data of a given size and initialize it to zero (only for scalar and comple...
handle_sso(handle_sso &&h) noexcept
Move constructor either copies the heap pointers or makes a deep copy of the stack data.
handle_sso(H const &h)
Construct a handle by making a deep copy of the data from another owning handle.
T const & operator[](long i) const noexcept
Subscript operator to access the data.
A handle for a memory block on the stack.
static constexpr auto address_space
nda::mem::AddressSpace in which the memory is allocated (always on Host).
handle_stack()=default
Default constructor leaves the data uninitialized.
handle_stack(long)
Construct a handle and initialize the data depending on the value type.
T & operator[](long i) noexcept
Subscript operator to access the data.
T * data() const noexcept
Get a pointer to the stored data.
handle_stack & operator=(handle_stack const &h)
Copy assignment operator makes a deep copy of the data from the source handle using placement new.
~handle_stack() noexcept
Destructor for the handle.
handle_stack(handle_stack const &h) noexcept
Copy constructor simply calls the copy assignment operator.
handle_stack(long, do_not_initialize_t)
Construct a handle and do not initialize the data.
handle_stack(handle_stack &&h) noexcept
Move constructor simply calls the copy assignment operator.
handle_stack & operator=(handle_stack &&h) noexcept
Move assignment operator simply calls the copy assignment operator.
handle_stack(long, init_zero_t)
Construct a handle and initialize the data to zero (only for scalar and complex types).
static constexpr long size() noexcept
Get the size of the handle.
static constexpr bool is_null() noexcept
Check if the handle is in a null state.
T const & operator[](long i) const noexcept
Subscript operator to access the data.
Tag used in constructors to indicate that the memory should be initialized to zero.
Accessor type of the nda::no_alias_accessor.
static __inline__ reference access(pointer p, std::ptrdiff_t i) noexcept
Access a specific element of the data.
static __inline__ T * offset(pointer p, std::ptrdiff_t i) noexcept
Offset the pointer by a certain number of elements.
Accessor for array and view types with no aliasing.
Memory policy using an nda::mem::handle_shared.
Memory policy using an nda::mem::handle_sso.
Memory policy using an nda::mem::handle_stack.