20 #ifndef TILEDARRAY_RANGE_H__INCLUDED 21 #define TILEDARRAY_RANGE_H__INCLUDED 43 typedef std::vector<size_type>
index;
77 template <
typename Index>
78 void init_range_data(
const Index& lower_bound,
const Index& upper_bound) {
84 const auto* MADNESS_RESTRICT
const lower_data =
detail::data(lower_bound);
85 const auto* MADNESS_RESTRICT
const upper_data =
detail::data(upper_bound);
92 for(
int i =
int(
rank_) - 1; i >= 0; --i) {
98 const size_type lower_bound_i = lower_data[i];
99 const size_type upper_bound_i = upper_data[i];
100 const size_type extent_i = upper_bound_i - lower_bound_i;
102 lower[i] = lower_bound_i;
103 upper[i] = upper_bound_i;
120 template <
typename Index,
122 typename Index::value_type>::value>::type* =
nullptr>
123 void init_range_data(
const Index& bound) {
129 const auto* MADNESS_RESTRICT
const bound_data =
detail::data(bound);
136 for(
int i =
int(
rank_) - 1; i >= 0; --i) {
138 const size_type lower_bound_i = bound_data[i].first;
139 const size_type upper_bound_i = bound_data[i].second;
140 const size_type extent_i = upper_bound_i - lower_bound_i;
144 TA_ASSERT(lower_bound_i < upper_bound_i);
146 lower[i] = lower_bound_i;
147 upper[i] = upper_bound_i;
163 template <
typename Index,
164 typename std::enable_if<detail::is_integral_list<
165 typename Index::value_type>::value>::type* =
nullptr>
166 void init_range_data(
const Index& extents) {
179 for(
int i =
int(
rank_) - 1; i >= 0; --i) {
202 template <
typename ... Indices,
203 typename std::enable_if<detail::is_integral_list<Indices...>::value>::type* =
nullptr>
204 void init_range_data(
const std::tuple<Indices...>& extents) {
205 const constexpr std::size_t
rank = std::tuple_size<std::tuple<Indices...>>::value;
213 init_range_data_helper(extents, std::make_index_sequence<rank>{});
216 template <
typename ... Indices, std::size_t ... Is>
217 void init_range_data_helper(
const std::tuple<Indices...>& extents, std::index_sequence<Is...>) {
218 int workers[] = {0, (init_range_data_helper_iter<Is>(extents),0)...};
222 template <std::size_t I,
typename ... Indices>
223 void init_range_data_helper_iter(
const std::tuple<Indices...>& extents) {
228 const size_type extent_i = std::get<I>(extents);
251 void init_range_data(
const Permutation& perm,
252 const size_type* MADNESS_RESTRICT
const other_lower_bound,
253 const size_type* MADNESS_RESTRICT
const other_upper_bound)
256 auto* MADNESS_RESTRICT
const lower =
data_;
257 auto* MADNESS_RESTRICT
const upper = lower +
rank_;
258 auto* MADNESS_RESTRICT
const extent = upper +
rank_;
262 for(
unsigned int i = 0u; i <
rank_; ++i) {
263 const auto perm_i = perm[i];
266 const auto other_lower_bound_i = other_lower_bound[i];
267 const auto other_upper_bound_i = other_upper_bound[i];
268 const auto other_extent_i = other_upper_bound_i - other_lower_bound_i;
271 lower[perm_i] = other_lower_bound_i;
272 upper[perm_i] = other_upper_bound_i;
273 extent[perm_i] = other_extent_i;
279 for(
int i =
int(
rank_) - 1; i >= 0; --i) {
280 const auto lower_i = lower[i];
281 const auto extent_i =
extent[i];
305 template <
typename Index,
306 typename std::enable_if<! std::is_integral<Index>::value>::type* =
nullptr>
307 Range(
const Index& lower_bound,
const Index& upper_bound) {
314 init_range_data(lower_bound, upper_bound);
327 template <
typename Index1,
328 typename std::enable_if<std::is_integral<Index1>::value>::type* =
nullptr>
329 Range(
const std::initializer_list<Index1>& lower_bound,
330 const std::initializer_list<Index1>& upper_bound)
338 init_range_data(lower_bound, upper_bound);
349 template <
typename Index,
350 typename std::enable_if<! std::is_integral<Index>::value &&
351 std::is_integral<typename Index::value_type>::value>::type* =
nullptr>
368 template <
typename Index1,
369 typename std::enable_if<std::is_integral<Index1>::value>::type* =
nullptr>
389 template <
typename Index,
390 typename std::enable_if<! std::is_integral<Index>::value &&
398 init_range_data(bounds);
411 template <
typename Index1,
typename Index2>
412 Range(
const std::initializer_list<std::pair<Index1,Index2>>& bounds) {
418 init_range_data(bounds);
428 template<
typename... Index,
430 explicit Range(
const Index... extents) :
431 Range(
std::array<size_t, sizeof...(Index)>{{
static_cast<std::size_t
>(extents)...}})
439 template <
typename ... IndexPairs,
440 typename std::enable_if<detail::is_integral_pair_list<IndexPairs...>::value>::type* =
nullptr 442 explicit Range(
const IndexPairs... bounds) :
443 Range(
std::array<
std::pair<
std::size_t,
std::size_t>, sizeof...(IndexPairs)>{{
static_cast<std::pair<std::size_t,std::size_t>
>(bounds)...}})
452 if(other.
rank_ > 0ul) {
469 other.data_ =
nullptr;
483 if(other.
rank_ > 0ul) {
530 other.data_ =
nullptr;
680 template <
typename Index,
681 typename std::enable_if<! std::is_integral<Index>::value,
bool>::type* =
nullptr>
687 bool result = (
rank_ > 0u);
688 auto it = std::begin(
index);
689 for(
unsigned int i = 0u; result && (i <
rank_); ++i, ++it) {
693 result = result && (index_i >= lower_i) && (index_i < upper_i);
708 template <
typename Integer>
710 return includes<std::initializer_list<Integer>>(
index);
719 template <
typename Ordinal>
720 typename std::enable_if<std::is_integral<Ordinal>::value,
bool>::type
722 return include_ordinal_(i);
725 template <
typename... Index>
726 typename std::enable_if<(
sizeof...(Index) > 1ul),
size_type>::type
753 template <
typename Index>
765 init_range_data(lower_bound, upper_bound);
777 template <
typename Index>
781 const auto* MADNESS_RESTRICT
const bound_shift_data =
detail::data(bound_shift);
787 for(
unsigned i = 0u; i <
rank_; ++i) {
789 const auto bound_shift_i = bound_shift_data[i];
790 auto lower_i = lower[i];
791 auto upper_i = upper[i];
792 const auto stride_i =
stride[i];
795 lower_i += bound_shift_i;
796 upper_i += bound_shift_i;
812 template <
typename Index>
838 template <
typename Index,
839 typename std::enable_if<! std::is_integral<Index>::value>::type* =
nullptr>
847 auto index_it = std::begin(
index);
848 for(
unsigned int i = 0u; i <
rank_; ++i, ++index_it) {
850 result += *(index_it) * stride_i;
863 template <
typename... Index,
864 typename std::enable_if<(
sizeof...(Index) > 1ul)>::type* =
nullptr>
885 size_type * MADNESS_RESTRICT
const result_data = result.data();
890 for(
int i =
int(
rank_) - 1; i >= 0; --i) {
899 result_data[i] = result_i;
911 template <
typename Index,
912 typename std::enable_if<! std::is_integral<Index>::value>::type* =
nullptr>
913 const Index&
idx(
const Index& i)
const {
918 template <
typename Archive,
919 typename std::enable_if<madness::archive::is_input_archive<Archive>::value>::type* =
nullptr>
922 unsigned int rank = 0ul;
926 const unsigned int four_x_rank =
rank << 2;
937 template <
typename Archive,
938 typename std::enable_if<madness::archive::is_output_archive<Archive>::value>::type* =
nullptr>
959 template <
typename Index>
960 typename std::enable_if<std::is_signed<Index>::value,
bool>::type
961 include_ordinal_(Index i)
const {
return (i >= Index(0)) && (i < Index(
volume_)); }
968 template <
typename Index>
969 typename std::enable_if<! std::is_signed<Index>::value,
bool>::type
970 include_ordinal_(Index i)
const {
return i <
volume_; }
978 void increment(
index& i)
const {
984 for(
int d =
int(
rank_) - 1; d >= 0; --d) {
1008 void advance(
index& i, std::ptrdiff_t n)
const {
1023 std::ptrdiff_t distance_to(
const index& first,
const index& last)
const {
1036 const size_type* MADNESS_RESTRICT
const temp_upper = temp_lower +
rank_;
1039 init_range_data(perm, temp_lower, temp_upper);
1042 delete[] temp_lower;
1059 return Range(perm, r);
1098 #endif // TILEDARRAY_RANGE_H__INCLUDED std::vector< size_type > index
Coordinate index type.
size_type volume_
Total number of elements.
constexpr bool operator==(const DenseShape &a, const DenseShape &b)
A (hyperrectangular) interval on , space of integer n-indices.
const size_type * extent_data() const
Range extent data accessor.
void swap(Range &r0, Range &r1)
Exchange the values of the give two ranges.
size_array lobound() const
Range lower bound accessor.
auto data(T &t)
Container data pointer accessor.
ordinal_type ordinal(const Index &index) const
calculate the ordinal index of index
Range_ shift(const Index &bound_shift)
Shift the lower and upper bound of this range.
std::size_t ordinal_type
Ordinal type, to conform Tensor Working Group spec.
size_type ordinal(const Index &... index) const
calculate the ordinal index of index
Range(const Permutation &perm, const Range_ &other)
Permuting copy constructor.
size_array extent_type
Range extent type, to conform Tensor Working Group spec.
size_type stride(size_t dim) const
Range stride element accessor.
Range_ & inplace_shift(const Index &bound_shift)
Shift the lower and upper bound of this range.
Range(const Index &extent)
Range constructor from a sequence of extents.
constexpr bool operator!=(const DenseShape &a, const DenseShape &b)
std::array< T, N > operator*(const Permutation &, const std::array< T, N > &)
Permute a std::array.
unsigned int rank() const
Rank accessor.
const size_type * stride_data() const
Range stride data accessor.
size_t size(const DistArray< Tile, Policy > &a)
const size_type * upbound_data() const
Range upper bound data accessor.
index_type dim() const
Domain size accessor.
Range(const std::initializer_list< Index1 > &extent)
Range constructor from an initializer list of extents.
ordinal_type volume() const
Range volume accessor.
std::enable_if<(sizeof...(Index) > 1ul), size_type >::type includes(const Index &... index) const
constexpr std::size_t size(T(&)[N])
Array size accessor.
detail::RangeIterator< size_type, Range_ > const_iterator
Coordinate iterator.
bool includes(const std::initializer_list< Integer > &index) const
Check the coordinate to make sure it is within the range.
void print_array(std::ostream &out, const A &a, const std::size_t n)
Print the content of an array like object.
std::enable_if< std::is_integral< Ordinal >::value, bool >::type includes(Ordinal i) const
Check the ordinal index to make sure it is within the range.
Range(const Index &lower_bound, const Index &upper_bound)
Construct range defined by upper and lower bound sequences.
Range_ & resize(const Index &lower_bound, const Index &upper_bound)
Resize range to a new upper and lower bound.
void serialize(const Archive &ar) const
size_type offset_
Ordinal index offset correction.
const_iterator end() const
Index iterator factory.
detail::SizeArray< const size_type > size_array
Size array type.
unsigned int rank_
The rank (or number of dimensions) in the range.
Range_ & operator=(const Range_ &other)
Copy assignment operator.
Range(Range_ &&other)
Copy Constructor.
DistArray< Tile, Policy > copy(const DistArray< Tile, Policy > &a)
std::ostream & operator<<(std::ostream &os, const DistArray< Tile, Policy > &a)
Add the tensor to an output stream.
size_type extent(size_t dim) const
Range extent element accessor.
size_array upbound() const
Range upper bound accessor.
bool includes(const Index &index) const
Check the coordinate to make sure it is within the range.
size_type upbound(size_t dim) const
Range upped bound element accessor.
Range_ & operator*=(const Permutation &perm)
Permute this range.
std::size_t size_type
Size type.
Permutation of a sequence of objects indexed by base-0 indices.
const size_type * lobound_data() const
Range lower bound data accessor.
Range(const Index &bounds)
Construct range defined by a sequence of {lower,upper} bound pairs.
const_iterator begin() const
Index iterator factory.
ordinal_type ordinal(const ordinal_type index) const
calculate the ordinal index of i
Range_ & operator=(Range_ &&other)
Move assignment operator.
index index_type
Coordinate index type, to conform Tensor Working Group spec.
void serialize(const Archive &ar)
const Index & idx(const Index &i) const
calculate the index of i
Range(const Index... extents)
Range constructor from a pack of extents for each dimension.
Range(const std::initializer_list< std::pair< Index1, Index2 >> &bounds)
Construct range defined by an initializer_list of {lower,upper} bound pairs.
Range Range_
This object type.
Range(const Range_ &other)
Copy Constructor.
Range(const std::initializer_list< Index1 > &lower_bound, const std::initializer_list< Index1 > &upper_bound)
Construct range defined by the upper and lower bound sequences.
extent_type extent() const
Range extent accessor.
size_type lobound(size_t dim) const
Range lower bound element accessor.
ordinal_type offset() const
Range offset.
Coordinate index iterate.
ordinal_type area() const
index idx(size_type index) const
calculate the coordinate index of the ordinal index, index.
Range()
Default constructor.
size_array stride() const
Range stride accessor.
Range(const IndexPairs... bounds)
Range constructor from a pack of {lo,up} bounds for each dimension.