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

Last change on this file since 762 was 762, checked in by mbanovic, 5 months ago

Merged branch "medipacksupport" from "git" into "svn"

The following commits were merged:

commit 0d1b5eec2cca8afdeea3cdffa196efb6cfd60a53
Merge: 72d114b 33bfdb5
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Mon Nov 5 10:03:04 2018 +0000

Merge branch 'medipackSupport' into 'medipacksupport'

Medipack support

See merge request adol-c/adol-c!26

commit 33bfdb5a006c782489bfef1b651ca3bdbceefaf2
Merge: ac55eab cf82982
Author: Max Sagebaum <max.sagebaum@…>
Date: Tue Oct 30 11:19:31 2018 +0100

Merge branch 'medipackSupport' into temp

commit ac55eab9dd8cb8c84926ee56456076392a047c1a
Merge: 72d114b caaac60
Author: Max Sagebaum <max.sagebaum@…>
Date: Tue Oct 30 11:14:09 2018 +0100

Merge remote-tracking branch 'origin/master' into temp

commit cf82982421aaa7d83405ffa3d0c9b6ef88251d0c
Merge: 6aeca20 caaac60
Author: Max Sagebaum <max.sagebaum@…>
Date: Tue Oct 30 11:13:25 2018 +0100

Merge remote-tracking branch 'origin/master' into medipackSupport

commit 6aeca205c2448b4bbc915eb76153ebde19448573
Author: Max Sagebaum <max.sagebaum@…>
Date: Tue Oct 23 22:30:28 2018 +0200

Added suport for ZOS, FOS, FOV forward and reverse.

commit caaac60da4c61b370d106c68064d38c42a7cb6e3
Merge: cc2e0b3 70fc288
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Mon Oct 8 08:53:40 2018 +0000

Merge branch 'fix_adtl_hov_refcntr' into 'master'

Fix undefined reference to adtl_hov::refcounter::refcnt

See merge request adol-c/adol-c!24

commit 70fc288b9ab95b16d3179fcf239ee2208ae1a2c4
Author: Jean-Paul Pelteret <jppelteret@…>
Date: Mon Oct 1 20:53:03 2018 +0200

Fix undefined reference to adtl_hov::refcounter::refcnt

commit cc2e0b3154fb6e62580def4501c4cf3f3d8e32ef
Merge: d7400f5 7c7f24b
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Mon Oct 1 12:26:39 2018 +0000

Merge branch 'docu' into 'master'

Refactor tapeless to traceless

See merge request adol-c/adol-c!23

commit ca397962cde23bde80e03924893e09c84d8728bf
Merge: 9cbc432 d7400f5
Author: Max Sagebaum <max.sagebaum@…>
Date: Fri Sep 28 10:07:41 2018 +0200

Merge remote-tracking branch 'origin/master' into medipackSupport

commit 9cbc4324e0d3e19f97ba5c5474121f0189e60f83
Author: Max Sagebaum <max.sagebaum@…>
Date: Thu Sep 27 14:38:30 2018 +0200

Missing MeDiPack? initialization on trace_on.

commit 76c30290365830d2370a354af949f3bf42df3885
Author: Max Sagebaum <max.sagebaum@…>
Date: Thu Sep 27 09:55:42 2018 +0200

Null pointer fix for initialization.

commit 7c7f24b25479870d58ff19d78a6e394ca28ddb58
Author: mflehmig <martin.schroschk@…>
Date: Thu Sep 20 13:16:06 2018 +0200

Refactor tapeless to traceless

As far as I can see, the official wording is traceless forward mode.
Additonally, the latex label and refs changed to 'traceless'.

commit 72d114b7ac42b8ac493030cedd1df8c9746ba5d4
Author: Max Sagebaum <max.sagebaum@…>
Date: Thu Oct 19 09:25:19 2017 +0200

Added support for MeDiPack? library.

Enable it with the configure options:
--enable-medipack --with-medipack=<path to MeDiPack?>

Tutorial on a how to use will follow.

commit b4ca76279d28407f29901d40953d02a0c5c9140e
Author: Max Sagebaum <max.sagebaum@…>
Date: Mon May 7 14:45:13 2018 +0200

Added support for cbrt function.

commit bc7b8ca61865058fac097410fd94a44fba281131
Author: Max Sagebaum <max.sagebaum@…>
Date: Thu Mar 1 10:31:18 2018 +0100

Changes for new interface.

commit cd1e82778c8540221b24559d5097bf6d00597e19
Author: Max Sagebaum <max.sagebaum@…>
Date: Thu Nov 16 14:31:07 2017 +0100

Changes to new MeDiPack? interface for adjoint values.

commit 55bcb0ffd5a9496817bffac0bd2c9489ed8ce992
Author: Max Sagebaum <max.sagebaum@…>
Date: Thu Oct 19 09:25:19 2017 +0200

Added support for MeDiPack? library.

Enable it with the configure options:
--enable-medipack --with-medipack=<path to MeDiPack?>

Tutorial on a how to use will follow.

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