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

Last change on this file since 710 was 710, checked in by kulshres, 3 years ago

Merge branch 'master' of 'gitclone' into 'svn'

The following commits have been merged:

commit 3bbd2a270ddfee5495e99a7283952f1da2370ad5
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Wed Aug 10 17:52:25 2016 +0200

make the FatalError? exception public so users may handle it if required

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

commit 4c79b2770e3860d21599420779dbc88b15a63942
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Wed Aug 10 13:02:37 2016 +0200

fix bug in retracing the same tag with different size problem

also if we're not tracing with keep, calling taylor_close() is useless
and causes wrong stats to be stored on trace.

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

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