QMCPACK
ConstantSizeMatrix.hpp
Go to the documentation of this file.
1 #ifndef CONSTANTSIZEMATRIX_H
2 #define CONSTANTSIZEMATRIX_H
3 
4 #include <vector>
5 #include <sstream>
6 #include <exception>
7 
9 
10 namespace qmcplusplus
11 {
12 /** Drop in replacement for OhmmsMatrix as a storage object
13  * backed by PooledMemory, does not support PETE.
14  * rows are contiguous i.e. it's row major like OhmmsMatrix
15  * Constant size removes worry about synchronizing DataSet in Walker.
16  *
17  * Reproduces some *creative* operator semantics from OhmmsMatrix,
18  * be careful.
19  *
20  * This is intended as a host object, Not for use on accelerators.
21  */
22 template<class T, typename ALLOC = std::allocator<T>>
24 {
25 public:
26  ConstantSizeMatrix(size_t m, size_t n, size_t m_max, size_t n_max, T val = T())
27  : m_(m), n_(n), m_max_(m_max), n_max_(n_max), capacity_(n_max * m_max), data_(n_max * m_max, val)
28  {
29  if (n_max <= 0 || n > n_max || m_max <= 0 || m > m_max)
30  throw std::runtime_error("Cannot construct ConstantSizeMatrix with an invalid size");
31  }
32 
34  : m_(csm.m_), n_(csm.n_), m_max_(csm.m_max_), n_max_(csm.n_max_), capacity_(csm.capacity_), data_(csm.capacity_)
35  {
36  //I don't just do an = here because of the posible semantics of allocator propagation.
37  data_.assign(csm.begin(), csm.end());
38  }
39 
40  /**@{*/
41  /** Methods for assignment or copy of identically sized or smaller
42  * ConstantSizeMatrix<T, ALLOC>.
43  *
44  */
45  template<class RHS, typename allocator = ALLOC, typename = IsHostSafe<allocator>>
46  void copy(const RHS& rhs)
47  {
48  if (this->data_.capacity() < rhs.size())
49  throw std::runtime_error("Constant size vector cannot fit matrix to be copied.");
50  data_.assign(rhs.begin(), rhs.end());
51  }
52  void copy(const ConstantSizeMatrix& rhs)
53  {
54  if (this->data_.capacity() < rhs.size())
55  throw std::runtime_error("Constant size vector cannot fit matrix to be copied.");
56  if (&rhs == this)
57  throw std::runtime_error("ConstantSizeMatrix.copy(ConstantSizeMatrix& rhs) &rhs == this");
58  data_.assign(rhs.data_.begin(), rhs.data_.end());
59  }
60 
62  {
63  if (this->data_.capacity() < rhs.size())
64  throw std::runtime_error("ConstantSizeMatrix cannot take assignment of larger than max size");
65  if (&rhs != this)
66  {
67  if (rhs.n_max_ == n_max_)
68  data_.assign(rhs.data_.begin(), rhs.data_.end());
69  else
70  throw std::runtime_error("ConstnatSizedMatrix assignment for mismatched n_max not yet supported.");
71  }
72  return *this;
73  }
74 
75  template<template<typename, class> class RHS,
76  typename TP,
77  class ALLOCP,
78  typename = IsHostSafe<ALLOC>,
79  typename = IsHostSafe<ALLOCP>>
80  ConstantSizeMatrix<T, ALLOC>& operator=(const RHS<TP, ALLOCP>& rhs)
81  {
82  if (this->data_.capacity() < rhs.size())
83  throw std::runtime_error("ConstantSizeMatrix cannot be assigned a matrix larger than itself.");
84  data_.assign(rhs.begin(), rhs.end());
85  return *this;
86  }
87 
88  template<class TP, class ALLOCP, typename = IsHostSafe<ALLOC>, typename = IsHostSafe<ALLOCP>>
90  {
91  if (this->data_.capacity() < rhs.size())
92  {
93  std::basic_ostringstream<char> error;
94  error << "ConstantSizeMatrix cannot take assignment of larger than max size (" << n_max_ << " by " << m_max_
95  << ") \n";
96  throw std::runtime_error(error.str());
97  }
98  if (this->n_max_ < rhs.cols())
99  {
100  std::basic_ostringstream<char> error;
101  error << "ConstantSizeMatrix cannot be assigned a matrix dimension larger than n_max (" << n_max_ << ")\n";
102  throw std::runtime_error(error.str());
103  }
104  n_ = rhs.cols();
105  m_ = rhs.rows();
106  for (size_t row = 0; row < rhs.rows(); ++row)
107  std::copy(rhs[row], rhs[row] + n_, (*this)[row]);
108  return *this;
109  }
110 
111  /** @} */
112  // returns a const pointer of i-th row
113  const T* operator[](size_t i) const { return data_.data() + i * n_max_; }
114 
115  // returns a pointer of i-th row
116  T* operator[](size_t i) { return data_.data() + i * n_max_; }
117 
118  // returns reference to i-th value in the first row
119  template<typename Allocator = ALLOC, typename = IsHostSafe<Allocator>>
120  T& operator()(size_t i)
121  {
122  // As far as I know no code does this and none should
123  if (n_ <= i)
124  throw std::runtime_error("ConstantSizeMatrix doesn't support access to second row values through operator()");
125  return data_[i];
126  }
127 
128  template<typename Allocator = ALLOC, typename = IsHostSafe<Allocator>>
129  T operator()(size_t i) const
130  {
131  // As far as I know no code does this and none should
132  if (n_ <= i)
133  throw std::runtime_error("ConstantSizeMatrix doesn't support access to second row values through operator()");
134  return data_[i];
135  }
136 
137  // returns val(i,j)
138  template<typename Allocator = ALLOC, typename = IsHostSafe<Allocator>>
139  T& operator()(size_t i, size_t j)
140  {
141  return data_[i * n_max_ + j];
142  }
143 
144  // returns val(i,j)
145  template<typename Allocator = ALLOC, typename = IsHostSafe<Allocator>>
146  const T& operator()(size_t i, size_t j) const
147  {
148  return data_[i * n_max_ + j];
149  }
150 
151  T* data() { return data_.data(); }
152  const T* data() const { return data_.data(); }
153 
154  size_t capacity() { return capacity_; }
155  size_t n_capacity() { return n_max_; }
156 
157  size_t size() const { return n_ * m_; }
158  size_t cols() const { return n_; }
159  size_t rows() const { return m_; }
160 
161  void resize(size_t m, size_t n)
162  {
163  if (n * m > capacity())
164  {
165  std::ostringstream error;
166  error << "You cannot resize a constant size matrix beyond its initial max dimensions ( " << m << "," << n << " > "
167  << m_max_ << "," << n_max_ << " )\n";
168  throw std::domain_error(error.str());
169  }
170 
171  if (n > n_max_)
172  {
173  n_max_ = n;
174  m_max_ = capacity() / n_max_;
175  }
176 
177  if (m > m_max_)
178  {
179  m_max_ = m;
180  n_max_ = capacity() / m_max_;
181  }
182 
183  n_ = n;
184  m_ = m;
185  }
186 
187  auto begin() { return data_.begin(); }
188  auto end() { return data_.end(); }
189  auto begin() const { return data_.begin(); }
190  auto end() const { return data_.end(); }
191 
192 private:
193  size_t m_;
194  size_t n_;
195  size_t m_max_;
196  size_t n_max_;
197  size_t capacity_;
198  std::vector<T, ALLOC> data_;
199 };
200 
201 extern template class ConstantSizeMatrix<float>;
202 extern template class ConstantSizeMatrix<double>;
203 
204 } // namespace qmcplusplus
205 
206 
207 #endif /* CONSTANTSIZEMATRIX_H */
ConstantSizeMatrix< T, ALLOC > & operator=(const Matrix< TP, ALLOCP > &rhs)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void copy(const RHS &rhs)
Methods for assignment or copy of identically sized or smaller ConstantSizeMatrix<T, ALLOC>.
std::enable_if_t< qmc_allocator_traits< Allocator >::is_host_accessible > IsHostSafe
ConstantSizeMatrix & operator=(const ConstantSizeMatrix &rhs)
size_type cols() const
Definition: OhmmsMatrix.h:78
void copy(const Array< T1, 3 > &src, Array< T2, 3 > &dest)
Definition: Blitz.h:639
T & operator()(size_t i, size_t j)
void error(char const *m)
Definition: Standard.h:204
size_type size() const
Definition: OhmmsMatrix.h:76
const T * operator[](size_t i) const
ConstantSizeMatrix(const ConstantSizeMatrix &csm)
ConstantSizeMatrix(size_t m, size_t n, size_t m_max, size_t n_max, T val=T())
size_type rows() const
Definition: OhmmsMatrix.h:77
Drop in replacement for OhmmsMatrix as a storage object backed by PooledMemory, does not support PETE...
void copy(const ConstantSizeMatrix &rhs)
const T & operator()(size_t i, size_t j) const
ConstantSizeMatrix< T, ALLOC > & operator=(const RHS< TP, ALLOCP > &rhs)