Go to the documentation of this file.
20 #ifndef TILEDARRAY_RANGE_H__INCLUDED
21 #define TILEDARRAY_RANGE_H__INCLUDED
66 static_assert(detail::is_range_v<index_type>);
102 template <
typename Index1,
typename Index2,
103 typename = std::enable_if_t<detail::is_integral_range_v<Index1> &&
104 detail::is_integral_range_v<Index2>>>
105 void init_range_data(
const Index1& lower_bound,
const Index2& upper_bound) {
107 auto* MADNESS_RESTRICT
const lower =
data();
108 auto* MADNESS_RESTRICT
const upper = lower +
rank_;
109 auto* MADNESS_RESTRICT
const extent = upper +
rank_;
117 auto lower_it = std::begin(lower_bound);
118 auto upper_it = std::begin(upper_bound);
119 auto lower_end = std::end(lower_bound);
120 auto upper_end = std::end(upper_bound);
121 for (
int d = 0; lower_it != lower_end && upper_it != upper_end;
122 ++lower_it, ++upper_it, ++d) {
124 const auto lower_bound_d = *lower_it;
125 const auto upper_bound_d = *upper_it;
126 lower[d] = lower_bound_d;
127 upper[d] = upper_bound_d;
130 extent[d] = upper[d] - lower[d];
132 static_cast<index1_type>(upper_bound_d - lower_bound_d));
141 for (
int d =
int(
rank_) - 1; d >= 0; --d) {
158 template <
typename PairRange,
159 typename = std::enable_if_t<detail::is_gpair_range_v<PairRange>>>
160 void init_range_data(
const PairRange& bounds) {
162 auto* MADNESS_RESTRICT
const lower =
data();
163 auto* MADNESS_RESTRICT
const upper = lower +
rank_;
164 auto* MADNESS_RESTRICT
const extent = upper +
rank_;
169 for (
auto&& bound_d : bounds) {
171 const auto lower_bound_d =
detail::at(bound_d, 0);
172 const auto upper_bound_d =
detail::at(bound_d, 1);
173 lower[d] = lower_bound_d;
174 upper[d] = upper_bound_d;
177 extent[d] = upper[d] - lower[d];
184 for (
int d =
int(
rank_) - 1; d >= 0; --d) {
199 template <
typename Index,
typename std::enable_if_t<
200 detail::is_integral_range_v<Index>>* =
nullptr>
201 void init_range_data(
const Index& extents) {
203 auto* MADNESS_RESTRICT
const lower =
data();
204 auto* MADNESS_RESTRICT
const upper = lower +
rank_;
205 auto* MADNESS_RESTRICT
const extent = upper +
rank_;
211 for (
int d = 0; it !=
end; ++it, ++d) {
212 const auto extent_d = *it;
224 for (
int d =
int(
rank_) - 1; d >= 0; --d) {
238 template <
typename... Indices,
239 typename std::enable_if<
240 detail::is_integral_list<Indices...>::value>::type* =
nullptr>
241 void init_range_data(
const std::tuple<Indices...>& extents) {
242 const constexpr std::size_t
rank =
243 std::tuple_size<std::tuple<Indices...>>::value;
251 init_range_data_helper(extents, std::make_index_sequence<rank>{});
254 template <
typename... Indices, std::size_t... Is>
255 void init_range_data_helper(
const std::tuple<Indices...>& extents,
256 std::index_sequence<Is...>) {
257 int workers[] = {0, (init_range_data_helper_iter<Is>(extents), 0)...};
261 template <std::size_t I,
typename... Indices>
262 void init_range_data_helper_iter(
const std::tuple<Indices...>& extents) {
264 const auto extent_i = std::get<I>(extents);
266 auto* MADNESS_RESTRICT
const lower =
data();
267 auto* MADNESS_RESTRICT
const upper = lower +
rank_;
268 auto* MADNESS_RESTRICT
const extent = upper +
rank_;
289 void init_range_data(
290 const Permutation& perm,
291 const index1_type* MADNESS_RESTRICT
const other_lower_bound,
292 const index1_type* MADNESS_RESTRICT
const other_upper_bound) {
294 auto* MADNESS_RESTRICT
const lower =
data();
295 auto* MADNESS_RESTRICT
const upper = lower +
rank_;
296 auto* MADNESS_RESTRICT
const extent = upper +
rank_;
300 for (
unsigned int i = 0u; i <
rank_; ++i) {
301 const auto perm_i = perm[i];
304 const auto other_lower_bound_i = other_lower_bound[i];
305 const auto other_upper_bound_i = other_upper_bound[i];
306 const auto other_extent_i = other_upper_bound_i - other_lower_bound_i;
309 lower[perm_i] = other_lower_bound_i;
310 upper[perm_i] = other_upper_bound_i;
311 extent[perm_i] = other_extent_i;
317 for (
int i =
int(
rank_) - 1; i >= 0; --i) {
318 const auto lower_i = lower[i];
319 const auto extent_i =
extent[i];
351 template <
typename Index1,
typename Index2,
352 typename std::enable_if_t<
353 detail::is_integral_sized_range_v<Index1> &&
354 detail::is_integral_sized_range_v<Index2>>* =
nullptr>
355 Range(
const Index1& lower_bound,
const Index2& upper_bound) {
357 const auto n = size(lower_bound);
363 init_range_data(lower_bound, upper_bound);
386 template <
typename Index1,
typename Index2,
387 typename = std::enable_if_t<std::is_integral_v<Index1> &&
388 std::is_integral_v<Index2>>>
389 Range(
const std::initializer_list<Index1>& lower_bound,
390 const std::initializer_list<Index2>& upper_bound) {
392 const auto n = size(lower_bound);
397 init_range_data(lower_bound, upper_bound);
411 template <
typename Index,
412 typename std::enable_if_t<
413 detail::is_integral_sized_range_v<Index>>* =
nullptr>
416 const auto n = size(
extent);
435 template <
typename Index,
436 typename = std::enable_if_t<std::is_integral_v<Index>>>
439 const auto n = size(
extent);
477 template <
typename PairRange,
478 typename = std::enable_if_t<detail::is_sized_range_v<PairRange> &&
479 detail::is_gpair_range_v<PairRange>>>
480 explicit Range(
const PairRange& bounds) {
481 const auto n = std::size(bounds);
486 init_range_data(bounds);
501 template <
typename GPair>
502 explicit Range(
const std::initializer_list<GPair>& bounds,
503 std::enable_if_t<detail::is_gpair_v<GPair>>* =
nullptr) {
506 if constexpr (detail::is_contiguous_range_v<GPair>) {
507 for (
auto&& bound_d : bounds) {
512 const auto n = size(bounds);
517 init_range_data(bounds);
535 template <
typename Index,
536 typename = std::enable_if_t<std::is_integral_v<Index>>>
538 const std::initializer_list<std::initializer_list<Index>>& bounds) {
540 const auto n = size(bounds);
543 for (
auto&& bound_d : bounds) {
550 init_range_data(bounds);
564 Index...>::value>::type* =
nullptr>
565 explicit Range(
const Index... extents)
566 :
Range(std::array<size_t, sizeof...(Index)>{
567 {
static_cast<std::size_t
>(extents)...}}) {}
578 template <
typename... IndexPairs,
581 explicit Range(
const IndexPairs... bounds)
582 :
Range(std::array<std::pair<std::size_t, std::size_t>,
583 sizeof...(IndexPairs)>{
584 {
static_cast<std::pair<std::size_t, std::size_t>
>(bounds)...}}) {}
600 other.datavec_.clear();
601 other.datavec_.shrink_to_fit();
614 if (other.
rank_ > 0ul) {
645 datavec_ = std::move(other.datavec_);
651 other.datavec_.clear();
652 other.datavec_.shrink_to_fit();
663 explicit operator bool()
const {
return rank() != 0; }
675 std::pair<index1_type, index1_type>
dim(std::size_t d)
const {
823 template <
typename Index,
824 typename std::enable_if<detail::is_integral_range_v<Index>,
825 bool>::type* =
nullptr>
828 const auto* MADNESS_RESTRICT
const lower =
lobound_data();
829 const auto* MADNESS_RESTRICT
const upper =
upbound_data();
831 bool result = (
rank_ > 0u);
833 for (
auto&& index_d :
index) {
835 const auto lower_d = lower[d];
836 const auto upper_d = upper[d];
837 result = result && (index_d >= lower_d) && (index_d < upper_d);
859 template <
typename Index,
860 typename = std::enable_if_t<std::is_integral_v<Index>>>
862 return includes<std::initializer_list<Index>>(
index);
870 template <
typename Ordinal>
871 typename std::enable_if<std::is_integral_v<Ordinal>,
bool>::type
includes(
874 return include_ordinal_(i);
877 template <
typename... Index>
879 (
sizeof...(Index) > 1ul) && (std::is_integral_v<Index> && ...),
bool>
905 typename Index1,
typename Index2,
906 typename = std::enable_if_t<detail::is_integral_sized_range_v<Index1> &&
907 detail::is_integral_sized_range_v<Index2>>>
910 const auto n = size(lower_bound);
919 init_range_data(lower_bound, upper_bound);
931 template <
typename Index,
932 typename = std::enable_if_t<detail::is_integral_range_v<Index>>>
941 for (
auto&& bound_shift_d : bound_shift) {
944 auto lower_d = lower[d];
945 auto upper_d = upper[d];
946 const auto stride_d =
stride[d];
949 lower_d += bound_shift_d;
950 upper_d += bound_shift_d;
969 template <
typename Index,
970 typename = std::enable_if_t<std::is_integral_v<Index>>>
972 return inplace_shift<std::initializer_list<Index>>(bound_shift);
980 template <
typename Index,
981 typename = std::enable_if_t<detail::is_integral_range_v<Index>>>
993 template <
typename Index,
994 typename = std::enable_if_t<std::is_integral_v<Index>>>
1020 template <
typename Index,
typename std::enable_if_t<
1021 detail::is_integral_range_v<Index>>* =
nullptr>
1029 for (
auto&& index_d :
index) {
1031 const auto stride_d =
stride[d];
1032 result += index_d * stride_d;
1047 template <
typename Index,
1048 typename = std::enable_if_t<std::is_integral_v<Index>>>
1050 return this->ordinal<std::initializer_list<Index>>(
index);
1062 typename std::enable_if_t<(
sizeof...(Index) > 1ul) &&
1063 (std::is_integral_v<Index> && ...)>* =
nullptr>
1065 const index1_type temp_index[
sizeof...(Index)] = {
1085 auto* MADNESS_RESTRICT
const result_data = result.data();
1086 const auto* MADNESS_RESTRICT
const lower =
lobound_data();
1087 const auto* MADNESS_RESTRICT
const size =
extent_data();
1090 for (
int i =
int(
rank_) - 1; i >= 0; --i) {
1091 const auto lower_i = lower[i];
1092 const auto size_i = size[i];
1095 const auto result_i = (
index % size_i) + lower_i;
1099 result_data[i] = result_i;
1112 template <
typename Index,
typename std::enable_if_t<
1113 detail::is_integral_range_v<Index>>* =
nullptr>
1114 const Index&
idx(
const Index& i)
const {
1119 template <
typename Archive>
1139 template <
typename Index>
1140 typename std::enable_if<std::is_integral_v<Index> && std::is_signed_v<Index>,
1142 include_ordinal_(Index i)
const {
1143 return (i >= Index(0)) && (i < Index(
volume_));
1151 template <
typename Index>
1152 typename std::enable_if<
1153 std::is_integral_v<Index> && !std::is_signed<Index>::value,
bool>::type
1154 include_ordinal_(Index i)
const {
1167 const auto* MADNESS_RESTRICT
const lower =
lobound_data();
1168 const auto* MADNESS_RESTRICT
const upper =
upbound_data();
1170 for (
int d =
int(
rank_) - 1; d >= 0; --d) {
1175 if (i[d] < upper[d])
return;
1183 std::copy(upper, upper +
rank_, i.begin());
1193 void advance(
index_type& i, std::ptrdiff_t n)
const {
1195 const auto o =
ordinal(i) + n;
1209 std::ptrdiff_t distance_to(
const index_type& first,
1224 const auto* MADNESS_RESTRICT
const temp_upper = temp_lower.data() +
rank_;
1227 init_range_data(perm, temp_lower.
data(), temp_upper);
1243 return Range(perm, r);
1252 template <
typename I,
typename = std::enable_if_t<std::is_
integral_v<I>>>
1315 #endif // TILEDARRAY_RANGE_H__INCLUDED
const index1_type * lobound_data() const
Range lower bound data accessor.
Range_ & operator=(const Range_ &other)=default
Copy assignment operator.
Coordinate index iterate.
std::enable_if<!TiledArray::detail::is_permutation_v< Perm >, TiledArray::Range >::type permute(const TiledArray::Range &r, const Perm &p)
Range_ & operator*=(const Permutation &perm)
Permute this range.
boost::container::small_vector< T, N > svector
index1_type * upbound_data_nc()
distance_type offset_
Ordinal index offset correction.
std::pair< index1_type, index1_type > dim(std::size_t d) const
Accessor of the d-th dimension of the range.
index_type size() const
Domain size accessor.
bool includes(const std::initializer_list< Index > &index) const
Check the coordinate to make sure it is within the range.
ordinal_type volume_
Total number of elements.
ordinal_type ordinal(const std::initializer_list< Index > &index) const
calculate the ordinal index of index
Range(const std::initializer_list< std::initializer_list< Index >> &bounds)
Construct range defined by an initializer_list of std::initializer_list{lower,upper} bounds.
Range(const Index1 &lower_bound, const Index2 &upper_bound)
Construct range defined by upper and lower bound ranges.
const Index & idx(const Index &i) const
calculate the index of i
std::make_signed_t< ordinal_type > distance_type
Distance type.
Permutation of a sequence of objects indexed by base-0 indices.
bool operator==(const BlockRange &r1, const BlockRange &r2)
BlockRange equality comparison.
const_iterator begin() const
Index iterator factory.
ordinal_type ordinal(const Index &... index) const
calculate the ordinal index of index
Range(const std::initializer_list< Index1 > &lower_bound, const std::initializer_list< Index2 > &upper_bound)
Construct range defined by the upper and lower bound ranges.
container::svector< index1_type > index_type
constexpr bool operator!=(const DenseShape &a, const DenseShape &b)
TA_1INDEX_TYPE index1_type
const index1_type * upbound_data() const
Range upper bound data accessor.
Range(const Range_ &other)=default
Copy Constructor.
Range_ & inplace_shift(const std::initializer_list< Index > &bound_shift)
Shift the lower and upper bound of this range.
index1_type upbound(size_t dim) const
Range upped bound element accessor.
Range_ shift(const std::initializer_list< Index > &bound_shift)
Create a Range with shiften lower and upper bounds.
const_iterator end() const
Index iterator factory.
constexpr auto end(const Eigen::Matrix< _Scalar, _Rows, 1, _Options, _MaxRows, 1 > &m)
ordinal_type ordinal(const ordinal_type index) const
calculate the ordinal index of i
std::array< T, N > operator*(const Permutation &, const std::array< T, N > &)
Permute a std::array.
ordinal_type ordinal(const Index &index) const
calculate the ordinal index of index
constexpr const bool is_integral_pair_list_v
const auto & data() const
Permutation data accessor.
index1_type * stride_data_nc()
#define TA_ASSERT(EXPR,...)
index_view_type lobound() const
Range lower bound accessor.
distance_type offset() const
Range offset.
index_view_type extent() const
Range extent accessor.
bool includes(const Index &index) const
Check the coordinate to make sure it is within the range.
index1_type * extent_data_nc()
Range(const Index... extents)
Range constructor from a pack of extents for each dimension.
void serialize(Archive &ar)
Range(const std::initializer_list< Index > &extent)
Range constructor from an initializer list of extents.
Range(const Permutation &perm, const Range_ &other)
Permuting copy constructor.
void init_datavec(unsigned int rank)
Range Range_
This object type.
Range_ & resize(const Index1 &lower_bound, const Index2 &upper_bound)
Resize range to a new upper and lower bound.
ordinal_type size_type
Size type (deprecated)
ordinal_type area() const
std::enable_if< std::is_integral_v< Ordinal >, bool >::type includes(Ordinal i) const
Check the ordinal index to make sure it is within the range.
bool is_contiguous(const BlockRange &range)
bool is_congruent(const BlockRange &r1, const BlockRange &r2)
Test that two BlockRange objects are congruent.
Range_ & operator=(Range_ &&other)
Move assignment operator.
index1_type extent(size_t dim) const
Range extent element accessor.
Range(const Index &extent)
Range constructor from a range of extents.
index1_type lobound(size_t dim) const
Range lower bound element accessor.
std::ostream & operator<<(std::ostream &os, const DistArray< Tile, Policy > &a)
Add the tensor to an output stream.
index_view_type stride() const
Range stride accessor.
container::svector< index1_type, 4 *TA_MAX_SOO_RANK_METADATA > datavec_
const index1_type * data() const
Range(const std::initializer_list< GPair > &bounds, std::enable_if_t< detail::is_gpair_v< GPair >> *=nullptr)
Construct range defined by an initializer_list of {lower,upper} bounds for each dimension given as a ...
const index1_type * stride_data() const
Range stride data accessor.
Range(const PairRange &bounds)
Construct Range defined by a range of {lower,upper} bound pairs.
Range()
Default constructor.
Range_ shift(const Index &bound_shift)
Create a Range with shiften lower and upper bounds.
Range(const IndexPairs... bounds)
void print_array(std::ostream &out, const A &a, const std::size_t n)
Print the content of an array like object.
index_type extent_type
Range extent type, to conform to TWG spec.
std::enable_if_t<(sizeof...(Index) > 1ul) &&(std::is_integral_v< Index > &&...), bool > includes(const Index &... index) const
index1_type stride(size_t dim) const
Range stride element accessor.
ordinal_type volume() const
Range volume accessor.
~Range()=default
Destructor.
detail::RangeIterator< index1_type, Range_ > const_iterator
Coordinate iterator.
unsigned int rank_
The rank (or number of dimensions) in the range.
index_type idx(ordinal_type index) const
calculate the coordinate index of the ordinal index, index.
decltype(auto) at(GeneralizedPair &&v, std::size_t idx)
at(pair, i) extracts i-th element from gpair
index_view_type upbound() const
Range upper bound accessor.
constexpr auto begin(const Eigen::Matrix< _Scalar, _Rows, 1, _Options, _MaxRows, 1 > &m)
std::size_t ordinal_type
Ordinal type, to conform to TWG spec.
const index1_type * extent_data() const
Range extent data accessor.
Range(Range_ &&other)
Move Constructor.
index_type index
Coordinate index type (deprecated)
void swap(Range &r0, Range &r1)
Exchange the values of the give two ranges.
Range_ & inplace_shift(const Index &bound_shift)
Shift the lower and upper bound of this range.
unsigned int rank() const
Rank accessor.
index1_type * lobound_data_nc()
A (hyperrectangular) interval on , space of integer -indices.
detail::SizeArray< const index1_type > index_view_type
Non-owning variant of index_type.