source: trunk/ADOL-C/src/tape_handling.cpp @ 708

Last change on this file since 708 was 671, checked in by kulshres, 4 years ago

Fix compilation with openMP

initialStoreSize check in Keeper moved to checkInitialStoreSize()
called from readConfigFile()

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

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