TiledArray  0.7.0
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 
29 #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> class TensorReference;
39  template <typename> class TensorConstReference;
40  template <typename, typename> class ArrayIterator;
41 
43 
45  template <typename Impl>
46  class TileReference {
47  private:
48 
49  template <typename, typename>
50  friend class ArrayIterator;
51 
52  template <typename>
53  friend class TileConstReference;
54 
55  typedef typename Impl::range_type range_type;
56  typedef typename Impl::range_type::index index_type;
57  typedef typename Impl::size_type ordinal_type;
58 
59  Impl* tensor_;
60  ordinal_type index_;
61 
62  // Not allowed
63  TileReference<Impl>& operator=(const TileReference<Impl>&);
64  public:
65 
66  TileReference(Impl* tensor, const typename Impl::size_type index) :
67  tensor_(tensor), index_(index)
68  { }
69 
71  tensor_(other.tensor_), index_(other.index_)
72  { }
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 {
107  return index_;
108  }
109 
111 
113  range_type make_range() const {
114  TA_ASSERT(tensor_);
115  return tensor_->trange().make_tile_range(index_);
116  }
117 
118  }; // class TileReference
119 
121  template <typename Impl>
123  const TileReference<Impl>& b) {
124  return a.get() == b.get();
125  }
126 
128  template <typename Impl>
130  const TileReference<Impl>& b) {
131  return !(a == b);
132  }
133 
135  template <typename Impl>
136  std::ostream& operator<<(std::ostream& os, const TileReference<Impl>& a) {
137  os << a.get();
138  return os;
139  }
140 
142 
144  template <typename Impl>
146  private:
147 
148  template <typename, typename>
149  friend class ArrayIterator;
150 
151  const Impl* tensor_;
152  typename Impl::size_type index_;
153 
154  // Not allowed
156  public:
157 
158  TileConstReference(const Impl* tensor, const typename Impl::size_type index) :
159  tensor_(tensor), index_(index)
160  { }
161 
163  tensor_(other.tensor_), index_(other.index_)
164  { }
165 
167  tensor_(other.tensor_), index_(other.index_)
168  { }
169 
170  typename Impl::future future() const {
171  TA_ASSERT(tensor_);
172  return tensor_->get(index_);
173  }
174 
175  typename Impl::value_type get() const {
176  // NOTE: return by value to avoid lifetime issues.
177  TA_ASSERT(tensor_);
178  return future().get();
179  }
180 
181  operator typename Impl::future() const { return tensor_->get(index_); }
182 
183  operator typename Impl::value_type() const { return get(); }
184  }; // class TileConstReference
185 
187  template <typename Impl>
189  const TileConstReference<Impl>& b) {
190  return a.get() == b.get();
191  }
192 
194  template <typename Impl>
196  const TileConstReference<Impl>& b) {
197  return !(a == b);
198  }
199 
201  template <typename Impl>
202  std::ostream& operator<<(std::ostream& os, const TileConstReference<Impl>& a) {
203  os << a.get();
204  return os;
205  }
206 
207  } // namespace detail
208 } // namespace TiledArray
209 
210 
211 namespace madness {
212  namespace detail {
213 
214  // The following class specializations are required so MADNESS will do the
215  // right thing when given a TileReference or TileConstReference object
216  // as an input for task functions.
217 
218  template <typename Impl>
219  struct task_arg<TiledArray::detail::TileReference<Impl> > {
220  typedef typename Impl::value_type type;
221  typedef typename Impl::future holderT;
222  }; // struct task_arg<TiledArray::detail::TileReference<Impl> >
223 
224  template <typename Impl>
225  struct task_arg<TiledArray::detail::TileConstReference<Impl> > {
226  typedef typename Impl::value_type type;
227  typedef typename Impl::future holderT;
228  }; // struct task_arg<TiledArray::detail::TileConstReference<Impl> >
229 
230  } // namespace detail
231 } // namespace madness
232 
233 
234 namespace TiledArray {
235  namespace detail {
236 
238 
244  template <typename Impl, typename Reference>
245  class ArrayIterator {
246  private:
247  // Give access to other iterator types.
248  template <typename, typename>
249  friend class ArrayIterator;
250 
251  Impl* array_;
252  typename Impl::pmap_interface::const_iterator it_;
253 
254  public:
255  typedef ptrdiff_t difference_type;
256  typedef typename Impl::future value_type;
257  typedef PointerProxy<value_type> pointer;
258  typedef Reference reference;
259  typedef std::forward_iterator_tag iterator_category;
261  typedef typename Impl::range_type::index index_type;
262  typedef typename Impl::size_type ordinal_type;
263  typedef typename Impl::range_type range_type;
264  typedef typename Impl::value_type tile_type;
265 
266  private:
267 
268  void advance() {
269  TA_ASSERT(array_);
270  const typename Impl::pmap_interface::const_iterator end =
271  array_->pmap()->end();
272  do {
273  ++it_;
274  } while((it_ != end) && array_->is_zero(*it_));
275  }
276 
277  public:
278 
280  ArrayIterator() : array_(NULL), it_() { }
281 
283  ArrayIterator(Impl* tensor, typename Impl::pmap_interface::const_iterator it) :
284  array_(tensor), it_(it)
285  { }
286 
288 
291  array_(other.array_), it_(other.it_)
292  { }
293 
295 
298  template <typename I, typename R,
299  typename std::enable_if<
300  !((! std::is_const<Impl>::value) &&
301  std::is_const<I>::value)
302  >::type* = nullptr>
304  array_(other.array_), it_(other.it_)
305  { }
306 
308 
312  array_ = other.array_;
313  it_ = other.it_;
314 
315  return *this;
316  }
317 
319 
323  template <typename R>
325  array_ = other.array_;
326  it_ = other.it_;
327 
328  return *this;
329  }
330 
332 
335  advance();
336  return *this;
337  }
338 
340 
343  ArrayIterator_ tmp(*this);
344  advance();
345  return tmp;
346  }
347 
349 
354  template <typename I, typename R>
355  bool operator==(const ArrayIterator<I, R>& other) const {
356  return (array_ == other.array_) && (it_ == other.it_);
357  }
358 
360 
365  template <typename I, typename R>
366  bool operator!=(const ArrayIterator<I, R>& other) const {
367  return (array_ != other.array_) || (it_ != other.it_);
368  }
369 
371 
374  TA_ASSERT(array_);
375  return reference(array_, *it_);
376  }
377 
379 
381  pointer operator->() const {
382  TA_ASSERT(array_);
383  return pointer(array_->get(*it_));
384  }
385 
387 
389  index_type index() const {
390  TA_ASSERT(array_);
391  return array_->tiles_range().idx(*it_);
392  }
393 
395 
398  TA_ASSERT(array_);
399  return *it_;
400  }
401 
403 
406  TA_ASSERT(array_);
407  TA_ASSERT(it_ != array_->pmap()->end());
408  return array_->trange().make_tile_range(*it_);
409  }
410 
411  }; // class TensorIterator
412 
414 
422  template <typename Tile, typename Policy>
423  class ArrayImpl : public TensorImpl<Policy> {
424  public:
433  typedef Tile value_type;
435  typedef typename numeric_type<value_type>::type
438  typedef typename storage_type::future future;
443 
444  private:
445 
446  storage_type data_;
447 
448  public:
449 
451 
460  const std::shared_ptr<pmap_interface>& pmap) :
462  data_(world, trange.tiles_range().volume(), pmap)
463  { }
464 
466  virtual ~ArrayImpl() { }
467 
469 
474  template <typename Index>
475  future get(const Index& i) const {
477  return data_.get(TensorImpl_::trange().tiles_range().ordinal(i));
478  }
479 
481 
486  template <typename Integer>
487  future get(const std::initializer_list<Integer>& i) const {
488  return get<std::initializer_list<Integer>>(i);
489  }
490 
492 
500  template <typename Index, typename Value>
501  void set(const Index& i, const Value& value) {
503  data_.set(TensorImpl_::trange().tiles_range().ordinal(i), value);
504  }
505 
507 
510  // Get the pmap iterator
511  typename pmap_interface::const_iterator it = TensorImpl_::pmap()->begin();
512 
513  // Find the fist non-zero iterator
514  const typename pmap_interface::const_iterator end = TensorImpl_::pmap()->end();
515  while((it != end) && TensorImpl_::is_zero(*it)) ++it;
516 
517  // Construct and return the iterator
518  return iterator(this, it);
519  }
520 
522 
525  // Get the pmap iterator
526  typename pmap_interface::const_iterator it = TensorImpl_::pmap()->begin();
527 
528  // Find the fist non-zero iterator
529  const typename pmap_interface::const_iterator end = TensorImpl_::pmap()->end();
530  while((it != end) && TensorImpl_::is_zero(*it)) ++it;
531 
532  // Construct and return the iterator
533  return const_iterator(this, it);
534  }
535 
537 
540  return iterator(this, TensorImpl_::pmap()->end());
541  }
542 
544 
547  return const_iterator(this, TensorImpl_::pmap()->end());
548  }
549 
551 
553  const madness::uniqueidT& id() const { return data_.id(); }
554 
555  }; // class ArrayImpl
556 
557 
558 #ifndef TILEDARRAY_HEADER_ONLY
559 
560  extern template
561  class ArrayImpl<Tensor<double, Eigen::aligned_allocator<double> >, DensePolicy>;
562  extern template
563  class ArrayImpl<Tensor<float, Eigen::aligned_allocator<float> >, DensePolicy>;
564  extern template
565  class ArrayImpl<Tensor<int, Eigen::aligned_allocator<int> >, DensePolicy>;
566  extern template
567  class ArrayImpl<Tensor<long, Eigen::aligned_allocator<long> >, DensePolicy>;
568 // extern template
569 // class ArrayImpl<Tensor<std::complex<double>, Eigen::aligned_allocator<std::complex<double> > >, DensePolicy>;
570 // extern template
571 // class ArrayImpl<Tensor<std::complex<float>, Eigen::aligned_allocator<std::complex<float> > >, DensePolicy>;
572 
573  extern template
574  class ArrayImpl<Tensor<double, Eigen::aligned_allocator<double> >, SparsePolicy>;
575  extern template
576  class ArrayImpl<Tensor<float, Eigen::aligned_allocator<float> >, SparsePolicy>;
577  extern template
578  class ArrayImpl<Tensor<int, Eigen::aligned_allocator<int> >, SparsePolicy>;
579  extern template
580  class ArrayImpl<Tensor<long, Eigen::aligned_allocator<long> >, SparsePolicy>;
581 // extern template
582 // class ArrayImpl<Tensor<std::complex<double>, Eigen::aligned_allocator<std::complex<double> > >, SparsePolicy>;
583 // extern template
584 // class ArrayImpl<Tensor<std::complex<float>, Eigen::aligned_allocator<std::complex<float> > >, SparsePolicy>;
585 
586 #endif // TILEDARRAY_HEADER_ONLY
587 
588  } // namespace detail
589 } // namespace TiledArray
590 
591 #endif // TILEDARRAY_ARRAY_IMPL_H__INCLUDED
TensorImpl_::range_type range_type
Elements/tiles range type.
Definition: array_impl.h:430
TensorImpl_::shape_type shape_type
Shape type.
Definition: array_impl.h:431
TensorImpl< Policy > TensorImpl_
The base class of this object.
Definition: array_impl.h:426
Distributed tensor iterator.
Definition: array_impl.h:40
ptrdiff_t difference_type
Difference type.
Definition: array_impl.h:255
const_iterator cbegin() const
Array begin iterator.
Definition: array_impl.h:524
ArrayIterator_ & operator=(const ArrayIterator_ &other)
Copy operator.
Definition: array_impl.h:311
const shape_type & shape() const
Tensor shape accessor.
Definition: tensor_impl.h:156
ArrayIterator(const ArrayIterator_ &other)
Copy constructor.
Definition: array_impl.h:290
const trange_type & trange() const
Tiled range accessor.
Definition: tensor_impl.h:161
Policy::range_type range_type
Element/tile range type.
Definition: tensor_impl.h:44
TileReference< ArrayImpl_ > reference
Tile reference type.
Definition: array_impl.h:439
ArrayIterator(Impl *tensor, typename Impl::pmap_interface::const_iterator it)
Constructor.
Definition: array_impl.h:283
Policy::pmap_interface pmap_interface
Process map interface type.
Definition: tensor_impl.h:47
bool operator==(const ArrayIterator< I, R > &other) const
Equality operator.
Definition: array_impl.h:355
Reference reference
Reference type to iterator value.
Definition: array_impl.h:258
bool operator!=(const TileReference< Impl > &a, const TileReference< Impl > &b)
inequality operator for TileReference objects
Definition: array_impl.h:129
std::forward_iterator_tag iterator_category
Iterator category type.
Definition: array_impl.h:259
future get(size_type i) const
Get local or remote element.
range_type make_range() const
Tile range factory function.
Definition: array_impl.h:405
iterator begin()
Array begin iterator.
Definition: array_impl.h:509
eval_trait< Tile >::type eval_type
The tile evaluation type.
Definition: array_impl.h:434
Tensor implementation and base for other tensor implementation objects.
Definition: tensor_impl.h:39
TileConstReference(const TileReference< Impl > &other)
Definition: array_impl.h:166
reference operator*() const
Dereference operator.
Definition: array_impl.h:373
ordinal_type ordinal() const
Tile ordinal index accessor.
Definition: array_impl.h:397
TensorImpl_::size_type size_type
Size type.
Definition: array_impl.h:427
Policy policy_type
Policy type.
Definition: tensor_impl.h:42
TileReference(const TileReference< Impl > &other)
Definition: array_impl.h:70
Policy::trange_type trange_type
Tiled range type.
Definition: tensor_impl.h:43
void set(size_type i, const value_type &value)
Set element i with value.
ArrayIterator< Impl, Reference > ArrayIterator_
This object type.
Definition: array_impl.h:260
index_type index() const
Tile coordinate index accessor.
Definition: array_impl.h:98
ArrayIterator< const ArrayImpl_, const_reference > const_iterator
Constant iterator type.
Definition: array_impl.h:442
bool operator!=(const ArrayIterator< I, R > &other) const
Inequality operator.
Definition: array_impl.h:366
DistributedStorage< value_type > storage_type
The data container type.
Definition: array_impl.h:437
Impl::future future() const
Definition: array_impl.h:80
Impl::value_type get() const
Definition: array_impl.h:175
TensorImpl_::trange_type trange_type
Tiled range type for this object.
Definition: array_impl.h:429
storage_type::future future
Future tile type.
Definition: array_impl.h:438
TileReference< Impl > & operator=(const Value &value)
Definition: array_impl.h:75
#define TA_ASSERT(a)
Definition: error.h:107
Tensor implementation and base for other tensor implementation objects.
Definition: array_impl.h:423
ArrayIterator_ & operator++()
Prefix increment operator.
Definition: array_impl.h:334
PointerProxy< value_type > pointer
Pointer type to iterator value.
Definition: array_impl.h:257
bool is_zero(const Index &i) const
Query for a zero tile.
Definition: tensor_impl.h:141
TensorImpl_::policy_type policy_type
Policy type for this object.
Definition: array_impl.h:428
TensorImpl_::pmap_interface pmap_interface
process map interface type
Definition: array_impl.h:432
const madness::uniqueidT & id() const
Unique object id accessor.
Definition: array_impl.h:553
Policy::size_type size_type
Size type.
Definition: tensor_impl.h:45
range_type make_range() const
Tile range factory function.
Definition: array_impl.h:113
index_type index() const
Tile coordinate index accessor.
Definition: array_impl.h:389
TileReference(Impl *tensor, const typename Impl::size_type index)
Definition: array_impl.h:66
operator typename Impl::future() const
Definition: array_impl.h:91
TileConstReference(const Impl *tensor, const typename Impl::size_type index)
Definition: array_impl.h:158
Impl::future value_type
Iterator dereference value type.
Definition: array_impl.h:256
ArrayImpl(World &world, const trange_type &trange, const shape_type &shape, const std::shared_ptr< pmap_interface > &pmap)
Constructor.
Definition: array_impl.h:459
TileConstReference< ArrayImpl_ > const_reference
Tile constant reference type.
Definition: array_impl.h:440
ArrayIterator()
Default constructor.
Definition: array_impl.h:280
ArrayIterator< ArrayImpl_, reference > iterator
Iterator type.
Definition: array_impl.h:441
ArrayIterator_ operator++(int)
Post-fix increment operator.
Definition: array_impl.h:342
bool operator==(const TileReference< Impl > &a, const TileReference< Impl > &b)
comparison operator for TileReference objects
Definition: array_impl.h:122
Impl::range_type::index index_type
Definition: array_impl.h:261
World & world() const
World accessor.
Definition: tensor_impl.h:169
ArrayIterator_ & operator=(const ArrayIterator< Impl, R > &other)
Copy operator.
Definition: array_impl.h:324
pointer operator->() const
Arrow dereference operator.
Definition: array_impl.h:381
Tensor tile reference.
Definition: array_impl.h:46
ArrayIterator(const ArrayIterator< I, R > &other)
Copy const iterator constructor.
Definition: array_impl.h:303
iterator end()
Array end iterator.
Definition: array_impl.h:539
virtual ~ArrayImpl()
Virtual destructor.
Definition: array_impl.h:466
ArrayImpl< Tile, Policy > ArrayImpl_
This object type.
Definition: array_impl.h:425
const range_type & tiles_range() const
Tiles range accessor.
Definition: tensor_impl.h:91
const_iterator cend() const
Array end iterator.
Definition: array_impl.h:546
ordinal_type ordinal() const
Tile ordinal index accessor.
Definition: array_impl.h:106
Future< value_type > future
Element container type.
const std::shared_ptr< pmap_interface > & pmap() const
Tensor process map accessor.
Definition: tensor_impl.h:85
Impl::value_type get() const
Definition: array_impl.h:85
An N-dimensional shallow copy wrapper for tile objects.
Definition: tile.h:80
TileConstReference(const TileConstReference< Impl > &other)
Definition: array_impl.h:162
numeric_type< value_type >::type numeric_type
the numeric type that supports Tile
Definition: array_impl.h:436
Policy::shape_type shape_type
Tensor shape type.
Definition: tensor_impl.h:46
Tile value_type
Tile or data type.
Definition: array_impl.h:433