/[escript]/trunk/escript/src/Taipan.cpp
ViewVC logotype

Contents of /trunk/escript/src/Taipan.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3911 - (show annotations)
Thu Jun 14 01:01:03 2012 UTC (7 years, 5 months ago) by jfenwick
File size: 8262 byte(s)
Copyright changes
1
2 /*******************************************************
3 *
4 * Copyright (c) 2003-2012 by University of Queensland
5 * Earth Systems Science Computational Center (ESSCC)
6 * http://www.uq.edu.au/esscc
7 *
8 * Primary Business: Queensland, Australia
9 * Licensed under the Open Software License version 3.0
10 * http://www.opensource.org/licenses/osl-3.0.php
11 *
12 *******************************************************/
13
14
15 #include "Taipan.h"
16
17 #include <iostream>
18 #include <cassert>
19
20 #ifdef _OPENMP
21 #include <omp.h>
22 #endif
23
24 using namespace std;
25
26 namespace escript {
27
28 Taipan::Taipan() :
29 memTable_Root(0),
30 totalElements(0)
31 {
32 // create and initialise a new StatTable
33 statTable = new Taipan_StatTable;
34 clear_stats();
35 }
36
37 Taipan::~Taipan() {
38
39 long len=0;
40 Taipan_MemTable *tab;
41 Taipan_MemTable *tab_next;
42
43 // dump memory usage statistics
44 dump_stats();
45
46 // deallocate StatTable object
47 delete statTable;
48
49 // deallocate all managed arrays and the memTable
50 tab = memTable_Root;
51 while (tab != 0) {
52 tab_next = tab->next;
53 len = tab->dim * tab->N;
54 totalElements -= len;
55 delete[] tab->array;
56 delete tab;
57 tab = tab_next;
58 }
59
60 assert(totalElements == 0);
61
62 // clear the MemTable root node
63 memTable_Root = 0;
64
65 // reset totalElements counter
66 totalElements = -1;
67 }
68
69 void
70 Taipan::release_unused_arrays()
71 {
72 long len=0;
73 Taipan_MemTable *tab;
74 Taipan_MemTable *tab_next, *tab_prev=0;
75 tab = memTable_Root;
76 while (tab != 0) {
77 tab_next = tab->next;
78 if (tab->free) {
79 delete[] tab->array;
80 len += tab->dim * tab->N;
81 if (tab_prev != 0) {
82 tab_prev->next = tab->next;
83 } else {
84 memTable_Root = tab->next;
85 }
86 delete tab;
87 // increment count of arrays dealloced
88 statTable->deallocations++;
89 } else {
90 tab_prev = tab;
91 }
92 tab = tab_next;
93 }
94 totalElements -= len;
95 statTable->deallocated_elements += len;
96 cout << static_cast<double>(len*sizeof(double))/1048576 << " Mbytes unused memory has been released." << endl;
97 }
98
99
100 double*
101 Taipan::new_array(size_type dim, size_type N) {
102
103 assert(totalElements >= 0);
104
105 size_type len = 0;
106 #ifdef _OPENMP
107 int numThreads = omp_get_num_threads();
108 #else
109 int numThreads = 1;
110 #endif
111
112 Taipan_MemTable *tab;
113 Taipan_MemTable *new_tab;
114 Taipan_MemTable *tab_prev=0;
115
116 // increment count of alloc operations called
117 statTable->requests++;
118
119 // is a suitable array already available?
120 if (memTable_Root != 0) {
121 tab = memTable_Root;
122 while (tab != 0) {
123 if (tab->dim == dim &&
124 tab->N == N &&
125 tab->free &&
126 tab->numThreads == numThreads) {
127 tab->free = false;
128 return tab->array;
129 }
130 tab_prev = tab;
131 tab = tab->next;
132 }
133 }
134
135 // otherwise a new array must be allocated
136
137 // create the corresponding memTable entry
138 len = dim * N;
139 new_tab = new Taipan_MemTable;
140 new_tab->dim = dim;
141 new_tab->N = N;
142 new_tab->numThreads = numThreads;
143 new_tab->free = false;
144 new_tab->next = 0;
145 if (memTable_Root == 0) {
146 memTable_Root = new_tab;
147 } else {
148 tab_prev->next = new_tab;
149 }
150
151 try
152 {
153 // allocate and initialise the new array
154 new_tab->array = new double[len];
155 }
156 catch (...)
157 {
158 cerr << "Memory manager failed to create array of size " << len << " doubles" << endl;
159 throw;
160 }
161 size_type i,j;
162 if (N==1) {
163 for (j=0; j<dim; j++)
164 new_tab->array[j]=0.0;
165 } else if (N>1) {
166 #pragma omp parallel for private(i,j) schedule(static)
167 for (i=0; i<N; i++) {
168 for (j=0; j<dim; j++)
169 new_tab->array[j+dim*i]=0.0;
170 }
171 }
172
173 totalElements += len;
174
175 // update maximum table size
176 statTable->max_tab_size = (statTable->max_tab_size < totalElements) ? totalElements : statTable->max_tab_size;
177
178 // increment count of arrays allocated
179 statTable->allocations++;
180
181 // increment count of elements allocated
182 statTable->allocated_elements += len;
183
184 return new_tab->array;
185 }
186
187 void
188 Taipan::delete_array(double* array) {
189
190 assert(totalElements >= 0);
191
192 size_type N;
193 size_type len = 0;
194 bool found = false;
195
196 Taipan_MemTable *tab;
197 Taipan_MemTable *tab_next;
198 Taipan_MemTable *tab_prev = 0;
199
200 // increment count of free operations called
201 statTable->frees++;
202
203 if (array == 0) {
204 // have been given an empty array, so quit now
205 return;
206 }
207
208 if (memTable_Root != 0) {
209
210 // find the table entry for this array and mark it as free
211 tab = memTable_Root;
212 while (tab != 0) {
213 if (tab->array == array) {
214 N = tab->N;
215 tab->free = true;
216 found = true;
217 break;
218 }
219 tab = tab->next;
220 }
221 if (!found) {
222 // this wasn't an array under management, so quit now
223 return;
224 }
225
226 if (N<=1) {
227 // we never deallocate arrays with N<=1, so quit now
228 return;
229 }
230
231 // are there any N block arrays still in use?
232 tab = memTable_Root;
233 while (tab != 0) {
234 if (tab->N==N && !tab->free)
235 return;
236 tab = tab->next;
237 }
238
239 // if not, all N block arrays are deallocated
240 tab = memTable_Root;
241 while (tab != 0) {
242 tab_next = tab->next;
243 if (tab->N == N) {
244 delete[] tab->array;
245 len += tab->dim * N;
246 if (tab_prev != 0) {
247 tab_prev->next = tab->next;
248 } else {
249 memTable_Root = tab->next;
250 }
251 delete tab;
252 // increment count of arrays dealloced
253 statTable->deallocations++;
254 } else {
255 tab_prev = tab;
256 }
257 tab = tab_next;
258 }
259
260 totalElements -= len;
261
262 // increment count of elements deallocated
263 statTable->deallocated_elements += len;
264
265 } else {
266 // what to do if no arrays under management?
267 }
268 }
269
270 int
271 Taipan::num_arrays() {
272
273 assert(totalElements >= 0);
274
275 int num_arrays = 0;
276
277 Taipan_MemTable *tab;
278
279 // count all managed arrays in the memTable
280 tab = memTable_Root;
281 while (tab != 0) {
282 num_arrays++;
283 tab = tab->next;
284 }
285
286 return num_arrays;
287 }
288
289 int
290 Taipan::num_arrays(size_type N) {
291
292 assert(totalElements >= 0);
293
294 int num_arrays = 0;
295
296 Taipan_MemTable *tab;
297
298 // count all managed arrays of N blocks in the memTable
299 tab = memTable_Root;
300 while (tab != 0) {
301 if (tab->N == N) {
302 num_arrays++;
303 }
304 tab = tab->next;
305 }
306
307 return num_arrays;
308 }
309
310 int
311 Taipan::num_free(size_type N) {
312
313 assert(totalElements >= 0);
314
315 int num_free = 0;
316
317 Taipan_MemTable *tab;
318
319 // count all free managed arrays of N blocks in the memTable
320 tab = memTable_Root;
321 while (tab != 0) {
322 if (tab->N == N) {
323 if (tab->free) {
324 num_free++;
325 }
326 }
327 tab = tab->next;
328 }
329 return num_free;
330 }
331
332 long
333 Taipan::num_elements() {
334
335 assert(totalElements >= 0);
336
337 return totalElements;
338 }
339
340 void
341 Taipan::dump_stats() {
342
343 assert(totalElements >= 0);
344 #ifdef TAIPAN_STATS
345 double elMb=statTable->allocated_elements*8.0/1048576;
346 double deelMb=statTable->deallocated_elements*8.0/1048576;
347 double tszMb=statTable->max_tab_size*8.0/1048576;
348
349 cout << "======= escript Mem Stats ===========================" << endl;
350 cout << "Total Num requests: " << statTable->requests << endl;
351 cout << "Total Num releases: " << statTable->frees << endl;
352 cout << "Total Num allocated arrays: " << statTable->allocations << endl;
353 cout << "Total Num deallocated arrays: " << statTable->deallocations << endl;
354 cout << "Total Num allocated elements: " << statTable->allocated_elements << " (" << elMb << " Mb)" << endl;
355 cout << "Total Num deallocated elements: " << statTable->deallocated_elements << " (" << deelMb << " Mb)" << endl;
356 cout << "Maximum memory buffer size: " << statTable->max_tab_size << " (" << tszMb << " Mb)" << endl;
357 cout << "Curr Num arrays: " << num_arrays() << endl;
358 cout << "Curr Num elements in buffer: " << num_elements() << endl;
359 cout << "==================================================" << endl;
360 #endif
361 }
362
363 void
364 Taipan::clear_stats() {
365
366 assert(totalElements >= 0);
367
368 statTable->requests=0;
369 statTable->frees=0;
370 statTable->allocations=0;
371 statTable->deallocations=0;
372 statTable->allocated_elements=0;
373 statTable->deallocated_elements=0;
374 statTable->max_tab_size=0;
375 }
376
377 } // end of namespace

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.26