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

Last change on this file since 275 was 275, checked in by awalther, 9 years ago

new NUM_EQ_PROD in tape_stats for improved hess_pat_calculation

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