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

Last change on this file since 71 was 59, checked in by awalther, 10 years ago

modified sparsity detection for jacobians

  • Property svn:keywords set to Author Date Id Revision
File size: 33.6 KB
Line 
1/*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File:     tape_handling.cpp
4 Revision: $Id: tape_handling.cpp 59 2009-11-17 19:58:21Z awalther $
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 <revolve.h>
17
18#include <iostream>
19#include <string.h>
20#ifdef HAVE_UNISTD_H
21#include <unistd.h>
22#endif
23#include <vector>
24#include <stack>
25#include <errno.h>
26
27using namespace std;
28
29/* vector of tape infos for all tapes in use */
30vector<TapeInfos *> ADOLC_TAPE_INFOS_BUFFER_DECL;
31
32/* stack of pointers to tape infos
33 * represents the order of tape usage when doing nested taping */
34stack<TapeInfos *> ADOLC_TAPE_STACK_DECL;
35
36/* the main tape info buffer and its fallback */
37TapeInfos ADOLC_CURRENT_TAPE_INFOS_DECL;
38TapeInfos ADOLC_CURRENT_TAPE_INFOS_FALLBACK_DECL;
39
40/* global tapeing variables */
41GlobalTapeVars ADOLC_GLOBAL_TAPE_VARS_DECL;
42
43#if defined(_OPENMP)
44static vector<TapeInfos *> *tapeInfosBuffer_s;
45static stack<TapeInfos *>  *tapeStack_s;
46static TapeInfos           *currentTapeInfos_s;
47static TapeInfos           *currentTapeInfos_fallBack_s;
48static GlobalTapeVars      *globalTapeVars_s;
49static ADOLC_BUFFER_TYPE   *ADOLC_extDiffFctsBuffer_s;
50static stack<StackElement> *ADOLC_checkpointsStack_s;
51static revolve_nums        *revolve_numbers_s;
52
53static vector<TapeInfos *> *tapeInfosBuffer_p;
54static stack<TapeInfos *>  *tapeStack_p;
55static TapeInfos           *currentTapeInfos_p;
56static TapeInfos           *currentTapeInfos_fallBack_p;
57static GlobalTapeVars      *globalTapeVars_p;
58static ADOLC_BUFFER_TYPE   *ADOLC_extDiffFctsBuffer_p;
59static stack<StackElement> *ADOLC_checkpointsStack_p;
60static revolve_nums        *revolve_numbers_p;
61#endif
62
63/*--------------------------------------------------------------------------*/
64/* This function sets the flag "newTape" if either a taylor buffer has been */
65/* created or a taping process has been performed. Calling the function is  */
66/* also useful to "convince" the linker of including the cleaner part into  */
67/* the binary when linking statically!                                      */
68/*--------------------------------------------------------------------------*/
69void markNewTape() {
70    ADOLC_OPENMP_THREAD_NUMBER;
71    ADOLC_OPENMP_GET_THREAD_NUMBER;
72    ADOLC_GLOBAL_TAPE_VARS.newTape = 1;
73}
74
75/* inits the struct for the new tape */
76void initTapeInfos(TapeInfos *newTapeInfos) {
77    char *ptr;
78
79    ptr = (char *)newTapeInfos;
80    for (unsigned int i = 0; i < sizeof(TapeInfos) -
81            sizeof(PersistantTapeInfos); ++i) ptr[i] = 0;
82}
83
84/* as above but keep allocated buffers if possible */
85void initTapeInfos_keep(TapeInfos *newTapeInfos) {
86    unsigned char *opBuffer = newTapeInfos->opBuffer;
87    locint *locBuffer = newTapeInfos->locBuffer;
88    double *valBuffer = newTapeInfos->valBuffer;
89    revreal *tayBuffer = newTapeInfos->tayBuffer;
90    FILE *tay_file = newTapeInfos->tay_file;
91
92    initTapeInfos(newTapeInfos);
93
94    newTapeInfos->opBuffer = opBuffer;
95    newTapeInfos->locBuffer = locBuffer;
96    newTapeInfos->valBuffer = valBuffer;
97    newTapeInfos->tayBuffer = tayBuffer;
98    newTapeInfos->tay_file = tay_file;
99}
100
101/* inits a new tape and updates the tape stack (called from start_trace)
102 * - returns 0 without error
103 * - returns 1 if tapeID was already/still in use */
104int initNewTape(short tapeID) {
105    TapeInfos *newTapeInfos = NULL;
106    bool newTI = false;
107    int retval = 0;
108
109    ADOLC_OPENMP_THREAD_NUMBER;
110    ADOLC_OPENMP_GET_THREAD_NUMBER;
111
112    /* check if tape is in use */
113    vector<TapeInfos *>::iterator tiIter;
114    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
115        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
116                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
117                ++tiIter) {
118            if ((*tiIter)->tapeID==tapeID) {
119                newTapeInfos=*tiIter;
120                if ((*tiIter)->inUse != 0) {
121                    if ((*tiIter)->tapingComplete == 0)
122                        fail(ADOLC_TAPING_TAPE_STILL_IN_USE);
123                    if ( (*tiIter)->stats[OP_FILE_ACCESS]  == 0 &&
124                            (*tiIter)->stats[LOC_FILE_ACCESS] == 0 &&
125                            (*tiIter)->stats[VAL_FILE_ACCESS] == 0  ) {
126#              if defined(ADOLC_DEBUG)
127                        fprintf(DIAG_OUT, "\nADOL-C warning: Tape %d existed in main memory"
128                                " only and gets overwritten!\n\n", tapeID);
129#              endif
130                        /* free associated resources */
131                        retval = 1;
132                    }
133                }
134                if ((*tiIter)->tay_file != NULL)
135                    rewind((*tiIter)->tay_file);
136                initTapeInfos_keep(*tiIter);
137                (*tiIter)->tapeID = tapeID;
138                break;
139            }
140        }
141    }
142
143    /* create new info struct and initialize it */
144    if (newTapeInfos == NULL) {
145        newTapeInfos = new TapeInfos(tapeID);
146        newTI = true;
147    }
148    newTapeInfos->traceFlag=1;
149    newTapeInfos->inUse=1;
150    newTapeInfos->pTapeInfos.inJacSparseUse=0;
151    newTapeInfos->pTapeInfos.inHessSparseUse=0;
152    newTapeInfos->pTapeInfos.sJinfos.B=NULL;
153    newTapeInfos->pTapeInfos.sJinfos.y=NULL;
154    newTapeInfos->pTapeInfos.sHinfos.Zppp=NULL;
155    newTapeInfos->pTapeInfos.sHinfos.Yppp=NULL;
156    newTapeInfos->pTapeInfos.sHinfos.Xppp=NULL;
157    newTapeInfos->pTapeInfos.sHinfos.Upp=NULL;
158    newTapeInfos->pTapeInfos.sHinfos.Hcomp=NULL;
159    newTapeInfos->stats[OP_BUFFER_SIZE] =
160        ADOLC_GLOBAL_TAPE_VARS.operationBufferSize;
161    newTapeInfos->stats[LOC_BUFFER_SIZE] =
162        ADOLC_GLOBAL_TAPE_VARS.locationBufferSize;
163    newTapeInfos->stats[VAL_BUFFER_SIZE] =
164        ADOLC_GLOBAL_TAPE_VARS.valueBufferSize;
165    newTapeInfos->stats[TAY_BUFFER_SIZE] =
166        ADOLC_GLOBAL_TAPE_VARS.taylorBufferSize;
167
168    /* update tapeStack and save tapeInfos */
169    if (ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr != NULL) {
170        memcpy(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr,
171                &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
172        ADOLC_TAPE_STACK.push(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
173    } else {
174        memcpy(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK,
175                &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
176        ADOLC_TAPE_STACK.push(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK);
177    }
178    if (newTI) ADOLC_TAPE_INFOS_BUFFER.push_back(newTapeInfos);
179
180    /* set the new tape infos as current */
181    memcpy(&ADOLC_CURRENT_TAPE_INFOS, newTapeInfos, sizeof(TapeInfos));
182    ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = newTapeInfos;
183
184    return retval;
185}
186
187/* opens an existing tape or creates a new handle for a tape on hard disk
188 * - called from init_for_sweep and init_rev_sweep */
189void openTape(short tapeID, char mode) {
190    TapeInfos *tempTapeInfos=NULL;
191
192    ADOLC_OPENMP_THREAD_NUMBER;
193    ADOLC_OPENMP_GET_THREAD_NUMBER;
194
195    /* check if tape information exist in memory */
196    vector<TapeInfos *>::iterator tiIter;
197    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
198        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
199                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
200                ++tiIter) {
201            if ((*tiIter)->tapeID == tapeID) {
202                /* tape has been used before (in the current program) */
203                if ((*tiIter)->inUse == 0) {
204                    /* forward sweep */
205                    if ((*tiIter)->tay_file != NULL)
206                        rewind((*tiIter)->tay_file);
207                    initTapeInfos_keep(*tiIter);
208                    (*tiIter)->traceFlag=1;
209                    (*tiIter)->tapeID = tapeID;
210                    (*tiIter)->tapingComplete = 1;
211                    (*tiIter)->inUse = 1;
212                    read_tape_stats(*tiIter);
213               }
214                if (ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr != NULL) {
215                    memcpy(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr,
216                            &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
217                    ADOLC_TAPE_STACK.push(
218                            ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
219                } else {
220                    memcpy(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK,
221                            &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
222                    ADOLC_TAPE_STACK.push(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK);
223                }
224                memcpy(&ADOLC_CURRENT_TAPE_INFOS, *tiIter, sizeof(TapeInfos));
225                ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = *tiIter;
226                return;
227            }
228        }
229    }
230
231    /* tapeID not used so far */
232    if (mode == ADOLC_REVERSE) {
233        failAdditionalInfo1 = tapeID;
234        fail(ADOLC_REVERSE_NO_TAYLOR_STACK);
235    }
236
237    /* create new info struct and initialize it */
238    tempTapeInfos = new TapeInfos(tapeID);
239    tempTapeInfos->traceFlag=1;
240    tempTapeInfos->inUse = 1;
241    tempTapeInfos->tapingComplete = 1;
242    ADOLC_TAPE_INFOS_BUFFER.push_back(tempTapeInfos);
243
244    read_tape_stats(tempTapeInfos);
245    /* update tapeStack and save tapeInfos */
246    if (ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr != NULL) {
247        memcpy(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr,
248                &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
249        ADOLC_TAPE_STACK.push(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr);
250    } else {
251        memcpy(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK,
252                &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
253        ADOLC_TAPE_STACK.push(&ADOLC_CURRENT_TAPE_INFOS_FALLBACK);
254    }
255
256    /* set the new tape infos as current */
257    memcpy(&ADOLC_CURRENT_TAPE_INFOS, tempTapeInfos, sizeof(TapeInfos));
258    ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = tempTapeInfos;
259}
260
261/* release the current tape and give control to the previous one */
262void releaseTape() {
263    ADOLC_OPENMP_THREAD_NUMBER;
264    ADOLC_OPENMP_GET_THREAD_NUMBER;
265
266    /* if operations, locations and constants tapes have been written and value
267     * stack information have not been created tapeInfos are no longer needed*/
268    if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors            == 0 &&
269            ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS]  == 1 &&
270            ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] == 1 &&
271            ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] == 1 ) {
272        ADOLC_CURRENT_TAPE_INFOS.inUse = 0;
273    }
274
275    memcpy(ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr,
276            &ADOLC_CURRENT_TAPE_INFOS, sizeof(TapeInfos));
277    ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = ADOLC_TAPE_STACK.top();
278    memcpy(&ADOLC_CURRENT_TAPE_INFOS,
279            ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr, sizeof(TapeInfos));
280    ADOLC_TAPE_STACK.pop();
281    if (ADOLC_TAPE_STACK.empty())
282        ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = NULL;
283}
284
285/* updates the tape infos for the given ID - a tapeInfos struct is created
286 * and registered if non is found but its state will remain "not in use" */
287TapeInfos *getTapeInfos(short tapeID) {
288    TapeInfos *tapeInfos;
289    vector<TapeInfos *>::iterator tiIter;
290
291    ADOLC_OPENMP_THREAD_NUMBER;
292    ADOLC_OPENMP_GET_THREAD_NUMBER;
293
294    /* check if TapeInfos for tapeID exist */
295    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
296        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
297                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
298                ++tiIter) {
299            if ((*tiIter)->tapeID==tapeID) {
300                tapeInfos=*tiIter;
301                if (tapeInfos->inUse==0) read_tape_stats(tapeInfos);
302                return tapeInfos;
303            }
304        }
305    }
306    /* create new TapeInfos, initialize and update tapeInfosBuffer */
307    tapeInfos = new TapeInfos(tapeID);
308    ADOLC_TAPE_INFOS_BUFFER.push_back(tapeInfos);
309    tapeInfos->traceFlag=1;
310    tapeInfos->inUse=0;
311    tapeInfos->pTapeInfos.inJacSparseUse=0;
312    tapeInfos->pTapeInfos.inHessSparseUse=0;
313    tapeInfos->tapingComplete = 1;
314    read_tape_stats(tapeInfos);
315    return tapeInfos;
316}
317
318/* updates the tape infos on sparse Jac for the given ID  */
319void setTapeInfoJacSparse(short tapeID, SparseJacInfos sJinfos) {
320    TapeInfos *tapeInfos;
321    vector<TapeInfos *>::iterator tiIter;
322
323    ADOLC_OPENMP_THREAD_NUMBER;
324    ADOLC_OPENMP_GET_THREAD_NUMBER;
325
326    /* check if TapeInfos for tapeID exist */
327    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
328        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
329                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
330                ++tiIter) {
331            if ((*tiIter)->tapeID==tapeID) {
332                tapeInfos=*tiIter;
333                    // memory deallocation is missing !!
334                    tapeInfos->pTapeInfos.sJinfos.y=sJinfos.y;
335                    tapeInfos->pTapeInfos.sJinfos.Seed=sJinfos.Seed;
336                    tapeInfos->pTapeInfos.sJinfos.B=sJinfos.B;
337                    tapeInfos->pTapeInfos.sJinfos.JP=sJinfos.JP;
338                    tapeInfos->pTapeInfos.sJinfos.nnz_in=sJinfos.nnz_in;
339                    tapeInfos->pTapeInfos.sJinfos.p=sJinfos.p;
340                    tapeInfos->pTapeInfos.sJinfos.g=sJinfos.g;
341            }
342        }
343    }
344}
345
346/* updates the tape infos on sparse Hess for the given ID  */
347void setTapeInfoHessSparse(short tapeID, SparseHessInfos sHinfos) {
348    TapeInfos *tapeInfos;
349    vector<TapeInfos *>::iterator tiIter;
350
351    ADOLC_OPENMP_THREAD_NUMBER;
352    ADOLC_OPENMP_GET_THREAD_NUMBER;
353
354    /* check if TapeInfos for tapeID exist */
355    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
356        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
357                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
358                ++tiIter) {
359            if ((*tiIter)->tapeID==tapeID) {
360                tapeInfos=*tiIter;
361                    // memory deallocation is missing !!
362                    tapeInfos->pTapeInfos.sHinfos.Hcomp=sHinfos.Hcomp;
363                    tapeInfos->pTapeInfos.sHinfos.Xppp=sHinfos.Xppp;
364                    tapeInfos->pTapeInfos.sHinfos.Yppp=sHinfos.Yppp;
365                    tapeInfos->pTapeInfos.sHinfos.Zppp=sHinfos.Zppp;
366                    tapeInfos->pTapeInfos.sHinfos.Upp=sHinfos.Upp;
367                    tapeInfos->pTapeInfos.sHinfos.HP=sHinfos.HP;
368                    tapeInfos->pTapeInfos.sHinfos.nnz_in=sHinfos.nnz_in;
369                    tapeInfos->pTapeInfos.sHinfos.p=sHinfos.p;
370                    tapeInfos->pTapeInfos.sHinfos.g=sHinfos.g;
371            }
372        }
373    }
374}
375
376void init() {
377    ADOLC_OPENMP_THREAD_NUMBER;
378    errno = 0;
379    ADOLC_OPENMP_GET_THREAD_NUMBER;
380
381#if defined(_OPENMP)
382    tapeInfosBuffer = new vector<TapeInfos *>;
383    tapeStack = new stack<TapeInfos *>;
384    currentTapeInfos = new TapeInfos;
385    currentTapeInfos->tapingComplete = 1;
386    currentTapeInfos_fallBack = new TapeInfos;
387    globalTapeVars = new GlobalTapeVars;
388    ADOLC_extDiffFctsBuffer = new ADOLC_BUFFER_TYPE;
389    ADOLC_checkpointsStack = new stack<StackElement>;
390    revolve_numbers = new revolve_nums;
391#endif /* _OPENMP */
392
393    ADOLC_CURRENT_TAPE_INFOS.traceFlag = 0;
394    ADOLC_CURRENT_TAPE_INFOS.keepTaylors = 0;
395
396    ADOLC_GLOBAL_TAPE_VARS.store=NULL;
397    ADOLC_GLOBAL_TAPE_VARS.maxLoc=1;
398    for (uint i=0; i<sizeof(locint)*8-1; ++i) {
399        ADOLC_GLOBAL_TAPE_VARS.maxLoc<<=1;
400        ++ADOLC_GLOBAL_TAPE_VARS.maxLoc;
401    }
402    ADOLC_GLOBAL_TAPE_VARS.locMinUnused = 0;
403    ADOLC_GLOBAL_TAPE_VARS.numMaxAlive = 0;
404    ADOLC_GLOBAL_TAPE_VARS.storeSize = 0;
405    ADOLC_GLOBAL_TAPE_VARS.numToFree = 0;
406    ADOLC_GLOBAL_TAPE_VARS.minLocToFree = 0;
407    ADOLC_GLOBAL_TAPE_VARS.inParallelRegion = 0;
408    ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = NULL;
409    ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = 1;
410
411    adolc_id.adolc_ver    = ADOLC_VERSION;
412    adolc_id.adolc_sub    = ADOLC_SUBVERSION;
413    adolc_id.adolc_lvl    = ADOLC_PATCHLEVEL;
414    adolc_id.locint_size  = sizeof(locint);
415    adolc_id.revreal_size = sizeof(revreal);
416
417    ADOLC_EXT_DIFF_FCTS_BUFFER.init(init_CpInfos);
418}
419
420/* does things like closing/removing temporary files, ... */
421void cleanUp() {
422    ADOLC_OPENMP_THREAD_NUMBER;
423    ADOLC_OPENMP_GET_THREAD_NUMBER;
424
425    vector<TapeInfos *>::iterator tiIter;
426    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
427        for (tiIter=ADOLC_TAPE_INFOS_BUFFER.begin();
428                tiIter!=ADOLC_TAPE_INFOS_BUFFER.end();
429                ++tiIter)
430        {
431            /* close open files though they may be incomplete */
432            if ((*tiIter)->op_file!=NULL)
433            {
434                fclose((*tiIter)->op_file);
435                (*tiIter)->op_file = NULL;
436            }
437            if ((*tiIter)->val_file!=NULL)
438            {
439                fclose((*tiIter)->val_file);
440                (*tiIter)->val_file = NULL;
441            }
442            if ((*tiIter)->loc_file!=NULL)
443            {
444                fclose((*tiIter)->loc_file);
445                (*tiIter)->loc_file = NULL;
446            }
447            if ((*tiIter)->tay_file!=NULL) {
448                fclose((*tiIter)->tay_file);
449                (*tiIter)->tay_file = NULL;
450                remove((*tiIter)->pTapeInfos.tay_fileName);
451            }
452            if ((*tiIter)->opBuffer != NULL)
453            {
454                free((*tiIter)->opBuffer);
455                (*tiIter)->opBuffer = NULL;
456            }
457            if ((*tiIter)->valBuffer != NULL)
458            {
459                free((*tiIter)->valBuffer);
460                (*tiIter)->valBuffer = NULL;
461            }
462            if ((*tiIter)->locBuffer != NULL)
463            {
464                free((*tiIter)->locBuffer);
465                (*tiIter)->locBuffer = NULL;
466            }
467            if ((*tiIter)->tayBuffer != NULL)
468            {
469                free((*tiIter)->tayBuffer);
470                (*tiIter)->tayBuffer = NULL;
471            }
472
473
474            if ((*tiIter)->pTapeInfos.sJinfos.B != NULL)
475            {
476                free((char*)  *(*tiIter)->pTapeInfos.sJinfos.B);
477                free((char*)   (*tiIter)->pTapeInfos.sJinfos.B);
478                (*tiIter)->pTapeInfos.sJinfos.B = NULL;
479            }
480            if ((*tiIter)->pTapeInfos.sJinfos.y != NULL)
481            {
482                free((*tiIter)->pTapeInfos.sJinfos.y);
483                (*tiIter)->pTapeInfos.sJinfos.y = NULL;
484            }
485
486            if ((*tiIter)->pTapeInfos.sHinfos.Zppp != NULL)
487            {
488                free((char*) **(*tiIter)->pTapeInfos.sHinfos.Zppp);
489                free((char*)  *(*tiIter)->pTapeInfos.sHinfos.Zppp);
490                free((char*)   (*tiIter)->pTapeInfos.sHinfos.Zppp);
491                (*tiIter)->pTapeInfos.sHinfos.Zppp = NULL;
492            }
493            if ((*tiIter)->pTapeInfos.sHinfos.Yppp != NULL)
494            {
495                free((char*) **(*tiIter)->pTapeInfos.sHinfos.Yppp);
496                free((char*)  *(*tiIter)->pTapeInfos.sHinfos.Yppp);
497                free((char*)   (*tiIter)->pTapeInfos.sHinfos.Yppp);
498                (*tiIter)->pTapeInfos.sHinfos.Yppp = NULL;
499            }
500            if ((*tiIter)->pTapeInfos.sHinfos.Xppp != NULL)
501            {
502                free((char*) **(*tiIter)->pTapeInfos.sHinfos.Xppp);
503                free((char*)  *(*tiIter)->pTapeInfos.sHinfos.Xppp);
504                free((char*)   (*tiIter)->pTapeInfos.sHinfos.Xppp);
505                (*tiIter)->pTapeInfos.sHinfos.Yppp = NULL;
506            }
507            if ((*tiIter)->pTapeInfos.sHinfos.Upp != NULL)
508            {
509                free((char*)  *(*tiIter)->pTapeInfos.sHinfos.Upp);
510                free((char*)   (*tiIter)->pTapeInfos.sHinfos.Upp);
511                (*tiIter)->pTapeInfos.sHinfos.Upp = NULL;
512            }
513            if ((*tiIter)->pTapeInfos.sHinfos.Hcomp != NULL)
514            {
515                free((char*)  *(*tiIter)->pTapeInfos.sHinfos.Hcomp);
516                free((char*)   (*tiIter)->pTapeInfos.sHinfos.Hcomp);
517                (*tiIter)->pTapeInfos.sHinfos.Hcomp = NULL;
518            }
519
520            /* remove "main" tape files if not all three have been written */
521            int filesWritten = (*tiIter)->stats[OP_FILE_ACCESS] +
522                (*tiIter)->stats[LOC_FILE_ACCESS] +
523                (*tiIter)->stats[VAL_FILE_ACCESS];
524            if ( (filesWritten > 0) && ((*tiIter)->pTapeInfos.keepTape == 0) )
525            {
526                /* try to remove all tapes (even those not written by this
527                 * run) => this ensures that there is no mixture of tapes from
528                 * different ADOLC runs */
529                if ( (*tiIter)->stats[OP_FILE_ACCESS] == 1 )
530                    remove((*tiIter)->pTapeInfos.op_fileName);
531                if ( (*tiIter)->stats[LOC_FILE_ACCESS] == 1 )
532                    remove((*tiIter)->pTapeInfos.loc_fileName);
533                if ( (*tiIter)->stats[VAL_FILE_ACCESS] == 1 )
534                    remove((*tiIter)->pTapeInfos.val_fileName);
535            }
536            if ((*tiIter)->pTapeInfos.op_fileName != NULL)
537            {
538                free((*tiIter)->pTapeInfos.op_fileName);
539                (*tiIter)->pTapeInfos.op_fileName = NULL;
540            }
541            if ((*tiIter)->pTapeInfos.val_fileName != NULL)
542            {
543                free((*tiIter)->pTapeInfos.val_fileName);
544                (*tiIter)->pTapeInfos.val_fileName = NULL;
545            }
546            if ((*tiIter)->pTapeInfos.loc_fileName != NULL)
547            {
548                free((*tiIter)->pTapeInfos.loc_fileName);
549                (*tiIter)->pTapeInfos.loc_fileName = NULL;
550            }
551            if ((*tiIter)->pTapeInfos.tay_fileName != NULL)
552            {
553                free((*tiIter)->pTapeInfos.tay_fileName);
554                (*tiIter)->pTapeInfos.tay_fileName = NULL;
555            }
556
557            delete *tiIter;
558        }
559    }
560
561    cp_clearStack();
562
563    if (ADOLC_GLOBAL_TAPE_VARS.store != NULL) {
564        free(ADOLC_GLOBAL_TAPE_VARS.store);
565        ADOLC_GLOBAL_TAPE_VARS.store = NULL;
566    }
567
568#if defined(_OPENMP)
569    if (ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 0) {
570        /* cleanup on program exit */
571        delete revolve_numbers;
572        delete ADOLC_checkpointsStack;
573        delete ADOLC_extDiffFctsBuffer;
574        delete globalTapeVars;
575        delete currentTapeInfos;
576        delete currentTapeInfos_fallBack;
577        delete tapeStack;
578        delete tapeInfosBuffer;
579    }
580#endif
581
582    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
583}
584
585int removeTape(short tapeID, short type) {
586    TapeInfos *tapeInfos = NULL;
587    vector<TapeInfos *>::iterator tiIter;
588    ADOLC_OPENMP_THREAD_NUMBER;
589    ADOLC_OPENMP_GET_THREAD_NUMBER;
590
591    /* check if TapeInfos for tapeID exist */
592    if (!ADOLC_TAPE_INFOS_BUFFER.empty()) {
593        for (tiIter = ADOLC_TAPE_INFOS_BUFFER.begin();
594                tiIter != ADOLC_TAPE_INFOS_BUFFER.end();
595                ++tiIter)
596        {
597            if ((*tiIter)->tapeID == tapeID) {
598                tapeInfos = *tiIter;
599                if (tapeInfos->tapingComplete == 0) return -1;
600                ADOLC_TAPE_INFOS_BUFFER.erase(tiIter);
601                break;
602            }
603        }
604    }
605
606    if (tapeInfos == NULL) { // might be on disk only
607        tapeInfos = new TapeInfos(tapeID);
608        tapeInfos->tapingComplete = 1;
609    }
610
611    freeTapeResources(tapeInfos);
612    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
613
614    if (type == ADOLC_REMOVE_COMPLETELY) {
615        remove(tapeInfos->pTapeInfos.op_fileName);
616        remove(tapeInfos->pTapeInfos.loc_fileName);
617        remove(tapeInfos->pTapeInfos.val_fileName);
618    }
619
620    free(tapeInfos->pTapeInfos.op_fileName);
621    free(tapeInfos->pTapeInfos.val_fileName);
622    free(tapeInfos->pTapeInfos.loc_fileName);
623    if (tapeInfos->pTapeInfos.tay_fileName != NULL)
624        free(tapeInfos->pTapeInfos.tay_fileName);
625
626    delete tapeInfos;
627
628    return 0;
629}
630
631/****************************************************************************/
632/* Initialization for the taping process. Creates buffers for this tape,    */
633/* sets files names, and calls appropriate setup routines.                  */
634/****************************************************************************/
635int trace_on(short tnum, int keepTaylors) {
636    int retval = 0;
637    ADOLC_OPENMP_THREAD_NUMBER;
638    ADOLC_OPENMP_GET_THREAD_NUMBER;
639
640    /* allocate memory for TapeInfos and update tapeStack */
641    retval = initNewTape(tnum);
642    ADOLC_CURRENT_TAPE_INFOS.keepTaylors=keepTaylors;
643    if (keepTaylors!=0) ADOLC_CURRENT_TAPE_INFOS.deg_save=1;
644    start_trace();
645    take_stock();               /* record all existing adoubles on the tape */
646    return retval;
647}
648
649int trace_on(short tnum, int keepTaylors,
650        uint obs, uint lbs, uint vbs, uint tbs)
651{
652    int retval = 0;
653    ADOLC_OPENMP_THREAD_NUMBER;
654    ADOLC_OPENMP_GET_THREAD_NUMBER;
655
656    /* allocate memory for TapeInfos and update tapeStack */
657    retval = initNewTape(tnum);
658    ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE] = obs;
659    ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE] = lbs;
660    ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE] = vbs;
661    ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE] = tbs;
662    ADOLC_CURRENT_TAPE_INFOS.keepTaylors=keepTaylors;
663    if (keepTaylors!=0) ADOLC_CURRENT_TAPE_INFOS.deg_save=1;
664    start_trace();
665    take_stock();               /* record all existing adoubles on the tape */
666    return retval;
667}
668
669/****************************************************************************/
670/* Stop Tracing. Cleans up, and turns off trace_flag. Flag not equal zero   */
671/* enforces writing of the three main tape files (op+loc+val).              */
672/****************************************************************************/
673void trace_off(int flag) {
674    ADOLC_OPENMP_THREAD_NUMBER;
675    ADOLC_OPENMP_GET_THREAD_NUMBER;
676    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.keepTape = flag;
677    keep_stock();         /* copy remaining live variables + trace_flag = 0 */
678    stop_trace(flag);
679    cout.flush();
680    ADOLC_CURRENT_TAPE_INFOS.tapingComplete = 1;
681    releaseTape();
682}
683
684bool isTaping() {
685    ADOLC_OPENMP_THREAD_NUMBER;
686    ADOLC_OPENMP_GET_THREAD_NUMBER;
687    return ADOLC_CURRENT_TAPE_INFOS.traceFlag != 0;
688}
689
690
691
692/****************************************************************************/
693/* A class for initialization/finalization and OpenMP handling              */
694/****************************************************************************/
695class Keeper {
696    public:
697        inline Keeper() {
698            dummy = 0;
699            init();
700            readConfigFile();
701        }
702        inline ~Keeper() {
703            cleanUp();
704        }
705
706        inline void touch() {
707            dummy = 1;
708        }
709
710    private:
711        int dummy;
712};
713
714/* a static instance that does all work */
715static Keeper theKeeper;
716
717/**
718 * Hope to convince the linker to link the keeper code into the executable. */
719void initADOLC() {
720    theKeeper.touch();
721}
722
723/****************************************************************************/
724/****************************************************************************/
725/* The following is necessary to provide a separate ADOL-C environment for  */
726/* each OpenMP worker.                                                      */
727/****************************************************************************/
728/****************************************************************************/
729#if defined(_OPENMP)
730#include "adolc_openmp.h"
731
732ADOLC_OpenMP ADOLC_OpenMP_Handler;
733ADOLC_OpenMP_NC ADOLC_OpenMP_Handler_NC;
734int ADOLC_parallel_doCopy;
735
736static bool waitForMaster_begin = true;
737static bool waitForMaster_end   = true;
738static bool firstParallel       = true;
739
740/****************************************************************************/
741/* Used by OpenMP to create a separate environment for every worker thread. */
742/****************************************************************************/
743void beginParallel() {
744    ADOLC_OPENMP_THREAD_NUMBER;
745#if defined(ADOLC_THREADSAVE_ERRNO)
746    errno = omp_get_thread_num();
747#endif
748    ADOLC_OPENMP_GET_THREAD_NUMBER;
749
750    if (ADOLC_threadNumber == 0) { /* master only */
751        int numThreads = omp_get_num_threads();
752
753        tapeInfosBuffer_s           = tapeInfosBuffer;
754        tapeStack_s                 = tapeStack;
755        currentTapeInfos_s          = currentTapeInfos;
756        currentTapeInfos_fallBack_s = currentTapeInfos_fallBack;
757        globalTapeVars_s            = globalTapeVars;
758        ADOLC_extDiffFctsBuffer_s   = ADOLC_extDiffFctsBuffer;
759        ADOLC_checkpointsStack_s    = ADOLC_checkpointsStack;
760        revolve_numbers_s           = revolve_numbers;
761
762        if (firstParallel) {
763            tapeInfosBuffer           = new vector<TapeInfos *>[numThreads];
764            tapeStack                 = new stack<TapeInfos *>[numThreads];
765            currentTapeInfos          = new TapeInfos[numThreads];
766            currentTapeInfos_fallBack = new TapeInfos[numThreads];
767            globalTapeVars            = new GlobalTapeVars[numThreads];
768            ADOLC_extDiffFctsBuffer   = new ADOLC_BUFFER_TYPE[numThreads];
769            ADOLC_checkpointsStack    = new stack<StackElement>[numThreads];
770            revolve_numbers           = new revolve_nums[numThreads];
771        } else {
772            tapeInfosBuffer           = tapeInfosBuffer_p;
773            tapeStack                 = tapeStack_p;
774            currentTapeInfos          = currentTapeInfos_p;
775            currentTapeInfos_fallBack = currentTapeInfos_fallBack_p;
776            globalTapeVars            = globalTapeVars_p;
777            ADOLC_extDiffFctsBuffer   = ADOLC_extDiffFctsBuffer_p;
778            ADOLC_checkpointsStack    = ADOLC_checkpointsStack_p;
779            revolve_numbers         = revolve_numbers_p;
780        }
781
782        /* - set inParallelRegion for tmpGlobalTapeVars because it is source
783         *   for initializing the parallel globalTapeVars structs
784         * - inParallelRegion has to be set to one for all workers by master.
785         *   This is necessary, to deter a speedy master from assuming all
786         *   workers are done, in endParallel, before they even leaved
787         *   beginParallel. */
788        globalTapeVars_s[0].inParallelRegion = 1;
789        for (int i = 0; i < numThreads; ++i)
790            globalTapeVars[i].inParallelRegion = 1;
791
792        waitForMaster_end = true;
793        waitForMaster_begin = false;
794    } else 
795        while (waitForMaster_begin) {
796            usleep(1000); /* if anyone knows a better value, ... :-) */
797        }
798
799    if (firstParallel) {
800        ADOLC_EXT_DIFF_FCTS_BUFFER.init(init_CpInfos);
801        memcpy(&ADOLC_GLOBAL_TAPE_VARS, globalTapeVars_s, sizeof(GlobalTapeVars));
802        ADOLC_GLOBAL_TAPE_VARS.store = (double *)
803            malloc(sizeof(double) * ADOLC_GLOBAL_TAPE_VARS.storeSize);
804        memcpy(ADOLC_GLOBAL_TAPE_VARS.store, globalTapeVars_s->store,
805                ADOLC_GLOBAL_TAPE_VARS.locMinUnused * sizeof(double));
806        ADOLC_GLOBAL_TAPE_VARS.newTape = 0;
807        ADOLC_CURRENT_TAPE_INFOS.tapingComplete = 1;
808        ADOLC_GLOBAL_TAPE_VARS.currentTapeInfosPtr = NULL;
809    } else {
810        if (ADOLC_parallel_doCopy) {
811            ADOLC_GLOBAL_TAPE_VARS.locMinUnused = globalTapeVars_s->locMinUnused;
812            ADOLC_GLOBAL_TAPE_VARS.numMaxAlive = globalTapeVars_s->numMaxAlive;
813            ADOLC_GLOBAL_TAPE_VARS.storeSize = globalTapeVars_s->storeSize;
814            ADOLC_GLOBAL_TAPE_VARS.numToFree = globalTapeVars_s->numToFree;
815            ADOLC_GLOBAL_TAPE_VARS.minLocToFree = globalTapeVars_s->minLocToFree;
816            ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = globalTapeVars_s->branchSwitchWarning;
817            free(ADOLC_GLOBAL_TAPE_VARS.store);
818            ADOLC_GLOBAL_TAPE_VARS.store = (double *)
819                malloc(sizeof(double) * ADOLC_GLOBAL_TAPE_VARS.storeSize);
820            memcpy(ADOLC_GLOBAL_TAPE_VARS.store, globalTapeVars_s->store,
821                    ADOLC_GLOBAL_TAPE_VARS.locMinUnused * sizeof(double));
822        }
823    }
824}
825
826/****************************************************************************/
827/* Used by OpenMP to destroy the separate environment of every worker.      */
828/****************************************************************************/
829/* There are n+1 instances of ADOLC_OpenMP => n within the parallel region
830 * and one in the serial part! */
831void endParallel() {
832    ADOLC_OPENMP_THREAD_NUMBER;
833    ADOLC_OPENMP_GET_THREAD_NUMBER;
834
835    /* do nothing if called at program exit (serial part) */
836    if (ADOLC_threadNumber == 0 &&
837            ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 0) return;
838
839    ADOLC_GLOBAL_TAPE_VARS.inParallelRegion = 0;
840
841    if (ADOLC_threadNumber == 0) { /* master only */
842        int num;
843        int numThreads = omp_get_num_threads();
844        bool firstIt = true;
845        do { /* wait until all slaves have left the parallel part */
846            if (firstIt) firstIt = false;
847            else usleep(1000); /* no busy waiting */
848            num = 1;
849            for (int i = 1; i < numThreads; ++i)
850                if (globalTapeVars[i].inParallelRegion == 0) ++num;
851        } while (num != numThreads);
852
853        firstParallel = false;
854
855        revolve_numbers_p           = revolve_numbers;
856        ADOLC_checkpointsStack_p    = ADOLC_checkpointsStack;
857        ADOLC_extDiffFctsBuffer_p   = ADOLC_extDiffFctsBuffer;
858        globalTapeVars_p            = globalTapeVars;
859        currentTapeInfos_p          = currentTapeInfos;
860        currentTapeInfos_fallBack_p = currentTapeInfos_fallBack;
861        tapeStack_p                 = tapeStack;
862        tapeInfosBuffer_p           = tapeInfosBuffer;
863
864        revolve_numbers           = revolve_numbers_s;
865        ADOLC_checkpointsStack    = ADOLC_checkpointsStack_s;
866        ADOLC_extDiffFctsBuffer   = ADOLC_extDiffFctsBuffer_s;
867        globalTapeVars            = globalTapeVars_s;
868        currentTapeInfos          = currentTapeInfos_s;
869        currentTapeInfos_fallBack = currentTapeInfos_fallBack_s;
870        tapeStack                 = tapeStack_s;
871        tapeInfosBuffer           = tapeInfosBuffer_s;
872
873        ADOLC_GLOBAL_TAPE_VARS.inParallelRegion = 0;
874        waitForMaster_begin = true;
875        waitForMaster_end = false;
876    } else
877        while (waitForMaster_end) {
878            usleep(1000); // no busy waiting
879        }
880}
881
882#endif /* _OPENMP */
883
884TapeInfos::TapeInfos() {
885    initTapeInfos(this);
886}
887
888TapeInfos::TapeInfos(short _tapeID) {
889    initTapeInfos(this);
890    tapeID = _tapeID;
891    pTapeInfos.op_fileName = createFileName(tapeID, OPERATIONS_TAPE);
892    pTapeInfos.loc_fileName = createFileName(tapeID, LOCATIONS_TAPE);
893    pTapeInfos.val_fileName = createFileName(tapeID, VALUES_TAPE);
894    pTapeInfos.tay_fileName = NULL;
895}
896
Note: See TracBrowser for help on using the repository browser.