47#include <initializer_list>
53#ifdef NDA_ENFORCE_BOUNDCHECK
112 template <
typename ValueType,
int Rank,
typename LayoutPolicy,
char Algebra,
typename ContainerPolicy>
115 static_assert(!std::is_const_v<ValueType>,
"Error in nda::basic_array: ValueType cannot be const");
116 static_assert((Algebra !=
'N'),
"Internal error in nda::basic_array: Algebra 'N' not supported");
117 static_assert((Algebra !=
'M') or (Rank == 2),
"Internal error in nda::basic_array: Algebra 'M' requires a rank 2 array");
118 static_assert((Algebra !=
'V') or (Rank == 1),
"Internal error in nda::basic_array: Algebra 'V' requires a rank 1 array");
128 using layout_t =
typename LayoutPolicy::template mapping<Rank>;
134 using storage_t =
typename ContainerPolicy::template handle<ValueType>;
140 static constexpr int rank = Rank;
143 static_assert(
has_contiguous(layout_t::layout_prop),
"Error in nda::basic_array: Memory layout has to be contiguous");
156 static constexpr bool is_const =
false;
159 static constexpr bool is_view =
false;
168 template <std::
integral Int =
long>
216 template <
char A,
typename CP>
228 template <std::integral... Ints>
229 requires(
sizeof...(Ints) == Rank)
232 lay =
layout_t{std::array{long(is)...}};
244 template <std::
integral Int,
typename RHS>
248 assign_from_scalar(val);
259 template <std::
integral Int =
long>
261 requires(std::is_default_constructible_v<ValueType>)
272 requires(std::is_default_constructible_v<ValueType>)
273 : lay{layout}, sto{lay.
size()} {}
291 template <ArrayOfRank<Rank> A>
292 requires(HasValueTypeConstructibleFrom<A, ValueType>)
294 static_assert(std::is_constructible_v<ValueType, get_value_t<A>>,
"Error in nda::basic_array: Incompatible value types in constructor");
297 if constexpr (std::is_same_v<ValueType, get_value_t<A>>)
298 assign_from_ndarray(a);
300 assign_from_ndarray(
nda::map([](
auto const &val) {
return ValueType(val); })(a));
303 nda::for_each(lay.lengths(), [&](
auto const &...is) { new (sto.data() + lay(is...)) ValueType{a(is...)}; });
316 template <ArrayInitializer<basic_array> Initializer>
318 initializer.invoke(*
this);
323 static std::array<long, 1> shape_from_init_list(std::initializer_list<ValueType>
const &l)
noexcept {
return {long(l.size())}; }
326 template <
typename L>
327 static auto shape_from_init_list(std::initializer_list<L>
const &l)
noexcept {
328 const auto [min, max] = std::minmax_element(std::begin(l), std::end(l), [](
auto &&x,
auto &&y) {
return x.size() < y.size(); });
329 EXPECTS_WITH_MESSAGE(min->size() == max->size(),
330 "Error in nda::basic_array: Arrays can only be initialized with rectangular initializer lists");
343 for (
auto const &x : l) {
new (sto.data() + lay(i++)) ValueType{x}; }
350 basic_array(std::initializer_list<std::initializer_list<ValueType>>
const &l2)
352 : lay(shape_from_init_list(l2)), sto{lay.size(), mem::do_not_initialize} {
354 for (
auto const &l1 : l2) {
355 for (
auto const &x : l1) {
new (sto.data() + lay(i, j++)) ValueType{x}; }
365 basic_array(std::initializer_list<std::initializer_list<std::initializer_list<ValueType>>>
const &l3)
367 : lay(shape_from_init_list(l3)), sto{lay.size(), mem::do_not_initialize} {
368 long i = 0, j = 0, k = 0;
369 for (
auto const &l2 : l3) {
370 for (
auto const &l1 : l2) {
371 for (
auto const &x : l1) {
new (sto.data() + lay(i, j, k++)) ValueType{x}; }
392 :
basic_array{a.indexmap(), std::move(a).storage()} {}
401 template <std::
integral Int =
long>
403 requires(std::is_standard_layout_v<ValueType> && std::is_trivially_copyable_v<ValueType>)
415 template <std::integral... Ints>
417 requires(
sizeof...(Ints) == Rank)
419 return zeros(std::array<long, Rank>{is...});
429 template <std::
integral Int =
long>
434 res() = ValueType{1};
445 template <std::integral... Ints>
447 requires(
sizeof...(Ints) == Rank)
449 return ones(std::array<long, Rank>{is...});
462 template <std::
integral Int =
long>
466 using namespace std::complex_literals;
467 auto static gen = std::mt19937(std::random_device{}());
470 auto static dist = std::uniform_real_distribution<typename ValueType::value_type>(0.0, 1.0);
471 for (
auto &x : res) x = dist(gen) + 1i * dist(gen);
473 auto static dist = std::uniform_real_distribution<ValueType>(0.0, 1.0);
474 for (
auto &x : res) x = dist(gen);
489 template <std::integral... Ints>
491 requires(
sizeof...(Ints) == Rank)
493 return rand(std::array<long, Rank>{is...});
512 template <
char A,
typename CP>
527 template <ArrayOfRank<Rank> RHS>
530 assign_from_ndarray(rhs);
544 template <
typename RHS>
548 assign_from_scalar(rhs);
561 template <ArrayInitializer<basic_array> Initializer>
563 resize(initializer.shape());
564 initializer.invoke(*
this);
578 template <std::integral... Ints>
580 static_assert(std::is_copy_constructible_v<ValueType>,
"Error in nda::basic_array: Resizing requires the value_type to be copy constructible");
581 static_assert(
sizeof...(is) == Rank,
"Error in nda::basic_array: Resizing requires exactly Rank arguments");
582 resize(std::array<long, Rank>{long(is)...});
594 [[gnu::noinline]]
void resize(std::array<long, Rank>
const &shape) {
596 if (sto.is_null() or (sto.size() != lay.size())) sto =
storage_t{lay.size()};
620[[nodiscard]]
constexpr auto const &
indexmap() const noexcept {
return lay; }
646[[nodiscard]]
constexpr auto stride_order() const noexcept {
return lay.stride_order; }
652[[nodiscard]] ValueType
const *
data() const noexcept {
return sto.data(); }
658[[nodiscard]] ValueType *
data() noexcept {
return sto.data(); }
664[[nodiscard]]
auto const &
shape() const noexcept {
return lay.lengths(); }
670[[nodiscard]]
auto const &
strides() const noexcept {
return lay.strides(); }
676[[nodiscard]]
long size() const noexcept {
return lay.size(); }
682[[nodiscard]]
long is_contiguous() const noexcept {
return lay.is_contiguous(); }
694[[nodiscard]]
bool empty()
const {
return sto.is_null(); }
697[[nodiscard]]
bool is_empty() const noexcept {
return sto.is_null(); }
703[[nodiscard]]
long extent(
int i)
const noexcept {
704#ifdef NDA_ENFORCE_BOUNDCHECK
705 if (i < 0 || i >= rank) {
706 std::cerr <<
"Error in extent: Dimension " << i <<
" is incompatible with array of rank " << rank << std::endl;
710 return lay.lengths()[i];
714[[nodiscard]]
long shape(
int i)
const noexcept {
return extent(i); }
720[[nodiscard]]
auto indices() const noexcept {
return itertools::product_range(shape()); }
744 if constexpr (layout_t::layout_prop == layout_prop_e::strided_1d)
745 return sto[idx.value * lay.min_stride()];
746 else if constexpr (layout_t::layout_prop == layout_prop_e::contiguous)
747 return sto[idx.value];
749 static_assert(
always_false<layout_t>,
"Internal error in array/view: Calling this type with a _linear_index_t is not allowed");
754 if constexpr (layout_t::layout_prop == layout_prop_e::strided_1d)
755 return sto[idx.value * lay.min_stride()];
756 else if constexpr (layout_t::layout_prop == layout_prop_e::contiguous)
757 return sto[idx.value];
759 static_assert(
always_false<layout_t>,
"Internal error in array/view: Calling this type with a _linear_index_t is not allowed");
764#ifdef NDA_ENFORCE_BOUNDCHECK
765static constexpr bool has_no_boundcheck =
false;
767static constexpr bool has_no_boundcheck =
true;
787template <
char ResultAlgebra,
bool SelfIsRvalue,
typename Self,
typename... Ts>
788FORCEINLINE
static decltype(
auto)
call(Self &&self, Ts
const &...idxs)
noexcept(has_no_boundcheck) {
790 using r_v_t = std::conditional_t<std::is_const_v<std::remove_reference_t<Self>>, ValueType
const, ValueType>;
796 }
else if constexpr (
sizeof...(Ts) == 0) {
801 static_assert(((layout_t::template argument_is_allowed_for_call_or_slice<Ts> + ...) > 0),
802 "Error in array/view: Slice arguments must be convertible to range, ellipsis, or long (or string if the layout permits it)");
805 static constexpr int n_args_long = (layout_t::template argument_is_allowed_for_call<Ts> + ...);
807 if constexpr (n_args_long == rank) {
809 long offset = self.lay(idxs...);
810 if constexpr (is_view or not SelfIsRvalue) {
812 return AccessorPolicy::template accessor<r_v_t>::access(self.sto.data(), offset);
815 return ValueType{self.sto[offset]};
819 auto const [offset, idxm] = self.lay.slice(idxs...);
820 static constexpr auto res_rank =
decltype(idxm)::rank();
822 static constexpr char newAlgebra = (ResultAlgebra ==
'M' and (res_rank == 1) ?
'V' : ResultAlgebra);
824 using r_layout_p =
typename detail::layout_to_policy<std::decay_t<
decltype(idxm)>>::type;
852template <
typename... Ts>
853FORCEINLINE
decltype(
auto)
operator()(Ts
const &...idxs)
const &
noexcept(has_no_boundcheck) {
854 static_assert((rank == -1) or (
sizeof...(Ts) == rank) or (
sizeof...(Ts) == 0) or (
ellipsis_is_present<Ts...> and (
sizeof...(Ts) <= rank + 1)),
855 "Error in array/view: Incorrect number of parameters in call operator");
856 return call<Algebra, false>(*
this, idxs...);
860template <
typename... Ts>
861FORCEINLINE
decltype(
auto)
operator()(Ts
const &...idxs) &
noexcept(has_no_boundcheck) {
862 static_assert((rank == -1) or (
sizeof...(Ts) == rank) or (
sizeof...(Ts) == 0) or (
ellipsis_is_present<Ts...> and (
sizeof...(Ts) <= rank + 1)),
863 "Error in array/view: Incorrect number of parameters in call operator");
864 return call<Algebra, false>(*
this, idxs...);
868template <
typename... Ts>
869FORCEINLINE
decltype(
auto)
operator()(Ts
const &...idxs) &&
noexcept(has_no_boundcheck) {
870 static_assert((rank == -1) or (
sizeof...(Ts) == rank) or (
sizeof...(Ts) == 0) or (
ellipsis_is_present<Ts...> and (
sizeof...(Ts) <= rank + 1)),
871 "Error in array/view: Incorrect number of parameters in call operator");
872 return call<Algebra, true>(*
this, idxs...);
893decltype(
auto)
operator[](T
const &idx)
const &
noexcept(has_no_boundcheck) {
894 static_assert((rank == 1),
"Error in array/view: Subscript operator is only available for rank 1 views/arrays in C++17/20");
895 return call<Algebra, false>(*
this, idx);
900decltype(
auto)
operator[](T
const &x) &
noexcept(has_no_boundcheck) {
901 static_assert((rank == 1),
"Error in array/view: Subscript operator is only available for rank 1 views/arrays in C++17/20");
902 return call<Algebra, false>(*
this, x);
907decltype(
auto)
operator[](T
const &x) &&
noexcept(has_no_boundcheck) {
908 static_assert((rank == 1),
"Error in array/view: Subscript operator is only available for rank 1 views/arrays in C++17/20");
909 return call<Algebra, true>(*
this, x);
913static constexpr int iterator_rank = (
has_strided_1d(layout_t::layout_prop) ? 1 : Rank);
923template <
typename Iterator>
924[[nodiscard]]
auto make_iterator(
bool at_end)
const noexcept {
925 if constexpr (iterator_rank == Rank) {
927 if constexpr (layout_t::is_stride_order_C()) {
929 return Iterator{indexmap().lengths(), indexmap().strides(), sto.data(), at_end};
937 return Iterator{std::array<long, 1>{size()}, std::array<long, 1>{indexmap().min_stride()}, sto.data(), at_end};
952[[nodiscard]]
const_iterator end() const noexcept {
return make_iterator<const_iterator>(
true); }
972template <
typename RHS>
974 static_assert(not is_const,
"Error in array/view: Can not assign to a const view");
975 return operator=(*
this + rhs);
990template <
typename RHS>
992 static_assert(not is_const,
"Error in array/view: Can not assign to a const view");
993 return operator=(*
this - rhs);
1008template <
typename RHS>
1010 static_assert(not is_const,
"Error in array/view: Can not assign to a const view");
1011 return operator=((*
this) * rhs);
1026template <
typename RHS>
1028 static_assert(not is_const,
"Error in array/view: Can not assign to a const view");
1029 return operator=(*
this / rhs);
1040template <std::ranges::contiguous_range R>
1050template <
typename RHS>
1051void assign_from_ndarray(RHS
const &rhs) {
1052#ifdef NDA_ENFORCE_BOUNDCHECK
1053 if (this->shape() != rhs.shape())
1054 NDA_RUNTIME_ERROR <<
"Error in assign_from_ndarray: Size mismatch:"
1055 <<
"\n LHS.shape() = " << this->shape() <<
"\n RHS.shape() = " << rhs.shape();
1058 static_assert(std::is_assignable_v<value_type &, get_value_t<RHS>>,
"Error in assign_from_ndarray: Incompatible value types");
1067 if constexpr (both_in_memory and same_stride_order) {
1068 if (rhs.empty())
return;
1073 for (
long i = 0; i < size(); ++i) (*
this)(
_linear_index_t{i}) = rhs(_linear_index_t{i});
1079 if (bl_layout_dst && bl_layout_src) {
1080 auto [n_bl_dst, bl_size_dst, bl_str_dst] = *bl_layout_dst;
1081 auto [n_bl_src, bl_size_src, bl_str_src] = *bl_layout_src;
1083 if (n_bl_dst * bl_size_dst != n_bl_src * bl_size_src) NDA_RUNTIME_ERROR <<
"Error in assign_from_ndarray: Incompatible block sizes";
1085 if (n_bl_dst == 1 && n_bl_src > 1) {
1086 n_bl_dst = n_bl_src;
1087 bl_size_dst /= n_bl_src;
1088 bl_str_dst = bl_size_dst;
1090 if (n_bl_src == 1 && n_bl_dst > 1) {
1091 n_bl_src = n_bl_dst;
1092 bl_size_src /= n_bl_dst;
1093 bl_str_src = bl_size_src;
1096 if (n_bl_dst == n_bl_src && bl_size_dst == bl_size_src) {
1098 bl_str_src *
sizeof(value_type), bl_size_src *
sizeof(value_type),
1107 NDA_RUNTIME_ERROR <<
"Error in assign_from_ndarray: Fallback to elementwise assignment not implemented for arrays/views on the GPU";
1109 nda::for_each(shape(), [
this, &rhs](
auto const &...args) { (*this)(args...) = rhs(args...); });
1113template <
typename Scalar>
1114void fill_with_scalar(Scalar
const &scalar)
noexcept {
1117 const long L = size();
1118 auto *__restrict
const p = data();
1120 for (
long i = 0; i < L; ++i) p[i] = scalar;
1122 const long stri = indexmap().min_stride();
1123 const long Lstri = L * stri;
1124 for (
long i = 0; i != Lstri; i += stri) p[i] = scalar;
1128 for (
auto &x : *
this) x = scalar;
1133template <
typename Scalar>
1134void assign_from_scalar(Scalar
const &scalar)
noexcept {
1135 static_assert(!is_const,
"Error in assign_from_ndarray: Cannot assign to a const view");
1136 if constexpr (Algebra !=
'M') {
1138 fill_with_scalar(scalar);
1144 fill_with_scalar(0);
1146 fill_with_scalar(Scalar{0 * scalar});
1147 const long imax = std::min(extent(0), extent(1));
1148 for (
long i = 0; i < imax; ++i)
operator()(i, i) = scalar;
1154 template <MemoryArray A>
1155 basic_array(A &&a) -> basic_array<get_value_t<A>, get_rank<A>, get_contiguous_layout_policy<get_rank<A>, get_layout_info<A>.stride_order>,
1156 get_algebra<A>, heap<mem::get_addr_space<A>>>;
1159 basic_array(A &&a) -> basic_array<get_value_t<A>, get_rank<A>, C_layout, get_algebra<A>, heap<>>;
Defines accessors for nda::array objects (cf. std::default_accessor).
Provides definitions and type traits involving the different memory address spaces supported by nda.
Provides utility functions for std::array.
Provides the generic class for views.
Provides basic functions to create and manipulate arrays and views.
Iterator for nda::basic_array and nda::basic_array_view types.
A generic view of a multi-dimensional array.
A generic multi-dimensional array.
auto & operator+=(RHS const &rhs) noexcept
Addition assignment operator.
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.
typename ContainerPolicy::template handle< ValueType > storage_t
Type of the memory handle (see Handles).
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.
basic_array(Initializer const &initializer)
Construct an array from an nda::ArrayInitializer object.
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.
typename LayoutPolicy::template mapping< Rank > layout_t
Type of the memory layout (an nda::idx_map).
basic_array(A const &a)
Construct an array from an nda::ArrayOfRank object with the same rank by copying each element.
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.
basic_array & operator=(Initializer const &initializer)
Assignment operator uses an nda::ArrayInitializer to assign to the array.
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.
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.
bool empty() const
Is the view/array empty?
void resize(std::array< long, Rank > const &shape)
Resize the array to a new shape.
long has_positive_strides() const noexcept
Are all the strides of the memory layout of the view/array positive?
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.
LayoutPolicy layout_policy_t
Type of the memory layout policy (see Layout policies).
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 & operator=(R const &rhs) noexcept
Assignment operator makes a deep copy of a general contiguous range and assigns it to the 1-dimension...
auto as_array_view()
Convert the current array to a view with an 'A' (array) algebra.
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.
ContainerPolicy container_policy_t
Type of the container policy (see Memory policies).
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
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=(RHS const &rhs) noexcept
Assignment operator assigns a scalar to the 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.
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.
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.
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.
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.
ValueType value_type
Type of the values in the array (can not be const).
static basic_array rand(std::array< Int, Rank > const &shape)
Make a random-initialized array with the given shape.
Check if a given type satisfies the memory array concept.
Provides concepts for the nda library.
Provides a custom runtime error class and macros to assert conditions and throw exceptions.
Provides for_each functions for multi-dimensional arrays/views.
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...
auto permuted_indices_view(A &&a)
Permute the indices/dimensions of an nda::basic_array or nda::basic_array_view.
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 ones(std::array< Int, Rank > const &shape)
Make an array of the given shape and one-initialize it.
mapped< F > map(F f)
Create a lazy function call expression on arrays/views.
constexpr bool have_same_value_type_v
Constexpr variable that is true if all types in As have the same value type as A0.
auto make_expr_call(F &&f, Args &&...args)
Create a function call expression from a callable object and a list of arguments.
constexpr bool is_any_lazy
Constexpr variable that is true if any of the given types is lazy.
constexpr bool ellipsis_is_present
Constexpr variable that is true if the parameter pack Args contains an nda::ellipsis.
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.
__inline__ void for_each(std::array< Int, R > const &shape, F &&f)
Loop over all possible index values of a given shape and apply a function to them.
constexpr bool has_layout_strided_1d
Constexpr variable that is true if type A has the strided_1d nda::layout_prop_e guarantee.
auto get_block_layout(A const &a)
Check if a given nda::MemoryArray has a block-strided layout.
constexpr layout_info_t get_layout_info
Constexpr variable that specifies the nda::layout_info_t of type A.
constexpr bool has_contiguous_layout
Constexpr variable that is true if type A has the contiguous nda::layout_prop_e guarantee.
static constexpr bool on_device
Constexpr variable that is true if all given types have a Device 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.
void memcpy2D(void *dest, size_t dpitch, const void *src, size_t spitch, size_t width, size_t height)
Call CUDA's cudaMemcpy2D function or simulate its behavior on the Host based on the given address spa...
static constexpr do_not_initialize_t do_not_initialize
Instance of nda::mem::do_not_initialize_t.
static constexpr init_zero_t init_zero
Instance of nda::mem::init_zero_t.
constexpr uint64_t encode(std::array< int, N > const &a)
Encode a std::array<int, N> in a uint64_t.
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+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 > 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 bool is_complex_v
Constexpr variable that is true if type T is a std::complex type.
static constexpr bool always_false
Constexpr variable that is always false regardless of the types in Ts (used to trigger static_assert)...
constexpr bool is_scalar_for_v
Constexpr variable used to check requirements when initializing an nda::basic_array or nda::basic_arr...
constexpr bool is_scalar_v
Constexpr variable that is true if type S is a scalar type, i.e. arithmetic or complex.
constexpr bool is_scalar_or_convertible_v
Constexpr variable that is true if type S is a scalar type (see nda::is_scalar_v) or if a std::comple...
Provides an iterator for nda::basic_array and nda::basic_array_view types.
Macros used in the nda library.
Defines various memory handling policies.
Provides a generic memcpy and memcpy2D function for different address spaces.
Provides utilities to work with permutations and to compactly encode/decode std::array objects.
Includes the itertools header and provides some additional utilities.
A small wrapper around a single long integer to be used as a linear index.
Memory policy using an nda::mem::handle_borrowed.
Default accessor for various array and view types.
uint64_t stride_order
Stride order of the array/view.
Tag used in constructors to indicate that the memory should be initialized to zero.
Provides type traits for the nda library.