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

Last change on this file since 206 was 206, checked in by kulshres, 9 years ago

correct mismatched free for a new'd pointer use delete[]

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

  • Property svn:keywords set to Author Date Id Revision
File size: 41.6 KB
Line 
1/*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File:     tape_handling.cpp
4 Revision: $Id: tape_handling.cpp 206 2011-03-29 15:43:41Z kulshres $
5 Contents: management of tape infos
6
7 Copyright (c) Andreas Kowarz, Andrea Walther
8 
9 This file is part of ADOL-C. This software is provided as open source.
10 Any use, reproduction, or distribution of the software constitutes
11 recipient's acceptance of the terms of the accompanying license file.
12 
13---------------------------------------------------------------------------*/
14#include "taping_p.h"
15#include "checkpointing_p.h"
16#include <adolc/revolve.h>
17
18#include <cassert>
19#include <limits>
20#include <iostream>
21#include <string.h>
22#ifdef HAVE_UNISTD_H
23#include <unistd.h>
24#endif
25#include <vector>
26#include <stack>
27#include <errno.h>
28
29using namespace std;
30
31#ifdef SPARSE
32BEGIN_C_DECLS
33extern void freeSparseJacInfos(double *y, double **B, unsigned int **JP, void *g, 
34                               void *jr1d, int seed_rows, int seed_clms, int depen);
35extern void freeSparseHessInfos(double **Hcomp, double ***Xppp, double ***Yppp, double ***Zppp, 
36                                double **Upp, unsigned int **HP,
37                                void *g, void *hr, int p, int indep);
38END_C_DECLS
39#endif
40
41GlobalTapeVarsCL::GlobalTapeVarsCL() {
42  store = 0;
43  storeSize = 0;
44  numLives = 0;
45  storeManagerPtr = new StoreManagerLocint(store, storeSize, numLives);
46}
47
48GlobalTapeVarsCL::~GlobalTapeVarsCL() {
49  if (storeManagerPtr) {
50    delete storeManagerPtr;
51    storeManagerPtr = 0;
52  }
53}
54
55StoreManagerLocint::StoreManagerLocint(double * &storePtr, size_t &size, size_t &numlives) : 
56    storePtr(storePtr),
57    indexFeld(0),
58    head(0),
59    groesse(size), anzahl(numlives)
60{
61#ifdef ADOLC_DEBUG
62    std::cerr << "StoreManagerInteger::StoreManagerInteger()\n";
63#endif
64}
65
66StoreManagerLocint::~StoreManagerLocint() 
67{
68#ifdef ADOLC_DEBUG
69    std::cerr << "StoreManagerInteger::~StoreManagerInteger()\n";
70#endif
71    if (storePtr) {
72        delete[] storePtr;
73        storePtr = 0;
74    }
75    if (indexFeld) {
76        delete[] indexFeld;
77        indexFeld = 0;
78    }
79    groesse = 0;
80    anzahl = 0;
81    head = 0;
82}
83
84locint StoreManagerLocint::next_loc() {
85    if (head == 0) {
86      grow();
87    }
88    assert(head);
89    locint const result = head;
90    head = indexFeld[head];
91    ++anzahl;
92#ifdef ADOLC_DEBUG
93    std::cerr << "next_loc: " << result << " fill: " << size() << "max: " << maxSize() << endl;
94#endif
95    return result;
96}
97
98void StoreManagerLocint::free_loc(locint loc) {
99    assert(0 < loc && loc < groesse);
100    indexFeld[loc] = head;
101    head = loc;
102    --anzahl;
103    storePtr[loc] = 0.0;
104#ifdef ADOLC_DEBUG
105    std::cerr << "free_loc: " << loc << " fill: " << size() << "max: " << maxSize() << endl;
106#endif
107}
108
109void StoreManagerLocint::grow() {
110    if (groesse == 0) groesse += initialeGroesse;
111    size_t const alteGroesse = groesse;
112    groesse *= 2;
113
114    if (groesse > std::numeric_limits<locint>::max()) {
115      // encapsulate this error message
116      fprintf(DIAG_OUT,"\nADOL-C error:\n");
117      fprintf(DIAG_OUT,"maximal number (%d) of live active variables exceeded\n\n", 
118              std::numeric_limits<locint>::max());
119      exit(-3);
120    }
121
122#ifdef ADOLC_DEBUG
123    // index 0 is not used, means one slot less
124    std::cerr << "StoreManagerInteger::grow(): increase size from " << alteGroesse
125         << " to " << groesse << " entries (currently " << size() << " entries used)\n";
126    assert(alteGroesse == initialeGroesse or size() == (alteGroesse-1));
127#endif
128
129    double *const oldStore = storePtr;
130    locint *const oldIndex = indexFeld;
131
132#if defined(ADOLC_DEBUG)
133    std::cerr << "StoreManagerInteger::grow(): allocate " << groesse * sizeof(double) << " B doubles " 
134         << "and " << groesse * sizeof(locint) << " B locints\n";
135#endif
136    storePtr = new double[groesse];
137    indexFeld = new locint[groesse];
138    memset(storePtr, 0, groesse*sizeof(double));
139    // we use index 0 as end-of-list marker
140    size_t i = 1;
141    storePtr[0] =  std::numeric_limits<double>::quiet_NaN();
142
143    if (alteGroesse != initialeGroesse) { // not the first time
144#if defined(ADOLC_DEBUG)
145      std::cerr << "StoreManagerInteger::grow(): copy values\n";
146#endif
147      for (size_t j = i; j < alteGroesse; ++j) {
148        indexFeld[j] = oldIndex[j];
149      }
150      for (size_t j = i; j < alteGroesse; ++j) {
151        storePtr[j] = oldStore[j];
152      }
153
154      // reset i to start of new slots (upper half)
155      i = alteGroesse;
156
157#if defined(ADOLC_DEBUG)
158      std::cerr << "StoreManagerInteger::grow(): free " << alteGroesse * sizeof(double)
159                << " + " << alteGroesse * sizeof(locint) << " B\n";
160#endif
161      delete [] oldStore;
162      delete [] oldIndex;
163    }
164
165    head = i;
166    // create initial linked list for new slots
167    for ( ; i < groesse-1; ++i) {
168      indexFeld[i] = i + 1;
169    }
170    indexFeld[i] = 0; // end marker
171    assert(i == groesse-1);
172}
173
174
175/****************************************************************************/
176/* Returns the next free location in "adouble" memory.                      */
177/****************************************************************************/
178locint next_loc() {
179  ADOLC_OPENMP_THREAD_NUMBER;
180  ADOLC_OPENMP_GET_THREAD_NUMBER;
181  return ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr->next_loc();
182}
183
184/****************************************************************************/
185/* frees the specified location in "adouble" memory                         */
186/****************************************************************************/
187void free_loc(locint loc) {
188  ADOLC_OPENMP_THREAD_NUMBER;
189  ADOLC_OPENMP_GET_THREAD_NUMBER;
190  ADOLC_GLOBAL_TAPE_VARS.storeManagerPtr->free_loc(loc);
191}
192
193/* vector of tape infos for all tapes in use */
194vector<TapeInfos *> ADOLC_TAPE_INFOS_BUFFER_DECL;
195
196/* stack of pointers to tape infos
197 * represents the order of tape usage when doing nested taping */
198stack<TapeInfos *> ADOLC_TAPE_STACK_DECL;
199
200/* the main tape info buffer and its fallback */
201TapeInfos ADOLC_CURRENT_TAPE_INFOS_DECL;
202TapeInfos ADOLC_CURRENT_TAPE_INFOS_FALLBACK_DECL;
203
204/* global tapeing variables */
205GlobalTapeVars ADOLC_GLOBAL_TAPE_VARS_DECL;
206
207#if defined(_OPENMP)
208static vector<TapeInfos *> *tapeInfosBuffer_s;
209static stack<TapeInfos *>  *tapeStack_s;
210static TapeInfos           *currentTapeInfos_s;
211static TapeInfos           *currentTapeInfos_fallBack_s;
212static GlobalTapeVars      *globalTapeVars_s;
213static ADOLC_BUFFER_TYPE   *ADOLC_extDiffFctsBuffer_s;
214static stack<StackElement> *ADOLC_checkpointsStack_s;
215static revolve_nums        *revolve_numbers_s;
216
217static vector<TapeInfos *> *tapeInfosBuffer_p;
218static stack<TapeInfos *>  *tapeStack_p;
219static TapeInfos           *currentTapeInfos_p;
220static TapeInfos           *currentTapeInfos_fallBack_p;
221static GlobalTapeVars      *globalTapeVars_p;
222static ADOLC_BUFFER_TYPE   *ADOLC_extDiffFctsBuffer_p;
223static stack<StackElement> *ADOLC_checkpointsStack_p;
224static revolve_nums        *revolve_numbers_p;
225#endif
226
227/*--------------------------------------------------------------------------*/
228/* This function sets the flag "newTape" if either a taylor buffer has been */
229/* created or a taping process has been performed. Calling the function is  */
230/* also useful to "convince" the linker of including the cleaner part into  */
231/* the binary when linking statically!                                      */
232/*--------------------------------------------------------------------------*/
233void markNewTape() {
234    ADOLC_OPENMP_THREAD_NUMBER;
235    ADOLC_OPENMP_GET_THREAD_NUMBER;
236    ADOLC_GLOBAL_TAPE_VARS.newTape = 1;
237}
238
239/* inits the struct for the new tape */
240void initTapeInfos(TapeInfos *newTapeInfos) {
241    char *ptr;
242
243    ptr = (char *)newTapeInfos;
244    for (unsigned int i = 0; i < sizeof(TapeInfos) -
245            sizeof(PersistantTapeInfos); ++i) ptr[i] = 0;
246}
247
248/* as above but keep allocated buffers if possible */
249void initTapeInfos_keep(TapeInfos *newTapeInfos) {
250    unsigned char *opBuffer = newTapeInfos->opBuffer;
251    locint *locBuffer = newTapeInfos->locBuffer;
252    double *valBuffer = newTapeInfos->valBuffer;
253    revreal *tayBuffer = newTapeInfos->tayBuffer;
254    FILE *tay_file = newTapeInfos->tay_file;
255
256    initTapeInfos(newTapeInfos);
257
258    newTapeInfos->opBuffer = opBuffer;
259    newTapeInfos->locBuffer = locBuffer;
260    newTapeInfos->valBuffer = valBuffer;
261    newTapeInfos->tayBuffer = tayBuffer;
262    newTapeInfos->tay_file = tay_file;
263}
264
265/* inits a new tape and updates the tape stack (called from start_trace)
266 * - returns 0 without error
267 * - returns 1 if tapeID was already/still in use */
268int initNewTape(short tapeID) {
269    TapeInfos *newTapeInfos = NULL;
270    bool newTI = false;
271    int retval = 0;
272
273    ADOLC_OPENMP_THREAD_NUMBER;
274    ADOLC_OPENMP_GET_THREAD_NUMBER;
275
276    /* check if tape is in use */
277    vector<TapeInfos *>::iterator tiIter;
278    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
279        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
280                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
281                ++tiIter) {
282            if ((*tiIter)->tapeID==tapeID) {
283                newTapeInfos=*tiIter;
284                if ((*tiIter)->inUse != 0) {
285                    if ((*tiIter)->tapingComplete == 0)
286                        fail(ADOLC_TAPING_TAPE_STILL_IN_USE);
287                    if ( (*tiIter)->stats[OP_FILE_ACCESS]  == 0 &&
288                            (*tiIter)->stats[LOC_FILE_ACCESS] == 0 &&
289                            (*tiIter)->stats[VAL_FILE_ACCESS] == 0  ) {
290#              if defined(ADOLC_DEBUG)
291                        fprintf(DIAG_OUT, "\nADOL-C warning: Tape %d existed in main memory"
292                                " only and gets overwritten!\n\n", tapeID);
293#              endif
294                        /* free associated resources */
295                        retval = 1;
296                    }
297                }
298                if ((*tiIter)->tay_file != NULL)
299                    rewind((*tiIter)->tay_file);
300                initTapeInfos_keep(*tiIter);
301                (*tiIter)->tapeID = tapeID;
302#ifdef SPARSE
303                freeSparseJacInfos(newTapeInfos->pTapeInfos.sJinfos.y,
304                                   newTapeInfos->pTapeInfos.sJinfos.B,
305                                   newTapeInfos->pTapeInfos.sJinfos.JP,
306                                   newTapeInfos->pTapeInfos.sJinfos.g,
307                                   newTapeInfos->pTapeInfos.sJinfos.jr1d,
308                                   newTapeInfos->pTapeInfos.sJinfos.seed_rows,
309                                   newTapeInfos->pTapeInfos.sJinfos.seed_clms,
310                                   newTapeInfos->pTapeInfos.sJinfos.depen);
311                freeSparseHessInfos(newTapeInfos->pTapeInfos.sHinfos.Hcomp, 
312                                    newTapeInfos->pTapeInfos.sHinfos.Xppp, 
313                                    newTapeInfos->pTapeInfos.sHinfos.Yppp, 
314                                    newTapeInfos->pTapeInfos.sHinfos.Zppp, 
315                                    newTapeInfos->pTapeInfos.sHinfos.Upp, 
316                                    newTapeInfos->pTapeInfos.sHinfos.HP,
317                                    newTapeInfos->pTapeInfos.sHinfos.g, 
318                                    newTapeInfos->pTapeInfos.sHinfos.hr, 
319                                    newTapeInfos->pTapeInfos.sHinfos.p, 
320                                    newTapeInfos->pTapeInfos.sHinfos.indep);   
321                newTapeInfos->pTapeInfos.inJacSparseUse=0;
322                newTapeInfos->pTapeInfos.inHessSparseUse=0;
323                newTapeInfos->pTapeInfos.sJinfos.B=NULL;
324                newTapeInfos->pTapeInfos.sJinfos.y=NULL;
325                newTapeInfos->pTapeInfos.sJinfos.g=NULL;
326                newTapeInfos->pTapeInfos.sJinfos.jr1d=NULL;
327                newTapeInfos->pTapeInfos.sJinfos.Seed=NULL;
328                newTapeInfos->pTapeInfos.sJinfos.JP=NULL;
329                newTapeInfos->pTapeInfos.sJinfos.depen=0;
330                newTapeInfos->pTapeInfos.sJinfos.nnz_in=0;
331                newTapeInfos->pTapeInfos.sJinfos.seed_rows=0;
332                newTapeInfos->pTapeInfos.sJinfos.seed_clms=0;
333                newTapeInfos->pTapeInfos.sHinfos.Zppp=NULL;
334                newTapeInfos->pTapeInfos.sHinfos.Yppp=NULL;
335                newTapeInfos->pTapeInfos.sHinfos.Xppp=NULL;
336                newTapeInfos->pTapeInfos.sHinfos.Upp=NULL;
337                newTapeInfos->pTapeInfos.sHinfos.Hcomp=NULL;
338                newTapeInfos->pTapeInfos.sHinfos.HP=NULL;
339                newTapeInfos->pTapeInfos.sHinfos.g=NULL;
340                newTapeInfos->pTapeInfos.sHinfos.hr=NULL;
341                newTapeInfos->pTapeInfos.sHinfos.nnz_in=0;
342                newTapeInfos->pTapeInfos.sHinfos.indep=0;
343                newTapeInfos->pTapeInfos.sHinfos.p=0;
344#endif
345                break;
346            }
347        }
348    }
349
350    /* create new info struct and initialize it */
351    if (newTapeInfos == NULL) {
352        newTapeInfos = new TapeInfos(tapeID);
353        newTI = true;
354    }
355    newTapeInfos->traceFlag=1;
356    newTapeInfos->inUse=1;
357#ifdef SPARSE
358    newTapeInfos->pTapeInfos.inJacSparseUse=0;
359    newTapeInfos->pTapeInfos.inHessSparseUse=0;
360    newTapeInfos->pTapeInfos.sJinfos.B=NULL;
361    newTapeInfos->pTapeInfos.sJinfos.y=NULL;
362    newTapeInfos->pTapeInfos.sJinfos.g=NULL;
363    newTapeInfos->pTapeInfos.sJinfos.jr1d=NULL;
364    newTapeInfos->pTapeInfos.sJinfos.Seed=NULL;
365    newTapeInfos->pTapeInfos.sJinfos.JP=NULL;
366    newTapeInfos->pTapeInfos.sJinfos.depen=0;
367    newTapeInfos->pTapeInfos.sJinfos.nnz_in=0;
368    newTapeInfos->pTapeInfos.sJinfos.seed_rows=0;
369    newTapeInfos->pTapeInfos.sJinfos.seed_clms=0;
370    newTapeInfos->pTapeInfos.sHinfos.Zppp=NULL;
371    newTapeInfos->pTapeInfos.sHinfos.Yppp=NULL;
372    newTapeInfos->pTapeInfos.sHinfos.Xppp=NULL;
373    newTapeInfos->pTapeInfos.sHinfos.Upp=NULL;
374    newTapeInfos->pTapeInfos.sHinfos.Hcomp=NULL;
375    newTapeInfos->pTapeInfos.sHinfos.HP=NULL;
376    newTapeInfos->pTapeInfos.sHinfos.g=NULL;
377    newTapeInfos->pTapeInfos.sHinfos.hr=NULL;
378    newTapeInfos->pTapeInfos.sHinfos.nnz_in=0;
379    newTapeInfos->pTapeInfos.sHinfos.indep=0;
380    newTapeInfos->pTapeInfos.sHinfos.p=0;
381#endif
382
383    newTapeInfos->stats[OP_BUFFER_SIZE] =
384        ADOLC_GLOBAL_TAPE_VARS.operationBufferSize;
385    newTapeInfos->stats[LOC_BUFFER_SIZE] =
386        ADOLC_GLOBAL_TAPE_VARS.locationBufferSize;
387    newTapeInfos->stats[VAL_BUFFER_SIZE] =
388        ADOLC_GLOBAL_TAPE_VARS.valueBufferSize;
389    newTapeInfos->stats[TAY_BUFFER_SIZE] =
390        ADOLC_GLOBAL_TAPE_VARS.taylorBufferSize;
391
392    /* update tapeStack and save tapeInfos */
393    if (ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr != NULL) {
394        memcpy(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr,
395                &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
396        ADOLC_TAPE_STACK.push(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
397    } else {
398        memcpy(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK,
399                &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
400        ADOLC_TAPE_STACK.push(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK);
401    }
402    if (newTI) ADOLC_TAPE_INFOS_BUFFER.push_back(newTapeInfos);
403
404    /* set the new tape infos as current */
405    memcpy(&ADOLC_CURRENT_TAPE_INFOS, newTapeInfos, sizeof(TapeInfos));
406    ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = newTapeInfos;
407
408    return retval;
409}
410
411/* opens an existing tape or creates a new handle for a tape on hard disk
412 * - called from init_for_sweep and init_rev_sweep */
413void openTape(short tapeID, char mode) {
414    TapeInfos *tempTapeInfos=NULL;
415
416    ADOLC_OPENMP_THREAD_NUMBER;
417    ADOLC_OPENMP_GET_THREAD_NUMBER;
418
419    /* check if tape information exist in memory */
420    vector<TapeInfos *>::iterator tiIter;
421    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
422        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
423                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
424                ++tiIter) {
425            if ((*tiIter)->tapeID == tapeID) {
426                /* tape has been used before (in the current program) */
427                if ((*tiIter)->inUse == 0) {
428                    /* forward sweep */
429                    if ((*tiIter)->tay_file != NULL)
430                        rewind((*tiIter)->tay_file);
431                    initTapeInfos_keep(*tiIter);
432                    (*tiIter)->traceFlag=1;
433                    (*tiIter)->tapeID = tapeID;
434                    (*tiIter)->tapingComplete = 1;
435                    (*tiIter)->inUse = 1;
436                    read_tape_stats(*tiIter);
437               }
438                if (ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr != NULL) {
439                    memcpy(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr,
440                            &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
441                    ADOLC_TAPE_STACK.push(
442                            ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
443                } else {
444                    memcpy(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK,
445                            &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
446                    ADOLC_TAPE_STACK.push(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK);
447                }
448                memcpy(&ADOLC_CURRENT_TAPE_INFOS, *tiIter, sizeof(TapeInfos));
449                ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = *tiIter;
450                return;
451            }
452        }
453    }
454
455    /* tapeID not used so far */
456    if (mode == ADOLC_REVERSE) {
457        failAdditionalInfo1 = tapeID;
458        fail(ADOLC_REVERSE_NO_TAYLOR_STACK);
459    }
460
461    /* create new info struct and initialize it */
462    tempTapeInfos = new TapeInfos(tapeID);
463    tempTapeInfos->traceFlag=1;
464    tempTapeInfos->inUse = 1;
465    tempTapeInfos->tapingComplete = 1;
466    ADOLC_TAPE_INFOS_BUFFER.push_back(tempTapeInfos);
467
468    read_tape_stats(tempTapeInfos);
469    /* update tapeStack and save tapeInfos */
470    if (ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr != NULL) {
471        memcpy(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr,
472                &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
473        ADOLC_TAPE_STACK.push(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
474    } else {
475        memcpy(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK,
476                &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
477        ADOLC_TAPE_STACK.push(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK);
478    }
479
480    /* set the new tape infos as current */
481    memcpy(&ADOLC_CURRENT_TAPE_INFOS, tempTapeInfos, sizeof(TapeInfos));
482    ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = tempTapeInfos;
483}
484
485/* release the current tape and give control to the previous one */
486void releaseTape() {
487    ADOLC_OPENMP_THREAD_NUMBER;
488    ADOLC_OPENMP_GET_THREAD_NUMBER;
489
490    /* if operations, locations and constants tapes have been written and value
491     * stack information have not been created tapeInfos are no longer needed*/
492    if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors            == 0 &&
493            ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS]  == 1 &&
494            ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] == 1 &&
495            ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] == 1 ) {
496        ADOLC_CURRENT_TAPE_INFOS.inUse = 0;
497    }
498
499    memcpy(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr,
500            &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
501    ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = ADOLC_TAPE_STACK.top();
502    memcpy(&ADOLC_CURRENT_TAPE_INFOS,
503            ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr, sizeof(TapeInfos));
504    ADOLC_TAPE_STACK.pop();
505    if (ADOLC_TAPE_STACK.empty())
506        ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = NULL;
507}
508
509/* updates the tape infos for the given ID - a tapeInfos struct is created
510 * and registered if non is found but its state will remain "not in use" */
511TapeInfos *getTapeInfos(short tapeID) {
512    TapeInfos *tapeInfos;
513    vector<TapeInfos *>::iterator tiIter;
514
515    ADOLC_OPENMP_THREAD_NUMBER;
516    ADOLC_OPENMP_GET_THREAD_NUMBER;
517
518    /* check if TapeInfos for tapeID exist */
519    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
520        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
521                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
522                ++tiIter) {
523            if ((*tiIter)->tapeID==tapeID) {
524                tapeInfos=*tiIter;
525                if (tapeInfos->inUse==0) read_tape_stats(tapeInfos);
526                return tapeInfos;
527            }
528        }
529    }
530    /* create new TapeInfos, initialize and update tapeInfosBuffer */
531    tapeInfos = new TapeInfos(tapeID);
532    ADOLC_TAPE_INFOS_BUFFER.push_back(tapeInfos);
533    tapeInfos->traceFlag=1;
534    tapeInfos->inUse=0;
535#ifdef SPARSE
536    tapeInfos->pTapeInfos.inJacSparseUse=0;
537    tapeInfos->pTapeInfos.inHessSparseUse=0;
538#endif
539    tapeInfos->tapingComplete = 1;
540    read_tape_stats(tapeInfos);
541    return tapeInfos;
542}
543
544#ifdef SPARSE
545/* updates the tape infos on sparse Jac for the given ID  */
546void setTapeInfoJacSparse(short tapeID, SparseJacInfos sJinfos) {
547    TapeInfos *tapeInfos;
548    vector<TapeInfos *>::iterator tiIter;
549
550    ADOLC_OPENMP_THREAD_NUMBER;
551    ADOLC_OPENMP_GET_THREAD_NUMBER;
552
553    /* check if TapeInfos for tapeID exist */
554    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
555        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
556                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
557                ++tiIter) {
558            if ((*tiIter)->tapeID==tapeID) {
559                tapeInfos=*tiIter;
560                // free memory of tape entry that had been used previously
561                freeSparseJacInfos(tapeInfos->pTapeInfos.sJinfos.y,
562                        tapeInfos->pTapeInfos.sJinfos.B,
563                        tapeInfos->pTapeInfos.sJinfos.JP,
564                        tapeInfos->pTapeInfos.sJinfos.g,
565                        tapeInfos->pTapeInfos.sJinfos.jr1d,
566                        tapeInfos->pTapeInfos.sJinfos.seed_rows,
567                        tapeInfos->pTapeInfos.sJinfos.seed_clms,
568                        tapeInfos->pTapeInfos.sJinfos.depen);
569                tapeInfos->pTapeInfos.sJinfos.y=sJinfos.y;
570                tapeInfos->pTapeInfos.sJinfos.Seed=sJinfos.Seed;
571                tapeInfos->pTapeInfos.sJinfos.B=sJinfos.B;
572                tapeInfos->pTapeInfos.sJinfos.JP=sJinfos.JP;
573                tapeInfos->pTapeInfos.sJinfos.depen=sJinfos.depen;
574                tapeInfos->pTapeInfos.sJinfos.nnz_in=sJinfos.nnz_in;
575                tapeInfos->pTapeInfos.sJinfos.seed_clms=sJinfos.seed_clms;
576                tapeInfos->pTapeInfos.sJinfos.seed_rows=sJinfos.seed_rows;
577                tapeInfos->pTapeInfos.sJinfos.g=sJinfos.g;
578                tapeInfos->pTapeInfos.sJinfos.jr1d=sJinfos.jr1d;
579            }
580        }
581    }
582}
583#endif
584
585#ifdef SPARSE
586/* updates the tape infos on sparse Hess for the given ID  */
587void setTapeInfoHessSparse(short tapeID, SparseHessInfos sHinfos) {
588    TapeInfos *tapeInfos;
589    vector<TapeInfos *>::iterator tiIter;
590
591    ADOLC_OPENMP_THREAD_NUMBER;
592    ADOLC_OPENMP_GET_THREAD_NUMBER;
593
594    /* check if TapeInfos for tapeID exist */
595    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
596        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
597                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
598                ++tiIter) {
599            if ((*tiIter)->tapeID==tapeID) {
600                tapeInfos=*tiIter;
601                // free memory of tape entry that had been used previously
602                    freeSparseHessInfos(tapeInfos->pTapeInfos.sHinfos.Hcomp, 
603                                        tapeInfos->pTapeInfos.sHinfos.Xppp, 
604                                        tapeInfos->pTapeInfos.sHinfos.Yppp, 
605                                        tapeInfos->pTapeInfos.sHinfos.Zppp, 
606                                        tapeInfos->pTapeInfos.sHinfos.Upp, 
607                                        tapeInfos->pTapeInfos.sHinfos.HP,
608                                        tapeInfos->pTapeInfos.sHinfos.g, 
609                                        tapeInfos->pTapeInfos.sHinfos.hr, 
610                                        tapeInfos->pTapeInfos.sHinfos.p, 
611                                        tapeInfos->pTapeInfos.sHinfos.indep);   
612                    tapeInfos->pTapeInfos.sHinfos.Hcomp=sHinfos.Hcomp;
613                    tapeInfos->pTapeInfos.sHinfos.Xppp=sHinfos.Xppp;
614                    tapeInfos->pTapeInfos.sHinfos.Yppp=sHinfos.Yppp;
615                    tapeInfos->pTapeInfos.sHinfos.Zppp=sHinfos.Zppp;
616                    tapeInfos->pTapeInfos.sHinfos.Upp=sHinfos.Upp;
617                    tapeInfos->pTapeInfos.sHinfos.HP=sHinfos.HP;
618                    tapeInfos->pTapeInfos.sHinfos.indep=sHinfos.indep;
619                    tapeInfos->pTapeInfos.sHinfos.nnz_in=sHinfos.nnz_in;
620                    tapeInfos->pTapeInfos.sHinfos.p=sHinfos.p;
621                    tapeInfos->pTapeInfos.sHinfos.g=sHinfos.g;
622                    tapeInfos->pTapeInfos.sHinfos.hr=sHinfos.hr;
623            }
624        }
625    }
626}
627#endif
628
629void init() {
630    ADOLC_OPENMP_THREAD_NUMBER;
631    errno = 0;
632    ADOLC_OPENMP_GET_THREAD_NUMBER;
633
634#if defined(_OPENMP)
635    tapeInfosBuffer = new vector<TapeInfos *>;
636    tapeStack = new stack<TapeInfos *>;
637    currentTapeInfos = new TapeInfos;
638    currentTapeInfos->tapingComplete = 1;
639    currentTapeInfos_fallBack = new TapeInfos;
640    globalTapeVars = new GlobalTapeVars;
641    ADOLC_extDiffFctsBuffer = new ADOLC_BUFFER_TYPE;
642    ADOLC_checkpointsStack = new stack<StackElement>;
643    revolve_numbers = new revolve_nums;
644#endif /* _OPENMP */
645
646    ADOLC_CURRENT_TAPE_INFOS.traceFlag = 0;
647    ADOLC_CURRENT_TAPE_INFOS.keepTaylors = 0;
648
649    ADOLC_GLOBAL_TAPE_VARS.maxLoc=1;
650    for (uint i=0; i<sizeof(locint)*8-1; ++i) {
651        ADOLC_GLOBAL_TAPE_VARS.maxLoc<<=1;
652        ++ADOLC_GLOBAL_TAPE_VARS.maxLoc;
653    }
654    ADOLC_GLOBAL_TAPE_VARS.inParallelRegion = 0;
655    ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = NULL;
656    ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = 1;
657
658    adolc_id.adolc_ver    = ADOLC_VERSION;
659    adolc_id.adolc_sub    = ADOLC_SUBVERSION;
660    adolc_id.adolc_lvl    = ADOLC_PATCHLEVEL;
661    adolc_id.locint_size  = sizeof(locint);
662    adolc_id.revreal_size = sizeof(revreal);
663
664    ADOLC_EXT_DIFF_FCTS_BUFFER.init(init_CpInfos);
665}
666
667/* does things like closing/removing temporary files, ... */
668void cleanUp() {
669    ADOLC_OPENMP_THREAD_NUMBER;
670    ADOLC_OPENMP_GET_THREAD_NUMBER;
671
672    vector<TapeInfos *>::iterator tiIter;
673    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
674        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
675                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
676                ++tiIter)
677        {
678            /* close open files though they may be incomplete */
679            if ((*tiIter)->op_file!=NULL)
680            {
681                fclose((*tiIter)->op_file);
682                (*tiIter)->op_file = NULL;
683            }
684            if ((*tiIter)->val_file!=NULL)
685            {
686                fclose((*tiIter)->val_file);
687                (*tiIter)->val_file = NULL;
688            }
689            if ((*tiIter)->loc_file!=NULL)
690            {
691                fclose((*tiIter)->loc_file);
692                (*tiIter)->loc_file = NULL;
693            }
694            if ((*tiIter)->tay_file!=NULL) {
695                fclose((*tiIter)->tay_file);
696                (*tiIter)->tay_file = NULL;
697                remove((*tiIter)->pTapeInfos.tay_fileName);
698            }
699            if ((*tiIter)->opBuffer != NULL)
700            {
701                free((*tiIter)->opBuffer);
702                (*tiIter)->opBuffer = NULL;
703            }
704            if ((*tiIter)->valBuffer != NULL)
705            {
706                free((*tiIter)->valBuffer);
707                (*tiIter)->valBuffer = NULL;
708            }
709            if ((*tiIter)->locBuffer != NULL)
710            {
711                free((*tiIter)->locBuffer);
712                (*tiIter)->locBuffer = NULL;
713            }
714            if ((*tiIter)->tayBuffer != NULL)
715            {
716                free((*tiIter)->tayBuffer);
717                (*tiIter)->tayBuffer = NULL;
718            }
719
720#ifdef SPARSE
721            freeSparseJacInfos((*tiIter)->pTapeInfos.sJinfos.y,
722                               (*tiIter)->pTapeInfos.sJinfos.B,
723                               (*tiIter)->pTapeInfos.sJinfos.JP,
724                               (*tiIter)->pTapeInfos.sJinfos.g,
725                               (*tiIter)->pTapeInfos.sJinfos.jr1d,
726                               (*tiIter)->pTapeInfos.sJinfos.seed_rows,
727                               (*tiIter)->pTapeInfos.sJinfos.seed_clms,
728                               (*tiIter)->pTapeInfos.sJinfos.depen);
729            freeSparseHessInfos((*tiIter)->pTapeInfos.sHinfos.Hcomp, 
730                                (*tiIter)->pTapeInfos.sHinfos.Xppp, 
731                                (*tiIter)->pTapeInfos.sHinfos.Yppp, 
732                                (*tiIter)->pTapeInfos.sHinfos.Zppp, 
733                                (*tiIter)->pTapeInfos.sHinfos.Upp, 
734                                (*tiIter)->pTapeInfos.sHinfos.HP,
735                                (*tiIter)->pTapeInfos.sHinfos.g, 
736                                (*tiIter)->pTapeInfos.sHinfos.hr, 
737                                (*tiIter)->pTapeInfos.sHinfos.p, 
738                                (*tiIter)->pTapeInfos.sHinfos.indep);   
739#endif
740
741            /* remove "main" tape files if not all three have been written */
742            int filesWritten = (*tiIter)->stats[OP_FILE_ACCESS] +
743                (*tiIter)->stats[LOC_FILE_ACCESS] +
744                (*tiIter)->stats[VAL_FILE_ACCESS];
745            if ( (filesWritten > 0) && ((*tiIter)->pTapeInfos.keepTape == 0) )
746            {
747                /* try to remove all tapes (even those not written by this
748                 * run) => this ensures that there is no mixture of tapes from
749                 * different ADOLC runs */
750                if ( (*tiIter)->stats[OP_FILE_ACCESS] == 1 )
751                    remove((*tiIter)->pTapeInfos.op_fileName);
752                if ( (*tiIter)->stats[LOC_FILE_ACCESS] == 1 )
753                    remove((*tiIter)->pTapeInfos.loc_fileName);
754                if ( (*tiIter)->stats[VAL_FILE_ACCESS] == 1 )
755                    remove((*tiIter)->pTapeInfos.val_fileName);
756            }
757            if ((*tiIter)->pTapeInfos.op_fileName != NULL)
758            {
759                free((*tiIter)->pTapeInfos.op_fileName);
760                (*tiIter)->pTapeInfos.op_fileName = NULL;
761            }
762            if ((*tiIter)->pTapeInfos.val_fileName != NULL)
763            {
764                free((*tiIter)->pTapeInfos.val_fileName);
765                (*tiIter)->pTapeInfos.val_fileName = NULL;
766            }
767            if ((*tiIter)->pTapeInfos.loc_fileName != NULL)
768            {
769                free((*tiIter)->pTapeInfos.loc_fileName);
770                (*tiIter)->pTapeInfos.loc_fileName = NULL;
771            }
772            if ((*tiIter)->pTapeInfos.tay_fileName != NULL)
773            {
774                free((*tiIter)->pTapeInfos.tay_fileName);
775                (*tiIter)->pTapeInfos.tay_fileName = NULL;
776            }
777
778            delete *tiIter;
779        }
780    }
781
782    cp_clearStack();
783
784    if (ADOLC_GLOBAL_TAPE_VARS.store != NULL) {
785        delete[] ADOLC_GLOBAL_TAPE_VARS.store;
786        ADOLC_GLOBAL_TAPE_VARS.store = NULL;
787    }
788
789#if defined(_OPENMP)
790    if (ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 0) {
791        /* cleanup on program exit */
792        delete revolve_numbers;
793        delete ADOLC_checkpointsStack;
794        delete ADOLC_extDiffFctsBuffer;
795        delete globalTapeVars;
796        delete currentTapeInfos;
797        delete currentTapeInfos_fallBack;
798        delete tapeStack;
799        delete tapeInfosBuffer;
800    }
801#endif
802
803    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
804    clearTapeBaseNames();
805}
806
807int removeTape(short tapeID, short type) {
808    TapeInfos *tapeInfos = NULL;
809    vector<TapeInfos *>::iterator tiIter;
810    ADOLC_OPENMP_THREAD_NUMBER;
811    ADOLC_OPENMP_GET_THREAD_NUMBER;
812
813    /* check if TapeInfos for tapeID exist */
814    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
815        for (tiIter = ADOLC_TAPE_INFOS_BUFFER.begin();
816                tiIter != ADOLC_TAPE_INFOS_BUFFER.end();
817                ++tiIter)
818        {
819            if ((*tiIter)->tapeID == tapeID) {
820                tapeInfos = *tiIter;
821                if (tapeInfos->tapingComplete == 0) return -1;
822                ADOLC_TAPE_INFOS_BUFFER.erase(tiIter);
823                break;
824            }
825        }
826    }
827
828    if (tapeInfos == NULL) { // might be on disk only
829        tapeInfos = new TapeInfos(tapeID);
830        tapeInfos->tapingComplete = 1;
831    }
832
833    freeTapeResources(tapeInfos);
834#ifdef SPARSE
835    freeSparseJacInfos(tapeInfos->pTapeInfos.sJinfos.y,
836                       tapeInfos->pTapeInfos.sJinfos.B,
837                       tapeInfos->pTapeInfos.sJinfos.JP,
838                       tapeInfos->pTapeInfos.sJinfos.g,
839                       tapeInfos->pTapeInfos.sJinfos.jr1d,
840                       tapeInfos->pTapeInfos.sJinfos.seed_rows,
841                       tapeInfos->pTapeInfos.sJinfos.seed_clms,
842                       tapeInfos->pTapeInfos.sJinfos.depen);
843    freeSparseHessInfos(tapeInfos->pTapeInfos.sHinfos.Hcomp, 
844                        tapeInfos->pTapeInfos.sHinfos.Xppp, 
845                        tapeInfos->pTapeInfos.sHinfos.Yppp, 
846                        tapeInfos->pTapeInfos.sHinfos.Zppp, 
847                        tapeInfos->pTapeInfos.sHinfos.Upp, 
848                        tapeInfos->pTapeInfos.sHinfos.HP,
849                        tapeInfos->pTapeInfos.sHinfos.g, 
850                        tapeInfos->pTapeInfos.sHinfos.hr, 
851                        tapeInfos->pTapeInfos.sHinfos.p, 
852                        tapeInfos->pTapeInfos.sHinfos.indep);   
853#endif
854    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
855
856    if (type == ADOLC_REMOVE_COMPLETELY) {
857        remove(tapeInfos->pTapeInfos.op_fileName);
858        remove(tapeInfos->pTapeInfos.loc_fileName);
859        remove(tapeInfos->pTapeInfos.val_fileName);
860    }
861
862    free(tapeInfos->pTapeInfos.op_fileName);
863    free(tapeInfos->pTapeInfos.val_fileName);
864    free(tapeInfos->pTapeInfos.loc_fileName);
865    if (tapeInfos->pTapeInfos.tay_fileName != NULL)
866        free(tapeInfos->pTapeInfos.tay_fileName);
867
868    delete tapeInfos;
869
870    return 0;
871}
872
873/****************************************************************************/
874/* Initialization for the taping process. Creates buffers for this tape,    */
875/* sets files names, and calls appropriate setup routines.                  */
876/****************************************************************************/
877int trace_on(short tnum, int keepTaylors) {
878    int retval = 0;
879    ADOLC_OPENMP_THREAD_NUMBER;
880    ADOLC_OPENMP_GET_THREAD_NUMBER;
881
882    /* allocate memory for TapeInfos and update tapeStack */
883    retval = initNewTape(tnum);
884    ADOLC_CURRENT_TAPE_INFOS.keepTaylors=keepTaylors;
885    if (keepTaylors!=0) ADOLC_CURRENT_TAPE_INFOS.deg_save=1;
886    start_trace();
887    take_stock();               /* record all existing adoubles on the tape */
888    return retval;
889}
890
891int trace_on(short tnum, int keepTaylors,
892        uint obs, uint lbs, uint vbs, uint tbs)
893{
894    int retval = 0;
895    ADOLC_OPENMP_THREAD_NUMBER;
896    ADOLC_OPENMP_GET_THREAD_NUMBER;
897
898    /* allocate memory for TapeInfos and update tapeStack */
899    retval = initNewTape(tnum);
900    ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE] = obs;
901    ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE] = lbs;
902    ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE] = vbs;
903    ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE] = tbs;
904    ADOLC_CURRENT_TAPE_INFOS.keepTaylors=keepTaylors;
905    if (keepTaylors!=0) ADOLC_CURRENT_TAPE_INFOS.deg_save=1;
906    start_trace();
907    take_stock();               /* record all existing adoubles on the tape */
908    return retval;
909}
910
911/****************************************************************************/
912/* Stop Tracing. Cleans up, and turns off trace_flag. Flag not equal zero   */
913/* enforces writing of the three main tape files (op+loc+val).              */
914/****************************************************************************/
915void trace_off(int flag) {
916    ADOLC_OPENMP_THREAD_NUMBER;
917    ADOLC_OPENMP_GET_THREAD_NUMBER;
918    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.keepTape = flag;
919    keep_stock();         /* copy remaining live variables + trace_flag = 0 */
920    stop_trace(flag);
921    cout.flush();
922    ADOLC_CURRENT_TAPE_INFOS.tapingComplete = 1;
923    releaseTape();
924}
925
926bool isTaping() {
927    ADOLC_OPENMP_THREAD_NUMBER;
928    ADOLC_OPENMP_GET_THREAD_NUMBER;
929    return ADOLC_CURRENT_TAPE_INFOS.traceFlag != 0;
930}
931
932
933
934/****************************************************************************/
935/* A class for initialization/finalization and OpenMP handling              */
936/****************************************************************************/
937class Keeper {
938    public:
939        inline Keeper() {
940            dummy = 0;
941            init();
942            readConfigFile();
943        }
944        inline ~Keeper() {
945            cleanUp();
946        }
947
948        inline void touch() {
949            dummy = 1;
950        }
951
952    private:
953        int dummy;
954};
955
956/* a static instance that does all work */
957static Keeper theKeeper;
958
959/**
960 * Hope to convince the linker to link the keeper code into the executable. */
961void initADOLC() {
962    theKeeper.touch();
963}
964
965/****************************************************************************/
966/****************************************************************************/
967/* The following is necessary to provide a separate ADOL-C environment for  */
968/* each OpenMP worker.                                                      */
969/****************************************************************************/
970/****************************************************************************/
971#if defined(_OPENMP)
972#include "adolc_openmp.h"
973
974ADOLC_OpenMP ADOLC_OpenMP_Handler;
975ADOLC_OpenMP_NC ADOLC_OpenMP_Handler_NC;
976int ADOLC_parallel_doCopy;
977
978static bool waitForMaster_begin = true;
979static bool waitForMaster_end   = true;
980static bool firstParallel       = true;
981
982/****************************************************************************/
983/* Used by OpenMP to create a separate environment for every worker thread. */
984/****************************************************************************/
985void beginParallel() {
986    ADOLC_OPENMP_THREAD_NUMBER;
987#if defined(ADOLC_THREADSAVE_ERRNO)
988    errno = omp_get_thread_num();
989#endif
990    ADOLC_OPENMP_GET_THREAD_NUMBER;
991
992    if (ADOLC_threadNumber == 0) { /* master only */
993        int numThreads = omp_get_num_threads();
994
995        tapeInfosBuffer_s           = tapeInfosBuffer;
996        tapeStack_s                 = tapeStack;
997        currentTapeInfos_s          = currentTapeInfos;
998        currentTapeInfos_fallBack_s = currentTapeInfos_fallBack;
999        globalTapeVars_s            = globalTapeVars;
1000        ADOLC_extDiffFctsBuffer_s   = ADOLC_extDiffFctsBuffer;
1001        ADOLC_checkpointsStack_s    = ADOLC_checkpointsStack;
1002        revolve_numbers_s           = revolve_numbers;
1003
1004        if (firstParallel) {
1005            tapeInfosBuffer           = new vector<TapeInfos *>[numThreads];
1006            tapeStack                 = new stack<TapeInfos *>[numThreads];
1007            currentTapeInfos          = new TapeInfos[numThreads];
1008            currentTapeInfos_fallBack = new TapeInfos[numThreads];
1009            globalTapeVars            = new GlobalTapeVars[numThreads];
1010            ADOLC_extDiffFctsBuffer   = new ADOLC_BUFFER_TYPE[numThreads];
1011            ADOLC_checkpointsStack    = new stack<StackElement>[numThreads];
1012            revolve_numbers           = new revolve_nums[numThreads];
1013        } else {
1014            tapeInfosBuffer           = tapeInfosBuffer_p;
1015            tapeStack                 = tapeStack_p;
1016            currentTapeInfos          = currentTapeInfos_p;
1017            currentTapeInfos_fallBack = currentTapeInfos_fallBack_p;
1018            globalTapeVars            = globalTapeVars_p;
1019            ADOLC_extDiffFctsBuffer   = ADOLC_extDiffFctsBuffer_p;
1020            ADOLC_checkpointsStack    = ADOLC_checkpointsStack_p;
1021            revolve_numbers         = revolve_numbers_p;
1022        }
1023
1024        /* - set inParallelRegion for tmpGlobalTapeVars because it is source
1025         *   for initializing the parallel globalTapeVars structs
1026         * - inParallelRegion has to be set to one for all workers by master.
1027         *   This is necessary, to deter a speedy master from assuming all
1028         *   workers are done, in endParallel, before they even leaved
1029         *   beginParallel. */
1030        globalTapeVars_s[0].inParallelRegion = 1;
1031        for (int i = 0; i < numThreads; ++i)
1032            globalTapeVars[i].inParallelRegion = 1;
1033
1034        waitForMaster_end = true;
1035        waitForMaster_begin = false;
1036    } else 
1037        while (waitForMaster_begin) {
1038            usleep(1000); /* if anyone knows a better value, ... :-) */
1039        }
1040
1041    if (firstParallel) {
1042        ADOLC_EXT_DIFF_FCTS_BUFFER.init(init_CpInfos);
1043        memcpy(&ADOLC_GLOBAL_TAPE_VARS, globalTapeVars_s, sizeof(GlobalTapeVars));
1044        ADOLC_GLOBAL_TAPE_VARS.store = (double *)
1045            malloc(sizeof(double) * ADOLC_GLOBAL_TAPE_VARS.storeSize);
1046        memcpy(ADOLC_GLOBAL_TAPE_VARS.store, globalTapeVars_s->store,
1047                ADOLC_GLOBAL_TAPE_VARS.locMinUnused * sizeof(double));
1048        ADOLC_GLOBAL_TAPE_VARS.newTape = 0;
1049        ADOLC_CURRENT_TAPE_INFOS.tapingComplete = 1;
1050        ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = NULL;
1051    } else {
1052        if (ADOLC_parallel_doCopy) {
1053            ADOLC_GLOBAL_TAPE_VARS.locMinUnused = globalTapeVars_s->locMinUnused;
1054            ADOLC_GLOBAL_TAPE_VARS.numMaxAlive = globalTapeVars_s->numMaxAlive;
1055            ADOLC_GLOBAL_TAPE_VARS.storeSize = globalTapeVars_s->storeSize;
1056            ADOLC_GLOBAL_TAPE_VARS.numToFree = globalTapeVars_s->numToFree;
1057            ADOLC_GLOBAL_TAPE_VARS.minLocToFree = globalTapeVars_s->minLocToFree;
1058            ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = globalTapeVars_s->branchSwitchWarning;
1059            free(ADOLC_GLOBAL_TAPE_VARS.store);
1060            ADOLC_GLOBAL_TAPE_VARS.store = (double *)
1061                malloc(sizeof(double) * ADOLC_GLOBAL_TAPE_VARS.storeSize);
1062            memcpy(ADOLC_GLOBAL_TAPE_VARS.store, globalTapeVars_s->store,
1063                    ADOLC_GLOBAL_TAPE_VARS.locMinUnused * sizeof(double));
1064        }
1065    }
1066}
1067
1068/****************************************************************************/
1069/* Used by OpenMP to destroy the separate environment of every worker.      */
1070/****************************************************************************/
1071/* There are n+1 instances of ADOLC_OpenMP => n within the parallel region
1072 * and one in the serial part! */
1073void endParallel() {
1074    ADOLC_OPENMP_THREAD_NUMBER;
1075    ADOLC_OPENMP_GET_THREAD_NUMBER;
1076
1077    /* do nothing if called at program exit (serial part) */
1078    if (ADOLC_threadNumber == 0 &&
1079            ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 0) return;
1080
1081    ADOLC_GLOBAL_TAPE_VARS.inParallelRegion = 0;
1082
1083    if (ADOLC_threadNumber == 0) { /* master only */
1084        int num;
1085        int numThreads = omp_get_num_threads();
1086        bool firstIt = true;
1087        do { /* wait until all slaves have left the parallel part */
1088            if (firstIt) firstIt = false;
1089            else usleep(1000); /* no busy waiting */
1090            num = 1;
1091            for (int i = 1; i < numThreads; ++i)
1092                if (globalTapeVars[i].inParallelRegion == 0) ++num;
1093        } while (num != numThreads);
1094
1095        firstParallel = false;
1096
1097        revolve_numbers_p           = revolve_numbers;
1098        ADOLC_checkpointsStack_p    = ADOLC_checkpointsStack;
1099        ADOLC_extDiffFctsBuffer_p   = ADOLC_extDiffFctsBuffer;
1100        globalTapeVars_p            = globalTapeVars;
1101        currentTapeInfos_p          = currentTapeInfos;
1102        currentTapeInfos_fallBack_p = currentTapeInfos_fallBack;
1103        tapeStack_p                 = tapeStack;
1104        tapeInfosBuffer_p           = tapeInfosBuffer;
1105
1106        revolve_numbers           = revolve_numbers_s;
1107        ADOLC_checkpointsStack    = ADOLC_checkpointsStack_s;
1108        ADOLC_extDiffFctsBuffer   = ADOLC_extDiffFctsBuffer_s;
1109        globalTapeVars            = globalTapeVars_s;
1110        currentTapeInfos          = currentTapeInfos_s;
1111        currentTapeInfos_fallBack = currentTapeInfos_fallBack_s;
1112        tapeStack                 = tapeStack_s;
1113        tapeInfosBuffer           = tapeInfosBuffer_s;
1114
1115        ADOLC_GLOBAL_TAPE_VARS.inParallelRegion = 0;
1116        waitForMaster_begin = true;
1117        waitForMaster_end = false;
1118    } else
1119        while (waitForMaster_end) {
1120            usleep(1000); // no busy waiting
1121        }
1122}
1123
1124#endif /* _OPENMP */
1125
1126TapeInfos::TapeInfos() {
1127    initTapeInfos(this);
1128}
1129
1130TapeInfos::TapeInfos(short _tapeID) {
1131    initTapeInfos(this);
1132    tapeID = _tapeID;
1133    pTapeInfos.op_fileName = createFileName(tapeID, OPERATIONS_TAPE);
1134    pTapeInfos.loc_fileName = createFileName(tapeID, LOCATIONS_TAPE);
1135    pTapeInfos.val_fileName = createFileName(tapeID, VALUES_TAPE);
1136    pTapeInfos.tay_fileName = NULL;
1137}
1138
Note: See TracBrowser for help on using the repository browser.