array_impl.h
Go to the documentation of this file.
1 /*
2  * This file is a part of TiledArray.
3  * Copyright (C) 2014 Virginia Tech
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Justus Calvin
19  * Department of Chemistry, Virginia Tech
20  *
21  * array_impl.h
22  * Oct 24, 2014
23  *
24  */
25 
26 #ifndef TILEDARRAY_ARRAY_IMPL_H__INCLUDED
27 #define TILEDARRAY_ARRAY_IMPL_H__INCLUDED
28 
30 #include <TiledArray/tensor_impl.h>
32 #include <TiledArray/type_traits.h>
33 
34 namespace TiledArray {
35 namespace detail {
36 
37 // Forward declaration
38 template <typename>
40 template <typename>
42 template <typename, typename>
43 class ArrayIterator;
44 
46 
48 template <typename Impl>
50  private:
51  template <typename, typename>
52  friend class ArrayIterator;
53 
54  template <typename>
55  friend class TileConstReference;
56 
57  typedef typename Impl::range_type range_type;
58  typedef typename Impl::range_type::index index_type;
59  typedef typename Impl::ordinal_type ordinal_type;
60 
61  Impl* tensor_;
62  ordinal_type index_;
63 
64  // Not allowed
65  TileReference<Impl>& operator=(const TileReference<Impl>&);
66 
67  public:
68  TileReference(Impl* tensor, const typename Impl::ordinal_type index)
69  : tensor_(tensor), index_(index) {}
70 
72  : tensor_(other.tensor_), index_(other.index_) {}
73 
74  template <typename Value>
75  TileReference<Impl>& operator=(const Value& value) {
76  tensor_->set(index_, value);
77  return *this;
78  }
79 
80  typename Impl::future future() const {
81  TA_ASSERT(tensor_);
82  return tensor_->get(index_);
83  }
84 
85  typename Impl::value_type get() const {
86  // NOTE: return by value to avoid lifetime issues.
87  TA_ASSERT(tensor_);
88  return future().get();
89  }
90 
91  operator typename Impl::future() const { return this->future(); }
92 
93  operator typename Impl::value_type() const { return get(); }
94 
96 
98  index_type index() const {
99  TA_ASSERT(tensor_);
100  return tensor_->tiles_range().idx(index_);
101  }
102 
104 
106  ordinal_type ordinal() const { return index_; }
107 
109 
111  range_type make_range() const {
112  TA_ASSERT(tensor_);
113  return tensor_->trange().make_tile_range(index_);
114  }
115 
116 }; // class TileReference
117 
119 template <typename Impl>
121  return a.get() == b.get();
122 }
123 
125 template <typename Impl>
127  return !(a == b);
128 }
129 
131 template <typename Impl>
132 std::ostream& operator<<(std::ostream& os, const TileReference<Impl>& a) {
133  os << a.get();
134  return os;
135 }
136 
138 
140 template <typename Impl>
142  private:
143  template <typename, typename>
144  friend class ArrayIterator;
145 
146  const Impl* tensor_;
147  typename Impl::ordinal_type index_;
148 
149  // Not allowed
151 
152  public:
153  TileConstReference(const Impl* tensor,
154  const typename Impl::ordinal_type index)
155  : tensor_(tensor), index_(index) {}
156 
158  : tensor_(other.tensor_), index_(other.index_) {}
159 
161  : tensor_(other.tensor_), index_(other.index_) {}
162 
163  typename Impl::future future() const {
164  TA_ASSERT(tensor_);
165  return tensor_->get(index_);
166  }
167 
168  typename Impl::value_type get() const {
169  // NOTE: return by value to avoid lifetime issues.
170  TA_ASSERT(tensor_);
171  return future().get();
172  }
173 
174  operator typename Impl::future() const { return tensor_->get(index_); }
175 
176  operator typename Impl::value_type() const { return get(); }
177 }; // class TileConstReference
178 
180 template <typename Impl>
182  const TileConstReference<Impl>& b) {
183  return a.get() == b.get();
184 }
185 
187 template <typename Impl>
189  const TileConstReference<Impl>& b) {
190  return !(a == b);
191 }
192 
194 template <typename Impl>
195 std::ostream& operator<<(std::ostream& os, const TileConstReference<Impl>& a) {
196  os << a.get();
197  return os;
198 }
199 
200 } // namespace detail
201 } // namespace TiledArray
202 
203 namespace madness {
204 namespace detail {
205 
206 // The following class specializations are required so MADNESS will do the
207 // right thing when given a TileReference or TileConstReference object
208 // as an input for task functions.
209 
210 template <typename Impl>
211 struct task_arg<TiledArray::detail::TileReference<Impl>> {
212  typedef typename Impl::value_type type;
213  typedef typename Impl::future holderT;
214 }; // struct task_arg<TiledArray::detail::TileReference<Impl> >
215 
216 template <typename Impl>
217 struct task_arg<TiledArray::detail::TileConstReference<Impl>> {
218  typedef typename Impl::value_type type;
219  typedef typename Impl::future holderT;
220 }; // struct task_arg<TiledArray::detail::TileConstReference<Impl> >
221 
222 } // namespace detail
223 } // namespace madness
224 
225 namespace TiledArray {
226 namespace detail {
227 
229 
235 template <typename Impl, typename Reference>
237  private:
238  // Give access to other iterator types.
239  template <typename, typename>
240  friend class ArrayIterator;
241 
242  Impl* array_;
243  typename Impl::pmap_interface::const_iterator it_;
244 
245  public:
246  typedef ptrdiff_t difference_type;
247  typedef
248  typename Impl::future value_type;
249  typedef PointerProxy<value_type> pointer;
250  typedef Reference reference;
251  typedef std::forward_iterator_tag
254  typedef typename Impl::range_type::index index_type;
255  typedef typename Impl::ordinal_type ordinal_type;
256  typedef typename Impl::range_type range_type;
257  typedef typename Impl::value_type tile_type;
258 
259  private:
260  void advance() {
261  TA_ASSERT(array_);
262  const typename Impl::pmap_interface::const_iterator end =
263  array_->pmap()->end();
264  do {
265  ++it_;
266  } while ((it_ != end) && array_->is_zero(*it_));
267  }
268 
269  public:
271  ArrayIterator() : array_(NULL), it_() {}
272 
274  ArrayIterator(Impl* tensor, typename Impl::pmap_interface::const_iterator it)
275  : array_(tensor), it_(it) {}
276 
278 
281  : array_(other.array_), it_(other.it_) {}
282 
284 
287  template <
288  typename I, typename R,
289  typename std::enable_if<!((!std::is_const<Impl>::value) &&
290  std::is_const<I>::value)>::type* = nullptr>
292  : array_(other.array_), it_(other.it_) {}
293 
295 
299  array_ = other.array_;
300  it_ = other.it_;
301 
302  return *this;
303  }
304 
306 
310  template <typename R>
312  array_ = other.array_;
313  it_ = other.it_;
314 
315  return *this;
316  }
317 
319 
322  advance();
323  return *this;
324  }
325 
327 
330  ArrayIterator_ tmp(*this);
331  advance();
332  return tmp;
333  }
334 
336 
341  template <typename I, typename R>
342  bool operator==(const ArrayIterator<I, R>& other) const {
343  return (array_ == other.array_) && (it_ == other.it_);
344  }
345 
347 
352  template <typename I, typename R>
353  bool operator!=(const ArrayIterator<I, R>& other) const {
354  return (array_ != other.array_) || (it_ != other.it_);
355  }
356 
358 
361  TA_ASSERT(array_);
362  return reference(array_, *it_);
363  }
364 
366 
368  pointer operator->() const {
369  TA_ASSERT(array_);
370  return pointer(array_->get(*it_));
371  }
372 
374 
376  index_type index() const {
377  TA_ASSERT(array_);
378  return array_->tiles_range().idx(*it_);
379  }
380 
382 
385  TA_ASSERT(array_);
386  return *it_;
387  }
388 
390 
393  TA_ASSERT(array_);
394  TA_ASSERT(it_ != array_->pmap()->end());
395  return array_->trange().make_tile_range(*it_);
396  }
397 
398 }; // class TensorIterator
399 
401 
409 template <typename Tile, typename Policy>
410 class ArrayImpl : public TensorImpl<Policy> {
411  public:
416  typedef typename TensorImpl_::policy_type
418  typedef typename TensorImpl_::trange_type
420  typedef typename TensorImpl_::range_type
423  typedef typename TensorImpl_::pmap_interface
425  typedef Tile value_type;
426  typedef
428  typedef typename numeric_type<value_type>::type
432  typedef typename storage_type::future future;
439 
440  private:
441  storage_type data_;
442 
443  public:
445 
454  const std::shared_ptr<pmap_interface>& pmap)
456  data_(world, trange.tiles_range().volume(), pmap) {}
457 
459  virtual ~ArrayImpl() {}
460 
462 
467  template <typename Index,
468  typename = std::enable_if_t<std::is_integral_v<Index> ||
469  detail::is_integral_range_v<Index>>>
470  future get(const Index& i) const {
472  return data_.get(TensorImpl_::trange().tiles_range().ordinal(i));
473  }
474 
476 
481  template <typename Integer,
482  typename = std::enable_if_t<std::is_integral_v<Integer>>>
483  future get(const std::initializer_list<Integer>& i) const {
484  return get<std::initializer_list<Integer>>(i);
485  }
486 
488 
493  template <typename Index,
494  typename = std::enable_if_t<std::is_integral_v<Index> ||
495  detail::is_integral_range_v<Index>>>
496  const future& get_local(const Index& i) const {
498  return data_.get_local(TensorImpl_::trange().tiles_range().ordinal(i));
499  }
500 
502 
507  template <typename Integer,
508  typename = std::enable_if_t<std::is_integral_v<Integer>>>
509  const future& get_local(const std::initializer_list<Integer>& i) const {
510  return get_local<std::initializer_list<Integer>>(i);
511  }
512 
514 
519  template <typename Index,
520  typename = std::enable_if_t<std::is_integral_v<Index> ||
521  detail::is_integral_range_v<Index>>>
522  future& get_local(const Index& i) {
524  return data_.get_local(TensorImpl_::trange().tiles_range().ordinal(i));
525  }
526 
528 
533  template <typename Integer,
534  typename = std::enable_if_t<std::is_integral_v<Integer>>>
535  future& get_local(const std::initializer_list<Integer>& i) {
536  return get_local<std::initializer_list<Integer>>(i);
537  }
538 
540 
548  template <typename Index, typename Value,
549  typename = std::enable_if_t<std::is_integral_v<Index> ||
550  detail::is_integral_range_v<Index>>>
551  void set(const Index& i, Value&& value) {
553  const auto ord = TensorImpl_::trange().tiles_range().ordinal(i);
554  data_.set(ord, std::forward<Value>(value));
555  if (set_notifier_accessor()) {
556  set_notifier_accessor()(*this, ord);
557  }
558  }
559 
561 
569  template <typename Index, typename Value,
570  typename = std::enable_if_t<std::is_integral_v<Index>>>
571  void set(const std::initializer_list<Index>& i, Value&& value) {
573  const auto ord = TensorImpl_::trange().tiles_range().ordinal(i);
574  data_.set(ord, std::forward<Value>(value));
575  if (set_notifier_accessor()) {
576  set_notifier_accessor()(*this, ord);
577  }
578  }
579 
581 
584  // Get the pmap iterator
585  typename pmap_interface::const_iterator it = TensorImpl_::pmap()->begin();
586 
587  // Find the first non-zero iterator
588  const typename pmap_interface::const_iterator end =
589  TensorImpl_::pmap()->end();
590  while ((it != end) && TensorImpl_::is_zero(*it)) ++it;
591 
592  // Construct and return the iterator
593  return iterator(this, it);
594  }
595 
597 
600  // Get the pmap iterator
601  typename pmap_interface::const_iterator it = TensorImpl_::pmap()->begin();
602 
603  // Find the fist non-zero iterator
604  const typename pmap_interface::const_iterator end =
605  TensorImpl_::pmap()->end();
606  while ((it != end) && TensorImpl_::is_zero(*it)) ++it;
607 
608  // Construct and return the iterator
609  return const_iterator(this, it);
610  }
611 
613 
615  iterator end() { return iterator(this, TensorImpl_::pmap()->end()); }
616 
618 
621  return const_iterator(this, TensorImpl_::pmap()->end());
622  }
623 
625 
627  const madness::uniqueidT& id() const { return data_.id(); }
628 
629  static std::function<void(const ArrayImpl_&, int64_t)>&
631  static std::function<void(const ArrayImpl_&, int64_t)> value;
632  return value;
633  }
634 
635 }; // class ArrayImpl
636 
637 #ifndef TILEDARRAY_HEADER_ONLY
638 
639 extern template class ArrayImpl<
641 extern template class ArrayImpl<Tensor<float, Eigen::aligned_allocator<float>>,
642  DensePolicy>;
643 extern template class ArrayImpl<Tensor<int, Eigen::aligned_allocator<int>>,
644  DensePolicy>;
645 extern template class ArrayImpl<Tensor<long, Eigen::aligned_allocator<long>>,
646  DensePolicy>;
647 // extern template
648 // class ArrayImpl<Tensor<std::complex<double>,
649 // Eigen::aligned_allocator<std::complex<double> > >, DensePolicy>; extern
650 // template class ArrayImpl<Tensor<std::complex<float>,
651 // Eigen::aligned_allocator<std::complex<float> > >, DensePolicy>;
652 
653 extern template class ArrayImpl<
655 extern template class ArrayImpl<Tensor<float, Eigen::aligned_allocator<float>>,
656  SparsePolicy>;
657 extern template class ArrayImpl<Tensor<int, Eigen::aligned_allocator<int>>,
658  SparsePolicy>;
659 extern template class ArrayImpl<Tensor<long, Eigen::aligned_allocator<long>>,
660  SparsePolicy>;
661 // extern template
662 // class ArrayImpl<Tensor<std::complex<double>,
663 // Eigen::aligned_allocator<std::complex<double> > >, SparsePolicy>; extern
664 // template class ArrayImpl<Tensor<std::complex<float>,
665 // Eigen::aligned_allocator<std::complex<float> > >, SparsePolicy>;
666 
667 #endif // TILEDARRAY_HEADER_ONLY
668 
669 } // namespace detail
670 } // namespace TiledArray
671 
672 #endif // TILEDARRAY_ARRAY_IMPL_H__INCLUDED
ArrayIterator_ & operator++()
Prefix increment operator.
Definition: array_impl.h:321
Policy policy_type
Policy type.
Definition: tensor_impl.h:42
TileConstReference(const Impl *tensor, const typename Impl::ordinal_type index)
Definition: array_impl.h:153
ordinal_type ordinal() const
Tile ordinal index accessor.
Definition: array_impl.h:384
static std::function< void(const ArrayImpl_ &, int64_t)> & set_notifier_accessor()
Definition: array_impl.h:630
const future & get_local(const size_type i) const
Get local element.
ArrayIterator_ operator++(int)
Post-fix increment operator.
Definition: array_impl.h:329
Tensor implementation and base for other tensor implementation objects.
Definition: array_impl.h:410
future get(const std::initializer_list< Integer > &i) const
Tile future accessor.
Definition: array_impl.h:483
bool operator!=(const ArrayIterator< I, R > &other) const
Inequality operator.
Definition: array_impl.h:353
TensorImpl_::ordinal_type ordinal_type
Ordinal type.
Definition: array_impl.h:415
World & world() const
World accessor.
Definition: tensor_impl.h:175
const_iterator cbegin() const
Array begin iterator.
Definition: array_impl.h:599
Tile value_type
Tile or data type.
Definition: array_impl.h:425
future & get_local(const Index &i)
Local tile future accessor.
Definition: array_impl.h:522
TileReference(Impl *tensor, const typename Impl::ordinal_type index)
Definition: array_impl.h:68
Impl::future future() const
Definition: array_impl.h:80
pointer operator->() const
Arrow dereference operator.
Definition: array_impl.h:368
void set(size_type i, const value_type &value)
Set element i with value.
TensorImpl_::index1_type index1_type
1-index type
Definition: array_impl.h:414
TileConstReference< ArrayImpl_ > const_reference
Tile constant reference type.
Definition: array_impl.h:435
TensorImpl_::range_type range_type
Elements/tiles range type.
Definition: array_impl.h:421
TensorImpl< Policy > TensorImpl_
The base class of this object.
Definition: array_impl.h:413
Distributed tensor iterator.
Definition: array_impl.h:236
bool is_zero(const Index &i) const
Query for a zero tile.
Definition: tensor_impl.h:147
TensorImpl_::pmap_interface pmap_interface
process map interface type
Definition: array_impl.h:424
index_type index() const
Tile coordinate index accessor.
Definition: array_impl.h:98
ArrayIterator< Impl, Reference > ArrayIterator_
This object type.
Definition: array_impl.h:253
range_type make_range() const
Tile range factory function.
Definition: array_impl.h:111
index_type index() const
Tile coordinate index accessor.
Definition: array_impl.h:376
TileReference< ArrayImpl_ > reference
Tile reference type.
Definition: array_impl.h:433
std::ostream & operator<<(std::ostream &os, const TileReference< Impl > &a)
redirect operator to std::ostream for TileReference objects
Definition: array_impl.h:132
virtual ~ArrayImpl()
Virtual destructor.
Definition: array_impl.h:459
TensorImpl_::policy_type policy_type
Policy type for this object.
Definition: array_impl.h:417
ArrayIterator(const ArrayIterator< I, R > &other)
Copy const iterator constructor.
Definition: array_impl.h:291
const range_type & tiles_range() const
Tiles range accessor.
Definition: tensor_impl.h:95
ArrayIterator< ArrayImpl_, reference > iterator
Iterator type.
Definition: array_impl.h:436
ArrayIterator(const ArrayIterator_ &other)
Copy constructor.
Definition: array_impl.h:280
Impl::value_type get() const
Definition: array_impl.h:168
const std::shared_ptr< pmap_interface > & pmap() const
Tensor process map accessor.
Definition: tensor_impl.h:89
Reference reference
Reference type to iterator value.
Definition: array_impl.h:250
Impl::value_type get() const
Definition: array_impl.h:85
iterator begin()
Array begin iterator.
Definition: array_impl.h:583
ArrayIterator(Impl *tensor, typename Impl::pmap_interface::const_iterator it)
Constructor.
Definition: array_impl.h:274
Tensor implementation and base for other tensor implementation objects.
Definition: tensor_impl.h:39
operator typename Impl::future() const
Definition: array_impl.h:91
bool operator==(const ArrayIterator< I, R > &other) const
Equality operator.
Definition: array_impl.h:342
#define TA_ASSERT(EXPR,...)
Definition: error.h:39
iterator end()
Array end iterator.
Definition: array_impl.h:615
Policy::ordinal_type ordinal_type
Ordinal type.
Definition: tensor_impl.h:46
Impl::range_type::index index_type
Definition: array_impl.h:254
ArrayIterator_ & operator=(const ArrayIterator_ &other)
Copy operator.
Definition: array_impl.h:298
DistributedStorage< value_type > storage_type
The data container type.
Definition: array_impl.h:431
ArrayImpl(World &world, const trange_type &trange, const shape_type &shape, const std::shared_ptr< pmap_interface > &pmap)
Constructor.
Definition: array_impl.h:453
TileConstReference(const TileReference< Impl > &other)
Definition: array_impl.h:160
ArrayImpl< Tile, Policy > ArrayImpl_
This object type.
Definition: array_impl.h:412
range_type make_range() const
Tile range factory function.
Definition: array_impl.h:392
Tensor tile reference.
Definition: array_impl.h:49
future get(size_type i) const
Get local or remote element.
future & get_local(const std::initializer_list< Integer > &i)
Local tile future accessor.
Definition: array_impl.h:535
void set(const Index &i, Value &&value)
Set tile.
Definition: array_impl.h:551
bool operator==(const TileReference< Impl > &a, const TileReference< Impl > &b)
comparison operator for TileReference objects
Definition: array_impl.h:120
const_iterator cend() const
Array end iterator.
Definition: array_impl.h:620
Policy::shape_type shape_type
Tensor shape type.
Definition: tensor_impl.h:47
ArrayIterator_ & operator=(const ArrayIterator< Impl, R > &other)
Copy operator.
Definition: array_impl.h:311
const future & get_local(const std::initializer_list< Integer > &i) const
Local tile future accessor.
Definition: array_impl.h:509
reference operator*() const
Dereference operator.
Definition: array_impl.h:360
std::forward_iterator_tag iterator_category
Iterator category type.
Definition: array_impl.h:252
TileConstReference(const TileConstReference< Impl > &other)
Definition: array_impl.h:157
ordinal_type ordinal() const
Tile ordinal index accessor.
Definition: array_impl.h:106
const future & get_local(const Index &i) const
Local tile future accessor.
Definition: array_impl.h:496
numeric_type< value_type >::type numeric_type
the numeric type that supports Tile
Definition: array_impl.h:429
const madness::uniqueidT & id() const
Unique object id accessor.
Definition: array_impl.h:627
Policy::range_type range_type
Element/tile range type.
Definition: tensor_impl.h:44
storage_type::future future
Future tile type.
Definition: array_impl.h:432
Policy::trange_type trange_type
Tiled range type.
Definition: tensor_impl.h:43
size_t volume(const DistArray< Tile, Policy > &a)
Definition: dist_array.h:1622
Policy::pmap_interface pmap_interface
Process map interface type.
Definition: tensor_impl.h:49
void set(const std::initializer_list< Index > &i, Value &&value)
Set tile.
Definition: array_impl.h:571
Policy::index1_type index1_type
1-index type
Definition: tensor_impl.h:45
eval_trait< Tile >::type eval_type
The tile evaluation type.
Definition: array_impl.h:427
Impl::ordinal_type ordinal_type
Definition: array_impl.h:255
future get(const Index &i) const
Tile future accessor.
Definition: array_impl.h:470
TileReference< Impl > & operator=(const Value &value)
Definition: array_impl.h:75
Determine the object type used in the evaluation of tensor expressions.
Definition: type_traits.h:580
const trange_type & trange() const
Tiled range accessor.
Definition: tensor_impl.h:167
const shape_type & shape() const
Tensor shape accessor.
Definition: tensor_impl.h:162
PointerProxy< value_type > pointer
Pointer type to iterator value.
Definition: array_impl.h:249
TensorImpl_::trange_type trange_type
Tiled range type for this object.
Definition: array_impl.h:419
ptrdiff_t difference_type
Difference type.
Definition: array_impl.h:246
An N-dimensional tensor object.
Definition: tensor.h:50
ArrayIterator< const ArrayImpl_, const_reference > const_iterator
Constant iterator type.
Definition: array_impl.h:438
Impl::future value_type
Iterator dereference value type.
Definition: array_impl.h:248
bool operator!=(const TileReference< Impl > &a, const TileReference< Impl > &b)
inequality operator for TileReference objects
Definition: array_impl.h:126
TileReference(const TileReference< Impl > &other)
Definition: array_impl.h:71
TensorImpl_::shape_type shape_type
Shape type.
Definition: array_impl.h:422
An N-dimensional shallow copy wrapper for tile objects.
Definition: tile.h:82
bool is_local(const Index &i) const
Query for a locally owned tile.
Definition: tensor_impl.h:134
ArrayIterator()
Default constructor.
Definition: array_impl.h:271