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

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

merge branch 'master' of 'gitclone' into 'svn'

The following commits have been merged:

commit 48aee4916d2ed907b772dbd1c1d6ce46cb273651
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Mon Aug 10 21:28:49 2015 +0200

modernise configure.ac

disable static library building. this causes more
problems than it solves.

commit 47332811a4c5c27cb884f75792c910c813378ef4
Merge: 0ee77fd 0d4eeec
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu Aug 6 22:33:46 2015 +0200

Merge branch 'edf-memory'

This is to reduce memory allocation and copying in ext_diff_fct

commit 0ee77fd33a1d6d55fcc67ad419937b2cb777ed4e
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Wed Aug 5 15:49:33 2015 +0200

Remove empty file from dist

this can be created during compilation

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

commit 51505c34571aa61b4b21ebce6cdf1728ff56ddaa
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Tue Aug 4 17:36:26 2015 +0200

adouble(const adub&) should match operator=(const adub&)

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

commit 03e49097aa0455337647d280cda530064987e6b9
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Fri Jul 3 11:17:53 2015 +0200

make a define for default contiguous locations

this is not needed during compilation of the library
only during compilation of user-code, if the user
wants to have all adouble* allocations to have
contiguous locations.

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

commit f00cfb5d0dc8a8993581fd8c08dd8c6c5cd23248
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Wed Jul 1 11:56:39 2015 +0200

rename adolc_lie.h to drivers.h

the old name led to an include <adolc/lie/adolc_lie.h>
which looks highly redundant.
new name makes for include <adolc/lie/drivers.h>

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

commit fcf78bf8426a227750a0bcaa32ff65e57ef329b8
Author: franke <mirko.franke@…>
Date: Wed May 20 16:39:16 2015 +0200

added Lie drivers

commit 0d4eeec7b6212aa64c8997db8a511f81b604b3e1
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Fri Jun 26 14:19:41 2015 +0200

minimise extra memory requirement and copies in ext_diff

This should in theory reduce the amount of memory required
to run an external function with the old interface. It also
reduced some copying operations.

Fingers crossed that we've not broken checkpointing and/or
fixpoint iterations.

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

commit 8811f02a4d4a15946a18f7513ab17dada66509c3
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Fri May 22 12:41:45 2015 +0200

try to streamline data copies in ext_diff_v2

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 608 2015-08-10 20:06:55Z 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
1010
1011
1012/****************************************************************************/
1013/* A class for initialization/finalization and OpenMP handling              */
1014/****************************************************************************/
1015class Keeper {
1016    public:
1017        inline Keeper() {
1018            dummy = 0;
1019            init();
1020            readConfigFile();
1021            if (ADOLC_GLOBAL_TAPE_VARS.initialStoreSize > 
1022                ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr->initialSize)
1023                ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr->grow(
1024                    ADOLC_GLOBAL_TAPE_VARS.initialStoreSize);
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
1578class FatalError: public exception{
1579protected:
1580    static const int MAX_MSG_SIZE = 4*1024;
1581    char msg[MAX_MSG_SIZE];
1582
1583public:
1584    explicit FatalError(int errorcode, const char* what, const char* function, const char* file, int line) {
1585        // need to use C-style functions that do not use exceptions themselves
1586        snprintf(this->msg, MAX_MSG_SIZE, "errorcode=%d function=%s file=%s line=%d what=%s", errorcode, function, file, line, what);
1587    }
1588
1589    virtual const char* what() const throw() {
1590        return msg;
1591    }
1592};
1593
1594void adolc_exit(int errorcode, const char *what, const char* function, const char *file, int line) {
1595    throw FatalError(errorcode, what, function, file, line);
1596}
1597
1598/* Only called during stop_trace() via save_params() */
1599void free_all_taping_params() {
1600    size_t np;
1601    ADOLC_OPENMP_THREAD_NUMBER;
1602    ADOLC_OPENMP_GET_THREAD_NUMBER;
1603
1604    np = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_PARAM];
1605    while ( np > 0 )
1606        ADOLC_GLOBAL_TAPE_VARS.paramStoreMgrPtr->free_loc(--np);
1607}
Note: See TracBrowser for help on using the repository browser.