18
19
20
24#include "./basic_functions.hpp"
26#include "./concepts.hpp"
27#include "./declarations.hpp"
28#include "./exceptions.hpp"
29#include "./iterators.hpp"
30#include "./layout/for_each.hpp"
31#include "./layout/idx_map.hpp"
32#include "./layout/permutation.hpp"
33#include "./layout/range.hpp"
34#include "./macros.hpp"
35#include "./mem/address_space.hpp"
36#include "./mem/memcpy.hpp"
37#include "./mem/policies.hpp"
38#include "./traits.hpp"
40#include <itertools/itertools.hpp>
50#ifdef NDA_ENFORCE_BOUNDCHECK
58
59
60
61
62 template <
typename V1,
int R1,
typename LP1,
char A1,
typename AP1,
typename OP1,
typename V2,
int R2,
typename LP2,
char A2,
typename AP2,
64 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;
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 template <
typename ValueType,
int Rank,
typename LayoutPolicy,
char Algebra,
typename AccessorPolicy,
typename OwningPolicy>
129 static_assert((Algebra !=
'N'),
"Internal error in nda::basic_array_view: Algebra 'N' not supported");
130 static_assert((Algebra !=
'M')
or (Rank == 2),
"Internal error in nda::basic_array_view: Algebra 'M' requires a rank 2 view");
131 static_assert((Algebra !=
'V')
or (Rank == 1),
"Internal error in nda::basic_array_view: Algebra 'V' requires a rank 1 view");
135 using value_type = ValueType;
138 using layout_policy_t = LayoutPolicy;
141 using layout_t =
typename LayoutPolicy::
template mapping<Rank>;
144 using accessor_policy_t = AccessorPolicy;
147 using owning_policy_t = OwningPolicy;
150 using storage_t =
typename OwningPolicy::
template handle<ValueType>;
153 using regular_type =
basic_array<std::remove_const_t<ValueType>, Rank,
C_layout, Algebra, heap<mem::get_addr_space<storage_t>>>;
156 static constexpr int rank = Rank;
163 static constexpr bool is_view =
true;
166 static constexpr bool is_const = std::is_const_v<ValueType>;
175 template <
typename T,
int R,
typename L,
char A,
typename CP>
179 template <
typename T,
int R,
typename L,
char A,
typename AP,
typename OP>
183 template <
typename L>
184 static constexpr bool requires_runtime_check =
not layout_property_compatible(L::
template mapping<Rank>::layout_prop, layout_t::layout_prop);
190
191
192
193
194
195
196
206 return basic_array_view<
const ValueType, Rank, LayoutPolicy,
'A', AccessorPolicy, OwningPolicy>{*
this};
219
220
221
222
223
224
225
226
227 template <MemoryArrayOfRank<Rank> A>
228 requires((get_layout_info<A>.stride_order == layout_t::stride_order_encoded)
229 and (std::is_same_v<std::remove_const_t<ValueType>, get_value_t<A>>)
230 and (std::is_const_v<ValueType>
or !std::is_const_v<
typename std::decay_t<A>::value_type>))
233 : lay(a.indexmap()), sto(a.storage()) {}
236
237
238
239
240
241
242
243
247
248
249
250
251
252
253
254
258
259
260
261
262
268
269
270
271
272
274 requires(Rank == 1
and std::is_const_v<ValueType>)
278
279
280
281
282
283 template <
std::
ranges::contiguous_range R>
284 requires(Rank == 1
and not MemoryArray<R>
285 and (std::is_same_v<std::ranges::range_value_t<R>, ValueType>
or std::is_same_v<
const std::ranges::range_value_t<R>, ValueType>))
289
290
291
292
293
294
295
297 assign_from_ndarray(rhs);
302
303
304
305
306
307
308
309
310 template <ArrayOfRank<Rank> RHS>
312 static_assert(!is_const,
"Cannot assign to an nda::basic_array_view with const value_type");
313 assign_from_ndarray(rhs);
318
319
320
321
322
323
324
325
326
327 template <
typename RHS>
331 static_assert(!is_const,
"Cannot assign to an nda::basic_array_view with const value_type");
332 assign_from_scalar(rhs);
337
338
339
340
341
342
343
346 EXPECTS(shape() == initializer.shape());
347 initializer.invoke(*
this);
352
353
354
355
356
357
358
359
360
361
362
363
364
365 template <
typename T,
int R,
typename LP,
char A,
typename AP,
typename OP>
367 static_assert(R == Rank,
"Cannot rebind a view to another view of a different rank");
368 static_assert(std::is_same_v<std::remove_const_t<T>, std::remove_const_t<ValueType>>,
369 "Cannot rebind a view to another view with a different value_type (except for const)");
370 static constexpr bool same_type = std::is_same_v<T, ValueType>;
371 static_assert(same_type
or is_const,
"Cannot rebind a view with non-const value_type to another view with const value_type");
372 if constexpr (same_type) {
376 }
else if constexpr (is_const) {
379 lay = layout_t{v.indexmap()};
380 sto = storage_t{v.storage()};
385
386
387
388
389
390
391
393 std::swap(a.lay, b.lay);
394 std::swap(a.sto, b.sto);
398
399
400
401
402
403
404
406 auto tmp = make_regular(a);
429
430
431
435
436
437
441
442
443
447
448
449
453
454
455
456
457
461
462
463
467
468
469
473
474
475
479
480
481
485
486
487
491
492
493
497
498
499
506
507
508
510#ifdef NDA_ENFORCE_BOUNDCHECK
511 if (i < 0 || i >= rank) {
512 std::cerr <<
"Error in extent: Dimension " << i <<
" is incompatible with array of rank " << rank << std::endl;
516 return lay.lengths()[i];
523
524
525
529
530
531
535
536
537
541
542
543
544
545
546
547
548
550 if constexpr (layout_t::layout_prop ==
layout_prop_e::strided_1d)
551 return sto[idx
.value * lay.min_stride()];
552 else if constexpr (layout_t::layout_prop ==
layout_prop_e::contiguous)
555 static_assert(always_false<layout_t>,
"Internal error in array/view: Calling this type with a _linear_index_t is not allowed");
560 if constexpr (layout_t::layout_prop ==
layout_prop_e::strided_1d)
561 return sto[idx
.value * lay.min_stride()];
562 else if constexpr (layout_t::layout_prop ==
layout_prop_e::contiguous)
565 static_assert(always_false<layout_t>,
"Internal error in array/view: Calling this type with a _linear_index_t is not allowed");
570#ifdef NDA_ENFORCE_BOUNDCHECK
573static constexpr bool has_no_boundcheck =
true;
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593template <
char ResultAlgebra,
bool SelfIsRvalue,
typename Self,
typename... Ts>
596 using r_v_t = std::conditional_t<std::is_const_v<std::remove_reference_t<Self>>, ValueType
const, ValueType>;
599 if constexpr (clef::is_any_lazy<Ts...>) {
601 return clef::make_expr_call(std::forward<Self>(self), idxs...);
602 }
else if constexpr (
sizeof...(Ts) == 0) {
604 return basic_array_view<r_v_t, Rank, LayoutPolicy, Algebra, AccessorPolicy, OwningPolicy>{self.lay, self.sto};
607 static_assert(((layout_t::
template argument_is_allowed_for_call_or_slice<Ts> + ...) > 0),
608 "Error in array/view: Slice arguments must be convertible to range, ellipsis, or long (or string if the layout permits it)");
611 static constexpr int n_args_long = (layout_t::
template argument_is_allowed_for_call<Ts> + ...);
613 if constexpr (n_args_long ==
rank) {
615 long offset = self.lay(idxs...);
616 if constexpr (is_view
or not SelfIsRvalue) {
618 return AccessorPolicy::
template accessor<ValueType>::access(self.sto.data(), offset);
621 return ValueType{self.sto[offset]};
625 auto const [offset, idxm] = self.lay.slice(idxs...);
626 static constexpr auto res_rank =
decltype(idxm)::rank();
628 static constexpr char newAlgebra = (ResultAlgebra ==
'M' and (res_rank == 1) ?
'V' : ResultAlgebra);
630 using r_layout_p =
typename detail::layout_to_policy<std::decay_t<
decltype(idxm)>>::type;
631 return basic_array_view<ValueType, res_rank, r_layout_p, newAlgebra, AccessorPolicy, OwningPolicy>{std::move(idxm), {self.sto, offset}};
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658template <
typename... Ts>
660 static_assert((
rank == -1)
or (
sizeof...(Ts) ==
rank)
or (
sizeof...(Ts) == 0)
or (ellipsis_is_present<Ts...>
and (
sizeof...(Ts) <=
rank + 1)),
661 "Error in array/view: Incorrect number of parameters in call operator");
662 return call<Algebra,
false>(*
this, idxs...);
666template <
typename... Ts>
668 static_assert((
rank == -1)
or (
sizeof...(Ts) ==
rank)
or (
sizeof...(Ts) == 0)
or (ellipsis_is_present<Ts...>
and (
sizeof...(Ts) <=
rank + 1)),
669 "Error in array/view: Incorrect number of parameters in call operator");
670 return call<Algebra,
false>(*
this, idxs...);
674template <
typename... Ts>
676 static_assert((
rank == -1)
or (
sizeof...(Ts) ==
rank)
or (
sizeof...(Ts) == 0)
or (ellipsis_is_present<Ts...>
and (
sizeof...(Ts) <=
rank + 1)),
677 "Error in array/view: Incorrect number of parameters in call operator");
678 return call<Algebra,
true>(*
this, idxs...);
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
700 static_assert((
rank == 1),
"Error in array/view: Subscript operator is only available for rank 1 views/arrays in C++17/20");
701 return call<Algebra,
false>(*
this, idx);
707 static_assert((
rank == 1),
"Error in array/view: Subscript operator is only available for rank 1 views/arrays in C++17/20");
708 return call<Algebra,
false>(*
this, x);
714 static_assert((
rank == 1),
"Error in array/view: Subscript operator is only available for rank 1 views/arrays in C++17/20");
715 return call<Algebra,
true>(*
this, x);
719static constexpr int iterator_rank = (has_strided_1d(layout_t::layout_prop) ? 1 : Rank);
729template <
typename Iterator>
730[[nodiscard]]
auto make_iterator(
bool at_end)
const noexcept {
733 if constexpr (layout_t::is_stride_order_C()) {
738 return Iterator{nda::permutations::apply(layout_t::stride_order,
indexmap().lengths()),
739 nda::permutations::apply(layout_t::stride_order,
indexmap().strides()), sto.data(), at_end};
743 return Iterator{std::array<
long, 1>{
size()}, std::array<
long, 1>{
indexmap().min_stride()}, sto.data(), at_end};
749[[
nodiscard]] const_iterator
begin()
const noexcept {
return make_iterator<const_iterator>(
false); }
752[[
nodiscard]] const_iterator
cbegin()
const noexcept {
return make_iterator<const_iterator>(
false); }
755iterator
begin()
noexcept {
return make_iterator<iterator>(
false); }
758[[
nodiscard]] const_iterator
end()
const noexcept {
return make_iterator<const_iterator>(
true); }
761[[
nodiscard]] const_iterator
cend()
const noexcept {
return make_iterator<const_iterator>(
true); }
764iterator
end()
noexcept {
return make_iterator<iterator>(
true); }
767
768
769
770
771
772
773
774
775
776
777
778template <
typename RHS>
780 static_assert(
not is_const,
"Error in array/view: Can not assign to a const view");
781 return operator=(*
this + rhs);
785
786
787
788
789
790
791
792
793
794
795
796template <
typename RHS>
798 static_assert(
not is_const,
"Error in array/view: Can not assign to a const view");
799 return operator=(*
this - rhs);
803
804
805
806
807
808
809
810
811
812
813
814template <
typename RHS>
816 static_assert(
not is_const,
"Error in array/view: Can not assign to a const view");
817 return operator=((*
this) * rhs);
821
822
823
824
825
826
827
828
829
830
831
832template <
typename RHS>
834 static_assert(
not is_const,
"Error in array/view: Can not assign to a const view");
835 return operator=(*
this / rhs);
839
840
841
842
843
844
845
846template <
std::
ranges::contiguous_range R>
848 requires(Rank == 1
and not MemoryArray<R>)
856template <
typename RHS>
857void assign_from_ndarray(RHS
const &rhs) {
858#ifdef NDA_ENFORCE_BOUNDCHECK
859 if (
this->shape() != rhs.shape())
860 NDA_RUNTIME_ERROR <<
"Error in assign_from_ndarray: Size mismatch:"
861 <<
"\n LHS.shape() = " <<
this->shape() <<
"\n RHS.shape() = " << rhs.shape();
864 static_assert(std::is_assignable_v<value_type &, get_value_t<RHS>>,
"Error in assign_from_ndarray: Incompatible value types");
867 static constexpr bool both_in_memory = MemoryArray<self_t>
and MemoryArray<RHS>;
870 static constexpr bool same_stride_order = get_layout_info<self_t>.stride_order == get_layout_info<RHS>.stride_order;
873 if constexpr (both_in_memory
and same_stride_order) {
874 if (rhs.empty())
return;
876 static constexpr bool both_1d_strided = has_layout_strided_1d<self_t>
and has_layout_strided_1d<RHS>;
877 if constexpr (mem::on_host<self_t, RHS>
and both_1d_strided) {
881 }
else if constexpr (!mem::on_host<self_t, RHS>
and have_same_value_type_v<self_t, RHS>) {
883 auto bl_layout_dst = get_block_layout(*
this);
884 auto bl_layout_src = get_block_layout(rhs);
885 if (bl_layout_dst && bl_layout_src) {
886 auto [n_bl_dst, bl_size_dst, bl_str_dst] = *bl_layout_dst;
887 auto [n_bl_src, bl_size_src, bl_str_src] = *bl_layout_src;
889 if (n_bl_dst * bl_size_dst != n_bl_src * bl_size_src)
NDA_RUNTIME_ERROR <<
"Error in assign_from_ndarray: Incompatible block sizes";
891 if (n_bl_dst == 1 && n_bl_src > 1) {
893 bl_size_dst /= n_bl_src;
894 bl_str_dst = bl_size_dst;
896 if (n_bl_src == 1 && n_bl_dst > 1) {
898 bl_size_src /= n_bl_dst;
899 bl_str_src = bl_size_src;
902 if (n_bl_dst == n_bl_src && bl_size_dst == bl_size_src) {
903 mem::memcpy2D<mem::get_addr_space<self_t>, mem::get_addr_space<RHS>>((
void *)data(), bl_str_dst *
sizeof(value_type), (
void *)rhs.data(),
904 bl_str_src *
sizeof(value_type), bl_size_src *
sizeof(value_type),
912 if constexpr (mem::on_device<self_t> || mem::on_device<RHS>) {
913 NDA_RUNTIME_ERROR <<
"Error in assign_from_ndarray: Fallback to elementwise assignment not implemented for arrays/views on the GPU";
915 nda::for_each(shape(), [
this, &rhs](
auto const &...args) { (*
this)(args...) = rhs(args...); });
919template <
typename Scalar>
920void fill_with_scalar(Scalar
const &scalar)
noexcept {
922 if constexpr (has_layout_strided_1d<self_t>) {
924 auto *
__restrict const p = data();
925 if constexpr (has_contiguous_layout<self_t>) {
926 for (
long i = 0; i < L; ++i) p[i] = scalar;
929 const long Lstri = L * stri;
930 for (
long i = 0; i < Lstri; i += stri) p[i] = scalar;
934 for (
auto &x : *
this) x = scalar;
939template <
typename Scalar>
940void assign_from_scalar(Scalar
const &scalar)
noexcept {
941 static_assert(!is_const,
"Error in assign_from_ndarray: Cannot assign to a const view");
942 if constexpr (Algebra !=
'M') {
944 fill_with_scalar(scalar);
949 if constexpr (is_scalar_or_convertible_v<Scalar>)
952 fill_with_scalar(Scalar{0 * scalar});
954 for (
long i = 0; i < imax; ++i) operator()(i, i) = scalar;
960 template <MemoryArray A>
961 basic_array_view(A &&a)
962 ->
basic_array_view<std::conditional_t<std::is_const_v<std::remove_reference_t<A>>,
const typename std::decay_t<A>::value_type,
963 typename std::decay_t<A>::value_type>,
964 get_rank<A>,
typename std::decay_t<A>::layout_policy_t, get_algebra<A>,
default_accessor,
borrowed<mem::get_addr_space<A>>>;
966 template <
typename V, size_t R>
967 basic_array_view(std::array<V, R> &a)
971 template <
typename V, size_t R>
972 basic_array_view(std::array<V, R>
const &a)
976 template <std::ranges::contiguous_range R>
977 basic_array_view(R &r) ->
basic_array_view<std::conditional_t<std::is_const_v<R>,
const typename R::value_type,
typename R::value_type>, 1,
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.
#define CUSOLVER_CHECK(X, info,...)
#define NDA_RUNTIME_ERROR
constexpr uint64_t static_extents(int i0, Is... is)
Encode the given shape into a single integer using the nda::encode function.
layout_prop_e
Compile-time guarantees of the memory layout of an array/view.
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.
#define EXPECTS_WITH_MESSAGE(X,...)
Contiguous layout policy with C-order (row-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.
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.
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.