QMCPACK
PooledMemory.h
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeongnim Kim, jeongnim.kim@intel.com, Intel Corp.
8 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
9 //
10 // File created by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 #ifndef QMCPLUSPLUS_POOLEDMEMORY_H
15 #define QMCPLUSPLUS_POOLEDMEMORY_H
16 
17 #include <complex>
18 #include <cstring>
20 #include "OhmmsPETE/OhmmsVector.h"
21 #include <stdexcept>
22 
23 namespace qmcplusplus
24 {
25 /** Memory pool to manage arrays+scalars with alignment
26  * @tparam T_scalar : type of the scalar data type, typically OHMMS_PRECISION_FULL
27  * @tparam PageSize : page size in bytes, default=4096 (4K)
28  * @tparam Alloc : allocator, Mallocator<T, PageSize>
29  *
30  * The bulk part is accessed directly by address
31  * The scalar part works as PooledData, all the values are static_cast to T_scalar.
32  */
33 #define DEFAULT_PAGE_SIZE 4096
34 template<typename T_scalar, typename Alloc = aligned_allocator<char, DEFAULT_PAGE_SIZE>>
36 {
37  using T = char;
38  using value_type = T;
40 
41  const int scalar_multiplier;
43  T_scalar* Scalar_ptr;
45 
46  ///default constructor
47  inline PooledMemory() : scalar_multiplier(sizeof(T_scalar)), Current(0), Current_scalar(0), Scalar_ptr(nullptr) {}
48 
49  ///copy constructor
52  Current(in.Current),
54  myData(in.myData)
55  {
56  Scalar_ptr = reinterpret_cast<T_scalar*>(myData.data() + in.scalar_offset());
57  }
58 
59  ///copy assign operator
61  {
62  myData = in.myData;
63  Current = in.Current;
65  Scalar_ptr = reinterpret_cast<T_scalar*>(myData.data() + in.scalar_offset());
66  return *this;
67  }
68 
69  ///return the size of the data
70  inline size_type byteSize() const { return sizeof(T) * myData.size(); }
71 
72  ///return the size of the data
73  inline size_type size() const { return myData.size(); }
74 
75  //return the cursor
76  inline size_type current() const { return Current; }
77 
78  //return the cursor of scalar
79  inline size_type current_scalar() const { return Current_scalar; }
80 
81  /** set the cursors
82  * @param cur locator to which Current is assigned
83  * @param cur_scalar locator to which Current_scalar is assigned
84  */
85  inline void rewind(size_type cur = 0, size_type cur_scalar = 0)
86  {
87  Current = cur;
88  Current_scalar = cur_scalar;
89  }
90 
91  ///clear the data and set Current=0
92  inline void clear()
93  {
94  myData.clear();
95  Current = 0;
96  Scalar_ptr = nullptr;
97  Current_scalar = 0;
98  }
99 
100  ///zero the data
101  inline void zero() { myData.zero(); }
102 
103  ///allocate the data
104  inline void allocate()
105  {
107  if ((size_t(myData.data())) & (QMC_SIMD_ALIGNMENT - 1))
108  throw std::runtime_error("Unaligned memory allocated in PooledMemory");
109  Scalar_ptr = reinterpret_cast<T_scalar*>(myData.data() + Current);
110  }
111 
112  template<typename T1>
113  inline void add(std::complex<T1>& x)
114  {
115  Current_scalar += 2;
116  }
117 
118  template<typename T1>
119  inline void add(T1& x)
120  {
121  Current_scalar++;
122  }
123 
124  template<typename T1>
125  inline void add(T1* first, T1* last)
126  {
127  constexpr int multiplier = sizeof(T1);
128  Current += getAlignedSize<T>((last - first) * multiplier);
129  }
130 
131  template<typename T1>
132  inline void get(std::complex<T1>& x)
133  {
134  x = std::complex<T1>(static_cast<T1>(Scalar_ptr[Current_scalar]), static_cast<T1>(Scalar_ptr[Current_scalar + 1]));
135  Current_scalar += 2;
136  }
137 
138  template<typename T1>
139  inline void get(T1& x)
140  {
141  x = static_cast<T1>(Scalar_ptr[Current_scalar++]);
142  }
143 
144  template<typename T1>
145  inline void get(T1* first, T1* last)
146  {
147  // for backward compatibility
148  const size_t nbytes = (last - first) * sizeof(T1);
149  std::memcpy(first, myData.data() + Current, nbytes);
150  Current += getAlignedSize<T>(nbytes);
151  }
152 
153  template<typename T1>
155  {
156  constexpr int multiplier = sizeof(T1);
157  T1* ptr = reinterpret_cast<T1*>(myData.data() + Current);
158  Current += getAlignedSize<T>(n * multiplier);
159  return ptr;
160  }
161 
162  inline void forward(size_type n) { Current += getAlignedSize<T>(n); }
163 
164  template<typename T1>
165  inline void put(std::complex<T1>& x)
166  {
167  Scalar_ptr[Current_scalar++] = static_cast<T_scalar>(x.real());
168  Scalar_ptr[Current_scalar++] = static_cast<T_scalar>(x.imag());
169  }
170 
171  template<typename T1>
172  inline void put(T1& x)
173  {
174  Scalar_ptr[Current_scalar++] = static_cast<T_scalar>(x);
175  }
176 
177  template<typename T1>
178  inline void put(T1* first, T1* last)
179  {
180  // for backward compatibility
181  const size_t nbytes = (last - first) * sizeof(T1);
182  std::memcpy(myData.data() + Current, first, nbytes);
183  Current += getAlignedSize<T>(nbytes);
184  }
185 
186  /** return the address of the first element **/
187  inline T* data() { return myData.data(); }
188 
189  /** return the address offset of the first scalar element **/
190  inline size_type scalar_offset() const { return reinterpret_cast<T*>(Scalar_ptr) - myData.data(); }
191 
192  template<class Msg>
193  inline Msg& putMessage(Msg& m)
194  {
195  m.Pack(myData.data(), myData.size());
196  return m;
197  }
198 
199  template<class Msg>
200  inline Msg& getMessage(Msg& m)
201  {
202  m.Unpack(myData.data(), myData.size());
203  return m;
204  }
205 
206  template<typename T1>
207  inline PooledMemory& operator<<(T1& x)
208  {
209  put(x);
210  return *this;
211  }
212 
213  template<typename T1>
214  inline PooledMemory& operator>>(T1& x)
215  {
216  get(x);
217  return *this;
218  }
219 };
220 
221 } // namespace qmcplusplus
222 #endif
void put(T1 *first, T1 *last)
Definition: PooledMemory.h:178
Vector< T, Alloc > myData
Definition: PooledMemory.h:44
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void forward(size_type n)
Definition: PooledMemory.h:162
void add(T1 *first, T1 *last)
Definition: PooledMemory.h:125
void allocate()
allocate the data
Definition: PooledMemory.h:104
void zero()
zero the data
Definition: PooledMemory.h:101
PooledMemory & operator=(const PooledMemory &in)
copy assign operator
Definition: PooledMemory.h:60
T * data()
return the address of the first element
Definition: PooledMemory.h:187
size_type byteSize() const
return the size of the data
Definition: PooledMemory.h:70
PooledMemory()
default constructor
Definition: PooledMemory.h:47
size_type current() const
Definition: PooledMemory.h:76
Declaraton of Vector<T,Alloc> Manage memory through Alloc directly and allow referencing an existing ...
size_type size() const
return the size of the data
Definition: PooledMemory.h:73
PooledMemory(const PooledMemory &in)
copy constructor
Definition: PooledMemory.h:50
PooledMemory & operator>>(T1 &x)
Definition: PooledMemory.h:214
PooledMemory & operator<<(T1 &x)
Definition: PooledMemory.h:207
typename Vector< T, aligned_allocator< char, DEFAULT_PAGE_SIZE > >::size_type size_type
Definition: PooledMemory.h:39
size_type current_scalar() const
Definition: PooledMemory.h:79
void clear()
clear the data and set Current=0
Definition: PooledMemory.h:92
typename Alloc::size_type size_type
Definition: OhmmsVector.h:40
void rewind(size_type cur=0, size_type cur_scalar=0)
set the cursors
Definition: PooledMemory.h:85
T1 * lendReference(size_type n)
Definition: PooledMemory.h:154
void put(std::complex< T1 > &x)
Definition: PooledMemory.h:165
size_type scalar_offset() const
return the address offset of the first scalar element
Definition: PooledMemory.h:190
void add(std::complex< T1 > &x)
Definition: PooledMemory.h:113