Psi4
memory_manager.h
Go to the documentation of this file.
1 /*
2  * @BEGIN LICENSE
3  *
4  * Psi4: an open-source quantum chemistry software package
5  *
6  * Copyright (c) 2007-2017 The Psi4 Developers.
7  *
8  * The copyrights for code used from other parties are included in
9  * the corresponding files.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  *
25  * @END LICENSE
26  */
27 
28 #ifndef _psi_src_bin_psimrccmemory_managerh_
29 #define _psi_src_bin_psimrccmemory_managerh_
30 
31 #include <map>
32 #include <vector>
33 #include <string>
34 
35 
36 namespace psi{
37 
38 /*
39  * Computes the size in mebibytes (MiB) of a given amount of type T
40  */
41 template <typename T>
42 double type_to_MiB(size_t n)
43 {
44  // 1 MiB = 1048576 bytes
45  size_t bites = n * static_cast<size_t>(sizeof(T));
46  return(static_cast<double>(bites)/1048576.0);
47 }
48 
49 /*
50  * Convert bytes to mebibytes (MiB)
51  */
52 double bytes_to_MiB(size_t n);
53 
54 typedef struct {
55  void* variable;
56  std::string type;
57  std::string variableName;
58  std::string fileName;
59  size_t lineNumber;
60  std::vector<size_t> argumentList;
62 
64 {
65 public:
66  MemoryManager(size_t maxcor = 256000000);
68 
69  void MemCheck(std::string output);
70 
71  size_t get_FreeMemory() const {return(MaximumAllowed - CurrentAllocated);}
72  size_t get_CurrentAllocated() const {return(CurrentAllocated);}
73  size_t get_MaximumAllowedMemory() const {return(MaximumAllowed);}
74 
75  template <typename T>
76  void allocate(const char *type, T*& matrix, size_t size, const char *variableName, const char *fileName, size_t lineNumber);
77  template <typename T>
78  void release_one(T*& matrix, const char *fileName, size_t lineNumber);
79 
80  template <typename T>
81  void allocate(const char *type, T**& matrix, size_t size1, size_t size2, const char *variableName, const char *fileName, size_t lineNumber);
82  template <typename T>
83  void release_two(T**& matrix, const char *fileName, size_t lineNumber);
84 
85  template <typename T>
86  void allocate(const char *type, T***& matrix,size_t size1,size_t size2,size_t size3, const char *variableName, const char *fileName, size_t lineNumber);
87  template <typename T>
88  void release_three(T***& matrix, const char *fileName, size_t lineNumber);
89 private:
90  void RegisterMemory(void *mem, AllocationEntry& entry, size_t size);
91  void UnregisterMemory(void *mem, size_t size, const char *fileName, size_t lineNumber);
92 
96  std::map<void *, AllocationEntry> AllocationTable;
97 };
98 
99 template <typename T>
100 void MemoryManager::allocate(const char *type, T*& matrix, size_t size, const char *variableName, const char *fileName, size_t lineNumber)
101 {
102  AllocationEntry newEntry;
103 
104  if(size<=0){
105  matrix = NULL;
106  }else{
107  matrix = new T[size];
108  for(size_t i=0;i<size;i++)
109  matrix[i]=static_cast<T>(0); // Zero all the elements
110 
111  newEntry.variable = matrix;
112  newEntry.type = type;
113  newEntry.variableName = variableName;
114  newEntry.fileName = fileName;
115  newEntry.lineNumber = lineNumber;
116  newEntry.argumentList.push_back(size);
117  RegisterMemory(static_cast<void*>(matrix), newEntry, size*sizeof(T));
118  }
119 }
120 
121 template <typename T>
122 void MemoryManager::release_one(T*& matrix, const char *fileName, size_t lineNumber)
123 {
124  if(matrix == NULL)
125  return;
126 
127  size_t size = AllocationTable[static_cast<void*>(matrix)].argumentList[0];
128 
129  UnregisterMemory(static_cast<void*>(matrix), size*sizeof(T),fileName,lineNumber);
130 
131  delete[] matrix;
132  matrix = NULL;
133 }
134 
135 template <typename T>
136 void MemoryManager::allocate(const char *type, T**& matrix, size_t size1, size_t size2, const char *variableName, const char *fileName, size_t lineNumber)
137 {
138  AllocationEntry newEntry;
139  size_t size = size1*size2;
140 
141  if(size<=0){
142  matrix = NULL;
143  return;
144  }else{
145  matrix = new T*[size1];
146  T* vector = new T[size];
147  for(size_t i=0;i<size;i++)
148  vector[i]=static_cast<T>(0); // Zero all the elements
149  for(size_t i=0;i<size1;i++)
150  matrix[i]=&(vector[i*size2]); // Assign the rows pointers
151 
152  newEntry.variable = matrix;
153  newEntry.type = type;
154  newEntry.variableName = variableName;
155  newEntry.fileName = fileName;
156  newEntry.lineNumber = lineNumber;
157  newEntry.argumentList.push_back(size1);
158  newEntry.argumentList.push_back(size2);
159  RegisterMemory(static_cast<void*>(matrix), newEntry, size*sizeof(T));
160  }
161 }
162 
163 template <typename T>
164 void MemoryManager::release_two(T**& matrix, const char *fileName, size_t lineNumber)
165 {
166  if(matrix == NULL)
167  return;
168 
169  size_t size = AllocationTable[static_cast<void*>(matrix)].argumentList[0] * AllocationTable[static_cast<void*>(matrix)].argumentList[1];
170 
171  UnregisterMemory(static_cast<void*>(matrix), size*sizeof(T),fileName,lineNumber);
172 
173  delete[] matrix[0];
174  delete[] matrix;
175  matrix = NULL;
176 }
177 
178 template <typename T>
179 void MemoryManager::allocate(const char *type, T***& matrix,size_t size1,size_t size2,size_t size3, const char *variableName, const char *fileName, size_t lineNumber)
180 {
181  AllocationEntry newEntry;
182  size_t size = size1*size2*size3;
183  if(size<=0){
184  matrix = NULL;
185  return;
186  }else{
187  matrix = new T**[size1];
188  for(size_t i=0;i<size1;i++)
189  matrix[i]= new T*[size2];
190  T* vector = new T[size];
191  for(size_t i=0;i<size;i++)
192  vector[i]=static_cast<T>(0); // Zero all the elements
193  for(size_t i=0;i<size1;i++)
194  for(size_t j=0;j<size2;j++)
195  matrix[i][j]=&(vector[i*size2*size3+j*size3]); // Assign the rows pointers
196  newEntry.variable = matrix;
197  newEntry.type = type;
198  newEntry.variableName = variableName;
199  newEntry.fileName = fileName;
200  newEntry.lineNumber = lineNumber;
201  newEntry.argumentList.push_back(size1);
202  newEntry.argumentList.push_back(size2);
203  newEntry.argumentList.push_back(size3);
204  RegisterMemory(static_cast<void*>(matrix), newEntry, size*sizeof(T));
205  }
206 }
207 
208 template <typename T>
209 void MemoryManager::release_three(T***& matrix, const char *fileName, size_t lineNumber)
210 {
211  if(matrix == NULL)
212  return;
213 
214  size_t size1 = AllocationTable[static_cast<void*>(matrix)].argumentList[0];
215  size_t size = AllocationTable[static_cast<void*>(matrix)].argumentList[0] * AllocationTable[static_cast<void*>(matrix)].argumentList[1]
216  * AllocationTable[static_cast<void*>(matrix)].argumentList[2];
217 
218  UnregisterMemory(static_cast<void*>(matrix), size*sizeof(T),fileName,lineNumber);
219 
220  delete[] matrix[0][0];
221  for(size_t i=0;i<size1;i++)
222  delete[] matrix[i];
223  delete[] matrix;
224  matrix = NULL;
225 }
226 
227 #define allocate1(type, variable, size) \
228  memory_manager->allocate(#type, variable, size, #variable, __FILE__, __LINE__);
229 #define release1(variable) \
230  memory_manager->release_one(variable, __FILE__, __LINE__);
231 
232 #define allocate2(type, variable, size1, size2) \
233  memory_manager->allocate(#type, variable, size1, size2, #variable, __FILE__, __LINE__);
234 #define release2(variable) \
235  memory_manager->release_two(variable, __FILE__, __LINE__);
236 
237 #define allocate3(type, variable, size1, size2, size3) \
238  memory_manager->allocate(#type, variable, size1, size2, size3, #variable, __FILE__, __LINE__);
239 #define release3(variable) \
240  memory_manager->release_three(variable, __FILE__, __LINE__);
241 
242 } /* End Namespaces */
243 
244 #endif // _psi_src_bin_psimrccmemory_managerh_
void RegisterMemory(void *mem, AllocationEntry &entry, size_t size)
Definition: memory_manager.cc:59
size_t get_FreeMemory() const
Definition: memory_manager.h:71
size_t CurrentAllocated
Definition: memory_manager.h:93
void release_three(T ***&matrix, const char *fileName, size_t lineNumber)
Definition: memory_manager.h:209
std::map< void *, AllocationEntry > AllocationTable
Definition: memory_manager.h:96
size_t MaximumAllocated
Definition: memory_manager.h:94
Definition: pointgrp.h:105
std::string variableName
Definition: memory_manager.h:57
size_t lineNumber
Definition: memory_manager.h:59
MemoryManager(size_t maxcor=256000000)
Definition: memory_manager.cc:49
size_t get_CurrentAllocated() const
Definition: memory_manager.h:72
std::string type
Definition: memory_manager.h:56
void release_two(T **&matrix, const char *fileName, size_t lineNumber)
Definition: memory_manager.h:164
void * variable
Definition: memory_manager.h:55
Definition: memory_manager.h:63
size_t get_MaximumAllowedMemory() const
Definition: memory_manager.h:73
size_t MaximumAllowed
Definition: memory_manager.h:95
std::string fileName
Definition: memory_manager.h:58
double bytes_to_MiB(size_t n)
Definition: memory_manager.cc:43
double type_to_MiB(size_t n)
Definition: memory_manager.h:42
std::vector< size_t > argumentList
Definition: memory_manager.h:60
void allocate(const char *type, T *&matrix, size_t size, const char *variableName, const char *fileName, size_t lineNumber)
Definition: memory_manager.h:100
void release_one(T *&matrix, const char *fileName, size_t lineNumber)
Definition: memory_manager.h:122
void MemCheck(std::string output)
Definition: memory_manager.cc:93
Definition: PsiFileImpl.h:39
void UnregisterMemory(void *mem, size_t size, const char *fileName, size_t lineNumber)
Definition: memory_manager.cc:76
Definition: memory_manager.h:54
~MemoryManager()
Definition: memory_manager.cc:55