source: trunk/ADOL-C/src/taping.c @ 71

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

set svn keywords property

  • Property svn:keywords set to Author Date Id Revision
File size: 95.5 KB
Line 
1/*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File:     taping.c
4 Revision: $Id: taping.c 42 2009-07-15 18:37:17Z awalther $
5 Contents: all C functions directly accessing at least one of the four tapes
6           (operations, locations, constants, value stack)
7
8 Copyright (c) Andrea Walther, Andreas Griewank, Andreas Kowarz,
9               Hristo Mitev, Sebastian Schlenkrich, Jean Utke, Olaf Vogel
10 
11 This file is part of ADOL-C. This software is provided as open source.
12 Any use, reproduction, or distribution of the software constitutes
13 recipient's acceptance of the terms of the accompanying license file.
14 
15----------------------------------------------------------------------------*/
16
17#include <math.h>
18#include <string.h>
19
20#include <oplate.h>
21#include <taping_p.h>
22
23/*--------------------------------------------------------------------------*/
24/* Tape identification (ADOLC & version check) */
25ADOLC_ID adolc_id;
26/* first version with new tape structure
27 * => to work with older tapes use older ADOL-C version */
28#define ADOLC_NEW_TAPE_VERSION 1
29#define ADOLC_NEW_TAPE_SUBVERSION 8
30#define ADOLC_NEW_TAPE_PATCHLEVEL 0
31
32/****************************************************************************/
33/****************************************************************************/
34/* HELP FUNCTIONS                                                           */
35/****************************************************************************/
36/****************************************************************************/
37
38/*--------------------------------------------------------------------------*/
39/* additional infos used by fail()                                          */
40int failAdditionalInfo1;
41int failAdditionalInfo2;
42locint failAdditionalInfo3;
43locint failAdditionalInfo4;
44void *failAdditionalInfo5;
45void *failAdditionalInfo6;
46
47/* outputs an appropriate error message using DIAG_OUT and exits the running
48 * program */
49void fail( int error ) {
50    ADOLC_OPENMP_THREAD_NUMBER;
51    ADOLC_OPENMP_GET_THREAD_NUMBER;
52    switch (error) {
53        case ADOLC_MALLOC_FAILED:
54            fprintf(DIAG_OUT, "ADOL-C error: Memory allocation failed!\n");
55            break;
56        case ADOLC_INTEGER_TAPE_FOPEN_FAILED:
57        case ADOLC_INTEGER_TAPE_FREAD_FAILED:
58            fprintf(DIAG_OUT, "ADOL-C error: "
59                    "reading integer tape number %d!\n",
60                    failAdditionalInfo1);
61            printError();
62            break;
63        case ADOLC_TAPE_TO_OLD:
64            fprintf(DIAG_OUT, "ADOL-C error: "
65                    "Used tape (%d) was written with ADOL-C version "
66                    "older than %d.%d.%d\n", failAdditionalInfo1,
67                    ADOLC_NEW_TAPE_VERSION, ADOLC_NEW_TAPE_SUBVERSION,
68                    ADOLC_NEW_TAPE_PATCHLEVEL);
69            fprintf(DIAG_OUT, "              "
70                    "This is ADOL-C %d.%d.%d\n", ADOLC_VERSION,
71                    ADOLC_SUBVERSION, ADOLC_PATCHLEVEL);
72            break;
73        case ADOLC_WRONG_LOCINT_SIZE:
74            fprintf(DIAG_OUT, "ADOL-C error: Used tape (%d) was written with "
75                    "locints of size %d, size %d required.\n",
76                    ADOLC_CURRENT_TAPE_INFOS.tapeID, failAdditionalInfo1,
77                    failAdditionalInfo2);
78            break;
79        case ADOLC_MORE_STAT_SPACE_REQUIRED:
80            fprintf(DIAG_OUT, "ADOL-C error: Not enough space for stats!\n"
81                    "              Please contact the ADOL-C team!\n");
82            break;
83
84        case ADOLC_TAPING_BUFFER_ALLOCATION_FAILED:
85            fprintf(DIAG_OUT, "ADOL-C error: Cannot allocate tape buffers!\n");
86            break;
87        case ADOLC_TAPING_TBUFFER_ALLOCATION_FAILED:
88            fprintf(DIAG_OUT, "ADOL-C error: Cannot allocate taylor buffer!\n");
89            break;
90        case ADOLC_TAPING_READ_ERROR_IN_TAYLOR_CLOSE:
91            fprintf(DIAG_OUT, "ADOL-C error: Read error in taylor_close n= %d\n",
92                    failAdditionalInfo1);
93            break;
94        case ADOLC_TAPING_TO_MANY_TAYLOR_BUFFERS:
95            fprintf(DIAG_OUT, "ADOL-C error: To many taylor buffers!\n"
96                    "              Increase ADOLC_GLOBAL_TAPE_VARS.maxNumberTaylorBuffers\n");
97            break;
98        case ADOLC_TAPING_TO_MANY_LOCINTS:
99            fprintf(DIAG_OUT, "ADOL-C error: Maximal number (%d) of live active "
100                    "variables exceeded!\n\n"
101                    "Possible remedies :\n\n"
102                    " 1. Use more automatic local variables and\n"
103                    "    allocate/deallocate adoubles on free store\n"
104                    "     in a strictly last in first out fashion\n\n"
105                    " 2. Extend the range by redefining the type of\n"
106                    "    locint (currently %d byte) from unsigned short "
107                    "(%d byte) or int\n"
108                    "    to int (%d byte) or long (%d byte).\n",
109                    failAdditionalInfo3, (int)sizeof(locint),
110                    (int)sizeof(unsigned short), (int)sizeof(int),
111                    (int)sizeof(long) );
112            break;
113        case ADOLC_TAPING_STORE_REALLOC_FAILED:
114            fprintf(DIAG_OUT, "ADOL-C error: Failure to reallocate storage for "
115                    "adouble values!\n\n"
116                    "              oldStore     = %p\n"
117                    "              newStore     = NULL\n"
118                    "              oldStoreSize = %u\n"
119                    "              newStoreSize = %u\n\n"
120                    "Possible remedies :\n"
121                    " 1. Use more automatic local variables and \n"
122                    "    allocate/deallocate adoubles on free store\n"
123                    "    in a strictly last in first out fashion\n"
124                    " 2. Enlarge your system stacksize limit\n"
125                    , failAdditionalInfo5, failAdditionalInfo3,
126                      failAdditionalInfo4
127                    );
128            break;
129        case ADOLC_TAPING_FATAL_IO_ERROR:
130            fprintf(DIAG_OUT, "ADOL-C error: Fatal error-doing a read or "
131                    "write!\n");
132            printError();
133            break;
134        case ADOLC_TAPING_TAPE_STILL_IN_USE:
135            fprintf(DIAG_OUT, "ADOL-C error: Tape %d is still in use!\n",
136                    failAdditionalInfo1);
137            break;
138        case ADOLC_TAPING_TAYLOR_OPEN_FAILED:
139            fprintf(DIAG_OUT, "ADOL-C error: while opening taylor file!\n");
140            printError();
141            break;
142
143        case ADOLC_EVAL_SEEK_VALUE_STACK:
144            fprintf(DIAG_OUT, "ADOL-C error: in seeking value stack file!\n");
145            break;
146        case ADOLC_EVAL_OP_TAPE_READ_FAILED:
147            fprintf(DIAG_OUT, "ADOL-C error: while reading operations tape!\n");
148            break;
149        case ADOLC_EVAL_VAL_TAPE_READ_FAILED:
150            fprintf(DIAG_OUT, "ADOL-C error: while reading values tape!\n");
151            break;
152        case ADOLC_EVAL_LOC_TAPE_READ_FAILED:
153            fprintf(DIAG_OUT, "ADOL-C error: while reading locations tape!\n");
154            break;
155        case ADOLC_EVAL_TAY_TAPE_READ_FAILED:
156            fprintf(DIAG_OUT, "ADOL-C error: while reading value stack tape!\n");
157            break;
158
159        case ADOLC_REVERSE_NO_TAYLOR_STACK:
160            fprintf(DIAG_OUT, "ADOL-C error: No taylor stack found for tape "
161                    "%d! => Check forward sweep!\n", failAdditionalInfo1);
162            break;
163        case ADOLC_REVERSE_COUNTS_MISMATCH:
164            fprintf(DIAG_OUT, "ADOL-C error: Reverse sweep on tape %d aborted!\n"
165                    "              Number of dependents(%u) and/or "
166                    "independents(%u)\n"
167                    "              variables passed to reverse is "
168                    "inconsistent\n"
169                    "              with number recorded on tape(%u/%u)!\n",
170                    ADOLC_CURRENT_TAPE_INFOS.tapeID, failAdditionalInfo3,
171                    failAdditionalInfo4,
172                    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_DEPENDENTS],
173                    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_INDEPENDENTS]);
174            break;
175        case ADOLC_REVERSE_TAYLOR_COUNTS_MISMATCH:
176            fprintf(DIAG_OUT, "ADOL-C error: Reverse fails on tape %d because "
177                    "the number of independent\n"
178                    "              and/or dependent variables given to"
179                    " reverse are inconsistent\n"
180                    "              with that of the internal taylor "
181                    "array!\n",
182                    ADOLC_CURRENT_TAPE_INFOS.tapeID);
183            break;
184
185        case ADOLC_BUFFER_NULLPOINTER_FUNCTION:
186            fprintf(DIAG_OUT, "ADOL-C error: NULL pointer supplied in buffer "
187                    "handling.\n");
188            break;
189        case ADOLC_BUFFER_INDEX_TO_LARGE:
190            fprintf(DIAG_OUT, "ADOL-C error: Index for buffer element too "
191                    "large.\n");
192            break;
193
194        case ADOLC_EXT_DIFF_NULLPOINTER_STRUCT:
195            fprintf(DIAG_OUT,
196                    "ADOL-C error: Got null pointer as pointer to struct "
197                    " containing ext. diff. function information!\n");
198            break;
199        case ADOLC_EXT_DIFF_WRONG_TAPESTATS:
200            fprintf(DIAG_OUT,
201                    "ADOL-C error: Number of independents/dependents recorded on"
202                    " tape differ from number suplied by user!\n");
203            break;
204        case ADOLC_EXT_DIFF_NULLPOINTER_FUNCTION:
205            fprintf(DIAG_OUT,
206                    "ADOL-C error: Got NULL pointer as "
207                    "extern function pointer!\n");
208            break;
209        case ADOLC_EXT_DIFF_NULLPOINTER_DIFFFUNC:
210            fprintf(DIAG_OUT,
211                    "ADOL-C error: No function for extern differentiation found"
212                    " to work with (null pointer)\n!");
213            break;
214        case ADOLC_EXT_DIFF_NULLPOINTER_ARGUMENT:
215            fprintf(DIAG_OUT,
216                    "ADOL-C error: Got at least one null pointer as argument to"
217                    " extern differnetiated function!\n");
218            break;
219        case ADOLC_EXT_DIFF_WRONG_FUNCTION_INDEX:
220            fprintf(DIAG_OUT,
221                    "ADOL-C error: Function with specified index not found!\n");
222            break;
223
224        case ADOLC_CHECKPOINTING_CPINFOS_NULLPOINTER:
225            fprintf(DIAG_OUT,
226                    "ADOL-C error: Got null pointer as pointer to struct "
227                    " containing checkpointing information!\n");
228            break;
229        case ADOLC_CHECKPOINTING_NULLPOINTER_ARGUMENT:
230            fprintf(DIAG_OUT,
231                    "ADOL-C error: Got null pointer instead of argument pointer "
232                    "within checkpointing infos!\n");
233            break;
234        case ADOLC_CHECKPOINTING_NULLPOINTER_FUNCTION:
235            fprintf(DIAG_OUT,
236                    "ADOL-C error: Got null pointer instead of function pointer "
237                    "within checkpointing infos!\n");
238            break;
239        case ADOLC_CHECKPOINTING_NULLPOINTER_FUNCTION_DOUBLE:
240            fprintf(DIAG_OUT,
241                    "ADOL-C error: Got null pointer instead of function (double "
242                    "version) pointer within checkpointing infos!\n");
243            break;
244        case ADOLC_CHECKPOINTING_REVOLVE_IRREGULAR_TERMINATED:
245            fprintf(DIAG_OUT,
246                    "ADOL-C error: Irregualar termination of REVOLVE!\n");
247            break;
248        case ADOLC_CHECKPOINTING_UNEXPECTED_REVOLVE_ACTION:
249            fprintf(DIAG_OUT,
250                    "ADOL-C error: Unextpected REVOLVE action in forward mode!\n"
251                   );
252            break;
253
254        default:
255            fprintf(DIAG_OUT, "ADOL-C error => unknown error type!\n");
256            exit (-1);
257            break;
258    }
259    exit (error + 1);
260}
261
262/* print an error message describing the error number */
263void printError() {
264    fprintf(DIAG_OUT, "              ");
265    switch (errno) {
266        case EACCES:
267            fprintf(DIAG_OUT, ">>> Access denied! <<<\n");
268            break;
269        case EFBIG:
270            fprintf(DIAG_OUT, ">>> File too big! <<<\n");
271            break;
272        case EMFILE:
273            fprintf(DIAG_OUT, ">>> Too many open files for this process! <<<\n");
274            break;
275        case ENAMETOOLONG:
276            fprintf(DIAG_OUT, ">>> Path/file name too long! <<<\n");
277            break;
278        case ENFILE:
279            fprintf(DIAG_OUT, ">>> Too many open files for this system! <<<\n");
280            break;
281        case ENOENT:
282            fprintf(DIAG_OUT, ">>> File or directory not found! <<<\n");
283            break;
284        case ENOSPC:
285            fprintf(DIAG_OUT, ">>> No space left on device! <<<\n");
286            break;
287        case EPERM:
288            fprintf(DIAG_OUT, ">>> Operation not permitted! <<<\n");
289            break;
290        case EROFS:
291            fprintf(DIAG_OUT, ">>> File system is mounted read only! <<<\n");
292            break;
293        default:
294            fprintf(DIAG_OUT, ">>> ");
295            fprintf(DIAG_OUT, strerror(errno));
296            fprintf(DIAG_OUT, " <<<\n");
297            break;
298    }
299}
300
301/* the base names of every tape type */
302const char *tapeBaseNames[] = {
303            ADOLC_LOCATIONS_NAME,
304            ADOLC_VALUES_NAME,
305            ADOLC_OPERATIONS_NAME,
306            ADOLC_TAYLORS_NAME
307        };
308
309/****************************************************************************/
310/* The subroutine get_fstr appends to the tape base name of type tapeType   */
311/* the number fnum and ".tap" and returns a pointer to the resulting string.*/
312/* The result string must be freed be thy caller!                           */
313/****************************************************************************/
314char *createFileName(short tapeID, int tapeType) {
315    char *numberString, *fileName, *extension = ".tap", *currPos;
316#if defined(_OPENMP)
317    char *threadName = "thread-", *threadNumberString = NULL;
318    int threadNumber, threadNumberStringLength = 0, threadNameLength = 0;
319#endif /* _OPENMP */
320    int tapeBaseNameLength, numberStringLength, fileNameLength;
321    ADOLC_OPENMP_THREAD_NUMBER;
322    ADOLC_OPENMP_GET_THREAD_NUMBER;
323
324    failAdditionalInfo1 = tapeID;
325    tapeBaseNameLength = strlen(tapeBaseNames[tapeType]);
326    /* determine length of the number string */
327    if (tapeID != 0)
328        numberStringLength = (int)log10((double)tapeID);
329    else numberStringLength = 0;
330    ++numberStringLength;
331    numberString = malloc(sizeof(char) * (numberStringLength + 1));
332    if (numberString == NULL) fail(ADOLC_MALLOC_FAILED);
333    sprintf(numberString, "%d", tapeID);
334#if defined(_OPENMP)
335    /* determine length of the thread number string */
336    if (ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 1) {
337        threadNameLength = strlen(threadName);
338        threadNumber = omp_get_thread_num();
339        if (threadNumber != 0)
340            threadNumberStringLength = (int)log10((double)threadNumber);
341        else threadNumberStringLength = 0;
342        ++threadNumberStringLength;
343        threadNumberString =
344            malloc(sizeof(char) * (threadNumberStringLength + 2));
345        if (threadNumberString == NULL) fail(ADOLC_MALLOC_FAILED);
346        sprintf(threadNumberString, "%d", threadNumber);
347        threadNumberString[threadNumberStringLength] = '_';
348        ++threadNumberStringLength;
349        threadNumberString[threadNumberStringLength] = 0;
350    }
351#endif /* _OPENMP */
352
353    /* malloc and create */
354    fileNameLength = tapeBaseNameLength + numberStringLength + 5;
355#if defined(_OPENMP)
356    if (ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 1)
357        fileNameLength += threadNameLength + threadNumberStringLength;
358#endif /* _OPENMP */
359    fileName = (char *)malloc(sizeof(char) * fileNameLength);
360    if (fileName == NULL) fail(ADOLC_MALLOC_FAILED);
361    currPos = fileName;
362    strncpy(currPos, tapeBaseNames[tapeType], tapeBaseNameLength);
363    currPos += tapeBaseNameLength;
364#if defined(_OPENMP)
365    if (ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 1) {
366        strncpy(currPos, threadName, threadNameLength);
367        currPos += threadNameLength;
368        strncpy(currPos, threadNumberString, threadNumberStringLength);
369        currPos += threadNumberStringLength;
370    }
371#endif /* _OPENMP */
372    strncpy(currPos, numberString, numberStringLength);
373    currPos += numberStringLength;
374    strncpy(currPos, extension, 4);
375    currPos += 4;
376    *currPos = 0;
377
378    free(numberString);
379#if defined(_OPENMP)
380    if (ADOLC_GLOBAL_TAPE_VARS.inParallelRegion == 1)
381        free(threadNumberString);
382#endif /* _OPENMP */
383
384    return fileName;
385}
386
387/****************************************************************************/
388/* Tries to read a local config file containing, e.g., buffer sizes         */
389/****************************************************************************/
390#define ADOLC_LINE_LENGTH 100
391void readConfigFile() {
392    FILE *configFile = NULL;
393    char inputLine[ADOLC_LINE_LENGTH + 1];
394    char *pos1 = NULL, *pos2 = NULL, *pos3 = NULL, *pos4 = NULL, *end = NULL;
395    long int number = 0;
396    ADOLC_OPENMP_THREAD_NUMBER;
397    ADOLC_OPENMP_GET_THREAD_NUMBER;
398
399    ADOLC_GLOBAL_TAPE_VARS.operationBufferSize = OBUFSIZE;
400    ADOLC_GLOBAL_TAPE_VARS.locationBufferSize = LBUFSIZE;
401    ADOLC_GLOBAL_TAPE_VARS.valueBufferSize = VBUFSIZE;
402    ADOLC_GLOBAL_TAPE_VARS.taylorBufferSize = TBUFSIZE;
403    ADOLC_GLOBAL_TAPE_VARS.maxNumberTaylorBuffers = TBUFNUM;
404    if ((configFile = fopen(".adolcrc", "r")) != NULL) {
405        fprintf(DIAG_OUT, "\nFile .adolcrc found! => Try to parse it!\n");
406        fprintf(DIAG_OUT, "****************************************\n");
407        while (fgets(inputLine, ADOLC_LINE_LENGTH + 1, configFile) == inputLine) {
408            if (strlen(inputLine) == ADOLC_LINE_LENGTH &&
409                    inputLine[ADOLC_LINE_LENGTH - 1] != 0xA) {
410                fprintf(DIAG_OUT, "ADOL-C warning: Input line in .adolcrc exceeds"
411                        " %d characters!\n", ADOLC_LINE_LENGTH);
412                fprintf(DIAG_OUT, "                => Parsing aborted!!\n");
413                break;
414            }
415            pos1 = strchr(inputLine, '"');
416            pos2 = NULL;
417            pos3 = NULL;
418            pos4 = NULL;
419            if (pos1 != NULL) {
420                pos2 = strchr(pos1 + 1, '"');
421                if (pos2 != NULL) {
422                    pos3 = strchr(pos2 + 1, '"');
423                    if (pos3 != NULL) pos4 = strchr(pos3 + 1, '"');
424                }
425            }
426            if (pos4 == NULL) {
427                if (pos1 != NULL)
428                    fprintf(DIAG_OUT, "ADOL-C warning: Malformed input line "
429                            "in .adolcrc ignored!\n");
430            } else {
431                number = strtol(pos3 + 1, &end, 10);
432                if (end == (pos3 + 1)) {
433                    fprintf(DIAG_OUT, "ADOL-C warning: Unable to parse number in "
434                            ".adolcrc!\n");
435                } else {
436                    *pos2 = 0;
437                    *pos4 = 0;
438                    if (strcmp(pos1 + 1, "OBUFSIZE") == 0) {
439                        ADOLC_GLOBAL_TAPE_VARS.operationBufferSize = (locint)number;
440                        fprintf(DIAG_OUT, "Found operation buffer size: %u\n",
441                                (locint)number);
442                    } else if (strcmp(pos1 + 1, "LBUFSIZE") == 0) {
443                        ADOLC_GLOBAL_TAPE_VARS.locationBufferSize = (locint)number;
444                        fprintf(DIAG_OUT, "Found location buffer size: %u\n",
445                                (locint)number);
446                    } else if (strcmp(pos1 + 1, "VBUFSIZE") == 0) {
447                        ADOLC_GLOBAL_TAPE_VARS.valueBufferSize = (locint)number;
448                        fprintf(DIAG_OUT, "Found value buffer size: %u\n",
449                                (locint)number);
450                    } else if (strcmp(pos1 + 1, "TBUFSIZE") == 0) {
451                        ADOLC_GLOBAL_TAPE_VARS.taylorBufferSize = (locint)number;
452                        fprintf(DIAG_OUT, "Found taylor buffer size: %u\n",
453                                (locint)number);
454                    } else if (strcmp(pos1 + 1, "TBUFNUM") == 0) {
455                        ADOLC_GLOBAL_TAPE_VARS.maxNumberTaylorBuffers = (int)number;
456                        fprintf(DIAG_OUT, "Found maximal number of taylor buffers: "
457                                "%d\n", (int)number);
458                    } else {
459                        fprintf(DIAG_OUT, "ADOL-C warning: Unable to parse "
460                                "parameter name in .adolcrc!\n");
461                    }
462                }
463            }
464        }
465        fprintf(DIAG_OUT, "****************************************\n\n");
466        fclose(configFile);
467    }
468    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
469}
470
471/****************************************************************************/
472/****************************************************************************/
473/* VALUE STACK FUNCTIONS                                                    */
474/****************************************************************************/
475/****************************************************************************/
476
477static unsigned int numTBuffersInUse = 0;
478
479/* record all existing adoubles on the tape
480 * - intended to be used in start_trace only */
481void take_stock() {
482    locint space_left, vals_left, loc = 0;
483    double *vals;
484    ADOLC_OPENMP_THREAD_NUMBER;
485
486    ADOLC_OPENMP_GET_THREAD_NUMBER;
487    space_left  = get_val_space(); /* remaining space in const. tape buffer */
488    vals_left = ADOLC_GLOBAL_TAPE_VARS.locMinUnused;
489    vals      = ADOLC_GLOBAL_TAPE_VARS.store;
490
491    /* fill the current values (real) tape buffer and write it to disk
492     * - do this as long as buffer can be fully filled */
493    while (space_left < vals_left) {
494        put_op(take_stock_op);
495        ADOLC_PUT_LOCINT(space_left);
496        ADOLC_PUT_LOCINT(loc);
497        put_vals_writeBlock(vals, space_left);
498        vals      += space_left;
499        vals_left -= space_left;
500        loc       += space_left;
501        space_left = get_val_space();
502    }
503    /* store the remaining adouble values to the values tape buffer
504     * -> no write to disk necessary */
505    if (vals_left > 0) {
506        put_op(take_stock_op);
507        ADOLC_PUT_LOCINT(vals_left);
508        ADOLC_PUT_LOCINT(loc);
509        put_vals_notWriteBlock(vals, vals_left);
510    }
511    ADOLC_CURRENT_TAPE_INFOS.traceFlag = 1;
512}
513
514/****************************************************************************/
515/* record all remaining live variables on the value stack tape              */
516/* - turns off trace_flag                                                   */
517/* - intended to be used in stop_trace only                                 */
518/****************************************************************************/
519locint keep_stock() {
520    ADOLC_OPENMP_THREAD_NUMBER;
521    ADOLC_OPENMP_GET_THREAD_NUMBER;
522    /* if we have adoubles in use */
523    if (ADOLC_GLOBAL_TAPE_VARS.numMaxAlive > 0) {
524        locint loc2 = ADOLC_GLOBAL_TAPE_VARS.numMaxAlive - 1;
525
526        /* special signal -> all alive adoubles recorded on the end of the
527         * value stack -> special handling at the beginning of reverse */
528        put_op(death_not);
529        ADOLC_PUT_LOCINT(0);    /* lowest loc */
530        ADOLC_PUT_LOCINT(loc2); /* highest loc */
531
532        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape += ADOLC_GLOBAL_TAPE_VARS.numMaxAlive;
533        /* now really do it if keepTaylors ist set */
534        if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors) {
535            do {
536                ADOLC_WRITE_SCAYLOR(ADOLC_GLOBAL_TAPE_VARS.store[loc2]);
537            } while (loc2-- > 0);
538        }
539    }
540    ADOLC_CURRENT_TAPE_INFOS.traceFlag = 0;
541    return ADOLC_GLOBAL_TAPE_VARS.numMaxAlive;
542}
543
544
545void updateLocs() {
546    ADOLC_OPENMP_THREAD_NUMBER;
547    ADOLC_OPENMP_GET_THREAD_NUMBER;
548
549    /* deallocate dead adoubles if they form a contiguous tail */
550    #ifdef overwrite
551    if (ADOLC_GLOBAL_TAPE_VARS.numToFree &&
552            ADOLC_GLOBAL_TAPE_VARS.minLocToFree + ADOLC_GLOBAL_TAPE_VARS.numToFree ==
553            ADOLC_GLOBAL_TAPE_VARS.locMinUnused) {
554        ADOLC_GLOBAL_TAPE_VARS.locMinUnused = ADOLC_GLOBAL_TAPE_VARS.minLocToFree ;
555        ADOLC_GLOBAL_TAPE_VARS.numToFree = 0;
556        ADOLC_GLOBAL_TAPE_VARS.minLocToFree = ADOLC_GLOBAL_TAPE_VARS.maxLoc;
557    }
558    #endif
559}
560
561/****************************************************************************/
562/* Returns the next free location in "adouble" memory.                      */
563/****************************************************************************/
564locint next_loc() {
565    locint newStoreSize;
566    ADOLC_OPENMP_THREAD_NUMBER;
567    ADOLC_OPENMP_GET_THREAD_NUMBER;
568
569    updateLocs();
570    if (ADOLC_GLOBAL_TAPE_VARS.locMinUnused == ADOLC_GLOBAL_TAPE_VARS.numMaxAlive)
571        ++ADOLC_GLOBAL_TAPE_VARS.numMaxAlive;
572    if (ADOLC_GLOBAL_TAPE_VARS.numMaxAlive > ADOLC_GLOBAL_TAPE_VARS.storeSize) {
573        /* try to double (plus 2) the available space */
574        ++ADOLC_GLOBAL_TAPE_VARS.storeSize;
575        if (ADOLC_GLOBAL_TAPE_VARS.storeSize == ADOLC_GLOBAL_TAPE_VARS.maxLoc) {
576            failAdditionalInfo1 = ADOLC_GLOBAL_TAPE_VARS.maxLoc;
577            fail(ADOLC_TAPING_TO_MANY_LOCINTS);
578        }
579        failAdditionalInfo3 = ADOLC_GLOBAL_TAPE_VARS.storeSize;
580        newStoreSize = ADOLC_GLOBAL_TAPE_VARS.storeSize * 2;
581        ADOLC_GLOBAL_TAPE_VARS.storeSize = newStoreSize;
582        failAdditionalInfo4 = newStoreSize;
583        failAdditionalInfo5 = ADOLC_GLOBAL_TAPE_VARS.store;
584        if (ADOLC_GLOBAL_TAPE_VARS.store == NULL) {
585            ADOLC_GLOBAL_TAPE_VARS.store =
586                (double *)malloc(ADOLC_GLOBAL_TAPE_VARS.storeSize * sizeof(double));
587            ADOLC_GLOBAL_TAPE_VARS.minLocToFree = ADOLC_GLOBAL_TAPE_VARS.maxLoc;
588        } else
589            ADOLC_GLOBAL_TAPE_VARS.store =
590                (double *)realloc((char *)ADOLC_GLOBAL_TAPE_VARS.store,
591                        ADOLC_GLOBAL_TAPE_VARS.storeSize * sizeof(double));
592        if (ADOLC_GLOBAL_TAPE_VARS.store == NULL)
593            fail(ADOLC_TAPING_STORE_REALLOC_FAILED);
594    }
595    return ADOLC_GLOBAL_TAPE_VARS.locMinUnused++;
596}
597
598/****************************************************************************/
599/* Returns the next #size free locations in "adouble" memory.               */
600/****************************************************************************/
601locint next_loc_v(int size) {
602    locint newStoreSize, retVal;
603    ADOLC_OPENMP_THREAD_NUMBER;
604    ADOLC_OPENMP_GET_THREAD_NUMBER;
605
606    updateLocs();
607    if (ADOLC_GLOBAL_TAPE_VARS.locMinUnused + size > ADOLC_GLOBAL_TAPE_VARS.numMaxAlive)
608        ADOLC_GLOBAL_TAPE_VARS.numMaxAlive = ADOLC_GLOBAL_TAPE_VARS.locMinUnused + size;
609    while (ADOLC_GLOBAL_TAPE_VARS.numMaxAlive > ADOLC_GLOBAL_TAPE_VARS.storeSize) {
610        /* try to double (plus 2) the available space */
611        ++ADOLC_GLOBAL_TAPE_VARS.storeSize;
612        if (ADOLC_GLOBAL_TAPE_VARS.storeSize*2 > ADOLC_GLOBAL_TAPE_VARS.maxLoc)
613            newStoreSize = ADOLC_GLOBAL_TAPE_VARS.maxLoc;
614        else newStoreSize = ADOLC_GLOBAL_TAPE_VARS.storeSize * 2;
615        if (newStoreSize == ADOLC_GLOBAL_TAPE_VARS.maxLoc) {
616            failAdditionalInfo3 = ADOLC_GLOBAL_TAPE_VARS.maxLoc;
617            fail(ADOLC_TAPING_TO_MANY_LOCINTS);
618        } else {
619            ADOLC_GLOBAL_TAPE_VARS.storeSize = newStoreSize;
620            if (ADOLC_GLOBAL_TAPE_VARS.storeSize == 2) {
621                ADOLC_GLOBAL_TAPE_VARS.store =
622                    (double *)malloc(ADOLC_GLOBAL_TAPE_VARS.storeSize * sizeof(double));
623                ADOLC_GLOBAL_TAPE_VARS.minLocToFree = ADOLC_GLOBAL_TAPE_VARS.maxLoc;
624            } else
625                ADOLC_GLOBAL_TAPE_VARS.store =
626                    (double *)realloc((char *)ADOLC_GLOBAL_TAPE_VARS.store,
627                            ADOLC_GLOBAL_TAPE_VARS.storeSize * sizeof(double));
628            if (ADOLC_GLOBAL_TAPE_VARS.store == NULL)
629                fail(ADOLC_TAPING_STORE_REALLOC_FAILED);
630        }
631    }
632    #if defined(ADOLC_DEBUG)
633    fprintf (DIAG_OUT, "ADOL-C debug: Top is: %d !\n",
634            ADOLC_GLOBAL_TAPE_VARS.locMinUnused + size);
635    #endif
636    retVal = ADOLC_GLOBAL_TAPE_VARS.locMinUnused;
637    ADOLC_GLOBAL_TAPE_VARS.locMinUnused += size;
638    return retVal;
639}
640
641/****************************************************************************/
642/* Set up statics for writing taylor data                                   */
643/****************************************************************************/
644void taylor_begin(uint bufferSize, double **Tg, int degreeSave) {
645    ADOLC_OPENMP_THREAD_NUMBER;
646    ADOLC_OPENMP_GET_THREAD_NUMBER;
647    if (ADOLC_CURRENT_TAPE_INFOS.tayBuffer != NULL) {
648        #     if defined(ADOLC_DEBUG)
649            fprintf(DIAG_OUT, "\nADOL-C warning: !!! Taylor information for tape %d"
650                    " found that will be overwritten !!!\n\n",
651                    ADOLC_CURRENT_TAPE_INFOS.tapeID);
652        #     endif
653        taylor_close(0);
654    } else { /* check if new buffer is allowed */
655        if (numTBuffersInUse == ADOLC_GLOBAL_TAPE_VARS.maxNumberTaylorBuffers)
656            fail(ADOLC_TAPING_TO_MANY_TAYLOR_BUFFERS);
657        ++numTBuffersInUse;
658        if (ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.tay_fileName == NULL)
659            ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.tay_fileName =
660                createFileName(ADOLC_CURRENT_TAPE_INFOS.tapeID, TAYLORS_TAPE);
661    }
662
663    /* initial setups */
664    ADOLC_CURRENT_TAPE_INFOS.dpp_T = Tg;
665    if (ADOLC_CURRENT_TAPE_INFOS.tayBuffer != NULL)
666        free(ADOLC_CURRENT_TAPE_INFOS.tayBuffer);
667    ADOLC_CURRENT_TAPE_INFOS.tayBuffer = (revreal *)
668            malloc(sizeof(revreal) * bufferSize);
669    if (ADOLC_CURRENT_TAPE_INFOS.tayBuffer == NULL)
670        fail(ADOLC_TAPING_TBUFFER_ALLOCATION_FAILED);
671    ADOLC_CURRENT_TAPE_INFOS.deg_save = degreeSave;
672    if (degreeSave >= 0 ) ADOLC_CURRENT_TAPE_INFOS.keepTaylors = 1;
673    ADOLC_CURRENT_TAPE_INFOS.currTay = ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
674    ADOLC_CURRENT_TAPE_INFOS.lastTayP1 = ADOLC_CURRENT_TAPE_INFOS.currTay + bufferSize;
675    ADOLC_CURRENT_TAPE_INFOS.inUse = 1;
676
677    ADOLC_CURRENT_TAPE_INFOS.numTays_Tape = 0;
678}
679
680/****************************************************************************/
681/* Close the taylor file, reset data.                                       */
682/****************************************************************************/
683void taylor_close(uint buffer) {
684    ADOLC_OPENMP_THREAD_NUMBER;
685    ADOLC_OPENMP_GET_THREAD_NUMBER;
686
687    if (buffer == 0) {
688        /* enforces failure of reverse => retaping */
689        ADOLC_CURRENT_TAPE_INFOS.deg_save = -1;
690        if (ADOLC_CURRENT_TAPE_INFOS.tay_file != NULL) {
691            fclose(ADOLC_CURRENT_TAPE_INFOS.tay_file);
692            remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.tay_fileName);
693            ADOLC_CURRENT_TAPE_INFOS.tay_file = NULL;
694        }
695        return;
696    }
697
698    if (ADOLC_CURRENT_TAPE_INFOS.tay_file != NULL) {
699        if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors)
700            put_tay_block(ADOLC_CURRENT_TAPE_INFOS.currTay);
701    } else {
702        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape =
703            ADOLC_CURRENT_TAPE_INFOS.currTay -
704            ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
705    }
706    ADOLC_CURRENT_TAPE_INFOS.lastTayBlockInCore = 1;
707    ADOLC_CURRENT_TAPE_INFOS.stats[TAY_STACK_SIZE] =
708        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape;
709
710    /* keep track of the Ind/Dep counts of the taylor stack */
711    ADOLC_CURRENT_TAPE_INFOS.tay_numInds =
712        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_INDEPENDENTS];
713    ADOLC_CURRENT_TAPE_INFOS.tay_numDeps =
714        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_DEPENDENTS];
715
716    #if defined(ADOLC_DEBUG)
717    if (ADOLC_CURRENT_TAPE_INFOS.tay_file != NULL)
718        fprintf(DIAG_OUT, "\n ADOL-C debug: Taylor file of length %d bytes "
719                "completed\n",
720                (int)(ADOLC_CURRENT_TAPE_INFOS.numTays_Tape*sizeof(revreal)));
721    else
722        fprintf(DIAG_OUT, "\n ADOL-C debug: Taylor array of length %d bytes "
723                "completed\n",
724                (int)(ADOLC_CURRENT_TAPE_INFOS.numTays_Tape*sizeof(revreal)));
725    #endif
726}
727
728/****************************************************************************/
729/* Initializes a reverse sweep.                                             */
730/****************************************************************************/
731void taylor_back (short tag, int* dep, int* ind, int* degree) {
732    int i, chunks;
733    size_t number, remain, chunkSize;
734    ADOLC_OPENMP_THREAD_NUMBER;
735    ADOLC_OPENMP_GET_THREAD_NUMBER;
736
737    /* this should be removed soon since values can be accessed via         */
738    /* ADOLC_CURRENT_TAPE_INFOS directly                                    */
739    *dep    = ADOLC_CURRENT_TAPE_INFOS.tay_numDeps;
740    *ind    = ADOLC_CURRENT_TAPE_INFOS.tay_numInds;
741    *degree = ADOLC_CURRENT_TAPE_INFOS.deg_save;
742
743    if (ADOLC_CURRENT_TAPE_INFOS.tayBuffer == NULL)
744        fail(ADOLC_REVERSE_NO_TAYLOR_STACK);
745    ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber =
746        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape /
747        ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE];
748    number = ADOLC_CURRENT_TAPE_INFOS.numTays_Tape %
749           ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE];
750    ADOLC_CURRENT_TAPE_INFOS.currTay =
751        ADOLC_CURRENT_TAPE_INFOS.tayBuffer + number;
752    if (ADOLC_CURRENT_TAPE_INFOS.lastTayBlockInCore != 1) {
753        if ( fseek(ADOLC_CURRENT_TAPE_INFOS.tay_file,
754                sizeof(revreal) *
755                ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber *
756                ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE],
757                SEEK_SET)
758                == -1 ) fail(ADOLC_EVAL_SEEK_VALUE_STACK);
759        chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(revreal);
760        chunks = number / chunkSize;
761        for (i = 0; i < chunks; ++i)
762            if ((failAdditionalInfo1 =
763                        fread(ADOLC_CURRENT_TAPE_INFOS.tayBuffer +
764                            i * chunkSize, chunkSize * sizeof(revreal), 1,
765                            ADOLC_CURRENT_TAPE_INFOS.tay_file)) != 1)
766                fail(ADOLC_TAPING_FATAL_IO_ERROR);
767        remain = number % chunkSize;
768        if (remain != 0)
769            if ((failAdditionalInfo1 =
770                        fread(ADOLC_CURRENT_TAPE_INFOS.tayBuffer +
771                            chunks * chunkSize, remain * sizeof(revreal), 1,
772                            ADOLC_CURRENT_TAPE_INFOS.tay_file)) != 1)
773                fail(ADOLC_TAPING_FATAL_IO_ERROR);
774    }
775    --ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber;
776}
777
778/****************************************************************************/
779/* Writes the block of size depth of taylor coefficients from point loc to  */
780/* the taylor buffer. If the buffer is filled, then it is written to the    */
781/* taylor tape.                                                             */
782/****************************************************************************/
783void write_taylor(locint loc, int keep) {
784    revreal *i;
785    double *T;
786    ADOLC_OPENMP_THREAD_NUMBER;
787
788    ADOLC_OPENMP_GET_THREAD_NUMBER;
789    T = ADOLC_CURRENT_TAPE_INFOS.dpp_T[loc];
790
791    /* write data to buffer and put buffer to disk as long as data remain in
792     * the T-buffer => don't create an empty value stack buffer! */
793    while (ADOLC_CURRENT_TAPE_INFOS.currTay + keep > ADOLC_CURRENT_TAPE_INFOS.lastTayP1) {
794        for (i = ADOLC_CURRENT_TAPE_INFOS.currTay; i < ADOLC_CURRENT_TAPE_INFOS.lastTayP1; ++i) {
795            *i = (revreal) * T;
796            /* In this assignment the precision will be sacrificed if the type
797             * revreal is defined as float. */
798            ++T;
799        }
800        keep -= ADOLC_CURRENT_TAPE_INFOS.lastTayP1 - ADOLC_CURRENT_TAPE_INFOS.currTay;
801        put_tay_block(ADOLC_CURRENT_TAPE_INFOS.lastTayP1);
802    }
803
804    for (i = ADOLC_CURRENT_TAPE_INFOS.currTay; i < ADOLC_CURRENT_TAPE_INFOS.currTay + keep; ++i) {
805        *i = (revreal) * T;
806        /* In this assignment the precision will be sacrificed
807         * if the type revreal is defined as float. */
808        ++T;
809    }
810    ADOLC_CURRENT_TAPE_INFOS.currTay += keep;
811}
812
813/****************************************************************************/
814/* Writes the block of size depth of taylor coefficients from point loc to  */
815/* the taylor buffer.  If the buffer is filled, then it is written to the   */
816/* taylor tape.                                                             */
817/*--------------------------------------------------------------------------*/
818void write_taylors(locint loc, int keep, int degree, int numDir) {
819    int i, j;
820    double *T;
821    ADOLC_OPENMP_THREAD_NUMBER;
822
823    ADOLC_OPENMP_GET_THREAD_NUMBER;
824    T = ADOLC_CURRENT_TAPE_INFOS.dpp_T[loc];
825
826    for (j = 0; j < numDir; ++j) {
827        for (i = 0; i < keep; ++i) {
828            if (ADOLC_CURRENT_TAPE_INFOS.currTay == ADOLC_CURRENT_TAPE_INFOS.lastTayP1)
829                put_tay_block(ADOLC_CURRENT_TAPE_INFOS.lastTayP1);
830            *ADOLC_CURRENT_TAPE_INFOS.currTay = (revreal) * T;
831            /* The precision will be sacrificed if the type
832             * revreal is defined as float. */
833            ++ADOLC_CURRENT_TAPE_INFOS.currTay;
834            ++T;
835        }
836/*        for (i = keep; i < degree; ++i) ++T;*/
837        if (degree > keep)
838            T += degree - keep;
839    }
840}
841
842/****************************************************************************/
843/* Write_scaylors writes # size elements from x to the taylor buffer.       */
844/****************************************************************************/
845void write_scaylors(revreal *x, uint size) {
846    revreal *i;
847    uint j = 0;
848    ADOLC_OPENMP_THREAD_NUMBER;
849    ADOLC_OPENMP_GET_THREAD_NUMBER;
850
851    /* write data to buffer and put buffer to disk as long as data remain in
852     * the x-buffer => don't create an empty value stack buffer! */
853    while (ADOLC_CURRENT_TAPE_INFOS.currTay + size > ADOLC_CURRENT_TAPE_INFOS.lastTayP1) {
854        for (i = ADOLC_CURRENT_TAPE_INFOS.currTay; i < ADOLC_CURRENT_TAPE_INFOS.lastTayP1; ++i) {
855            *i = x[j];
856            ++j;
857        }
858        size -= ADOLC_CURRENT_TAPE_INFOS.lastTayP1 - ADOLC_CURRENT_TAPE_INFOS.currTay;
859        put_tay_block(ADOLC_CURRENT_TAPE_INFOS.lastTayP1);
860    }
861
862    for (i = ADOLC_CURRENT_TAPE_INFOS.currTay; i < ADOLC_CURRENT_TAPE_INFOS.tayBuffer + size; ++i) {
863        *ADOLC_CURRENT_TAPE_INFOS.currTay = x[j];
864        ++j;
865    }
866    ADOLC_CURRENT_TAPE_INFOS.currTay += size;
867}
868
869/****************************************************************************/
870/* Writes the value stack buffer onto hard disk.                            */
871/****************************************************************************/
872void put_tay_block(revreal *lastTayP1) {
873    int i, chunks;
874    size_t number, remain, chunkSize;
875    ADOLC_OPENMP_THREAD_NUMBER;
876    ADOLC_OPENMP_GET_THREAD_NUMBER;
877
878    if (ADOLC_CURRENT_TAPE_INFOS.tay_file == NULL) {
879        ADOLC_CURRENT_TAPE_INFOS.tay_file =
880            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.tay_fileName, "w+b");
881        if (ADOLC_CURRENT_TAPE_INFOS.tay_file == NULL)
882            fail(ADOLC_TAPING_TAYLOR_OPEN_FAILED);
883    }
884    number = lastTayP1 - ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
885    if (number != 0) {
886        chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(revreal);
887        chunks = number / chunkSize;
888        for (i = 0; i < chunks; ++i)
889            if ((failAdditionalInfo1 =
890                    fwrite(ADOLC_CURRENT_TAPE_INFOS.tayBuffer + i *
891                            chunkSize, chunkSize * sizeof(revreal), 1,
892                            ADOLC_CURRENT_TAPE_INFOS.tay_file) ) != 1)
893                fail(ADOLC_TAPING_FATAL_IO_ERROR);
894        remain = number % chunkSize;
895        if (remain != 0)
896            if ((failAdditionalInfo1 =
897                    fwrite(ADOLC_CURRENT_TAPE_INFOS.tayBuffer + chunks *
898                            chunkSize, remain * sizeof(revreal), 1,
899                            ADOLC_CURRENT_TAPE_INFOS.tay_file) ) != 1)
900                fail(ADOLC_TAPING_FATAL_IO_ERROR);
901        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape += number;
902    }
903    ADOLC_CURRENT_TAPE_INFOS.currTay = ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
904    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
905}
906
907/****************************************************************************/
908/* Puts a block of taylor coefficients from the value stack buffer to the   */
909/* taylor buffer. --- Higher Order Scalar                                   */
910/****************************************************************************/
911void get_taylors(locint loc, int degree) {
912    int j;
913    revreal *i;
914    revreal *T;
915    ADOLC_OPENMP_THREAD_NUMBER;
916
917    ADOLC_OPENMP_GET_THREAD_NUMBER;
918    T = ADOLC_CURRENT_TAPE_INFOS.rpp_T[loc] + degree;
919
920    /* As long as all values from the taylor stack buffer will be used copy
921     * them into the taylor buffer and load the next (previous) buffer. */
922    while (ADOLC_CURRENT_TAPE_INFOS.currTay - degree < ADOLC_CURRENT_TAPE_INFOS.tayBuffer) {
923        for ( i = ADOLC_CURRENT_TAPE_INFOS.currTay - 1;
924                i >= ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
925                --i ) {
926            --T;
927            *T = *i;
928        }
929        degree -= ADOLC_CURRENT_TAPE_INFOS.currTay - ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
930        get_tay_block_r();
931    }
932
933    /* Copy the remaining values from the stack into the buffer ... */
934    for (j = 0; j < degree; ++j) {
935        --ADOLC_CURRENT_TAPE_INFOS.currTay;
936        --T;
937        *T = *ADOLC_CURRENT_TAPE_INFOS.currTay;
938    }
939}
940
941/****************************************************************************/
942/* Puts a block of taylor coefficients from the value stack buffer to the   */
943/* taylor buffer. --- Higher Order Vector                                   */
944/****************************************************************************/
945void get_taylors_p(locint loc, int degree, int numDir) {
946    int i, j;
947    revreal *T;
948    ADOLC_OPENMP_THREAD_NUMBER;
949
950    ADOLC_OPENMP_GET_THREAD_NUMBER;
951    T = ADOLC_CURRENT_TAPE_INFOS.rpp_T[loc] + degree * numDir;
952
953    /* update the directions except the base point parts */
954    for (j = 0; j < numDir; ++j) {
955        for (i = 1; i < degree; ++i) {
956            if (ADOLC_CURRENT_TAPE_INFOS.currTay == ADOLC_CURRENT_TAPE_INFOS.tayBuffer)
957                get_tay_block_r();
958            --ADOLC_CURRENT_TAPE_INFOS.currTay;
959            --T;
960            *T = *ADOLC_CURRENT_TAPE_INFOS.currTay;
961        }
962        --T; /* skip the base point part */
963    }
964    /* now update the base point parts */
965    --ADOLC_CURRENT_TAPE_INFOS.currTay;
966    for (i = 0; i < numDir; ++i) {
967        *T = *ADOLC_CURRENT_TAPE_INFOS.currTay;
968        T += degree;
969    }
970}
971
972/****************************************************************************/
973/* Gets the next (previous block) of the value stack                        */
974/****************************************************************************/
975void get_tay_block_r() {
976    int i, chunks;
977    size_t number, remain, chunkSize;
978    ADOLC_OPENMP_THREAD_NUMBER;
979    ADOLC_OPENMP_GET_THREAD_NUMBER;
980
981    ADOLC_CURRENT_TAPE_INFOS.lastTayBlockInCore = 0;
982    number = ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE];
983    if ( fseek(ADOLC_CURRENT_TAPE_INFOS.tay_file, sizeof(revreal) *
984                ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber * number, SEEK_SET)
985            == -1 )
986        fail(ADOLC_EVAL_SEEK_VALUE_STACK);
987    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(revreal);
988    chunks = number / chunkSize;
989    for (i = 0; i < chunks; ++i)
990        if ((failAdditionalInfo1 = fread(ADOLC_CURRENT_TAPE_INFOS.tayBuffer +
991                        i * chunkSize, chunkSize * sizeof(revreal), 1,
992                        ADOLC_CURRENT_TAPE_INFOS.tay_file)) != 1)
993            fail(ADOLC_TAPING_FATAL_IO_ERROR);
994    remain = number % chunkSize;
995    if (remain != 0)
996        if ((failAdditionalInfo1 = fread(ADOLC_CURRENT_TAPE_INFOS.tayBuffer +
997                        chunks * chunkSize, remain * sizeof(revreal), 1,
998                        ADOLC_CURRENT_TAPE_INFOS.tay_file)) != 1)
999            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1000    ADOLC_CURRENT_TAPE_INFOS.currTay = ADOLC_CURRENT_TAPE_INFOS.lastTayP1;
1001    --ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber;
1002}
1003
1004
1005/****************************************************************************/
1006/****************************************************************************/
1007/* NON-VALUE-STACK FUNCTIONS                                                */
1008/****************************************************************************/
1009/****************************************************************************/
1010
1011void initTapeBuffers() {
1012    ADOLC_OPENMP_THREAD_NUMBER;
1013    ADOLC_OPENMP_GET_THREAD_NUMBER;
1014
1015    if (ADOLC_CURRENT_TAPE_INFOS.opBuffer == NULL)
1016        ADOLC_CURRENT_TAPE_INFOS.opBuffer = (unsigned char *)
1017                malloc(ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE] *
1018                       sizeof(unsigned char));
1019    if (ADOLC_CURRENT_TAPE_INFOS.locBuffer == NULL)
1020        ADOLC_CURRENT_TAPE_INFOS.locBuffer = (locint *)
1021                malloc(ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE] * sizeof(locint));
1022    if (ADOLC_CURRENT_TAPE_INFOS.valBuffer == NULL)
1023        ADOLC_CURRENT_TAPE_INFOS.valBuffer = (double *)
1024                malloc(ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE] * sizeof(double));
1025    if ( ADOLC_CURRENT_TAPE_INFOS.opBuffer  == NULL ||
1026            ADOLC_CURRENT_TAPE_INFOS.locBuffer == NULL ||
1027            ADOLC_CURRENT_TAPE_INFOS.valBuffer == NULL )
1028        fail(ADOLC_TAPING_BUFFER_ALLOCATION_FAILED);
1029    ADOLC_CURRENT_TAPE_INFOS.lastOpP1 = ADOLC_CURRENT_TAPE_INFOS.opBuffer +
1030            ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE];
1031    ADOLC_CURRENT_TAPE_INFOS.lastLocP1 = ADOLC_CURRENT_TAPE_INFOS.locBuffer +
1032            ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1033    ADOLC_CURRENT_TAPE_INFOS.lastValP1 = ADOLC_CURRENT_TAPE_INFOS.valBuffer +
1034            ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1035}
1036
1037/****************************************************************************/
1038/* start_trace: (part of trace_on)                                          */
1039/* Initialization for the taping process. Does buffer allocation, sets      */
1040/* files names, and calls appropriate setup routines.                       */
1041/****************************************************************************/
1042void start_trace() {
1043    int i, space;
1044    ADOLC_OPENMP_THREAD_NUMBER;
1045    ADOLC_OPENMP_GET_THREAD_NUMBER;
1046
1047    initTapeBuffers();
1048    ADOLC_CURRENT_TAPE_INFOS.currOp  = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1049    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1050    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1051
1052    /* Put operation denoting the start_of_the tape */
1053    put_op(start_of_tape);
1054
1055    /* Leave space for the stats */
1056    space = STAT_SIZE * sizeof(uint) + sizeof(ADOLC_ID);
1057    if (space > statSpace * sizeof(locint))
1058        fail(ADOLC_MORE_STAT_SPACE_REQUIRED);
1059    for (i = 0; i < statSpace; ++i) ADOLC_PUT_LOCINT(0);
1060
1061    /* free locations if possible => take_stock may benefit */
1062    if (ADOLC_GLOBAL_TAPE_VARS.minLocToFree +
1063            ADOLC_GLOBAL_TAPE_VARS.numToFree ==
1064            ADOLC_GLOBAL_TAPE_VARS.locMinUnused) {
1065        ADOLC_GLOBAL_TAPE_VARS.locMinUnused =
1066            ADOLC_GLOBAL_TAPE_VARS.minLocToFree ;
1067        ADOLC_GLOBAL_TAPE_VARS.numToFree = 0;
1068        ADOLC_GLOBAL_TAPE_VARS.minLocToFree = ADOLC_GLOBAL_TAPE_VARS.maxLoc;
1069    }
1070
1071    /* initialize value stack if necessary */
1072    if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors)
1073        taylor_begin(ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE], NULL, 0);
1074
1075    /* mark possible (hard disk) tape creation */
1076    markNewTape();
1077}
1078
1079/****************************************************************************/
1080/* Stop Tracing.  Clean up, and turn off trace_flag.                        */
1081/****************************************************************************/
1082void stop_trace(int flag) {
1083    ADOLC_OPENMP_THREAD_NUMBER;
1084    ADOLC_OPENMP_GET_THREAD_NUMBER;
1085    put_op(end_of_tape);        /* Mark end of tape. */
1086
1087    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_INDEPENDENTS] =
1088        ADOLC_CURRENT_TAPE_INFOS.numInds;
1089    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_DEPENDENTS] =
1090        ADOLC_CURRENT_TAPE_INFOS.numDeps;
1091    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_MAX_LIVES] =
1092        ADOLC_GLOBAL_TAPE_VARS.numMaxAlive;
1093
1094    taylor_close(ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE]);
1095
1096    /* The taylor stack size base estimation results in a doubled taylor count
1097     * if we tape with keep (taylors counted in adouble.cpp/avector.cpp and
1098     * "keep_stock" even if not written and a second time when actually
1099     * written by "put_tay_block"). Correction follows here. */
1100    if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors != 0 &&
1101            ADOLC_CURRENT_TAPE_INFOS.tay_file != NULL)
1102    {
1103        ADOLC_CURRENT_TAPE_INFOS.stats[TAY_STACK_SIZE] /= 2;
1104        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape /= 2;
1105    }
1106
1107    close_tape(flag); /* closes the tape, files up stats, and writes the
1108                         tape stats to the integer tape */
1109}
1110
1111/****************************************************************************/
1112/* Close open tapes, update stats and clean up.                             */
1113/****************************************************************************/
1114void close_tape(int flag) {
1115    ADOLC_OPENMP_THREAD_NUMBER;
1116    ADOLC_OPENMP_GET_THREAD_NUMBER;
1117    /* finish operations tape, close it, update stats */
1118    if (flag != 0 || ADOLC_CURRENT_TAPE_INFOS.op_file != NULL) {
1119        if (ADOLC_CURRENT_TAPE_INFOS.currOp !=
1120                ADOLC_CURRENT_TAPE_INFOS.opBuffer)
1121        {
1122            put_op_block(ADOLC_CURRENT_TAPE_INFOS.currOp);
1123        }
1124        if (ADOLC_CURRENT_TAPE_INFOS.op_file != NULL)
1125            fclose(ADOLC_CURRENT_TAPE_INFOS.op_file);
1126        ADOLC_CURRENT_TAPE_INFOS.op_file = NULL;
1127        ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS] = 1;
1128        free(ADOLC_CURRENT_TAPE_INFOS.opBuffer);
1129        ADOLC_CURRENT_TAPE_INFOS.opBuffer = NULL;
1130    } else ADOLC_CURRENT_TAPE_INFOS.numOps_Tape =
1131        ADOLC_CURRENT_TAPE_INFOS.currOp - ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1132    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] =
1133        ADOLC_CURRENT_TAPE_INFOS.numOps_Tape;
1134
1135    /* finish constants tape, close it, update stats */
1136    if (flag != 0 || ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) {
1137        if (ADOLC_CURRENT_TAPE_INFOS.currVal !=
1138                ADOLC_CURRENT_TAPE_INFOS.valBuffer)
1139        {
1140            put_val_block(ADOLC_CURRENT_TAPE_INFOS.currVal);
1141        }
1142        if (ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) 
1143            fclose(ADOLC_CURRENT_TAPE_INFOS.val_file);
1144        ADOLC_CURRENT_TAPE_INFOS.val_file = NULL;
1145        ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] = 1;
1146        free(ADOLC_CURRENT_TAPE_INFOS.valBuffer);
1147        ADOLC_CURRENT_TAPE_INFOS.valBuffer = NULL;
1148    } else ADOLC_CURRENT_TAPE_INFOS.numVals_Tape =
1149        ADOLC_CURRENT_TAPE_INFOS.currVal - ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1150    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] =
1151        ADOLC_CURRENT_TAPE_INFOS.numVals_Tape;
1152
1153    /* finish locations tape, update and write tape stats, close tape */
1154    if (flag != 0 || ADOLC_CURRENT_TAPE_INFOS.loc_file != NULL) {
1155        if (ADOLC_CURRENT_TAPE_INFOS.currLoc !=
1156                ADOLC_CURRENT_TAPE_INFOS.locBuffer)
1157        {
1158            put_loc_block(ADOLC_CURRENT_TAPE_INFOS.currLoc);
1159        }
1160        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] =
1161            ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape;
1162        ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] = 1;
1163        /* write tape stats */
1164        fseek(ADOLC_CURRENT_TAPE_INFOS.loc_file, 0, 0);
1165        fwrite(&adolc_id, sizeof(ADOLC_ID), 1,
1166                ADOLC_CURRENT_TAPE_INFOS.loc_file);
1167        fwrite(ADOLC_CURRENT_TAPE_INFOS.stats, STAT_SIZE * sizeof(uint), 1,
1168               ADOLC_CURRENT_TAPE_INFOS.loc_file);
1169        fclose(ADOLC_CURRENT_TAPE_INFOS.loc_file);
1170        ADOLC_CURRENT_TAPE_INFOS.loc_file = NULL;
1171        free(ADOLC_CURRENT_TAPE_INFOS.locBuffer);
1172        ADOLC_CURRENT_TAPE_INFOS.locBuffer = NULL;
1173    } else ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape  =
1174        ADOLC_CURRENT_TAPE_INFOS.currLoc - ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1175    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] =
1176        ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape;
1177}
1178
1179/****************************************************************************/
1180/* Free all resources used by a tape before overwriting the tape.           */
1181/****************************************************************************/
1182void freeTapeResources(TapeInfos *tapeInfos) {
1183    free(tapeInfos->opBuffer);
1184    tapeInfos->opBuffer = NULL;
1185    free(tapeInfos->locBuffer);
1186    tapeInfos->locBuffer = NULL;
1187    free(tapeInfos->valBuffer);
1188    tapeInfos->valBuffer = NULL;
1189    if (tapeInfos->tayBuffer != NULL) {
1190        free(tapeInfos->tayBuffer);
1191        tapeInfos->tayBuffer = NULL;
1192        --numTBuffersInUse;
1193    }
1194    if (tapeInfos->op_file != NULL) {
1195        fclose(tapeInfos->op_file);
1196        tapeInfos->op_file = NULL;
1197    }
1198    if (tapeInfos->loc_file != NULL) {
1199        fclose(tapeInfos->loc_file);
1200        tapeInfos->loc_file = NULL;
1201    }
1202    if (tapeInfos->val_file != NULL) {
1203        fclose(tapeInfos->val_file);
1204        tapeInfos->val_file = NULL;
1205    }
1206    if (tapeInfos->tay_file != NULL) {
1207        fclose(tapeInfos->tay_file);
1208        tapeInfos->tay_file = NULL;
1209    }
1210}
1211
1212/****************************************************************************/
1213/* Tapestats:                                                               */
1214/* Returns statistics on the tape tag with following meaning:               */
1215/* tape_stat[0] = # of independent variables.                               */
1216/* tape_stat[1] = # of dependent variables.                                 */
1217/* tape_stat[2] = max # of live variables.                                  */
1218/* tape_stat[3] = value stack size.                                         */
1219/* tape_stat[4] = buffer size (# of chars, # of doubles, # of locints)      */
1220/* tape_stat[5] = # of operations.                                          */
1221/* tape_stat[6] = operation file access flag (1 = file in use, 0 otherwise) */
1222/* tape_stat[7] = # of saved locations.                                     */
1223/* tape_stat[8] = location file access flag (1 = file in use, 0 otherwise)  */
1224/* tape_stat[9] = # of saved constant values.                               */
1225/* tape_stat[10]= value file access flag (1 = file in use, 0 otherwise)     */
1226/****************************************************************************/
1227void tapestats(short tag, int *tape_stats) {
1228    int i;
1229    TapeInfos *tapeInfos;
1230
1231    /* get the tapeInfos for tag */
1232    tapeInfos = getTapeInfos(tag);
1233    /* copy stats to the users field */
1234    for (i = 0; i < STAT_SIZE; ++i)
1235        tape_stats[i] = tapeInfos->stats[i];
1236}
1237
1238/****************************************************************************/
1239/* An all-in-one tape stats printing routine.                               */
1240/****************************************************************************/
1241void printTapeStats(FILE *stream, short tag) {
1242    int stats[STAT_SIZE];
1243
1244    tapestats(tag, (int *)&stats);
1245    fprintf(stream, "\n*** TAPE STATS (tape %d) **********\n", (int)tag);
1246    fprintf(stream, "Number of independents: %10d\n", stats[NUM_INDEPENDENTS]);
1247    fprintf(stream, "Number of dependents:   %10d\n", stats[NUM_DEPENDENTS]);
1248    fprintf(stream, "\n");
1249    fprintf(stream, "Max # of live adoubles: %10d\n", stats[NUM_MAX_LIVES]);
1250    fprintf(stream, "Taylor stack size:      %10d\n", stats[TAY_STACK_SIZE]);
1251    fprintf(stream, "\n");
1252    fprintf(stream, "Number of operations:   %10d\n", stats[NUM_OPERATIONS]);
1253    fprintf(stream, "Number of locations:    %10d\n", stats[NUM_LOCATIONS]);
1254    fprintf(stream, "Number of values:       %10d\n", stats[NUM_VALUES]);
1255    fprintf(stream, "\n");
1256    fprintf(stream, "Operation file written: %10d\n", stats[OP_FILE_ACCESS]);
1257    fprintf(stream, "Location file written:  %10d\n", stats[LOC_FILE_ACCESS]);
1258    fprintf(stream, "Value file written:     %10d\n", stats[VAL_FILE_ACCESS]);
1259    fprintf(stream, "\n");
1260    fprintf(stream, "Operation buffer size:  %10d\n", stats[OP_BUFFER_SIZE]);
1261    fprintf(stream, "Location buffer size:   %10d\n", stats[LOC_BUFFER_SIZE]);
1262    fprintf(stream, "Value buffer size:      %10d\n", stats[VAL_BUFFER_SIZE]);
1263    fprintf(stream, "Taylor buffer size:     %10d\n", stats[TAY_BUFFER_SIZE]);
1264    fprintf(stream, "\n");
1265    fprintf(stream, "Operation type size:    %10d\n",
1266            (int)sizeof(unsigned char));
1267    fprintf(stream, "Location type size:     %10d\n", (int)sizeof(locint));
1268    fprintf(stream, "Value type size:        %10d\n", (int)sizeof(double));
1269    fprintf(stream, "Taylor type size:       %10d\n", (int)sizeof(revreal));
1270    fprintf(stream, "**********************************\n\n");
1271}
1272
1273/****************************************************************************/
1274/* Does the actual reading from the hard disk into the stats buffer         */
1275/****************************************************************************/
1276void read_tape_stats(TapeInfos *tapeInfos) {
1277    FILE *loc_file;
1278    int tapeVersion, limitVersion;
1279    ADOLC_ID tape_ADOLC_ID;
1280
1281    if (tapeInfos->inUse != 0 && tapeInfos->tapingComplete == 0) return;
1282
1283    limitVersion = 100 * ADOLC_NEW_TAPE_VERSION    +
1284            10 * ADOLC_NEW_TAPE_SUBVERSION +
1285            1  * ADOLC_NEW_TAPE_PATCHLEVEL ;
1286
1287    if ((loc_file = fopen(tapeInfos->pTapeInfos.loc_fileName, "rb")) == NULL)
1288        fail(ADOLC_INTEGER_TAPE_FOPEN_FAILED);
1289    if (fread(&tape_ADOLC_ID, sizeof(ADOLC_ID), 1, loc_file) != 1)
1290        fail(ADOLC_INTEGER_TAPE_FREAD_FAILED);
1291    if (fread(tapeInfos->stats, STAT_SIZE * sizeof(uint), 1, loc_file) != 1)
1292        fail(ADOLC_INTEGER_TAPE_FREAD_FAILED);
1293
1294    failAdditionalInfo1 = tapeInfos->tapeID;
1295    tapeVersion = 100 * tape_ADOLC_ID.adolc_ver +
1296            10 * tape_ADOLC_ID.adolc_sub +
1297            1  * tape_ADOLC_ID.adolc_lvl ;
1298    if (tapeVersion < limitVersion) fail(ADOLC_TAPE_TO_OLD);
1299
1300    if (tape_ADOLC_ID.locint_size != adolc_id.locint_size) {
1301        failAdditionalInfo1 = tape_ADOLC_ID.locint_size;
1302        failAdditionalInfo2 = adolc_id.locint_size;
1303        fail(ADOLC_WRONG_LOCINT_SIZE);
1304    }
1305
1306    fclose(loc_file);
1307    tapeInfos->tapingComplete = 1;
1308}
1309
1310/****************************************************************************/
1311/* Initialize a forward sweep. Get stats, open tapes, fill buffers, ...     */
1312/****************************************************************************/
1313void init_for_sweep(short tag) {
1314    int i = 0, chunks, numLocsForStats;
1315    size_t number, remain, chunkSize;
1316    ADOLC_OPENMP_THREAD_NUMBER;
1317    ADOLC_OPENMP_GET_THREAD_NUMBER;
1318
1319    /* mark possible (hard disk) tape creation */
1320    markNewTape();
1321
1322    /* make room for tapeInfos and read tape stats if necessary, keep value
1323     * stack information */
1324    openTape(tag, ADOLC_FORWARD);
1325    initTapeBuffers();
1326
1327    /* init operations */
1328    number = 0;
1329    if (ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS] == 1) {
1330        ADOLC_CURRENT_TAPE_INFOS.op_file =
1331            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "rb");
1332        /* how much to read ? */
1333        number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE],
1334                ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS]);
1335        if (number != 0) {
1336            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1337            chunks = number / chunkSize;
1338            for (i = 0; i < chunks; ++i)
1339                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1340                            chunkSize * sizeof(unsigned char), 1,
1341                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1342                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1343            remain = number % chunkSize;
1344            if (remain != 0)
1345                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks *
1346                            chunkSize, remain * sizeof(unsigned char), 1,
1347                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1348                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1349        }
1350        /* how much remains ? */
1351        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] - number;
1352    }
1353    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape = number;
1354    ADOLC_CURRENT_TAPE_INFOS.currOp = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1355
1356    /* init locations */
1357    number = 0;
1358    if (ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] == 1) {
1359        ADOLC_CURRENT_TAPE_INFOS.loc_file =
1360            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "rb");
1361        /* how much to read ? */
1362        number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE],
1363                ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS]);
1364        if (number != 0) {
1365            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1366            chunks = number / chunkSize;
1367            for (i = 0; i < chunks; ++i)
1368                if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1369                            chunkSize * sizeof(locint), 1,
1370                            ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1371                    fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1372            remain = number % chunkSize;
1373            if (remain != 0)
1374            if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks * chunkSize,
1375                        remain * sizeof(locint), 1,
1376                        ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1377                fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1378        }
1379        /* how much remains ? */
1380        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] - number;
1381    }
1382    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape = number;
1383
1384    /* skip stats */
1385    numLocsForStats = statSpace;
1386    while (numLocsForStats >= ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE])
1387    {
1388        get_loc_block_f();
1389        numLocsForStats -= ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1390    }
1391    ADOLC_CURRENT_TAPE_INFOS.currLoc =
1392        ADOLC_CURRENT_TAPE_INFOS.locBuffer + numLocsForStats;
1393
1394    /* init constants */
1395    number = 0;
1396    if (ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] == 1) {
1397        ADOLC_CURRENT_TAPE_INFOS.val_file =
1398            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "rb");
1399        /* how much to read ? */
1400        number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE],
1401                ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES]);
1402        if (number != 0) {
1403            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1404            chunks = number / chunkSize;
1405            for (i = 0; i < chunks; ++i)
1406                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1407                            chunkSize * sizeof(double), 1,
1408                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1409                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1410            remain = number % chunkSize;
1411            if (remain != 0)
1412                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks *
1413                            chunkSize, remain * sizeof(double), 1,
1414                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1415                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1416        }
1417        /* how much remains ? */
1418        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] - number;
1419    }
1420    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape = number;
1421    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1422}
1423
1424/****************************************************************************/
1425/* Initialize a reverse sweep. Get stats, open tapes, fill buffers, ...     */
1426/****************************************************************************/
1427void init_rev_sweep(short tag) {
1428    int i, chunks;
1429    size_t number, remain, chunkSize;
1430    ADOLC_OPENMP_THREAD_NUMBER;
1431    ADOLC_OPENMP_GET_THREAD_NUMBER;
1432
1433    /* mark possible (hard disk) tape creation */
1434    markNewTape();
1435
1436    /* make room for tapeInfos and read tape stats if necessary, keep value
1437     * stack information */
1438    openTape(tag, ADOLC_REVERSE);
1439    initTapeBuffers();
1440
1441    /* init operations */
1442    number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS];
1443    if (ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS] == 1) {
1444        ADOLC_CURRENT_TAPE_INFOS.op_file =
1445            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "rb");
1446        number = (ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] /
1447                ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE]) *
1448                ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE];
1449        fseek(ADOLC_CURRENT_TAPE_INFOS.op_file,
1450                number * sizeof(unsigned char), SEEK_SET);
1451        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] %
1452                ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE] ;
1453        if (number != 0) {
1454            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1455            chunks = number / chunkSize;
1456            for (i = 0; i < chunks; ++i)
1457                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1458                            chunkSize * sizeof(unsigned char), 1,
1459                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1460                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1461            remain = number % chunkSize;
1462            if (remain != 0)
1463                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks *
1464                            chunkSize, remain * sizeof(unsigned char), 1,
1465                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1466                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1467        }
1468    }
1469    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape =
1470        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] - number;
1471    ADOLC_CURRENT_TAPE_INFOS.currOp =
1472        ADOLC_CURRENT_TAPE_INFOS.opBuffer + number;
1473
1474    /* init locations */
1475    number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS];
1476    if (ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] == 1) {
1477        ADOLC_CURRENT_TAPE_INFOS.loc_file =
1478            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "rb");
1479        number = (ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] /
1480                ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE]) *
1481                ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1482        fseek(ADOLC_CURRENT_TAPE_INFOS.loc_file,
1483                number * sizeof(locint), SEEK_SET);
1484        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] %
1485                ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1486        if (number != 0) {
1487            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1488            chunks = number / chunkSize;
1489            for (i = 0; i < chunks; ++i)
1490                if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1491                            chunkSize * sizeof(locint), 1,
1492                            ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1493                    fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1494            remain = number % chunkSize;
1495            if (remain != 0)
1496                if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks *
1497                            chunkSize, remain * sizeof(locint), 1,
1498                            ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1499                    fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1500        }
1501    }
1502    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape =
1503        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] - number;
1504    ADOLC_CURRENT_TAPE_INFOS.currLoc =
1505        ADOLC_CURRENT_TAPE_INFOS.locBuffer + number;
1506
1507    /* init constants */
1508    number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES];
1509    if (ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] == 1) {
1510        ADOLC_CURRENT_TAPE_INFOS.val_file =
1511            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "rb");
1512        number = (ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] /
1513                ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE]) *
1514                ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1515        fseek(ADOLC_CURRENT_TAPE_INFOS.val_file,
1516                number * sizeof(double), SEEK_SET);
1517        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] %
1518                ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1519        if (number != 0) {
1520            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1521            chunks = number / chunkSize;
1522            for (i = 0; i < chunks; ++i)
1523                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1524                            chunkSize * sizeof(double), 1,
1525                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1526                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1527            remain = number % chunkSize;
1528            if (remain != 0)
1529                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks *
1530                            chunkSize, remain * sizeof(double), 1,
1531                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1532                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1533        }
1534    }
1535    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape =
1536        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] - number;
1537    ADOLC_CURRENT_TAPE_INFOS.currVal =
1538        ADOLC_CURRENT_TAPE_INFOS.valBuffer + number;
1539}
1540
1541/****************************************************************************/
1542/* Finish a forward or reverse sweep.                                       */
1543/****************************************************************************/
1544void end_sweep() {
1545    ADOLC_OPENMP_THREAD_NUMBER;
1546    ADOLC_OPENMP_GET_THREAD_NUMBER;
1547    if (ADOLC_CURRENT_TAPE_INFOS.op_file != NULL) {
1548        fclose(ADOLC_CURRENT_TAPE_INFOS.op_file);
1549        ADOLC_CURRENT_TAPE_INFOS.op_file = NULL;
1550    }
1551    if (ADOLC_CURRENT_TAPE_INFOS.loc_file != NULL) {
1552        fclose(ADOLC_CURRENT_TAPE_INFOS.loc_file);
1553        ADOLC_CURRENT_TAPE_INFOS.loc_file = NULL;
1554    }
1555    if (ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) {
1556        fclose(ADOLC_CURRENT_TAPE_INFOS.val_file);
1557        ADOLC_CURRENT_TAPE_INFOS.val_file = NULL;
1558    }
1559    if (ADOLC_CURRENT_TAPE_INFOS.deg_save > 0) releaseTape(1); /* keep value stack */
1560    else releaseTape(0); /* no value stack */
1561}
1562
1563/* --- Operations --- */
1564
1565/****************************************************************************/
1566/* Puts an operation into the operation buffer. Ensures that location buffer*/
1567/* and constants buffer are prepared to take the belonging stuff.           */
1568/****************************************************************************/
1569void put_op(unsigned char op) {
1570    ADOLC_OPENMP_THREAD_NUMBER;
1571    ADOLC_OPENMP_GET_THREAD_NUMBER;
1572    /* every operation writes <5 locations */
1573    if (ADOLC_CURRENT_TAPE_INFOS.currLoc + 5 > ADOLC_CURRENT_TAPE_INFOS.lastLocP1) {
1574        *(ADOLC_CURRENT_TAPE_INFOS.lastLocP1 - 1) = ADOLC_CURRENT_TAPE_INFOS.lastLocP1 -
1575                ADOLC_CURRENT_TAPE_INFOS.currLoc;
1576        put_loc_block(ADOLC_CURRENT_TAPE_INFOS.lastLocP1);
1577        /* every operation writes 1 opcode */
1578        if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1579            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1580            put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1581            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1582            ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1583        }
1584        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_int;
1585        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1586    }
1587    /* every operation writes <5 values --- 3 should be sufficient */
1588    if (ADOLC_CURRENT_TAPE_INFOS.currVal + 5 > ADOLC_CURRENT_TAPE_INFOS.lastValP1) {
1589        ADOLC_PUT_LOCINT(ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1590        put_val_block(ADOLC_CURRENT_TAPE_INFOS.lastValP1);
1591        /* every operation writes 1 opcode */
1592        if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1593            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1594            put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1595            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1596            ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1597        }
1598        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_val;
1599        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1600    }
1601    /* every operation writes 1 opcode */
1602    if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1603        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1604        put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1605        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1606        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1607    }
1608    *ADOLC_CURRENT_TAPE_INFOS.currOp = op;
1609    ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1610}
1611
1612/****************************************************************************/
1613/* Writes a block of operations onto hard disk and handles file creation,   */
1614/* removal, ...                                                             */
1615/****************************************************************************/
1616void put_op_block(unsigned char *lastOpP1) {
1617    int i, chunks;
1618    size_t number, remain, chunkSize;
1619    ADOLC_OPENMP_THREAD_NUMBER;
1620    ADOLC_OPENMP_GET_THREAD_NUMBER;
1621
1622    if (ADOLC_CURRENT_TAPE_INFOS.op_file == NULL) {
1623        ADOLC_CURRENT_TAPE_INFOS.op_file =
1624            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "rb");
1625        if (ADOLC_CURRENT_TAPE_INFOS.op_file != NULL) {
1626            #if defined(ADOLC_DEBUG)
1627            fprintf(DIAG_OUT, "ADOL-C debug: Old tapefile %s gets removed!\n",
1628                    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName);
1629            #endif
1630            fclose(ADOLC_CURRENT_TAPE_INFOS.op_file);
1631            ADOLC_CURRENT_TAPE_INFOS.op_file = NULL;
1632            if (remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName))
1633                fprintf(DIAG_OUT, "ADOL-C warning: "
1634                        "Unable to remove old tapefile\n");
1635            ADOLC_CURRENT_TAPE_INFOS.op_file =
1636                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "wb");
1637        } else {
1638            ADOLC_CURRENT_TAPE_INFOS.op_file =
1639                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "wb");
1640        }
1641    }
1642
1643    number = lastOpP1 - ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1644    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1645    chunks = number / chunkSize;
1646    for (i = 0; i < chunks; ++i)
1647        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.opBuffer +
1648                        i * chunkSize, chunkSize *
1649                        sizeof(unsigned char), 1,
1650                        ADOLC_CURRENT_TAPE_INFOS.op_file) ) != 1 )
1651            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1652    remain = number % chunkSize;
1653    if (remain != 0)
1654        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.opBuffer +
1655                        chunks * chunkSize, remain *
1656                        sizeof(unsigned char), 1,
1657                        ADOLC_CURRENT_TAPE_INFOS.op_file) ) != 1 )
1658            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1659    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape += number;
1660    ADOLC_CURRENT_TAPE_INFOS.currOp = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1661    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1662}
1663
1664/****************************************************************************/
1665/* Reads the next operations block into the internal buffer.                */
1666/****************************************************************************/
1667void get_op_block_f() {
1668    int i, chunks;
1669    size_t number, remain, chunkSize;
1670    ADOLC_OPENMP_THREAD_NUMBER;
1671    ADOLC_OPENMP_GET_THREAD_NUMBER;
1672
1673    number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE],
1674            ADOLC_CURRENT_TAPE_INFOS.numOps_Tape);
1675    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1676    chunks = number / chunkSize;
1677    for (i = 0; i < chunks; ++i)
1678        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1679                    chunkSize * sizeof(unsigned char), 1,
1680                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1681            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1682    remain = number % chunkSize;
1683    if (remain != 0)
1684        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks * chunkSize,
1685                    remain * sizeof(unsigned char), 1,
1686                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1687            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1688    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape -= remain;
1689    ADOLC_CURRENT_TAPE_INFOS.currOp = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1690}
1691
1692/****************************************************************************/
1693/* Reads the previous block of operations into the internal buffer.         */
1694/****************************************************************************/
1695void get_op_block_r() {
1696    int i, chunks;
1697    size_t number, remain, chunkSize;
1698    ADOLC_OPENMP_THREAD_NUMBER;
1699    ADOLC_OPENMP_GET_THREAD_NUMBER;
1700
1701    number = ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE];
1702    fseek(ADOLC_CURRENT_TAPE_INFOS.op_file, sizeof(unsigned char) *
1703            (ADOLC_CURRENT_TAPE_INFOS.numOps_Tape - number), SEEK_SET);
1704    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1705    chunks = number / chunkSize;
1706    for (i = 0; i < chunks; ++i)
1707        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1708                    chunkSize * sizeof(unsigned char), 1,
1709                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1710            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1711    remain = number % chunkSize;
1712    if (remain != 0)
1713        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks * chunkSize,
1714                    remain * sizeof(unsigned char), 1,
1715                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1716            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1717    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape -= number;
1718    ADOLC_CURRENT_TAPE_INFOS.currOp =
1719        ADOLC_CURRENT_TAPE_INFOS.opBuffer + number;
1720}
1721
1722/* --- Locations --- */
1723
1724/****************************************************************************/
1725/* Writes a block of locations onto hard disk and handles file creation,   */
1726/* removal, ...                                                             */
1727/****************************************************************************/
1728void put_loc_block(locint *lastLocP1) {
1729    int i, chunks;
1730    size_t number, remain, chunkSize;
1731    ADOLC_OPENMP_THREAD_NUMBER;
1732    ADOLC_OPENMP_GET_THREAD_NUMBER;
1733
1734    if (ADOLC_CURRENT_TAPE_INFOS.loc_file == NULL) {
1735        ADOLC_CURRENT_TAPE_INFOS.loc_file =
1736            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "rb");
1737        if (ADOLC_CURRENT_TAPE_INFOS.loc_file != NULL) {
1738            #if defined(ADOLC_DEBUG)
1739            fprintf(DIAG_OUT, "ADOL-C debug: Old tapefile %s gets removed!\n",
1740                    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName);
1741            #endif
1742            fclose(ADOLC_CURRENT_TAPE_INFOS.loc_file);
1743            ADOLC_CURRENT_TAPE_INFOS.loc_file = NULL;
1744            if (remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName))
1745                fprintf(DIAG_OUT, "ADOL-C warning: "
1746                        "Unable to remove old tapefile!\n");
1747            ADOLC_CURRENT_TAPE_INFOS.loc_file =
1748                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "wb");
1749        } else {
1750            ADOLC_CURRENT_TAPE_INFOS.loc_file =
1751                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "wb");
1752        }
1753    }
1754
1755    number = lastLocP1 - ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1756    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1757    chunks = number / chunkSize;
1758    for (i = 0; i < chunks; ++i)
1759        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.locBuffer +
1760                        i * chunkSize, chunkSize * sizeof(locint), 1,
1761                        ADOLC_CURRENT_TAPE_INFOS.loc_file) ) != 1)
1762            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1763    remain = number % chunkSize;
1764    if (remain != 0)
1765        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.locBuffer +
1766                        chunks * chunkSize, remain * sizeof(locint), 1,
1767                        ADOLC_CURRENT_TAPE_INFOS.loc_file) ) != 1)
1768            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1769    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape += number;
1770    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1771    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1772}
1773
1774/****************************************************************************/
1775/* Reads the next block of locations into the internal buffer.              */
1776/****************************************************************************/
1777void get_loc_block_f() {
1778    int i, chunks;
1779    size_t number, remain, chunkSize;
1780    ADOLC_OPENMP_THREAD_NUMBER;
1781    ADOLC_OPENMP_GET_THREAD_NUMBER;
1782
1783    number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE],
1784            ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape);
1785    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof (locint);
1786    chunks = number / chunkSize;
1787    for (i = 0; i < chunks; ++i)
1788        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1789                    chunkSize * sizeof(locint), 1,
1790                    ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1791            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1792    remain = number % chunkSize;
1793    if (remain != 0)
1794        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks * chunkSize,
1795                    remain * sizeof(locint), 1,
1796                    ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1797            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1798    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape -= number;
1799    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1800}
1801
1802/****************************************************************************/
1803/* Reads the previous block of locations into the internal buffer.          */
1804/****************************************************************************/
1805void get_loc_block_r() {
1806    int i, chunks;
1807    size_t number, remain, chunkSize;
1808    ADOLC_OPENMP_THREAD_NUMBER;
1809    ADOLC_OPENMP_GET_THREAD_NUMBER;
1810
1811    number = ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1812    fseek(ADOLC_CURRENT_TAPE_INFOS.loc_file, sizeof(locint) *
1813            (ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape - number), SEEK_SET);
1814    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1815    chunks = number / chunkSize;
1816    for (i = 0; i < chunks; ++i)
1817        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1818                   chunkSize * sizeof(locint), 1,
1819                   ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1820            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1821    remain = number % chunkSize;
1822    if (remain != 0)
1823        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks * chunkSize,
1824                   remain * sizeof(locint), 1,
1825                   ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1826            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1827    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape -=
1828        ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1829    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.lastLocP1 -
1830            *(ADOLC_CURRENT_TAPE_INFOS.lastLocP1 - 1);
1831}
1832
1833/* --- Values (Constants -- Real) --- */
1834
1835/****************************************************************************/
1836/* Writes a block of constants (real) onto hard disk and handles file       */
1837/* creation, removal, ...                                                   */
1838/****************************************************************************/
1839void put_vals_writeBlock(double *vals, locint numVals) {
1840    int i;
1841    ADOLC_OPENMP_THREAD_NUMBER;
1842    ADOLC_OPENMP_GET_THREAD_NUMBER;
1843
1844    for (i = 0; i < numVals; ++i) {
1845        *ADOLC_CURRENT_TAPE_INFOS.currVal = vals[i];
1846        ++ADOLC_CURRENT_TAPE_INFOS.currVal;
1847    }
1848    ADOLC_PUT_LOCINT(ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1849    put_val_block(ADOLC_CURRENT_TAPE_INFOS.lastValP1);
1850    /* every operation writes 1 opcode */
1851    if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1852        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1853        put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1854        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1855        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1856    }
1857    *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_val;
1858    ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1859}
1860
1861/****************************************************************************/
1862/* Write some constants to the buffer without disk access                   */
1863/****************************************************************************/
1864void put_vals_notWriteBlock(double *vals, locint numVals) {
1865    int i;
1866    ADOLC_OPENMP_THREAD_NUMBER;
1867    ADOLC_OPENMP_GET_THREAD_NUMBER;
1868
1869    for (i = 0; i < numVals; ++i) {
1870        *ADOLC_CURRENT_TAPE_INFOS.currVal = vals[i];
1871        ++ADOLC_CURRENT_TAPE_INFOS.currVal;
1872    }
1873}
1874
1875/****************************************************************************/
1876/* Writes a block of constants (real) onto tape and handles file creation   */
1877/* removal, ...                                                             */
1878/****************************************************************************/
1879void put_val_block(double *lastValP1) {
1880    int i, chunks;
1881    size_t number, remain, chunkSize;
1882    ADOLC_OPENMP_THREAD_NUMBER;
1883    ADOLC_OPENMP_GET_THREAD_NUMBER;
1884
1885    if (ADOLC_CURRENT_TAPE_INFOS.val_file == NULL) {
1886        ADOLC_CURRENT_TAPE_INFOS.val_file =
1887            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "rb");
1888        if (ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) {
1889            #if defined(ADOLC_DEBUG)
1890            fprintf(DIAG_OUT, "ADOL-C debug: Old tapefile %s gets removed!\n",
1891                    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName);
1892            #endif
1893            fclose(ADOLC_CURRENT_TAPE_INFOS.val_file);
1894            ADOLC_CURRENT_TAPE_INFOS.val_file = NULL;
1895            if (remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName))
1896                fprintf(DIAG_OUT, "ADOL-C warning: "
1897                        "Unable to remove old tapefile\n");
1898            ADOLC_CURRENT_TAPE_INFOS.val_file =
1899                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "wb");
1900        } else {
1901            ADOLC_CURRENT_TAPE_INFOS.val_file =
1902                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "wb");
1903        }
1904    }
1905
1906    number = lastValP1 - ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1907    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1908    chunks = number / chunkSize;
1909    for (i = 0; i < chunks; ++i)
1910        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.valBuffer +
1911                        i * chunkSize, chunkSize * sizeof(double), 1,
1912                        ADOLC_CURRENT_TAPE_INFOS.val_file) ) != 1)
1913            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1914    remain = number % chunkSize;
1915    if (remain != 0)
1916        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.valBuffer +
1917                        chunks * chunkSize, remain * sizeof(double), 1,
1918                        ADOLC_CURRENT_TAPE_INFOS.val_file) ) != 1)
1919            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1920    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape += number;
1921    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1922    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1923}
1924
1925/****************************************************************************/
1926/* Reads the next block of constants into the internal buffer.              */
1927/****************************************************************************/
1928void get_val_block_f() {
1929    int i, chunks;
1930    size_t number, remain, chunkSize;
1931    ADOLC_OPENMP_THREAD_NUMBER;
1932    ADOLC_OPENMP_GET_THREAD_NUMBER;
1933
1934    number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE],
1935            ADOLC_CURRENT_TAPE_INFOS.numVals_Tape);
1936    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof (double);
1937    chunks = number / chunkSize;
1938    for (i = 0; i < chunks; ++i)
1939        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1940                    chunkSize * sizeof(double), 1,
1941                    ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1942            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1943    remain = number % chunkSize;
1944    if (remain != 0)
1945        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks * chunkSize,
1946                    remain * sizeof(double), 1,
1947                    ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1948            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1949    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape -= number;
1950    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1951    /* get_locint_f(); value used in reverse only */
1952    ++ADOLC_CURRENT_TAPE_INFOS.currLoc;
1953}
1954
1955/****************************************************************************/
1956/* Reads the previous block of values into the internal buffer.             */
1957/****************************************************************************/
1958void get_val_block_r() {
1959    int i, chunks;
1960    size_t number, remain, chunkSize;
1961    locint temp;
1962    ADOLC_OPENMP_THREAD_NUMBER;
1963    ADOLC_OPENMP_GET_THREAD_NUMBER;
1964
1965    number = ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1966    fseek(ADOLC_CURRENT_TAPE_INFOS.val_file, sizeof(double) *
1967            (ADOLC_CURRENT_TAPE_INFOS.numVals_Tape - number), SEEK_SET);
1968    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1969    chunks = number / chunkSize;
1970    for (i = 0; i < chunks; ++i)
1971        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1972                   chunkSize * sizeof(double), 1,
1973                   ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1974            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1975    remain = number % chunkSize;
1976    if (remain != 0)
1977        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks * chunkSize,
1978                    remain * sizeof(double), 1,
1979                    ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1980            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1981    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape -= number;
1982    --ADOLC_CURRENT_TAPE_INFOS.currLoc;
1983    temp = *ADOLC_CURRENT_TAPE_INFOS.currLoc;
1984    ADOLC_CURRENT_TAPE_INFOS.currVal =
1985        ADOLC_CURRENT_TAPE_INFOS.lastValP1 - temp;
1986}
1987
1988/****************************************************************************/
1989/* Returns the number of free constants in the real tape. Ensures that it   */
1990/* is at least 5.                                                           */
1991/****************************************************************************/
1992locint get_val_space(void) {
1993    ADOLC_OPENMP_THREAD_NUMBER;
1994    ADOLC_OPENMP_GET_THREAD_NUMBER;
1995    if (ADOLC_CURRENT_TAPE_INFOS.lastValP1 - 5 < ADOLC_CURRENT_TAPE_INFOS.currVal) {
1996        ADOLC_PUT_LOCINT(ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1997        put_val_block(ADOLC_CURRENT_TAPE_INFOS.lastValP1);
1998        /* every operation writes 1 opcode */
1999        if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
2000            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
2001            put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
2002            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
2003            ++ADOLC_CURRENT_TAPE_INFOS.currOp;
2004        }
2005        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_val;
2006        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
2007    }
2008    return (ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
2009}
2010
2011/****************************************************************************/
2012/* Returns a pointer to the first element of a values vector and skips the  */
2013/* vector. -- Forward Mode --                                               */
2014/****************************************************************************/
2015double *get_val_v_f(locint size) {
2016    double *temp;
2017    ADOLC_OPENMP_THREAD_NUMBER;
2018
2019    ADOLC_OPENMP_GET_THREAD_NUMBER;
2020    temp = ADOLC_CURRENT_TAPE_INFOS.currVal;
2021    ADOLC_CURRENT_TAPE_INFOS.currVal += size;
2022    return temp;
2023}
2024
2025/****************************************************************************/
2026/* Returns a pointer to the first element of a values vector and skips the  */
2027/* vector. -- Reverse Mode --                                               */
2028/****************************************************************************/
2029double *get_val_v_r(locint size) {
2030    ADOLC_OPENMP_THREAD_NUMBER;
2031    ADOLC_OPENMP_GET_THREAD_NUMBER;
2032    ADOLC_CURRENT_TAPE_INFOS.currVal -= size;
2033    return ADOLC_CURRENT_TAPE_INFOS.currVal;
2034}
2035
2036/* --- Updates / Corrections --- */
2037
2038/****************************************************************************/
2039/* Not sure what's going on here! -> vector class ?  --- kowarz             */
2040/****************************************************************************/
2041void reset_val_r(void) {
2042    ADOLC_OPENMP_THREAD_NUMBER;
2043    ADOLC_OPENMP_GET_THREAD_NUMBER;
2044    if (ADOLC_CURRENT_TAPE_INFOS.currVal == ADOLC_CURRENT_TAPE_INFOS.valBuffer)
2045        get_val_block_r();
2046}
2047
2048/****************************************************************************/
2049/* Update locations tape to remove assignments involving temp. variables.   */
2050/* e.g.  t = a + b ; y = t  =>  y = a + b                                   */
2051/****************************************************************************/
2052int upd_resloc(locint temp, locint lhs) {
2053    ADOLC_OPENMP_THREAD_NUMBER;
2054    ADOLC_OPENMP_GET_THREAD_NUMBER;
2055    if (ADOLC_CURRENT_TAPE_INFOS.currLoc - ADOLC_CURRENT_TAPE_INFOS.locBuffer < 1) return 0;
2056    if (temp == *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1)) {
2057        *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1) = lhs;
2058        return 1;
2059    }
2060    return 0;
2061}
2062
2063/****************************************************************************/
2064/* Update locations and operations tape to remove special operations inv.   */
2065/* temporary variables. e.g.  t = a * b ; y += t  =>  y += a * b            */
2066/****************************************************************************/
2067int upd_resloc_inc_prod(locint temp, locint newlhs, unsigned char newop) {
2068    ADOLC_OPENMP_THREAD_NUMBER;
2069    ADOLC_OPENMP_GET_THREAD_NUMBER;
2070    if (ADOLC_CURRENT_TAPE_INFOS.currLoc - ADOLC_CURRENT_TAPE_INFOS.locBuffer < 3) return 0;
2071    if (ADOLC_CURRENT_TAPE_INFOS.currOp - ADOLC_CURRENT_TAPE_INFOS.opBuffer < 1) return 0;
2072    if (temp == *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1)    &&
2073            mult_a_a == *(ADOLC_CURRENT_TAPE_INFOS.currOp - 1) &&
2074            /* skipping recursive case */
2075            newlhs != *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 2)  &&
2076            newlhs != *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 3)    ) {
2077        *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1) = newlhs;
2078        *(ADOLC_CURRENT_TAPE_INFOS.currOp - 1) = newop;
2079        return 1;
2080    }
2081    return 0;
2082}
2083
2084void enableBranchSwitchWarnings() {
2085    ADOLC_OPENMP_THREAD_NUMBER;
2086    ADOLC_OPENMP_GET_THREAD_NUMBER;
2087    ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = 1;
2088}
2089
2090void disableBranchSwitchWarnings() {
2091    ADOLC_OPENMP_THREAD_NUMBER;
2092    ADOLC_OPENMP_GET_THREAD_NUMBER;
2093    ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = 0;
2094}
2095
2096/****************************************************************************/
2097/*                                                                    UTILs */
2098/****************************************************************************/
2099double make_nan() {
2100    double a, b;
2101    #ifdef inf_num
2102    a = non_num;
2103    b = non_den;
2104    #endif
2105    return a / b;
2106}
2107
2108double make_inf() {
2109    double a, b;
2110    #ifdef inf_num
2111    a = inf_num;
2112    b = inf_den;
2113    #endif
2114    return a / b;
2115}
2116
2117/****************************************************************************/
2118/*                                                          DEBUG FUNCTIONS */
2119#if defined(ADOLC_HARDDEBUG)
2120
2121/*--------------------------------------------------------------------------*/
2122unsigned char get_op_f() {
2123    unsigned char temp;
2124    ADOLC_OPENMP_THREAD_NUMBER;
2125    ADOLC_OPENMP_GET_THREAD_NUMBER;
2126
2127    temp = *ADOLC_CURRENT_TAPE_INFOS.currOp;
2128    ++ADOLC_CURRENT_TAPE_INFOS.currOp;
2129    fprintf(DIAG_OUT, "f_op: %i\n", temp - '\0'); /* why -'\0' ??? kowarz */
2130    return temp;
2131}
2132
2133/*--------------------------------------------------------------------------*/
2134unsigned char get_op_r() {
2135    unsigned char temp;
2136    ADOLC_OPENMP_THREAD_NUMBER;
2137    ADOLC_OPENMP_GET_THREAD_NUMBER;
2138
2139    --ADOLC_CURRENT_TAPE_INFOS.currOp;
2140    temp = *ADOLC_CURRENT_TAPE_INFOS.currOp;
2141    fprintf(DIAG_OUT, "r_op: %i\n", temp - '\0');
2142    return temp;
2143}
2144
2145/*--------------------------------------------------------------------------*/
2146locint get_locint_f() {
2147    locint temp;
2148    ADOLC_OPENMP_THREAD_NUMBER;
2149    ADOLC_OPENMP_GET_THREAD_NUMBER;
2150
2151    temp = *ADOLC_CURRENT_TAPE_INFOS.currLoc;
2152    ++ADOLC_CURRENT_TAPE_INFOS.currLoc;
2153    fprintf(DIAG_OUT, "f_loc: %i\n", temp);
2154    return temp;
2155}
2156
2157/*--------------------------------------------------------------------------*/
2158locint get_locint_r() {
2159    unsigned char temp;
2160    ADOLC_OPENMP_THREAD_NUMBER;
2161    ADOLC_OPENMP_GET_THREAD_NUMBER;
2162
2163    --ADOLC_CURRENT_TAPE_INFOS.currLoc;
2164    temp = *ADOLC_CURRENT_TAPE_INFOS.currLoc;
2165    fprintf(DIAG_OUT, "r_loc: %i\n", temp);
2166    return temp;
2167}
2168
2169/*--------------------------------------------------------------------------*/
2170double get_val_f() {
2171    double temp;
2172    ADOLC_OPENMP_THREAD_NUMBER;
2173    ADOLC_OPENMP_GET_THREAD_NUMBER;
2174
2175    temp = *ADOLC_CURRENT_TAPE_INFOS.currVal;
2176    ++ADOLC_CURRENT_TAPE_INFOS.currVal;
2177    fprintf(DIAG_OUT, "f_val: %e\n", temp);
2178    return temp;
2179}
2180
2181/*--------------------------------------------------------------------------*/
2182double get_val_r() {
2183    double temp;
2184    ADOLC_OPENMP_THREAD_NUMBER;
2185    ADOLC_OPENMP_GET_THREAD_NUMBER;
2186
2187    --ADOLC_CURRENT_TAPE_INFOS.currVal;
2188    temp = *ADOLC_CURRENT_TAPE_INFOS.currVal;
2189    fprintf(DIAG_OUT, "r_val: %e\n", temp);
2190    return temp;
2191}
2192
2193#endif
2194
Note: See TracBrowser for help on using the repository browser.