1 /*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File: tape_handling.cpp
4 Revision: $Id: tape_handling.cpp 764 2019-01-30 14:44:40Z mbanovic $
5 Contents: management of tape infos
6
7 Copyright (c) Andreas Kowarz, Andrea Walther, Kshitij Kulshreshtha,
8 Benjamin Letschert, Jean Utke
9
10 This file is part of ADOL-C. This software is provided as open source.
11 Any use, reproduction, or distribution of the software constitutes
12 recipient's acceptance of the terms of the accompanying license file.
13
14 ---------------------------------------------------------------------------*/
15 #include "taping_p.h"
16 #include "checkpointing_p.h"
17 #include "dvlparms.h"
18 #include <adolc/revolve.h>
19 #include <adolc/adalloc.h>
20
21 #ifdef ADOLC_MEDIPACK_SUPPORT
22 #include "medipacksupport_p.h"
23 #endif
24
25 #include <cassert>
26 #include <limits>
27 #include <iostream>
28 #include <string.h>
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #include <vector>
33 #include <stack>
34 #include <errno.h>
35
36 using namespace std;
37
38 #ifdef SPARSE
39 BEGIN_C_DECLS
40 extern void freeSparseJacInfos(double *y, double **B, unsigned int **JP, void *g,
41 void *jr1d, int seed_rows, int seed_clms, int depen);
42 extern void freeSparseHessInfos(double **Hcomp, double ***Xppp, double ***Yppp, double ***Zppp,
43 double **Upp, unsigned int **HP,
44 void *g, void *hr, int p, int indep);
45 END_C_DECLS
46 #endif
47
GlobalTapeVarsCL()48 GlobalTapeVarsCL::GlobalTapeVarsCL() {
49 store = NULL;
50 #if defined(ADOLC_TRACK_ACTIVITY)
51 actStore = NULL;
52 #endif
53 storeSize = 0;
54 numLives = 0;
55 nominmaxFlag = 0;
56 pStore = NULL;
57 numparam = 0;
58 maxparam = 0;
59 initialStoreSize = 0;
60 #if defined(ADOLC_TRACK_ACTIVITY)
61 storeManagerPtr = new StoreManagerLocintBlock(store, actStore, storeSize, numLives);
62 #else
63 storeManagerPtr = new StoreManagerLocintBlock(store, storeSize, numLives);
64 #endif
65 paramStoreMgrPtr = new StoreManagerLocintBlock(pStore, maxparam, numparam);
66 }
67
~GlobalTapeVarsCL()68 GlobalTapeVarsCL::~GlobalTapeVarsCL() {
69 if (storeManagerPtr != NULL) {
70 delete storeManagerPtr;
71 storeManagerPtr = NULL;
72 }
73 if (paramStoreMgrPtr != NULL) {
74 delete paramStoreMgrPtr;
75 paramStoreMgrPtr = NULL;
76 }
77 }
78
operator =(const GlobalTapeVarsCL & gtv)79 const GlobalTapeVarsCL& GlobalTapeVarsCL::operator=(const GlobalTapeVarsCL& gtv) {
80 storeSize = gtv.storeSize;
81 numLives = gtv.numLives;
82 maxLoc = gtv.maxLoc;
83 operationBufferSize = gtv.operationBufferSize;
84 locationBufferSize = gtv.locationBufferSize;
85 valueBufferSize = gtv.valueBufferSize;
86 taylorBufferSize = gtv.taylorBufferSize;
87 maxNumberTaylorBuffers = gtv.maxNumberTaylorBuffers;
88 inParallelRegion = gtv.inParallelRegion;
89 newTape = gtv.newTape;
90 branchSwitchWarning = gtv.branchSwitchWarning;
91 currentTapeInfosPtr = gtv.currentTapeInfosPtr;
92 initialStoreSize = gtv.initialStoreSize;
93 store = new double[storeSize];
94 memcpy(store, gtv.store, storeSize*sizeof(double));
95 #if defined(ADOLC_TRACK_ACTIVITY)
96 actStore = new char[storeSize];
97 memcpy(actStore, gtv.actStore, storeSize*sizeof(char));
98 #endif
99 storeManagerPtr = new
100 StoreManagerLocintBlock(
101 dynamic_cast<StoreManagerLocintBlock*>(gtv.storeManagerPtr),
102 store,
103 #if defined(ADOLC_TRACK_ACTIVITY)
104 actStore,
105 #endif
106 storeSize, numLives);
107 paramStoreMgrPtr = new
108 StoreManagerLocintBlock(
109 dynamic_cast<StoreManagerLocintBlock*>(gtv.paramStoreMgrPtr),
110 pStore, maxparam, numparam);
111 return *this;
112 }
113
114 #if defined(ADOLC_TRACK_ACTIVITY)
115
116 char const* const StoreManagerLocint::nowhere = NULL;
117
StoreManagerLocint(double * & storePtr,char * & actStorePtr,size_t & size,size_t & numlives)118 StoreManagerLocint::StoreManagerLocint(double * &storePtr, char* &actStorePtr, size_t &size, size_t &numlives) :
119 storePtr(storePtr),
120 activityTracking(1),
121 actStorePtr(actStorePtr),
122 indexFree(0),
123 head(0),
124 maxsize(size), currentfill(numlives)
125 {
126 #ifdef ADOLC_DEBUG
127 std::cerr << "StoreManagerInteger::StoreManagerInteger()\n";
128 #endif
129 }
130
StoreManagerLocint(const StoreManagerLocint * const stm,double * & storePtr,char * & actStorePtr,size_t & size,size_t & numlives)131 StoreManagerLocint::StoreManagerLocint(const StoreManagerLocint *const stm,
132 double * &storePtr, char* &actStorePtr, size_t &size, size_t &numlives) :
133 storePtr(storePtr),
134 actStorePtr(actStorePtr),
135 activityTracking(1),
136 maxsize(size), currentfill(numlives)
137 {
138 #ifdef ADOLC_DEBUG
139 std::cerr << "StoreManagerInteger::StoreManagerInteger()\n";
140 #endif
141 head = stm->head;
142 indexFree = new locint[maxsize];
143 for (size_t i = 0; i < maxsize; i++)
144 indexFree[i] = stm->indexFree[i];
145 }
146 #endif
147
StoreManagerLocint(double * & storePtr,size_t & size,size_t & numlives)148 StoreManagerLocint::StoreManagerLocint(double * &storePtr, size_t &size, size_t &numlives) :
149 storePtr(storePtr),
150 #if defined(ADOLC_TRACK_ACTIVITY)
151 activityTracking(0),
152 actStorePtr(const_cast<char*&>(nowhere)),
153 #endif
154 indexFree(0),
155 head(0),
156 maxsize(size), currentfill(numlives)
157 {
158 #ifdef ADOLC_DEBUG
159 std::cerr << "StoreManagerInteger::StoreManagerInteger()\n";
160 #endif
161 }
162
~StoreManagerLocint()163 StoreManagerLocint::~StoreManagerLocint()
164 {
165 #ifdef ADOLC_DEBUG
166 std::cerr << "StoreManagerInteger::~StoreManagerInteger()\n";
167 #endif
168 if (storePtr) {
169 delete[] storePtr;
170 storePtr = 0;
171 }
172 if (indexFree) {
173 delete[] indexFree;
174 indexFree = 0;
175 }
176 #if defined(ADOLC_TRACK_ACTIVITY)
177 if (activityTracking && actStorePtr) {
178 delete[] actStorePtr;
179 }
180 #endif
181 maxsize = 0;
182 currentfill = 0;
183 head = 0;
184 }
185
StoreManagerLocint(const StoreManagerLocint * const stm,double * & storePtr,size_t & size,size_t & numlives)186 StoreManagerLocint::StoreManagerLocint(const StoreManagerLocint *const stm,
187 double * &storePtr, size_t &size, size_t &numlives) :
188 storePtr(storePtr),
189 #if defined(ADOLC_TRACK_ACTIVITY)
190 activityTracking(0),
191 actStorePtr(const_cast<char*&>(nowhere)),
192 #endif
193 maxsize(size), currentfill(numlives)
194 {
195 #ifdef ADOLC_DEBUG
196 std::cerr << "StoreManagerInteger::StoreManagerInteger()\n";
197 #endif
198 head = stm->head;
199 indexFree = new locint[maxsize];
200 for (size_t i = 0; i < maxsize; i++)
201 indexFree[i] = stm->indexFree[i];
202 }
203
next_loc()204 locint StoreManagerLocint::next_loc() {
205 if (head == 0) {
206 grow();
207 }
208 assert(head);
209 locint const result = head;
210 head = indexFree[head];
211 ++currentfill;
212 #ifdef ADOLC_DEBUG
213 std::cerr << "next_loc: " << result << " fill: " << size() << "max: " << maxSize() << endl;
214 #endif
215 return result;
216 }
217
free_loc(locint loc)218 void StoreManagerLocint::free_loc(locint loc) {
219 assert(0 < loc && loc < maxsize);
220 indexFree[loc] = head;
221 head = loc;
222 --currentfill;
223 #ifdef ADOLC_DEBUG
224 std::cerr << "free_loc: " << loc << " fill: " << size() << "max: " << maxSize() << endl;
225 #endif
226 }
227
ensure_block(size_t n)228 void StoreManagerLocint::ensure_block(size_t n) {
229 fprintf(DIAG_OUT,"ADOL-C error: Location block required from singleton location store");
230 adolc_exit(-4,"ADOL-C error: Location blocks not alowed",__func__,__FILE__,__LINE__);
231 }
232
grow(size_t mingrow)233 void StoreManagerLocint::grow(size_t mingrow) {
234 if (maxsize == 0) maxsize += initialSize;
235 size_t const oldMaxsize = maxsize;
236 maxsize *= 2;
237 if (maxsize < mingrow) maxsize = mingrow;
238
239 if (maxsize > std::numeric_limits<locint>::max()) {
240 // encapsulate this error message
241 fprintf(DIAG_OUT,"\nADOL-C error:\n");
242 fprintf(DIAG_OUT,"maximal number (%d) of live active variables exceeded\n\n",
243 std::numeric_limits<locint>::max());
244 adolc_exit(-3,"",__func__,__FILE__,__LINE__);
245 }
246
247 #ifdef ADOLC_DEBUG
248 std::cerr << "StoreManagerInteger::grow(): increase size from " << oldMaxsize
249 << " to " << maxsize << " entries (currently " << size() << " entries used)\n";
250 assert(oldMaxsize == initialSize or size() == oldMaxsize);
251 #endif
252
253 double *const oldStore = storePtr;
254 locint *const oldIndex = indexFree;
255 #if defined(ADOLC_TRACK_ACTIVITY)
256 char * oldactStore;
257 if (activityTracking) {
258 oldactStore = actStorePtr;
259 }
260 #endif
261
262 #if defined(ADOLC_DEBUG)
263 std::cerr << "StoreManagerInteger::grow(): allocate " << maxsize * sizeof(double) << " B doubles "
264 << "and " << maxsize * sizeof(locint) << " B locints\n";
265 #endif
266 storePtr = new double[maxsize];
267 indexFree = new locint[maxsize];
268 #if defined(ADOLC_TRACK_ACTIVITY)
269 if (activityTracking)
270 actStorePtr = new char[maxsize];
271 #endif
272 // we use index 0 as end-of-list marker
273 size_t i = 1;
274 storePtr[0] = std::numeric_limits<double>::quiet_NaN();
275
276 if (oldMaxsize != initialSize) { // not the first time
277 #if defined(ADOLC_DEBUG)
278 std::cerr << "StoreManagerInteger::grow(): copy values\n";
279 #endif
280 for (size_t j = i; j < oldMaxsize; ++j) {
281 indexFree[j] = oldIndex[j];
282 }
283 for (size_t j = i; j < oldMaxsize; ++j) {
284 storePtr[j] = oldStore[j];
285 }
286 #if defined(ADOLC_TRACK_ACTIVITY)
287 if (activityTracking) {
288 for (size_t j = i; j < oldMaxsize; ++j) {
289 actStorePtr[j] = oldactStore[j];
290 }
291 }
292 #endif
293 // reset i to start of new slots (upper half)
294 i = oldMaxsize;
295
296 #if defined(ADOLC_DEBUG)
297 std::cerr << "StoreManagerInteger::grow(): free " << oldMaxsize * sizeof(double)
298 << " + " << oldMaxsize * sizeof(locint) << " B\n";
299 #endif
300 delete [] oldStore;
301 delete [] oldIndex;
302 #if defined(ADOLC_TRACK_ACTIVITY)
303 if (activityTracking)
304 delete [] oldactStore;
305 #endif
306 }
307
308 head = i;
309 // create initial linked list for new slots
310 for ( ; i < maxsize-1; ++i) {
311 indexFree[i] = i + 1;
312 }
313 indexFree[i] = 0; // end marker
314 assert(i == maxsize-1);
315 }
316
317
318 /****************************************************************************/
319 /* Returns the next free location in "adouble" memory. */
320 /****************************************************************************/
next_loc()321 locint next_loc() {
322 ADOLC_OPENMP_THREAD_NUMBER;
323 ADOLC_OPENMP_GET_THREAD_NUMBER;
324 return ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr->next_loc();
325 }
326
327 /****************************************************************************/
328 /* frees the specified location in "adouble" memory */
329 /****************************************************************************/
free_loc(locint loc)330 void free_loc(locint loc) {
331 ADOLC_OPENMP_THREAD_NUMBER;
332 ADOLC_OPENMP_GET_THREAD_NUMBER;
333 ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr->free_loc(loc);
334 }
335
336 /* vector of tape infos for all tapes in use */
337 vector<TapeInfos *> ADOLC_TAPE_INFOS_BUFFER_DECL;
338
339 /* stack of pointers to tape infos
340 * represents the order of tape usage when doing nested taping */
341 stack<TapeInfos *> ADOLC_TAPE_STACK_DECL;
342
343 /* the main tape info buffer and its fallback */
344 TapeInfos ADOLC_CURRENT_TAPE_INFOS_DECL;
345 TapeInfos ADOLC_CURRENT_TAPE_INFOS_FALLBACK_DECL;
346
347 /* global tapeing variables */
348 GlobalTapeVars ADOLC_GLOBAL_TAPE_VARS_DECL;
349
350 #if defined(_OPENMP)
351 static vector<TapeInfos *> *tapeInfosBuffer_s;
352 static stack<TapeInfos *> *tapeStack_s;
353 static TapeInfos *currentTapeInfos_s;
354 static TapeInfos *currentTapeInfos_fallBack_s;
355 static GlobalTapeVars *globalTapeVars_s;
356 static ADOLC_BUFFER_TYPE *ADOLC_extDiffFctsBuffer_s;
357 static stack<StackElement> *ADOLC_checkpointsStack_s;
358 static revolve_nums *revolve_numbers_s;
359
360 static vector<TapeInfos *> *tapeInfosBuffer_p;
361 static stack<TapeInfos *> *tapeStack_p;
362 static TapeInfos *currentTapeInfos_p;
363 static TapeInfos *currentTapeInfos_fallBack_p;
364 static GlobalTapeVars *globalTapeVars_p;
365 static ADOLC_BUFFER_TYPE *ADOLC_extDiffFctsBuffer_p;
366 static stack<StackElement> *ADOLC_checkpointsStack_p;
367 static revolve_nums *revolve_numbers_p;
368 #endif
369
370 /*--------------------------------------------------------------------------*/
371 /* This function sets the flag "newTape" if either a taylor buffer has been */
372 /* created or a taping process has been performed. Calling the function is */
373 /* also useful to "convince" the linker of including the cleaner part into */
374 /* the binary when linking statically! */
375 /*--------------------------------------------------------------------------*/
markNewTape()376 void markNewTape() {
377 ADOLC_OPENMP_THREAD_NUMBER;
378 ADOLC_OPENMP_GET_THREAD_NUMBER;
379 ADOLC_GLOBAL_TAPE_VARS.newTape = 1;
380 }
381
382 /* inits the struct for the new tape */
initTapeInfos(TapeInfos * newTapeInfos)383 void initTapeInfos(TapeInfos *newTapeInfos) {
384 char *ptr, *end;
385
386 ptr = (char *)(&newTapeInfos->tapeID);
387 end = (char *)(&newTapeInfos->pTapeInfos);
388 for ( ; ptr != end ; ptr++ )
389 *ptr = 0;
390 }
391
392 /* as above but keep allocated buffers if possible */
initTapeInfos_keep(TapeInfos * newTapeInfos)393 void initTapeInfos_keep(TapeInfos *newTapeInfos) {
394 unsigned char *opBuffer = newTapeInfos->opBuffer;
395 locint *locBuffer = newTapeInfos->locBuffer;
396 double *valBuffer = newTapeInfos->valBuffer;
397 revreal *tayBuffer = newTapeInfos->tayBuffer;
398 double *signature = newTapeInfos->signature;
399 FILE *tay_file = newTapeInfos->tay_file;
400
401 initTapeInfos(newTapeInfos);
402
403 newTapeInfos->opBuffer = opBuffer;
404 newTapeInfos->locBuffer = locBuffer;
405 newTapeInfos->valBuffer = valBuffer;
406 newTapeInfos->tayBuffer = tayBuffer;
407 newTapeInfos->signature = signature;
408 newTapeInfos->tay_file = tay_file;
409 }
410
411 /* inits a new tape and updates the tape stack (called from start_trace)
412 * - returns 0 without error
413 * - returns 1 if tapeID was already/still in use */
initNewTape(short tapeID)414 int initNewTape(short tapeID) {
415 TapeInfos *newTapeInfos = NULL;
416 bool newTI = false;
417 int retval = 0;
418
419 ADOLC_OPENMP_THREAD_NUMBER;
420 ADOLC_OPENMP_GET_THREAD_NUMBER;
421
422 /* check if tape is in use */
423 vector<TapeInfos *>::iterator tiIter;
424 if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
425 for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
426 tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
427 ++tiIter) {
428 if ((*tiIter)->tapeID==tapeID) {
429 newTapeInfos=*tiIter;
430 if ((*tiIter)->inUse != 0) {
431 if ((*tiIter)->tapingComplete == 0)
432 fail(ADOLC_TAPING_TAPE_STILL_IN_USE);
433 if ( (*tiIter)->stats[OP_FILE_ACCESS] == 0 &&
434 (*tiIter)->stats[LOC_FILE_ACCESS] == 0 &&
435 (*tiIter)->stats[VAL_FILE_ACCESS] == 0 ) {
436 # if defined(ADOLC_DEBUG)
437 fprintf(DIAG_OUT, "\nADOL-C warning: Tape %d existed in main memory"
438 " only and gets overwritten!\n\n", tapeID);
439 # endif
440 /* free associated resources */
441 retval = 1;
442 }
443 }
444 if ((*tiIter)->tay_file != NULL)
445 rewind((*tiIter)->tay_file);
446 initTapeInfos_keep(*tiIter);
447 (*tiIter)->tapeID = tapeID;
448 #ifdef SPARSE
449 freeSparseJacInfos(newTapeInfos->pTapeInfos.sJinfos.y,
450 newTapeInfos->pTapeInfos.sJinfos.B,
451 newTapeInfos->pTapeInfos.sJinfos.JP,
452 newTapeInfos->pTapeInfos.sJinfos.g,
453 newTapeInfos->pTapeInfos.sJinfos.jr1d,
454 newTapeInfos->pTapeInfos.sJinfos.seed_rows,
455 newTapeInfos->pTapeInfos.sJinfos.seed_clms,
456 newTapeInfos->pTapeInfos.sJinfos.depen);
457 freeSparseHessInfos(newTapeInfos->pTapeInfos.sHinfos.Hcomp,
458 newTapeInfos->pTapeInfos.sHinfos.Xppp,
459 newTapeInfos->pTapeInfos.sHinfos.Yppp,
460 newTapeInfos->pTapeInfos.sHinfos.Zppp,
461 newTapeInfos->pTapeInfos.sHinfos.Upp,
462 newTapeInfos->pTapeInfos.sHinfos.HP,
463 newTapeInfos->pTapeInfos.sHinfos.g,
464 newTapeInfos->pTapeInfos.sHinfos.hr,
465 newTapeInfos->pTapeInfos.sHinfos.p,
466 newTapeInfos->pTapeInfos.sHinfos.indep);
467 newTapeInfos->pTapeInfos.sJinfos.B=NULL;
468 newTapeInfos->pTapeInfos.sJinfos.y=NULL;
469 newTapeInfos->pTapeInfos.sJinfos.g=NULL;
470 newTapeInfos->pTapeInfos.sJinfos.jr1d=NULL;
471 newTapeInfos->pTapeInfos.sJinfos.Seed=NULL;
472 newTapeInfos->pTapeInfos.sJinfos.JP=NULL;
473 newTapeInfos->pTapeInfos.sJinfos.depen=0;
474 newTapeInfos->pTapeInfos.sJinfos.nnz_in=0;
475 newTapeInfos->pTapeInfos.sJinfos.seed_rows=0;
476 newTapeInfos->pTapeInfos.sJinfos.seed_clms=0;
477 newTapeInfos->pTapeInfos.sHinfos.Zppp=NULL;
478 newTapeInfos->pTapeInfos.sHinfos.Yppp=NULL;
479 newTapeInfos->pTapeInfos.sHinfos.Xppp=NULL;
480 newTapeInfos->pTapeInfos.sHinfos.Upp=NULL;
481 newTapeInfos->pTapeInfos.sHinfos.Hcomp=NULL;
482 newTapeInfos->pTapeInfos.sHinfos.HP=NULL;
483 newTapeInfos->pTapeInfos.sHinfos.g=NULL;
484 newTapeInfos->pTapeInfos.sHinfos.hr=NULL;
485 newTapeInfos->pTapeInfos.sHinfos.nnz_in=0;
486 newTapeInfos->pTapeInfos.sHinfos.indep=0;
487 newTapeInfos->pTapeInfos.sHinfos.p=0;
488 #endif
489 break;
490 }
491 }
492 }
493
494 /* create new info struct and initialize it */
495 if (newTapeInfos == NULL) {
496 newTapeInfos = new TapeInfos(tapeID);
497 newTI = true;
498 }
499 newTapeInfos->traceFlag=1;
500 newTapeInfos->inUse=1;
501
502 newTapeInfos->stats[OP_BUFFER_SIZE] =
503 ADOLC_GLOBAL_TAPE_VARS.operationBufferSize;
504 newTapeInfos->stats[LOC_BUFFER_SIZE] =
505 ADOLC_GLOBAL_TAPE_VARS.locationBufferSize;
506 newTapeInfos->stats[VAL_BUFFER_SIZE] =
507 ADOLC_GLOBAL_TAPE_VARS.valueBufferSize;
508 newTapeInfos->stats[TAY_BUFFER_SIZE] =
509 ADOLC_GLOBAL_TAPE_VARS.taylorBufferSize;
510
511 /* update tapeStack and save tapeInfos */
512 if (ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr != NULL) {
513 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr->copy(
514 ADOLC_CURRENT_TAPE_INFOS);
515 ADOLC_TAPE_STACK.push(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
516 } else {
517 ADOLC_CURRENT_TAPE_INFOS_FALLBACK.copy(
518 ADOLC_CURRENT_TAPE_INFOS);
519 ADOLC_TAPE_STACK.push(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK);
520 }
521 if (newTI) ADOLC_TAPE_INFOS_BUFFER.push_back(newTapeInfos);
522
523 newTapeInfos->pTapeInfos.skipFileCleanup=0;
524
525 /* set the new tape infos as current */
526 ADOLC_CURRENT_TAPE_INFOS.copy(*newTapeInfos);
527 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = newTapeInfos;
528
529 return retval;
530 }
531
532 /* opens an existing tape or creates a new handle for a tape on hard disk
533 * - called from init_for_sweep and init_rev_sweep */
openTape(short tapeID,char mode)534 void openTape(short tapeID, char mode) {
535 TapeInfos *tempTapeInfos=NULL;
536
537 ADOLC_OPENMP_THREAD_NUMBER;
538 ADOLC_OPENMP_GET_THREAD_NUMBER;
539
540 /* check if tape information exist in memory */
541 vector<TapeInfos *>::iterator tiIter;
542 if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
543 for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
544 tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
545 ++tiIter) {
546 if ((*tiIter)->tapeID == tapeID) {
547 /* tape has been used before (in the current program) */
548 if ((*tiIter)->inUse == 0) {
549 /* forward sweep */
550 if ((*tiIter)->tay_file != NULL)
551 rewind((*tiIter)->tay_file);
552 initTapeInfos_keep(*tiIter);
553 (*tiIter)->traceFlag=1;
554 (*tiIter)->tapeID = tapeID;
555 (*tiIter)->tapingComplete = 1;
556 (*tiIter)->inUse = 1;
557 read_tape_stats(*tiIter);
558 }
559 if (ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr != NULL) {
560 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr->copy(
561 ADOLC_CURRENT_TAPE_INFOS);
562 ADOLC_TAPE_STACK.push(
563 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
564 } else {
565 ADOLC_CURRENT_TAPE_INFOS_FALLBACK.copy(
566 ADOLC_CURRENT_TAPE_INFOS);
567 ADOLC_TAPE_STACK.push(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK);
568 }
569 ADOLC_CURRENT_TAPE_INFOS.copy(**tiIter);
570 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = *tiIter;
571 return;
572 }
573 }
574 }
575
576 /* tapeID not used so far */
577 if (mode == ADOLC_REVERSE) {
578 failAdditionalInfo1 = tapeID;
579 fail(ADOLC_REVERSE_NO_TAYLOR_STACK);
580 }
581
582 /* create new info struct and initialize it */
583 tempTapeInfos = new TapeInfos(tapeID);
584 tempTapeInfos->traceFlag=1;
585 tempTapeInfos->inUse = 1;
586 tempTapeInfos->tapingComplete = 1;
587 ADOLC_TAPE_INFOS_BUFFER.push_back(tempTapeInfos);
588
589 read_tape_stats(tempTapeInfos);
590 /* update tapeStack and save tapeInfos */
591 if (ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr != NULL) {
592 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr->copy(
593 ADOLC_CURRENT_TAPE_INFOS);
594 ADOLC_TAPE_STACK.push(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
595 } else {
596 ADOLC_CURRENT_TAPE_INFOS_FALLBACK.copy(
597 ADOLC_CURRENT_TAPE_INFOS);
598 ADOLC_TAPE_STACK.push(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK);
599 }
600
601 /* set the new tape infos as current */
602 ADOLC_CURRENT_TAPE_INFOS.copy(*tempTapeInfos);
603 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = tempTapeInfos;
604 }
605
606 /* release the current tape and give control to the previous one */
releaseTape()607 void releaseTape() {
608 ADOLC_OPENMP_THREAD_NUMBER;
609 ADOLC_OPENMP_GET_THREAD_NUMBER;
610
611 /* if operations, locations and constants tapes have been written and value
612 * stack information have not been created tapeInfos are no longer needed*/
613 if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors == 0 &&
614 ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS] == 1 &&
615 ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] == 1 &&
616 ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] == 1 ) {
617 ADOLC_CURRENT_TAPE_INFOS.inUse = 0;
618 }
619
620 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr->copy(
621 ADOLC_CURRENT_TAPE_INFOS);
622 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = ADOLC_TAPE_STACK.top();
623 ADOLC_CURRENT_TAPE_INFOS.copy(
624 *ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
625 ADOLC_TAPE_STACK.pop();
626 if (ADOLC_TAPE_STACK.empty())
627 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = NULL;
628 }
629
630 /* updates the tape infos for the given ID - a tapeInfos struct is created
631 * and registered if non is found but its state will remain "not in use" */
getTapeInfos(short tapeID)632 TapeInfos *getTapeInfos(short tapeID) {
633 TapeInfos *tapeInfos;
634 vector<TapeInfos *>::iterator tiIter;
635
636 ADOLC_OPENMP_THREAD_NUMBER;
637 ADOLC_OPENMP_GET_THREAD_NUMBER;
638
639 /* check if TapeInfos for tapeID exist */
640 if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
641 for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
642 tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
643 ++tiIter) {
644 if ((*tiIter)->tapeID==tapeID) {
645 tapeInfos=*tiIter;
646 if (tapeInfos->inUse==0) read_tape_stats(tapeInfos);
647 return tapeInfos;
648 }
649 }
650 }
651 /* create new TapeInfos, initialize and update tapeInfosBuffer */
652 tapeInfos = new TapeInfos(tapeID);
653 ADOLC_TAPE_INFOS_BUFFER.push_back(tapeInfos);
654 tapeInfos->traceFlag=1;
655 tapeInfos->inUse=0;
656 tapeInfos->tapingComplete = 1;
657 read_tape_stats(tapeInfos);
658 return tapeInfos;
659 }
660
661 /****************************************************************************/
662 /* Set a trace to nested_ctx */
663 /****************************************************************************/
set_nested_ctx(short tag,char nested)664 void set_nested_ctx(short tag, char nested) {
665 TapeInfos* tiInfos = getTapeInfos(tag);
666 tiInfos->in_nested_ctx = nested;
667 }
668 /****************************************************************************/
669 /* Check whether a tape has been set to nested_ctx */
670 /****************************************************************************/
currently_nested(short tag)671 char currently_nested(short tag) {
672 TapeInfos* tiInfos = getTapeInfos(tag);
673 return tiInfos->in_nested_ctx;
674 }
675
676
cachedTraceTags(std::vector<short> & result)677 void cachedTraceTags(std::vector<short>& result) {
678 vector<TapeInfos *>::const_iterator tiIter;
679 vector<short>::iterator tIdIter;
680 ADOLC_OPENMP_THREAD_NUMBER;
681 ADOLC_OPENMP_GET_THREAD_NUMBER;
682
683 result.resize(ADOLC_TAPE_INFOS_BUFFER.size());
684 if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
685 for(tiIter=ADOLC_TAPE_INFOS_BUFFER.begin(), tIdIter=result.begin();
686 tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
687 ++tiIter, ++tIdIter) {
688 *tIdIter = (*tiIter)->tapeID;
689 }
690 }
691 }
692
693 #ifdef SPARSE
694 /* updates the tape infos on sparse Jac for the given ID */
setTapeInfoJacSparse(short tapeID,SparseJacInfos sJinfos)695 void setTapeInfoJacSparse(short tapeID, SparseJacInfos sJinfos) {
696 TapeInfos *tapeInfos;
697 vector<TapeInfos *>::iterator tiIter;
698
699 ADOLC_OPENMP_THREAD_NUMBER;
700 ADOLC_OPENMP_GET_THREAD_NUMBER;
701
702 /* check if TapeInfos for tapeID exist */
703 if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
704 for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
705 tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
706 ++tiIter) {
707 if ((*tiIter)->tapeID==tapeID) {
708 tapeInfos=*tiIter;
709 // free memory of tape entry that had been used previously
710 freeSparseJacInfos(tapeInfos->pTapeInfos.sJinfos.y,
711 tapeInfos->pTapeInfos.sJinfos.B,
712 tapeInfos->pTapeInfos.sJinfos.JP,
713 tapeInfos->pTapeInfos.sJinfos.g,
714 tapeInfos->pTapeInfos.sJinfos.jr1d,
715 tapeInfos->pTapeInfos.sJinfos.seed_rows,
716 tapeInfos->pTapeInfos.sJinfos.seed_clms,
717 tapeInfos->pTapeInfos.sJinfos.depen);
718 tapeInfos->pTapeInfos.sJinfos.y=sJinfos.y;
719 tapeInfos->pTapeInfos.sJinfos.Seed=sJinfos.Seed;
720 tapeInfos->pTapeInfos.sJinfos.B=sJinfos.B;
721 tapeInfos->pTapeInfos.sJinfos.JP=sJinfos.JP;
722 tapeInfos->pTapeInfos.sJinfos.depen=sJinfos.depen;
723 tapeInfos->pTapeInfos.sJinfos.nnz_in=sJinfos.nnz_in;
724 tapeInfos->pTapeInfos.sJinfos.seed_clms=sJinfos.seed_clms;
725 tapeInfos->pTapeInfos.sJinfos.seed_rows=sJinfos.seed_rows;
726 tapeInfos->pTapeInfos.sJinfos.g=sJinfos.g;
727 tapeInfos->pTapeInfos.sJinfos.jr1d=sJinfos.jr1d;
728 }
729 }
730 }
731 }
732 #endif
733
734 #ifdef SPARSE
735 /* updates the tape infos on sparse Hess for the given ID */
setTapeInfoHessSparse(short tapeID,SparseHessInfos sHinfos)736 void setTapeInfoHessSparse(short tapeID, SparseHessInfos sHinfos) {
737 TapeInfos *tapeInfos;
738 vector<TapeInfos *>::iterator tiIter;
739
740 ADOLC_OPENMP_THREAD_NUMBER;
741 ADOLC_OPENMP_GET_THREAD_NUMBER;
742
743 /* check if TapeInfos for tapeID exist */
744 if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
745 for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
746 tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
747 ++tiIter) {
748 if ((*tiIter)->tapeID==tapeID) {
749 tapeInfos=*tiIter;
750 // free memory of tape entry that had been used previously
751 freeSparseHessInfos(tapeInfos->pTapeInfos.sHinfos.Hcomp,
752 tapeInfos->pTapeInfos.sHinfos.Xppp,
753 tapeInfos->pTapeInfos.sHinfos.Yppp,
754 tapeInfos->pTapeInfos.sHinfos.Zppp,
755 tapeInfos->pTapeInfos.sHinfos.Upp,
756 tapeInfos->pTapeInfos.sHinfos.HP,
757 tapeInfos->pTapeInfos.sHinfos.g,
758 tapeInfos->pTapeInfos.sHinfos.hr,
759 tapeInfos->pTapeInfos.sHinfos.p,
760 tapeInfos->pTapeInfos.sHinfos.indep);
761 tapeInfos->pTapeInfos.sHinfos.Hcomp=sHinfos.Hcomp;
762 tapeInfos->pTapeInfos.sHinfos.Xppp=sHinfos.Xppp;
763 tapeInfos->pTapeInfos.sHinfos.Yppp=sHinfos.Yppp;
764 tapeInfos->pTapeInfos.sHinfos.Zppp=sHinfos.Zppp;
765 tapeInfos->pTapeInfos.sHinfos.Upp=sHinfos.Upp;
766 tapeInfos->pTapeInfos.sHinfos.HP=sHinfos.HP;
767 tapeInfos->pTapeInfos.sHinfos.indep=sHinfos.indep;
768 tapeInfos->pTapeInfos.sHinfos.nnz_in=sHinfos.nnz_in;
769 tapeInfos->pTapeInfos.sHinfos.p=sHinfos.p;
770 tapeInfos->pTapeInfos.sHinfos.g=sHinfos.g;
771 tapeInfos->pTapeInfos.sHinfos.hr=sHinfos.hr;
772 }
773 }
774 }
775 }
776 #endif
777
init_lib()778 static void init_lib() {
779 ADOLC_OPENMP_THREAD_NUMBER;
780 errno = 0;
781 ADOLC_OPENMP_GET_THREAD_NUMBER;
782
783 #if defined(_OPENMP)
784 tapeInfosBuffer = new vector<TapeInfos *>;
785 tapeStack = new stack<TapeInfos *>;
786 currentTapeInfos = new TapeInfos;
787 currentTapeInfos->tapingComplete = 1;
788 currentTapeInfos_fallBack = new TapeInfos;
789 globalTapeVars = new GlobalTapeVars;
790 ADOLC_extDiffFctsBuffer = new ADOLC_BUFFER_TYPE;
791 ADOLC_checkpointsStack = new stack<StackElement>;
792 revolve_numbers = new revolve_nums;
793 #endif /* _OPENMP */
794
795 ADOLC_CURRENT_TAPE_INFOS.traceFlag = 0;
796 ADOLC_CURRENT_TAPE_INFOS.keepTaylors = 0;
797
798 ADOLC_GLOBAL_TAPE_VARS.maxLoc=1;
799 for (uint i=0; i<sizeof(locint)*8-1; ++i) {
800 ADOLC_GLOBAL_TAPE_VARS.maxLoc<<=1;
801 ++ADOLC_GLOBAL_TAPE_VARS.maxLoc;
802 }
803 ADOLC_GLOBAL_TAPE_VARS.inParallelRegion = 0;
804 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = NULL;
805 ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = 1;
806
807 adolc_id.adolc_ver = ADOLC_VERSION;
808 adolc_id.adolc_sub = ADOLC_SUBVERSION;
809 adolc_id.adolc_lvl = ADOLC_PATCHLEVEL;
810 adolc_id.locint_size = sizeof(locint);
811 adolc_id.revreal_size = sizeof(revreal);
812 adolc_id.address_size = sizeof(size_t);
813
814 ADOLC_EXT_DIFF_FCTS_BUFFER.init(init_CpInfos);
815 readConfigFile();
816 }
817
clearCurrentTape()818 static void clearCurrentTape() {
819 ADOLC_OPENMP_THREAD_NUMBER;
820 ADOLC_OPENMP_GET_THREAD_NUMBER;
821 TapeInfos* tmpTapeInfos = new TapeInfos;
822
823 ADOLC_CURRENT_TAPE_INFOS.copy(*tmpTapeInfos);
824 ADOLC_CURRENT_TAPE_INFOS_FALLBACK.copy(*tmpTapeInfos);
825 delete tmpTapeInfos;
826 }
827
828 /* does things like closing/removing temporary files, ... */
cleanUp()829 void cleanUp() {
830 ADOLC_OPENMP_THREAD_NUMBER;
831 ADOLC_OPENMP_GET_THREAD_NUMBER;
832
833 TapeInfos** tiIter;
834 clearCurrentTape();
835 while (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
836 tiIter = &ADOLC_TAPE_INFOS_BUFFER.back();
837 ADOLC_TAPE_INFOS_BUFFER.pop_back();
838 {
839 /* close open files though they may be incomplete */
840 if ((*tiIter)->op_file!=NULL)
841 {
842 fclose((*tiIter)->op_file);
843 (*tiIter)->op_file = NULL;
844 }
845 if ((*tiIter)->val_file!=NULL)
846 {
847 fclose((*tiIter)->val_file);
848 (*tiIter)->val_file = NULL;
849 }
850 if ((*tiIter)->loc_file!=NULL)
851 {
852 fclose((*tiIter)->loc_file);
853 (*tiIter)->loc_file = NULL;
854 }
855 if ((*tiIter)->tay_file!=NULL && (*tiIter)->pTapeInfos.skipFileCleanup==0 ) {
856 fclose((*tiIter)->tay_file);
857 (*tiIter)->tay_file = NULL;
858 remove((*tiIter)->pTapeInfos.tay_fileName);
859 }
860 if ((*tiIter)->opBuffer != NULL)
861 {
862 free((*tiIter)->opBuffer);
863 (*tiIter)->opBuffer = NULL;
864 }
865 if ((*tiIter)->valBuffer != NULL)
866 {
867 free((*tiIter)->valBuffer);
868 (*tiIter)->valBuffer = NULL;
869 }
870 if ((*tiIter)->locBuffer != NULL)
871 {
872 free((*tiIter)->locBuffer);
873 (*tiIter)->locBuffer = NULL;
874 }
875 if ((*tiIter)->signature != NULL)
876 {
877 free((*tiIter)->signature);
878 (*tiIter)->signature = NULL;
879 }
880 if ((*tiIter)->tayBuffer != NULL)
881 {
882 free((*tiIter)->tayBuffer);
883 (*tiIter)->tayBuffer = NULL;
884 }
885
886 #ifdef SPARSE
887 freeSparseJacInfos((*tiIter)->pTapeInfos.sJinfos.y,
888 (*tiIter)->pTapeInfos.sJinfos.B,
889 (*tiIter)->pTapeInfos.sJinfos.JP,
890 (*tiIter)->pTapeInfos.sJinfos.g,
891 (*tiIter)->pTapeInfos.sJinfos.jr1d,
892 (*tiIter)->pTapeInfos.sJinfos.seed_rows,
893 (*tiIter)->pTapeInfos.sJinfos.seed_clms,
894 (*tiIter)->pTapeInfos.sJinfos.depen);
895 freeSparseHessInfos((*tiIter)->pTapeInfos.sHinfos.Hcomp,
896 (*tiIter)->pTapeInfos.sHinfos.Xppp,
897 (*tiIter)->pTapeInfos.sHinfos.Yppp,
898 (*tiIter)->pTapeInfos.sHinfos.Zppp,
899 (*tiIter)->pTapeInfos.sHinfos.Upp,
900 (*tiIter)->pTapeInfos.sHinfos.HP,
901 (*tiIter)->pTapeInfos.sHinfos.g,
902 (*tiIter)->pTapeInfos.sHinfos.hr,
903 (*tiIter)->pTapeInfos.sHinfos.p,
904 (*tiIter)->pTapeInfos.sHinfos.indep);
905 #endif
906
907 /* remove "main" tape files if not all three have been written */
908 int filesWritten = (*tiIter)->stats[OP_FILE_ACCESS] +
909 (*tiIter)->stats[LOC_FILE_ACCESS] +
910 (*tiIter)->stats[VAL_FILE_ACCESS];
911 if ( (filesWritten > 0) && ((*tiIter)->pTapeInfos.keepTape == 0) && (*tiIter)->pTapeInfos.skipFileCleanup==0 )
912 {
913 /* try to remove all tapes (even those not written by this
914 * run) => this ensures that there is no mixture of tapes from
915 * different ADOLC runs */
916 if ( (*tiIter)->stats[OP_FILE_ACCESS] == 1 )
917 remove((*tiIter)->pTapeInfos.op_fileName);
918 if ( (*tiIter)->stats[LOC_FILE_ACCESS] == 1 )
919 remove((*tiIter)->pTapeInfos.loc_fileName);
920 if ( (*tiIter)->stats[VAL_FILE_ACCESS] == 1 )
921 remove((*tiIter)->pTapeInfos.val_fileName);
922 }
923 if ((*tiIter)->pTapeInfos.op_fileName != NULL)
924 {
925 free((*tiIter)->pTapeInfos.op_fileName);
926 (*tiIter)->pTapeInfos.op_fileName = NULL;
927 }
928 if ((*tiIter)->pTapeInfos.val_fileName != NULL)
929 {
930 free((*tiIter)->pTapeInfos.val_fileName);
931 (*tiIter)->pTapeInfos.val_fileName = NULL;
932 }
933 if ((*tiIter)->pTapeInfos.loc_fileName != NULL)
934 {
935 free((*tiIter)->pTapeInfos.loc_fileName);
936 (*tiIter)->pTapeInfos.loc_fileName = NULL;
937 }
938 if ((*tiIter)->pTapeInfos.tay_fileName != NULL)
939 {
940 free((*tiIter)->pTapeInfos.tay_fileName);
941 (*tiIter)->pTapeInfos.tay_fileName = NULL;
942 }
943
944 delete *tiIter;
945 *tiIter = NULL;
946 }
947 }
948
949 cp_clearStack();
950
951 if (ADOLC_GLOBAL_TAPE_VARS.store != NULL) {
952 delete[] ADOLC_GLOBAL_TAPE_VARS.store;
953 ADOLC_GLOBAL_TAPE_VARS.store = NULL;
954 }
955 if (ADOLC_GLOBAL_TAPE_VARS.pStore != NULL) {
956 delete[] ADOLC_GLOBAL_TAPE_VARS.pStore;
957 ADOLC_GLOBAL_TAPE_VARS.pStore = NULL;
958 }
959
960 #if defined(_OPENMP)
961 if (ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 0) {
962 /* cleanup on program exit */
963 delete revolve_numbers;
964 delete ADOLC_checkpointsStack;
965 delete ADOLC_extDiffFctsBuffer;
966 delete globalTapeVars;
967 delete currentTapeInfos;
968 delete currentTapeInfos_fallBack;
969 delete tapeStack;
970 delete tapeInfosBuffer;
971 }
972 #endif
973
974 ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
975 clearTapeBaseNames();
976 }
977
removeTape(short tapeID,short type)978 int removeTape(short tapeID, short type) {
979 TapeInfos *tapeInfos = NULL;
980 vector<TapeInfos *>::iterator tiIter;
981 ADOLC_OPENMP_THREAD_NUMBER;
982 ADOLC_OPENMP_GET_THREAD_NUMBER;
983
984 /* check if TapeInfos for tapeID exist */
985 if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
986 for (tiIter = ADOLC_TAPE_INFOS_BUFFER.begin();
987 tiIter != ADOLC_TAPE_INFOS_BUFFER.end();
988 ++tiIter)
989 {
990 if ((*tiIter)->tapeID == tapeID) {
991 tapeInfos = *tiIter;
992 if (tapeInfos->tapingComplete == 0) return -1;
993 ADOLC_TAPE_INFOS_BUFFER.erase(tiIter);
994 break;
995 }
996 }
997 }
998
999 if (tapeInfos == NULL) { // might be on disk only
1000 tapeInfos = new TapeInfos(tapeID);
1001 tapeInfos->tapingComplete = 1;
1002 }
1003
1004 freeTapeResources(tapeInfos);
1005 #ifdef SPARSE
1006 freeSparseJacInfos(tapeInfos->pTapeInfos.sJinfos.y,
1007 tapeInfos->pTapeInfos.sJinfos.B,
1008 tapeInfos->pTapeInfos.sJinfos.JP,
1009 tapeInfos->pTapeInfos.sJinfos.g,
1010 tapeInfos->pTapeInfos.sJinfos.jr1d,
1011 tapeInfos->pTapeInfos.sJinfos.seed_rows,
1012 tapeInfos->pTapeInfos.sJinfos.seed_clms,
1013 tapeInfos->pTapeInfos.sJinfos.depen);
1014 freeSparseHessInfos(tapeInfos->pTapeInfos.sHinfos.Hcomp,
1015 tapeInfos->pTapeInfos.sHinfos.Xppp,
1016 tapeInfos->pTapeInfos.sHinfos.Yppp,
1017 tapeInfos->pTapeInfos.sHinfos.Zppp,
1018 tapeInfos->pTapeInfos.sHinfos.Upp,
1019 tapeInfos->pTapeInfos.sHinfos.HP,
1020 tapeInfos->pTapeInfos.sHinfos.g,
1021 tapeInfos->pTapeInfos.sHinfos.hr,
1022 tapeInfos->pTapeInfos.sHinfos.p,
1023 tapeInfos->pTapeInfos.sHinfos.indep);
1024 #endif
1025 ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1026
1027 if (type == ADOLC_REMOVE_COMPLETELY) {
1028 remove(tapeInfos->pTapeInfos.op_fileName);
1029 remove(tapeInfos->pTapeInfos.loc_fileName);
1030 remove(tapeInfos->pTapeInfos.val_fileName);
1031 }
1032
1033 free(tapeInfos->pTapeInfos.op_fileName);
1034 free(tapeInfos->pTapeInfos.val_fileName);
1035 free(tapeInfos->pTapeInfos.loc_fileName);
1036 if (tapeInfos->pTapeInfos.tay_fileName != NULL)
1037 free(tapeInfos->pTapeInfos.tay_fileName);
1038
1039 delete tapeInfos;
1040
1041 return 0;
1042 }
1043
1044 /****************************************************************************/
1045 /* Initialization for the taping process. Creates buffers for this tape, */
1046 /* sets files names, and calls appropriate setup routines. */
1047 /****************************************************************************/
trace_on(short tnum,int keepTaylors)1048 int trace_on(short tnum, int keepTaylors) {
1049 int retval = 0;
1050 ADOLC_OPENMP_THREAD_NUMBER;
1051 ADOLC_OPENMP_GET_THREAD_NUMBER;
1052
1053 /* allocate memory for TapeInfos and update tapeStack */
1054 retval = initNewTape(tnum);
1055 #ifdef ADOLC_MEDIPACK_SUPPORT
1056 mediInitTape(tnum);
1057 #endif
1058 ADOLC_CURRENT_TAPE_INFOS.keepTaylors=keepTaylors;
1059 ADOLC_CURRENT_TAPE_INFOS.stats[NO_MIN_MAX] =
1060 ADOLC_GLOBAL_TAPE_VARS.nominmaxFlag;
1061 if (keepTaylors!=0) ADOLC_CURRENT_TAPE_INFOS.deg_save=1;
1062 start_trace();
1063 take_stock(); /* record all existing adoubles on the tape */
1064 return retval;
1065 }
1066
trace_on(short tnum,int keepTaylors,uint obs,uint lbs,uint vbs,uint tbs,int skipFileCleanup)1067 int trace_on(short tnum, int keepTaylors,
1068 uint obs, uint lbs, uint vbs, uint tbs, int skipFileCleanup)
1069 {
1070 int retval = 0;
1071 ADOLC_OPENMP_THREAD_NUMBER;
1072 ADOLC_OPENMP_GET_THREAD_NUMBER;
1073
1074 /* allocate memory for TapeInfos and update tapeStack */
1075 retval = initNewTape(tnum);
1076 #ifdef ADOLC_MEDIPACK_SUPPORT
1077 mediInitTape(tnum);
1078 #endif
1079 freeTapeResources(&ADOLC_CURRENT_TAPE_INFOS);
1080 ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE] = obs;
1081 ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE] = lbs;
1082 ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE] = vbs;
1083 ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE] = tbs;
1084 ADOLC_CURRENT_TAPE_INFOS.keepTaylors=keepTaylors;
1085 ADOLC_CURRENT_TAPE_INFOS.stats[NO_MIN_MAX] =
1086 ADOLC_GLOBAL_TAPE_VARS.nominmaxFlag;
1087 ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.skipFileCleanup=skipFileCleanup;
1088 if (keepTaylors!=0) ADOLC_CURRENT_TAPE_INFOS.deg_save=1;
1089 start_trace();
1090 take_stock(); /* record all existing adoubles on the tape */
1091 return retval;
1092 }
1093
1094 /****************************************************************************/
1095 /* Stop Tracing. Cleans up, and turns off trace_flag. Flag not equal zero */
1096 /* enforces writing of the three main tape files (op+loc+val). */
1097 /****************************************************************************/
trace_off(int flag)1098 void trace_off(int flag) {
1099 ADOLC_OPENMP_THREAD_NUMBER;
1100 ADOLC_OPENMP_GET_THREAD_NUMBER;
1101 if (ADOLC_CURRENT_TAPE_INFOS.workMode != ADOLC_TAPING) {
1102 failAdditionalInfo1 = ADOLC_CURRENT_TAPE_INFOS.tapeID;
1103 fail(ADOLC_TAPING_NOT_ACTUALLY_TAPING);
1104 }
1105 ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.keepTape = flag;
1106 keep_stock(); /* copy remaining live variables + trace_flag = 0 */
1107 stop_trace(flag);
1108 cout.flush();
1109 ADOLC_CURRENT_TAPE_INFOS.tapingComplete = 1;
1110 ADOLC_CURRENT_TAPE_INFOS.workMode = ADOLC_NO_MODE;
1111 releaseTape();
1112 }
1113
isTaping()1114 bool isTaping() {
1115 ADOLC_OPENMP_THREAD_NUMBER;
1116 ADOLC_OPENMP_GET_THREAD_NUMBER;
1117 return ADOLC_CURRENT_TAPE_INFOS.traceFlag != 0;
1118 }
1119
checkInitialStoreSize(GlobalTapeVars * gtv)1120 void checkInitialStoreSize(GlobalTapeVars *gtv) {
1121 if (gtv->initialStoreSize >
1122 gtv->storeManagerPtr->initialSize)
1123 gtv->storeManagerPtr->grow(
1124 gtv->initialStoreSize);
1125 }
1126
1127 /****************************************************************************/
1128 /* A class for initialization/finalization and OpenMP handling */
1129 /****************************************************************************/
1130 class Keeper {
1131 public:
Keeper()1132 inline Keeper() {
1133 dummy = 0;
1134 init_lib();
1135 }
~Keeper()1136 inline ~Keeper() {
1137 cleanUp();
1138 }
1139
touch()1140 inline void touch() {
1141 dummy = 1;
1142 }
1143
1144 private:
1145 int dummy;
1146 };
1147
1148 /* a static instance that does all work */
1149 static Keeper theKeeper;
1150
1151 /**
1152 * Hope to convince the linker to link the keeper code into the executable. */
initADOLC()1153 void initADOLC() {
1154 theKeeper.touch();
1155 }
1156
1157 /****************************************************************************/
1158 /****************************************************************************/
1159 /* The following is necessary to provide a separate ADOL-C environment for */
1160 /* each OpenMP worker. */
1161 /****************************************************************************/
1162 /****************************************************************************/
1163 #if defined(_OPENMP)
1164 #include <adolc/adolc_openmp.h>
1165
1166 ADOLC_OpenMP ADOLC_OpenMP_Handler;
1167 ADOLC_OpenMP_NC ADOLC_OpenMP_Handler_NC;
1168 int ADOLC_parallel_doCopy;
1169
1170 static bool waitForMaster_begin = true;
1171 static bool waitForMaster_end = true;
1172 static bool firstParallel = true;
1173
1174 /****************************************************************************/
1175 /* Used by OpenMP to create a separate environment for every worker thread. */
1176 /****************************************************************************/
beginParallel()1177 void beginParallel() {
1178 ADOLC_OPENMP_THREAD_NUMBER;
1179 #if defined(ADOLC_THREADSAVE_ERRNO)
1180 errno = omp_get_thread_num();
1181 #endif
1182 ADOLC_OPENMP_GET_THREAD_NUMBER;
1183
1184 if (ADOLC_threadNumber == 0) { /* master only */
1185 int numThreads = omp_get_num_threads();
1186
1187 tapeInfosBuffer_s = tapeInfosBuffer;
1188 tapeStack_s = tapeStack;
1189 currentTapeInfos_s = currentTapeInfos;
1190 currentTapeInfos_fallBack_s = currentTapeInfos_fallBack;
1191 globalTapeVars_s = globalTapeVars;
1192 ADOLC_extDiffFctsBuffer_s = ADOLC_extDiffFctsBuffer;
1193 ADOLC_checkpointsStack_s = ADOLC_checkpointsStack;
1194 revolve_numbers_s = revolve_numbers;
1195
1196 if (firstParallel) {
1197 tapeInfosBuffer = new vector<TapeInfos *>[numThreads];
1198 tapeStack = new stack<TapeInfos *>[numThreads];
1199 currentTapeInfos = new TapeInfos[numThreads];
1200 currentTapeInfos_fallBack = new TapeInfos[numThreads];
1201 globalTapeVars = new GlobalTapeVars[numThreads];
1202 ADOLC_extDiffFctsBuffer = new ADOLC_BUFFER_TYPE[numThreads];
1203 ADOLC_checkpointsStack = new stack<StackElement>[numThreads];
1204 revolve_numbers = new revolve_nums[numThreads];
1205 } else {
1206 tapeInfosBuffer = tapeInfosBuffer_p;
1207 tapeStack = tapeStack_p;
1208 currentTapeInfos = currentTapeInfos_p;
1209 currentTapeInfos_fallBack = currentTapeInfos_fallBack_p;
1210 globalTapeVars = globalTapeVars_p;
1211 ADOLC_extDiffFctsBuffer = ADOLC_extDiffFctsBuffer_p;
1212 ADOLC_checkpointsStack = ADOLC_checkpointsStack_p;
1213 revolve_numbers = revolve_numbers_p;
1214 }
1215
1216 /* - set inParallelRegion for tmpGlobalTapeVars because it is source
1217 * for initializing the parallel globalTapeVars structs
1218 * - inParallelRegion has to be set to one for all workers by master.
1219 * This is necessary, to deter a speedy master from assuming all
1220 * workers are done, in endParallel, before they even leaved
1221 * beginParallel. */
1222 globalTapeVars_s[0].inParallelRegion = 1;
1223 for (int i = 0; i < numThreads; ++i)
1224 globalTapeVars[i].inParallelRegion = 1;
1225
1226 waitForMaster_end = true;
1227 waitForMaster_begin = false;
1228 } else
1229 while (waitForMaster_begin) {
1230 usleep(1000); /* if anyone knows a better value, ... :-) */
1231 }
1232
1233 if (firstParallel) {
1234 ADOLC_EXT_DIFF_FCTS_BUFFER.init(init_CpInfos);
1235
1236 /* Use assignment operator instead of open coding
1237 * this copies the store and the storemanager too
1238 */
1239 ADOLC_GLOBAL_TAPE_VARS = *globalTapeVars_s;
1240
1241 ADOLC_GLOBAL_TAPE_VARS.newTape = 0;
1242 ADOLC_CURRENT_TAPE_INFOS.tapingComplete = 1;
1243 ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = NULL;
1244 } else {
1245 if (ADOLC_parallel_doCopy) {
1246 ADOLC_GLOBAL_TAPE_VARS.storeSize = globalTapeVars_s->storeSize;
1247 ADOLC_GLOBAL_TAPE_VARS.numLives = globalTapeVars_s->numLives;
1248
1249 ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = globalTapeVars_s->branchSwitchWarning;
1250
1251 /* deleting the storemanager deletes the store too */
1252 delete ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr;
1253
1254 ADOLC_GLOBAL_TAPE_VARS.store = new
1255 double[ADOLC_GLOBAL_TAPE_VARS.storeSize];
1256 memcpy(ADOLC_GLOBAL_TAPE_VARS.store, globalTapeVars_s->store,
1257 ADOLC_GLOBAL_TAPE_VARS.storeSize * sizeof(double));
1258 ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr = new
1259 StoreManagerLocintBlock(
1260 dynamic_cast<StoreManagerLocintBlock*>(globalTapeVars_s->storeManagerPtr),
1261 ADOLC_GLOBAL_TAPE_VARS.store,
1262 ADOLC_GLOBAL_TAPE_VARS.storeSize,
1263 ADOLC_GLOBAL_TAPE_VARS.numLives);
1264 }
1265 }
1266 }
1267
1268 /****************************************************************************/
1269 /* Used by OpenMP to destroy the separate environment of every worker. */
1270 /****************************************************************************/
1271 /* There are n+1 instances of ADOLC_OpenMP => n within the parallel region
1272 * and one in the serial part! */
endParallel()1273 void endParallel() {
1274 ADOLC_OPENMP_THREAD_NUMBER;
1275 ADOLC_OPENMP_GET_THREAD_NUMBER;
1276
1277 /* do nothing if called at program exit (serial part) */
1278 if (ADOLC_threadNumber == 0 &&
1279 ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 0) return;
1280
1281 ADOLC_GLOBAL_TAPE_VARS.inParallelRegion = 0;
1282
1283 if (ADOLC_threadNumber == 0) { /* master only */
1284 int num;
1285 int numThreads = omp_get_num_threads();
1286 bool firstIt = true;
1287 do { /* wait until all slaves have left the parallel part */
1288 if (firstIt) firstIt = false;
1289 else usleep(1000); /* no busy waiting */
1290 num = 1;
1291 for (int i = 1; i < numThreads; ++i)
1292 if (globalTapeVars[i].inParallelRegion == 0) ++num;
1293 } while (num != numThreads);
1294
1295 firstParallel = false;
1296
1297 revolve_numbers_p = revolve_numbers;
1298 ADOLC_checkpointsStack_p = ADOLC_checkpointsStack;
1299 ADOLC_extDiffFctsBuffer_p = ADOLC_extDiffFctsBuffer;
1300 globalTapeVars_p = globalTapeVars;
1301 currentTapeInfos_p = currentTapeInfos;
1302 currentTapeInfos_fallBack_p = currentTapeInfos_fallBack;
1303 tapeStack_p = tapeStack;
1304 tapeInfosBuffer_p = tapeInfosBuffer;
1305
1306 revolve_numbers = revolve_numbers_s;
1307 ADOLC_checkpointsStack = ADOLC_checkpointsStack_s;
1308 ADOLC_extDiffFctsBuffer = ADOLC_extDiffFctsBuffer_s;
1309 globalTapeVars = globalTapeVars_s;
1310 currentTapeInfos = currentTapeInfos_s;
1311 currentTapeInfos_fallBack = currentTapeInfos_fallBack_s;
1312 tapeStack = tapeStack_s;
1313 tapeInfosBuffer = tapeInfosBuffer_s;
1314
1315 ADOLC_GLOBAL_TAPE_VARS.inParallelRegion = 0;
1316 waitForMaster_begin = true;
1317 waitForMaster_end = false;
1318 } else
1319 while (waitForMaster_end) {
1320 usleep(1000); // no busy waiting
1321 }
1322 }
1323
1324 #endif /* _OPENMP */
1325
TapeInfos()1326 TapeInfos::TapeInfos() : pTapeInfos() {
1327 initTapeInfos(this);
1328 }
1329
TapeInfos(short _tapeID)1330 TapeInfos::TapeInfos(short _tapeID) : pTapeInfos() {
1331 initTapeInfos(this);
1332 tapeID = _tapeID;
1333 pTapeInfos.op_fileName = createFileName(tapeID, OPERATIONS_TAPE);
1334 pTapeInfos.loc_fileName = createFileName(tapeID, LOCATIONS_TAPE);
1335 pTapeInfos.val_fileName = createFileName(tapeID, VALUES_TAPE);
1336 pTapeInfos.tay_fileName = NULL;
1337 }
1338
copy(const TapeInfos & tInfos)1339 void TapeInfos::copy(const TapeInfos& tInfos) {
1340 char *ptr, *end;
1341 char const* tIptr = (char const*)(&tInfos.tapeID);
1342
1343 ptr = (char *)(&this->tapeID);
1344 end = (char *)(&this->pTapeInfos);
1345 for ( ; ptr != end ; ptr++, tIptr++ )
1346 *ptr = *tIptr;
1347 this->pTapeInfos.copy(tInfos.pTapeInfos);
1348 }
1349
PersistantTapeInfos()1350 PersistantTapeInfos::PersistantTapeInfos() {
1351 char *ptr = (char*)(&forodec_nax), *end = (char*)(¶mstore);
1352 for (; ptr != end ; ptr++ )
1353 *ptr = 0;
1354 paramstore = NULL;
1355 }
1356
copy(const PersistantTapeInfos & pTInfos)1357 void PersistantTapeInfos::copy(const PersistantTapeInfos& pTInfos) {
1358 char *ptr = (char*)(&this->forodec_nax), *end = (char*)(&this->paramstore);
1359 char const* pTIptr = (char const*)(&pTInfos.forodec_nax);
1360 for (; ptr != end ; ptr++, pTIptr++ )
1361 *ptr = *pTIptr;
1362 paramstore = pTInfos.paramstore;
1363 }
1364
~PersistantTapeInfos()1365 PersistantTapeInfos::~PersistantTapeInfos() {
1366 if (jacSolv_nax) {
1367 free(jacSolv_ci);
1368 free(jacSolv_ri);
1369 myfree1(jacSolv_xold);
1370 myfreeI2(jacSolv_nax, jacSolv_I);
1371 myfree2(jacSolv_J);
1372 jacSolv_nax = 0;
1373 }
1374 if (forodec_nax) {
1375 myfree1(forodec_y);
1376 myfree1(forodec_z);
1377 myfree2(forodec_Z);
1378 forodec_nax = 0;
1379 }
1380 if (paramstore != NULL) {
1381 free(paramstore);
1382 paramstore = NULL;
1383 }
1384 }
1385
1386 #if defined(ADOLC_TRACK_ACTIVITY)
1387
1388 char const* const StoreManagerLocintBlock::nowhere = NULL;
1389
StoreManagerLocintBlock(double * & storePtr,char * & actStorePtr,size_t & size,size_t & numlives)1390 StoreManagerLocintBlock::StoreManagerLocintBlock(double * &storePtr, char* &actStorePtr, size_t &size, size_t &numlives) :
1391 storePtr(storePtr),
1392 actStorePtr(actStorePtr),
1393 activityTracking(1),
1394 maxsize(size),
1395 currentfill(numlives)
1396 #ifdef ADOLC_LOCDEBUG
1397 ,ensure_blockCallsSinceLastConsolidateBlocks(0)
1398 #endif
1399 {
1400 indexFree.clear();
1401 #ifdef ADOLC_LOCDEBUG
1402 std::cerr << "StoreManagerIntegerBlock::StoreManagerIntegerBlock()\n";
1403 #endif
1404 }
1405
StoreManagerLocintBlock(const StoreManagerLocintBlock * const stm,double * & storePtr,char * & actStorePtr,size_t & size,size_t & numlives)1406 StoreManagerLocintBlock::StoreManagerLocintBlock(
1407 const StoreManagerLocintBlock *const stm,
1408 double * &storePtr, char * &actStorePtr, size_t &size, size_t &numlives) :
1409 storePtr(storePtr),
1410 #if defined(ADOLC_TRACK_ACTIVITY)
1411 actStorePtr(actStorePtr),
1412 activityTracking(1),
1413 #endif
1414 maxsize(size),
1415 currentfill(numlives)
1416 #ifdef ADOLC_LOCDEBUG
1417 ,ensure_blockCallsSinceLastConsolidateBlocks(0)
1418 #endif
1419 {
1420 #ifdef ADOLC_LOCDEBUG
1421 std::cerr << "StoreManagerInteger::StoreManagerInteger()\n";
1422 #endif
1423 indexFree.clear();
1424 forward_list<struct FreeBlock>::const_iterator iter = stm->indexFree.begin();
1425 for (; iter != stm->indexFree.end(); iter++)
1426 indexFree.emplace_front( *iter );
1427 }
1428 #endif
1429
StoreManagerLocintBlock(double * & storePtr,size_t & size,size_t & numlives)1430 StoreManagerLocintBlock::StoreManagerLocintBlock(double * &storePtr, size_t &size, size_t &numlives) :
1431 storePtr(storePtr),
1432 #if defined(ADOLC_TRACK_ACTIVITY)
1433 activityTracking(0),
1434 actStorePtr(const_cast<char*&>(nowhere)),
1435 #endif
1436 maxsize(size),
1437 currentfill(numlives)
1438 #ifdef ADOLC_LOCDEBUG
1439 ,ensure_blockCallsSinceLastConsolidateBlocks(0)
1440 #endif
1441 {
1442 indexFree.clear();
1443 #ifdef ADOLC_LOCDEBUG
1444 std::cerr << "StoreManagerIntegerBlock::StoreManagerIntegerBlock()\n";
1445 #endif
1446 }
1447
~StoreManagerLocintBlock()1448 StoreManagerLocintBlock::~StoreManagerLocintBlock()
1449 {
1450 #ifdef ADOLC_LOCDEBUG
1451 std::cerr << "StoreManagerIntegerBlock::~StoreManagerIntegerBlock()\n";
1452 #endif
1453 if (storePtr != NULL) {
1454 delete[] storePtr;
1455 storePtr = NULL;
1456 }
1457 if (!indexFree.empty() ) {
1458 indexFree.clear();
1459 }
1460 #if defined(ADOLC_TRACK_ACTIVITY)
1461 if (activityTracking && actStorePtr) {
1462 delete[] actStorePtr;
1463 }
1464 #endif
1465 maxsize = 0;
1466 currentfill = 0;
1467 }
1468
StoreManagerLocintBlock(const StoreManagerLocintBlock * const stm,double * & storePtr,size_t & size,size_t & numlives)1469 StoreManagerLocintBlock::StoreManagerLocintBlock(
1470 const StoreManagerLocintBlock *const stm,
1471 double * &storePtr, size_t &size, size_t &numlives) :
1472 storePtr(storePtr),
1473 #if defined(ADOLC_TRACK_ACTIVITY)
1474 activityTracking(0),
1475 actStorePtr(const_cast<char*&>(nowhere)),
1476 #endif
1477 maxsize(size),
1478 currentfill(numlives)
1479 #ifdef ADOLC_LOCDEBUG
1480 ,ensure_blockCallsSinceLastConsolidateBlocks(0)
1481 #endif
1482 {
1483 #ifdef ADOLC_LOCDEBUG
1484 std::cerr << "StoreManagerInteger::StoreManagerInteger()\n";
1485 #endif
1486 indexFree.clear();
1487 forward_list<struct FreeBlock>::const_iterator iter = stm->indexFree.begin();
1488 for (; iter != stm->indexFree.end(); iter++)
1489 indexFree.emplace_front( *iter );
1490 }
1491
1492
next_loc()1493 locint StoreManagerLocintBlock::next_loc() {
1494 if ( indexFree.empty() )
1495 grow();
1496
1497 struct FreeBlock &front = indexFree.front();
1498 locint const result = front.next;
1499 if (--front.size == 0) {
1500 if (next(indexFree.cbegin()) == indexFree.cend()) {
1501 front.next++;
1502 grow();
1503 } else
1504 indexFree.pop_front();
1505 } else
1506 front.next++;
1507
1508 ++currentfill;
1509
1510 #ifdef ADOLC_LOCDEBUG
1511 std::cerr << "StoreManagerLocintBlock::next_loc: result: " << result << " fill: " << size() << "max: " << maxSize() << endl;
1512 forward_list<struct FreeBlock>::iterator iter = indexFree.begin();
1513 for( ; iter != indexFree.end(); iter++ )
1514 std::cerr << "INDEXFELD ( " << iter->next << " , " << iter->size << ")" << endl;
1515 #endif
1516
1517 return result;
1518 }
1519
ensure_block(size_t n)1520 void StoreManagerLocintBlock::ensure_block(size_t n) {
1521 bool found = false;
1522 #ifdef ADOLC_LOCDEBUG
1523 ++ensure_blockCallsSinceLastConsolidateBlocks;
1524 std::cerr << "StoreManagerLocintBlock::ensure_Block: required " << n << " ... ";
1525 std::cerr << "searching for big enough block " << endl;
1526 #endif
1527 if (maxSize()-size()>n) {
1528 if (indexFree.front().size>=n) found = true;
1529 if ((!found) && ((double(maxSize())/double(size()))>gcTriggerRatio() || maxSize()>gcTriggerMaxSize())) {
1530 consolidateBlocks();
1531 #ifdef ADOLC_LOCDEBUG
1532 std::cerr << "ADOLC: GC called consolidateBlocks because " << maxSize() << "/" << size() << ">" << gcTriggerRatio() << " or " << maxSize() << ">" << gcTriggerMaxSize() << " after " << ensure_blockCallsSinceLastConsolidateBlocks << std::endl;
1533 ensure_blockCallsSinceLastConsolidateBlocks=0;
1534 #endif
1535 forward_list<struct FreeBlock>::iterator
1536 biter = indexFree.before_begin(),
1537 iter = indexFree.begin();
1538 for (; iter != indexFree.end() ; biter++, iter++ ) {
1539 if ( iter->size >= n) {
1540 if (iter != indexFree.begin() ) {
1541 indexFree.emplace_front(*iter);
1542 indexFree.erase_after(biter);
1543 }
1544 found = true;
1545 break;
1546 }
1547 }
1548 }
1549 }
1550 if (!found) {
1551 #ifdef ADOLC_LOCDEBUG
1552 std::cerr << "no big enough block...growing " << endl;
1553 #endif
1554 grow(n);
1555 }
1556
1557 #ifdef ADOLC_LOCDEBUG
1558 std::cerr << "StoreManagerLocintBlock::ensure_Block: " << " fill: " << size() << "max: " << maxSize() << " ensure_Block (" << n << ")" << endl;
1559 forward_list<struct FreeBlock>::iterator iter = indexFree.begin();
1560 for( ; iter != indexFree.end(); iter++ )
1561 std::cerr << "INDEXFELD ( " << iter->next << " , " << iter->size << ")" << endl;
1562 #endif
1563 }
1564
grow(size_t minGrow)1565 void StoreManagerLocintBlock::grow(size_t minGrow) {
1566 // first figure out what eventual size we want
1567 size_t const oldMaxsize = maxsize;
1568
1569 if (maxsize == 0){
1570 maxsize = initialSize;
1571 } else {
1572 maxsize *= 2;
1573 }
1574
1575 if (minGrow > 0) {
1576 while (maxsize - oldMaxsize < minGrow) {
1577 maxsize *= 2;
1578 }
1579 }
1580
1581 if (maxsize > std::numeric_limits<locint>::max()) {
1582 // encapsulate this error message
1583 fprintf(DIAG_OUT,"\nADOL-C error:\n");
1584 fprintf(DIAG_OUT,"maximal number (%u) of live active variables exceeded\n\n",
1585 std::numeric_limits<locint>::max());
1586 adolc_exit(-3,"",__func__,__FILE__,__LINE__);
1587 }
1588
1589 #ifdef ADOLC_LOCDEBUG
1590 // index 0 is not used, means one slot less
1591 std::cerr << "StoreManagerIntegerBlock::grow(): increase size from " << oldMaxsize
1592 << " to " << maxsize << " entries (currently " << size() << " entries used)\n";
1593 #endif
1594
1595 double *const oldStore = storePtr;
1596 #if defined(ADOLC_TRACK_ACTIVITY)
1597 char * oldactStore;
1598 if (activityTracking)
1599 oldactStore = actStorePtr;
1600 #endif
1601 #if defined(ADOLC_LOCDEBUG)
1602 std::cerr << "StoreManagerInteger::grow(): allocate " << maxsize * sizeof(double) << " B doubles\n";
1603 #endif
1604 storePtr = new double[maxsize];
1605 assert(storePtr);
1606 memset(storePtr, 0, maxsize*sizeof(double));
1607 #if defined(ADOLC_TRACK_ACTIVITY)
1608 if (activityTracking) {
1609 actStorePtr = new char[maxsize];
1610 memset(actStorePtr,0,maxsize*sizeof(char));
1611 }
1612 #endif
1613
1614 if (oldStore != NULL) { // not the first time
1615 #if defined(ADOLC_LOCDEBUG)
1616 std::cerr << "StoreManagerInteger::grow(): copy values\n";
1617 #endif
1618
1619 memcpy(storePtr, oldStore, oldMaxsize*sizeof(double));
1620 #if defined(ADOLC_TRACK_ACTIVITY)
1621 if (activityTracking) {
1622 memcpy(actStorePtr, oldactStore, oldMaxsize*sizeof(char));
1623 }
1624 #endif
1625
1626 #if defined(ADOLC_LOCDEBUG)
1627 std::cerr << "StoreManagerInteger::grow(): free " << oldMaxsize * sizeof(double) << "\n";
1628 #endif
1629 delete [] oldStore;
1630 #if defined(ADOLC_TRACK_ACTIVITY)
1631 if (activityTracking) {
1632 delete[] oldactStore;
1633 }
1634 #endif
1635
1636 }
1637
1638 bool foundTail = false;
1639 forward_list<struct FreeBlock>::iterator
1640 biter = indexFree.before_begin(),
1641 iter = indexFree.begin();
1642 for (; iter != indexFree.end() ; biter++,iter++ ) {
1643 if (iter->next + iter->size == oldMaxsize ) {
1644 iter->size += (maxsize - oldMaxsize);
1645 indexFree.emplace_front(*iter);
1646 indexFree.erase_after(biter);
1647 foundTail = true;
1648 break;
1649 }
1650 }
1651
1652 if (! foundTail) {
1653 indexFree.emplace_front(
1654 #if defined(_MSC_VER) && _MSC_VER <= 1800
1655 FreeBlock(
1656 #endif
1657 oldMaxsize,(maxsize - oldMaxsize)
1658 #if defined(_MSC_VER) && _MSC_VER <= 1800
1659 )
1660 #endif
1661 );
1662 }
1663
1664 biter = indexFree.before_begin();
1665 iter = indexFree.begin();
1666 while (iter != indexFree.end()) {
1667 if (iter->size == 0) {
1668 indexFree.erase_after(biter); // don't leave 0 blocks around
1669 iter = next(biter);
1670 }
1671 else {
1672 biter++;
1673 iter++;
1674 }
1675 }
1676 #ifdef ADOLC_LOCDEBUG
1677 std::cerr << "Growing:" << endl;
1678 iter = indexFree.begin();
1679 for( ; iter != indexFree.end(); iter++ )
1680 std::cerr << "INDEXFELD ( " << iter->next << " , " << iter->size << ")" << endl;
1681 #endif
1682 }
1683
free_loc(locint loc)1684 void StoreManagerLocintBlock::free_loc(locint loc) {
1685 assert( loc < maxsize);
1686
1687 struct FreeBlock &front = indexFree.front();
1688 if ((loc+1 == front.next)
1689 || (front.next + front.size == loc)) {
1690 front.size++;
1691 if (loc + 1 == front.next)
1692 front.next = loc;
1693 }
1694 else {
1695 indexFree.emplace_front(
1696 #if defined(_MSC_VER) && _MSC_VER <= 1800
1697 FreeBlock(
1698 #endif
1699 loc,1
1700 #if defined(_MSC_VER) && _MSC_VER <= 1800
1701 )
1702 #endif
1703 );
1704 }
1705
1706 --currentfill;
1707 #ifdef ADOLC_LOCDEBUG
1708 std::cerr << "free_loc: " << loc << " fill: " << size() << "max: " << maxSize() << endl;
1709 forward_list<struct FreeBlock>::iterator iter = indexFree.begin();
1710 for( ; iter != indexFree.end(); iter++ )
1711 std::cerr << "INDEXFELD ( " << iter->next << " , " << iter->size << ")" << endl;
1712 #endif
1713 }
1714
ensureContiguousLocations(size_t n)1715 void ensureContiguousLocations(size_t n) {
1716 ADOLC_OPENMP_THREAD_NUMBER;
1717 ADOLC_OPENMP_GET_THREAD_NUMBER;
1718 ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr->ensure_block(n);
1719 }
1720
setStoreManagerControl(double gcTriggerRatio,size_t gcTriggerMaxSize)1721 void setStoreManagerControl(double gcTriggerRatio, size_t gcTriggerMaxSize) {
1722 ADOLC_OPENMP_THREAD_NUMBER;
1723 ADOLC_OPENMP_GET_THREAD_NUMBER;
1724 ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr->setStoreManagerControl(gcTriggerRatio,gcTriggerMaxSize);
1725 }
1726
consolidateBlocks()1727 void StoreManagerLocintBlock::consolidateBlocks() {
1728 indexFree.sort();
1729 forward_list<struct FreeBlock>::iterator
1730 iter = indexFree.begin(),
1731 niter = iter++;
1732 while (iter != indexFree.end()) {
1733 if (niter->next + niter->size == iter->next) {
1734 niter->size += iter->size;
1735 indexFree.erase_after(niter);
1736 iter = next(niter);
1737 } else {
1738 niter++;
1739 iter++;
1740 }
1741 }
1742 #ifdef ADOLC_LOCDEBUG
1743 std::cerr << "StoreManagerLocintBlock::consolidateBlocks: " << " fill: " << size() << "max: " << maxSize() << endl;
1744 iter = indexFree.begin();
1745 for( ; iter != indexFree.end(); iter++ )
1746 std::cerr << "INDEXFELD ( " << iter->next << " , " << iter->size << ")" << endl;
1747 #endif
1748 }
1749
enableMinMaxUsingAbs()1750 void enableMinMaxUsingAbs() {
1751 ADOLC_OPENMP_THREAD_NUMBER;
1752 ADOLC_OPENMP_GET_THREAD_NUMBER;
1753
1754 if (!isTaping())
1755 ADOLC_GLOBAL_TAPE_VARS.nominmaxFlag = 1;
1756 else
1757 fprintf(DIAG_OUT, "ADOL-C warning: "
1758 "change from native Min/Max to using Abs during tracing "
1759 "will lead to inconsistent results, not changing behaviour now\n"
1760 " "
1761 "call %s before trace_on(tape_id) for the correct behaviour\n"
1762 ,__FUNCTION__);
1763 }
1764
disableMinMaxUsingAbs()1765 void disableMinMaxUsingAbs() {
1766 ADOLC_OPENMP_THREAD_NUMBER;
1767 ADOLC_OPENMP_GET_THREAD_NUMBER;
1768
1769 if (!isTaping())
1770 ADOLC_GLOBAL_TAPE_VARS.nominmaxFlag = 0;
1771 else
1772 fprintf(DIAG_OUT, "ADOL-C warning: "
1773 "change from native Min/Max to using Abs during tracing "
1774 "will lead to inconsistent results, not changing behaviour now\n"
1775 " "
1776 "call %s after trace_off() for the correct behaviour\n"
1777 ,__FUNCTION__);
1778 }
1779
1780 #include <adolc/adolc_fatalerror.h>
1781
adolc_exit(int errorcode,const char * what,const char * function,const char * file,int line)1782 void adolc_exit(int errorcode, const char *what, const char* function, const char *file, int line) {
1783 throw FatalError(errorcode, what, function, file, line);
1784 }
1785
1786 /* Only called during stop_trace() via save_params() */
free_all_taping_params()1787 void free_all_taping_params() {
1788 size_t np;
1789 ADOLC_OPENMP_THREAD_NUMBER;
1790 ADOLC_OPENMP_GET_THREAD_NUMBER;
1791
1792 np = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_PARAM];
1793 while ( np > 0 )
1794 ADOLC_GLOBAL_TAPE_VARS.paramStoreMgrPtr->free_loc(--np);
1795 }
1796
setStoreManagerType(unsigned char type)1797 void setStoreManagerType(unsigned char type) {
1798 ADOLC_OPENMP_THREAD_NUMBER;
1799 ADOLC_OPENMP_GET_THREAD_NUMBER;
1800
1801 if (ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr->storeType() != type) {
1802 if (ADOLC_GLOBAL_TAPE_VARS.numLives == 0) {
1803 ADOLC_GLOBAL_TAPE_VARS.reallocStore(type);
1804 } else {
1805 fprintf(DIAG_OUT,"ADOL-C-warning: called %s after allocating %d active variables\n"
1806 "*** WILL NOT CHANGE ***\nto change type deallocate all active variables\n"
1807 "continuing ...\n"
1808 , __func__, ADOLC_GLOBAL_TAPE_VARS.numLives);
1809 }
1810 } else {
1811 fprintf(DIAG_OUT,"ADOL-C-warning: called %s with same type as before\n"
1812 "*** NO CHANGE ***\ncontinuing ...\n",__func__);
1813 }
1814 }
1815
reallocStore(unsigned char type)1816 void GlobalTapeVarsCL::reallocStore(unsigned char type) {
1817 if (storeManagerPtr != NULL)
1818 delete storeManagerPtr;
1819
1820 store = NULL;
1821 #if defined(ADOLC_TRACK_ACTIVITY)
1822 actStore = NULL;
1823 #endif
1824 storeSize = 0;
1825 numLives = 0;
1826 switch (type) {
1827 case ADOLC_LOCATION_BLOCKS:
1828 #if defined(ADOLC_TRACK_ACTIVITY)
1829 storeManagerPtr = new StoreManagerLocintBlock(store, actStore, storeSize, numLives);
1830 #else
1831 storeManagerPtr = new StoreManagerLocintBlock(store, storeSize, numLives);
1832 #endif
1833 break;
1834 case ADOLC_LOCATION_SINGLETONS:
1835 #if defined(ADOLC_TRACK_ACTIVITY)
1836 storeManagerPtr = new StoreManagerLocint(store, actStore, storeSize, numLives);
1837 #else
1838 storeManagerPtr = new StoreManagerLocint(store, storeSize, numLives);
1839 #endif
1840 break;
1841 }
1842 }
1843