val_array.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  * val_array.h
22  * Feb 17, 2014
23  *
24  */
25 
26 #ifndef TILEDARRAY_SHARED_BUFFER_H__INCLUDED
27 #define TILEDARRAY_SHARED_BUFFER_H__INCLUDED
28 
29 #include <TiledArray/size_array.h>
30 
31 #ifndef TILEDARRAY_DEFAULT_ALIGNMENT
32 #define TILEDARRAY_DEFAULT_ALIGNMENT 16
33 #endif // TILEDARRAY_ALIGNMENT
34 
35 namespace TiledArray {
36 namespace detail {
37 
39 
43 template <typename T>
44 class ValArray : private SizeArray<T> {
45  public:
50  typedef typename SizeArray<T>::const_reference
52  typedef typename SizeArray<T>::pointer pointer;
53  typedef typename SizeArray<T>::const_pointer
55  typedef typename SizeArray<T>::difference_type
57  typedef typename SizeArray<T>::iterator iterator;
58  typedef typename SizeArray<T>::const_iterator
60 
61  static const std::size_t alignment = TILEDARRAY_DEFAULT_ALIGNMENT;
62 
63  private:
65  mutable madness::AtomicInt* counter_ = nullptr;
66 
67  template <typename U>
68  typename std::enable_if<detail::is_scalar_v<U>>::type default_construct(
69  const size_type, U* MADNESS_RESTRICT) {}
70 
71  template <typename U>
72  typename std::enable_if<!detail::is_scalar_v<U>>::type default_construct(
73  const size_type n, U* MADNESS_RESTRICT u) {
74  size_type i = 0ul;
75  try {
76  for (; i < n; ++i) new (u + i) U();
77  } catch (...) {
79  throw;
80  }
81  }
82 
83  void deallocate() {
84  if (counter_) {
85  const int count = (*counter_)--;
86  if (count == 1) {
88  free(counter_);
89  }
90  }
91  }
92 
93  void init(const size_type n) {
94  typedef std::integral_constant<
95  size_type,
96  sizeof(madness::AtomicInt) +
97  ((alignment - (sizeof(madness::AtomicInt) & (alignment - 1ul))) &
98  ~alignment)>
99  sizeof_aligned_atomic_int;
100 
101  // Allocate buffer
102  void* buffer = nullptr;
103  if (posix_memalign(
104  &buffer, alignment,
105  (n * sizeof(value_type)) + sizeof_aligned_atomic_int::value) != 0)
106  throw std::bad_alloc();
107 
108  // Initialize counter
109  counter_ = reinterpret_cast<madness::AtomicInt*>(buffer);
110  new (counter_) madness::AtomicInt;
111  *counter_ = 1;
112 
113  // Initialize the array
114  pointer const array = reinterpret_cast<pointer>(
115  reinterpret_cast<char*>(buffer) + sizeof_aligned_atomic_int::value);
116  SizeArray<T>::set(array, n);
117  }
118 
119  public:
120  ValArray() = default;
121 
122  explicit ValArray(const size_type n) {
123  init(n);
124  default_construct(n, SizeArray<T>::data());
125  }
126 
127  template <typename Value, typename std::enable_if<std::is_convertible<
128  value_type, Value>::value>::type* = nullptr>
129  ValArray(const size_type n, const Value& value) {
130  init(n);
132  }
133 
134  template <typename Arg>
135  ValArray(const size_type n, const Arg* const arg) {
136  init(n);
138  }
139 
140  template <typename Arg, typename Op>
141  ValArray(const size_type n, const Arg* MADNESS_RESTRICT const arg,
142  const Op& op) {
143  init(n);
145  }
146 
147  template <typename U, typename Op>
148  ValArray(const ValArray<U>& arg, const Op& op) {
149  init(arg.size());
150  math::uninitialized_unary_vector_op(arg.size(), arg.data(),
151  SizeArray<T>::data(), op);
152  }
153 
154  template <typename Left, typename Right, typename Op>
155  ValArray(const size_type n, const Left* MADNESS_RESTRICT const left,
156  const Right* MADNESS_RESTRICT const right, const Op& op) {
157  init(n);
159  op);
160  }
161 
162  template <typename U, typename V, typename Op>
163  ValArray(const ValArray<U>& left, const ValArray<V>& right, const Op& op) {
164  TA_ASSERT(left.size() == right.size());
165  init(left.size());
166  math::uninitialized_binary_vector_op(left.size(), left.data(), right.data(),
167  SizeArray<T>::data(), op);
168  }
169 
170  ValArray(const ValArray_& other)
171  : SizeArray<T>(const_cast<pointer>(other.begin()),
172  const_cast<pointer>(other.end())),
173  counter_(other.counter_) {
174  if (counter_) (*counter_)++;
175  }
176 
177  ValArray_& operator=(const ValArray_& other) {
178  if (counter_ != other.counter_) {
179  // Cache pointers from other
180  madness::AtomicInt* const counter = other.counter_;
181  pointer const first = const_cast<pointer>(other.begin());
182  pointer const last = const_cast<pointer>(other.end());
183 
184  // Increment the reference counter for other
185  if (counter) (*counter)++;
186 
187  // Destroy this object
188  deallocate();
189 
190  // Set the data
191  counter_ = counter;
192  SizeArray<T>::set(first, last);
193  }
194 
195  return *this;
196  }
197 
198  ~ValArray() { deallocate(); }
199 
200  // Import SizeArray interface
201 
202  using SizeArray<T>::begin;
203  using SizeArray<T>::end;
204  using SizeArray<T>::rbegin;
205  using SizeArray<T>::rend;
206  using SizeArray<T>::operator[];
207  using SizeArray<T>::at;
208  using SizeArray<T>::front;
209  using SizeArray<T>::back;
210  using SizeArray<T>::size;
211  using SizeArray<T>::empty;
213  using SizeArray<T>::data;
214  using SizeArray<T>::assign;
215  using SizeArray<T>::binary;
216  using SizeArray<T>::unary;
217  using SizeArray<T>::reduce;
220  using SizeArray<T>::outer;
222 
223  // ValArray wrappers for vector operations
224 
226 
236  template <typename U, typename Op>
237  void binary(const ValArray<U>& arg, const Op& op) {
238  TA_ASSERT(arg.size() == SizeArray<T>::size());
239  SizeArray<T>::binary(arg.data(), op);
240  }
241 
243 
254  template <typename U, typename V, typename Op>
255  void binary(const ValArray<U>& left, const ValArray<V>& right, const Op& op) {
256  TA_ASSERT(left.size() == SizeArray<T>::size());
257  TA_ASSERT(right.size() == SizeArray<T>::size());
258  SizeArray<T>::binary(left.data(), right.data(), op);
259  }
260 
262 
271  template <typename U, typename Op>
272  void unary(const ValArray<U>& arg, const Op& op) {
273  TA_ASSERT(arg.size() == SizeArray<T>::size());
274  SizeArray<T>::unary(arg.data(), op);
275  }
276 
278 
290  template <typename U, typename Result, typename Op>
291  Result reduce(const ValArray<U>& arg, Result& result, const Op& op) {
292  TA_ASSERT(arg.size() == SizeArray<T>::size());
293  return SizeArray<T>::reduce(arg.data(), result, op);
294  }
295 
297 
309  template <typename U, typename V, typename Op>
310  void row_reduce(const ValArray<U>& left, const ValArray<V>& right,
311  const Op& op) {
312  TA_ASSERT(left.size() == (SizeArray<T>::size() * right.size()));
313  SizeArray<T>::row_reduce(right.size(), left.data(), right.data(), op);
314  }
315 
317 
326  template <typename U, typename Op>
327  void row_reduce(const ValArray<U>& arg, const Op& op) {
328  TA_ASSERT((arg.size() % SizeArray<T>::size()) == 0ul);
329  SizeArray<T>::row_reduce(arg.size() / SizeArray<T>::size(), arg, op);
330  }
331 
333 
345  template <typename U, typename V, typename Op>
346  void col_reduce(const ValArray<U>& left, const ValArray<V>& right,
347  const Op& op) {
348  TA_ASSERT(left.size() == (SizeArray<T>::size() * right.size()));
349  SizeArray<T>::col_reduce(right.size(), left.data(), right.data(), op);
350  }
351 
353 
362  template <typename U, typename Op>
363  void col_reduce(const ValArray<U>& arg, const Op& op) {
364  TA_ASSERT((arg.size() % SizeArray<T>::size()) == 0ul);
365  SizeArray<T>::col_reduce(arg.size() / SizeArray<T>::size(), arg, op);
366  }
367 
369 
381  template <typename U, typename V, typename Op>
382  void outer(const ValArray<U>& left, const ValArray<V>& right, const Op& op) {
383  TA_ASSERT(SizeArray<T>::size() == (left.size() * right.size()));
384  SizeArray<T>::outer(left.size(), right.size(), left.data(), right.data(),
385  op);
386  }
387 
389 
401  template <typename U, typename V, typename Op>
402  void outer_fill(const ValArray<U>& left, const ValArray<V>& right,
403  const Op& op) {
404  TA_ASSERT(SizeArray<T>::size() == (left.size() * right.size()));
405  SizeArray<T>::outer_fill(left.size(), right.size(), left.data(),
406  right.data(), op);
407  }
408 
410 
423  template <typename U, typename V, typename A, typename Op>
424  void outer_fill(const ValArray<U>& left, const ValArray<V>& right,
425  const ValArray<A>& a, const Op& op) {
426  TA_ASSERT(SizeArray<T>::size() == (left.size() * right.size()));
427  TA_ASSERT(a.size() == SizeArray<T>::size());
428  SizeArray<T>::outer_fill(left.size(), right.size(), left.data(),
429  right.data(), a.data(), op);
430  }
431 
432  void swap(ValArray_& other) {
433  std::swap(counter_, other.counter_);
434  pointer const first = other.begin();
435  pointer const last = other.end();
436  other.set(begin(), end());
437  SizeArray<T>::set(first, last);
438  }
439 
440  // Comparison operators
441  template <typename U>
442  bool operator==(const ValArray<U>& other) const {
443  return SizeArray<T>::operator==(other);
444  }
445 
446  template <typename U>
447  bool operator!=(const ValArray<U>& other) const {
448  return SizeArray<T>::operator!=(other);
449  }
450 
452 
455  template <typename Archive,
456  typename = std::enable_if_t<
458  void serialize(Archive& ar) const {
459  // need to write size first to be able to init when deserializing
460  ar& size() & madness::archive::wrap(data(), size());
461  }
462 
464 
467  template <typename Archive,
468  typename = std::enable_if_t<
470  void serialize(Archive& ar) {
471  size_t sz = 0;
472  ar& sz;
473  init(sz);
474  ar& madness::archive::wrap(data(), size());
475  }
476 
477 }; // class ValArray
478 
479 template <typename T>
480 inline std::ostream& operator<<(std::ostream& os,
481  const ValArray<T>& val_array) {
482  print_array(os, val_array);
483  return os;
484 }
485 
486 } // namespace detail
487 } // namespace TiledArray
488 
489 #endif // TILEDARRAY_SHARED_BUFFER_H__INCLUDED
archive_array< T > wrap(const T *, unsigned int)
ValArray(const size_type n, const Value &value)
Definition: val_array.h:129
::blas::Op Op
Definition: blas.h:46
SizeArray< T >::reference reference
Reference type.
Definition: val_array.h:49
Result reduce(const ValArray< U > &arg, Result &result, const Op &op)
Binary reduce operation.
Definition: val_array.h:291
SizeArray< T >::const_iterator const_iterator
Const iterator type.
Definition: val_array.h:59
std::ptrdiff_t difference_type
Definition: size_array.h:55
ValArray(const size_type n, const Arg *const arg)
Definition: val_array.h:135
void swap(Bitset< B > &b0, Bitset< B > &b1)
Definition: bitset.h:565
void outer_fill(const size_type m, const size_type n, const Left *const left, const Right *const right, const Op &op)
Outer fill operation.
Definition: size_array.h:401
SizeArray< T >::const_reference const_reference
Const reference type.
Definition: val_array.h:51
void unary(const Op &op)
Unary vector operation.
Definition: size_array.h:252
ValArray(const size_type n, const Left *MADNESS_RESTRICT const left, const Right *MADNESS_RESTRICT const right, const Op &op)
Definition: val_array.h:155
void col_reduce(const ValArray< U > &left, const ValArray< V > &right, const Op &op)
Reduce column operation.
Definition: val_array.h:346
std::enable_if<!(detail::is_scalar_v< Arg > &&detail::is_scalar_v< Result >)>::type uninitialized_unary_vector_op(const std::size_t n, const Arg *const arg, Result *const result, Op &&op)
Definition: vector_op.h:719
SizeArray< T >::const_pointer const_pointer
Const data pointer type.
Definition: val_array.h:54
bool operator==(const SizeArray< U > &other) const
Definition: size_array.h:189
std::ostream & operator<<(std::ostream &os, const TileReference< Impl > &a)
redirect operator to std::ostream for TileReference objects
Definition: array_impl.h:132
SizeArray< T >::iterator iterator
Iterator type.
Definition: val_array.h:57
SizeArray< T >::pointer pointer
Data pointer type.
Definition: val_array.h:52
void row_reduce(const ValArray< U > &arg, const Op &op)
Reduce row operation.
Definition: val_array.h:327
const_pointer data() const
Definition: size_array.h:177
SizeArray< T >::size_type size_type
size type
Definition: val_array.h:47
void outer_fill(const ValArray< U > &left, const ValArray< V > &right, const ValArray< A > &a, const Op &op)
Outer operation.
Definition: val_array.h:424
std::enable_if<!(detail::is_scalar_v< Arg > &&detail::is_scalar_v< Result >)>::type uninitialized_copy_vector(const std::size_t n, const Arg *const arg, Result *const result)
Definition: vector_op.h:674
std::enable_if<!detail::is_scalar_v< Arg > >::type destroy_vector(const std::size_t n, Arg *const arg)
Definition: vector_op.h:706
size_type size() const
Definition: size_array.h:167
void outer(const size_type m, const size_type n, const Left *const left, const Right *const right, const Op &op)
Outer operation.
Definition: size_array.h:382
void binary(const ValArray< U > &arg, const Op &op)
Binary vector operation.
Definition: val_array.h:237
ValArray(const size_type n)
Definition: val_array.h:122
#define TA_ASSERT(EXPR,...)
Definition: error.h:39
static const std::size_t alignment
Definition: val_array.h:61
ValArray(const ValArray< U > &left, const ValArray< V > &right, const Op &op)
Definition: val_array.h:163
ValArray< T > ValArray_
This object type.
Definition: val_array.h:46
std::enable_if<!(detail::is_scalar_v< Left > &&detail::is_scalar_v< Right > &&detail::is_scalar_v< Result >)>::type uninitialized_binary_vector_op(const std::size_t n, const Left *const left, const Right *const right, Result *const result, Op &&op)
Definition: vector_op.h:739
void serialize(Archive &ar)
(De)serialization
Definition: val_array.h:470
SizeArray< T >::value_type value_type
Element type.
Definition: val_array.h:48
void col_reduce(const size_type m, const Left *const left, const Right *right, const Op &op)
Column reduce operation.
Definition: size_array.h:350
std::enable_if<!(detail::is_scalar_v< Arg > &&detail::is_scalar_v< Result >)>::type uninitialized_fill_vector(const std::size_t n, const Arg &arg, Result *const result)
Definition: vector_op.h:691
void binary(const ValArray< U > &left, const ValArray< V > &right, const Op &op)
Binary vector operation.
Definition: val_array.h:255
ValArray(const size_type n, const Arg *MADNESS_RESTRICT const arg, const Op &op)
Definition: val_array.h:141
Result reduce(const Arg *const arg, Result result, const ReduceOp &reduce_op, const JoinOp &join_op) const
Binary reduction operation.
Definition: size_array.h:283
void outer(const ValArray< U > &left, const ValArray< V > &right, const Op &op)
Outer operation.
Definition: val_array.h:382
void print_array(std::ostream &out, const A &a, const std::size_t n)
Print the content of an array like object.
Definition: utility.h:48
void row_reduce(const ValArray< U > &left, const ValArray< V > &right, const Op &op)
Reduce row operation.
Definition: val_array.h:310
void swap(ValArray_ &other)
Definition: val_array.h:432
void unary(const ValArray< U > &arg, const Op &op)
Unary vector operation.
Definition: val_array.h:272
void binary(const Arg *const arg, const Op &op)
Binary vector operation.
Definition: size_array.h:225
bool operator!=(const SizeArray< U > &other) const
Definition: size_array.h:202
void row_reduce(const size_type n, const Left *const left, const Right *right, const Op &op)
Row reduce operation.
Definition: size_array.h:319
bool operator!=(const ValArray< U > &other) const
Definition: val_array.h:447
void outer_fill(const ValArray< U > &left, const ValArray< V > &right, const Op &op)
Outer fill operation.
Definition: val_array.h:402
ValArray(const ValArray_ &other)
Definition: val_array.h:170
ValArray_ & operator=(const ValArray_ &other)
Definition: val_array.h:177
bool operator==(const ValArray< U > &other) const
Definition: val_array.h:442
SizeArray< T >::difference_type difference_type
Difference type.
Definition: val_array.h:56
void set(pointer const first, const size_type n)
Definition: size_array.h:69
ValArray(const ValArray< U > &arg, const Op &op)
Definition: val_array.h:148
#define TILEDARRAY_DEFAULT_ALIGNMENT
Definition: val_array.h:32
void col_reduce(const ValArray< U > &arg, const Op &op)
Reduce column operation.
Definition: val_array.h:363
void serialize(Archive &ar) const
Serialization.
Definition: val_array.h:458