/[escript]/branches/subworld2/escriptcore/src/Taipan.cpp
ViewVC logotype

Contents of /branches/subworld2/escriptcore/src/Taipan.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5504 - (show annotations)
Wed Mar 4 22:58:13 2015 UTC (4 years, 1 month ago) by jfenwick
File size: 8453 byte(s)
Again with a more up to date copy


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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.26