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

Last change on this file since 294 was 294, checked in by kulshres, 8 years ago

convert tape stats to size_t from uint

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

  • Property svn:keywords set to Author Date Id Revision
File size: 93.4 KB
Line 
1/*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File:     taping.c
4 Revision: $Id: taping.c 294 2012-02-29 07:53:03Z kulshres $
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(size_t) + 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 {
1118        ADOLC_CURRENT_TAPE_INFOS.numOps_Tape =
1119            ADOLC_CURRENT_TAPE_INFOS.currOp - ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1120    }
1121    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] =
1122        ADOLC_CURRENT_TAPE_INFOS.numOps_Tape;
1123
1124    /* finish constants tape, close it, update stats */
1125    if (flag != 0 || ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) {
1126        if (ADOLC_CURRENT_TAPE_INFOS.currVal !=
1127                ADOLC_CURRENT_TAPE_INFOS.valBuffer)
1128        {
1129            put_val_block(ADOLC_CURRENT_TAPE_INFOS.currVal);
1130        }
1131        if (ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) 
1132            fclose(ADOLC_CURRENT_TAPE_INFOS.val_file);
1133        ADOLC_CURRENT_TAPE_INFOS.val_file = NULL;
1134        ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] = 1;
1135        free(ADOLC_CURRENT_TAPE_INFOS.valBuffer);
1136        ADOLC_CURRENT_TAPE_INFOS.valBuffer = NULL;
1137    } else {
1138        ADOLC_CURRENT_TAPE_INFOS.numVals_Tape =
1139            ADOLC_CURRENT_TAPE_INFOS.currVal - ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1140    }
1141    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] =
1142        ADOLC_CURRENT_TAPE_INFOS.numVals_Tape;
1143
1144    /* finish locations tape, update and write tape stats, close tape */
1145    if (flag != 0 || ADOLC_CURRENT_TAPE_INFOS.loc_file != NULL) {
1146        if (ADOLC_CURRENT_TAPE_INFOS.currLoc !=
1147                ADOLC_CURRENT_TAPE_INFOS.locBuffer)
1148        {
1149            put_loc_block(ADOLC_CURRENT_TAPE_INFOS.currLoc);
1150        }
1151        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] =
1152            ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape;
1153        ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] = 1;
1154        /* write tape stats */
1155        fseek(ADOLC_CURRENT_TAPE_INFOS.loc_file, 0, 0);
1156        fwrite(&adolc_id, sizeof(ADOLC_ID), 1,
1157                ADOLC_CURRENT_TAPE_INFOS.loc_file);
1158        fwrite(ADOLC_CURRENT_TAPE_INFOS.stats, STAT_SIZE * sizeof(size_t), 1,
1159               ADOLC_CURRENT_TAPE_INFOS.loc_file);
1160        fclose(ADOLC_CURRENT_TAPE_INFOS.loc_file);
1161        ADOLC_CURRENT_TAPE_INFOS.loc_file = NULL;
1162        free(ADOLC_CURRENT_TAPE_INFOS.locBuffer);
1163        ADOLC_CURRENT_TAPE_INFOS.locBuffer = NULL;
1164    } else {
1165        ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape  =
1166            ADOLC_CURRENT_TAPE_INFOS.currLoc - ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1167        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] =
1168            ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape;
1169    }
1170}
1171
1172/****************************************************************************/
1173/* Free all resources used by a tape before overwriting the tape.           */
1174/****************************************************************************/
1175void freeTapeResources(TapeInfos *tapeInfos) {
1176    free(tapeInfos->opBuffer);
1177    tapeInfos->opBuffer = NULL;
1178    free(tapeInfos->locBuffer);
1179    tapeInfos->locBuffer = NULL;
1180    free(tapeInfos->valBuffer);
1181    tapeInfos->valBuffer = NULL;
1182    if (tapeInfos->tayBuffer != NULL) {
1183        free(tapeInfos->tayBuffer);
1184        tapeInfos->tayBuffer = NULL;
1185        --numTBuffersInUse;
1186    }
1187    if (tapeInfos->op_file != NULL) {
1188        fclose(tapeInfos->op_file);
1189        tapeInfos->op_file = NULL;
1190    }
1191    if (tapeInfos->loc_file != NULL) {
1192        fclose(tapeInfos->loc_file);
1193        tapeInfos->loc_file = NULL;
1194    }
1195    if (tapeInfos->val_file != NULL) {
1196        fclose(tapeInfos->val_file);
1197        tapeInfos->val_file = NULL;
1198    }
1199    if (tapeInfos->tay_file != NULL) {
1200        fclose(tapeInfos->tay_file);
1201        tapeInfos->tay_file = NULL;
1202    }
1203}
1204
1205/****************************************************************************/
1206/* Tapestats:                                                               */
1207/* Returns statistics on the tape tag with following meaning:               */
1208/* tape_stat[0] = # of independent variables.                               */
1209/* tape_stat[1] = # of dependent variables.                                 */
1210/* tape_stat[2] = max # of live variables.                                  */
1211/* tape_stat[3] = value stack size.                                         */
1212/* tape_stat[4] = buffer size (# of chars, # of doubles, # of locints)      */
1213/* tape_stat[5] = # of operations.                                          */
1214/* tape_stat[6] = operation file access flag (1 = file in use, 0 otherwise) */
1215/* tape_stat[7] = # of saved locations.                                     */
1216/* tape_stat[8] = location file access flag (1 = file in use, 0 otherwise)  */
1217/* tape_stat[9] = # of saved constant values.                               */
1218/* tape_stat[10]= value file access flag (1 = file in use, 0 otherwise)     */
1219/****************************************************************************/
1220void tapestats(short tag, size_t *tape_stats) {
1221    int i;
1222    TapeInfos *tapeInfos;
1223
1224    /* get the tapeInfos for tag */
1225    tapeInfos = getTapeInfos(tag);
1226    /* copy stats to the users field */
1227    for (i = 0; i < STAT_SIZE; ++i)
1228        tape_stats[i] = tapeInfos->stats[i];
1229}
1230
1231/****************************************************************************/
1232/* An all-in-one tape stats printing routine.                               */
1233/****************************************************************************/
1234void printTapeStats(FILE *stream, short tag) {
1235    size_t stats[STAT_SIZE];
1236
1237    tapestats(tag, (size_t *)&stats);
1238    fprintf(stream, "\n*** TAPE STATS (tape %d) **********\n", (int)tag);
1239    fprintf(stream, "Number of independents: %10zd\n", stats[NUM_INDEPENDENTS]);
1240    fprintf(stream, "Number of dependents:   %10zd\n", stats[NUM_DEPENDENTS]);
1241    fprintf(stream, "\n");
1242    fprintf(stream, "Max # of live adoubles: %10zd\n", stats[NUM_MAX_LIVES]);
1243    fprintf(stream, "Taylor stack size:      %10zd\n", stats[TAY_STACK_SIZE]);
1244    fprintf(stream, "\n");
1245    fprintf(stream, "Number of operations:   %10zd\n", stats[NUM_OPERATIONS]);
1246    fprintf(stream, "Number of locations:    %10zd\n", stats[NUM_LOCATIONS]);
1247    fprintf(stream, "Number of values:       %10zd\n", stats[NUM_VALUES]);
1248    fprintf(stream, "\n");
1249    fprintf(stream, "Operation file written: %10zd\n", stats[OP_FILE_ACCESS]);
1250    fprintf(stream, "Location file written:  %10zd\n", stats[LOC_FILE_ACCESS]);
1251    fprintf(stream, "Value file written:     %10zd\n", stats[VAL_FILE_ACCESS]);
1252    fprintf(stream, "\n");
1253    fprintf(stream, "Operation buffer size:  %10zd\n", stats[OP_BUFFER_SIZE]);
1254    fprintf(stream, "Location buffer size:   %10zd\n", stats[LOC_BUFFER_SIZE]);
1255    fprintf(stream, "Value buffer size:      %10zd\n", stats[VAL_BUFFER_SIZE]);
1256    fprintf(stream, "Taylor buffer size:     %10zd\n", stats[TAY_BUFFER_SIZE]);
1257    fprintf(stream, "\n");
1258    fprintf(stream, "Operation type size:    %10zd\n",
1259            (size_t)sizeof(unsigned char));
1260    fprintf(stream, "Location type size:     %10zd\n", (size_t)sizeof(locint));
1261    fprintf(stream, "Value type size:        %10zd\n", (size_t)sizeof(double));
1262    fprintf(stream, "Taylor type size:       %10zd\n", (size_t)sizeof(revreal));
1263    fprintf(stream, "**********************************\n\n");
1264}
1265
1266/****************************************************************************/
1267/* Does the actual reading from the hard disk into the stats buffer         */
1268/****************************************************************************/
1269void read_tape_stats(TapeInfos *tapeInfos) {
1270    FILE *loc_file;
1271    int tapeVersion, limitVersion;
1272    ADOLC_ID tape_ADOLC_ID;
1273
1274    if (tapeInfos->inUse != 0 && tapeInfos->tapingComplete == 0) return;
1275
1276    limitVersion = 100 * ADOLC_NEW_TAPE_VERSION    +
1277            10 * ADOLC_NEW_TAPE_SUBVERSION +
1278            1  * ADOLC_NEW_TAPE_PATCHLEVEL ;
1279
1280    if ((loc_file = fopen(tapeInfos->pTapeInfos.loc_fileName, "rb")) == NULL)
1281        fail(ADOLC_INTEGER_TAPE_FOPEN_FAILED);
1282    if (fread(&tape_ADOLC_ID, sizeof(ADOLC_ID), 1, loc_file) != 1)
1283        fail(ADOLC_INTEGER_TAPE_FREAD_FAILED);
1284    if (fread(tapeInfos->stats, STAT_SIZE * sizeof(size_t), 1, loc_file) != 1)
1285        fail(ADOLC_INTEGER_TAPE_FREAD_FAILED);
1286
1287    failAdditionalInfo1 = tapeInfos->tapeID;
1288    tapeVersion = 100 * tape_ADOLC_ID.adolc_ver +
1289            10 * tape_ADOLC_ID.adolc_sub +
1290            1  * tape_ADOLC_ID.adolc_lvl ;
1291    if (tapeVersion < limitVersion) fail(ADOLC_TAPE_TO_OLD);
1292
1293    if (tape_ADOLC_ID.locint_size != adolc_id.locint_size) {
1294        failAdditionalInfo1 = tape_ADOLC_ID.locint_size;
1295        failAdditionalInfo2 = adolc_id.locint_size;
1296        fail(ADOLC_WRONG_LOCINT_SIZE);
1297    }
1298
1299    fclose(loc_file);
1300    tapeInfos->tapingComplete = 1;
1301}
1302
1303/****************************************************************************/
1304/* Initialize a forward sweep. Get stats, open tapes, fill buffers, ...     */
1305/****************************************************************************/
1306void init_for_sweep(short tag) {
1307    int i = 0, chunks, numLocsForStats;
1308    size_t number, remain, chunkSize;
1309    ADOLC_OPENMP_THREAD_NUMBER;
1310    ADOLC_OPENMP_GET_THREAD_NUMBER;
1311
1312    /* mark possible (hard disk) tape creation */
1313    markNewTape();
1314
1315    /* make room for tapeInfos and read tape stats if necessary, keep value
1316     * stack information */
1317    openTape(tag, ADOLC_FORWARD);
1318    initTapeBuffers();
1319
1320    /* init operations */
1321    number = 0;
1322    if (ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS] == 1) {
1323        ADOLC_CURRENT_TAPE_INFOS.op_file =
1324            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "rb");
1325        /* how much to read ? */
1326        number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE],
1327                ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS]);
1328        if (number != 0) {
1329            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1330            chunks = number / chunkSize;
1331            for (i = 0; i < chunks; ++i)
1332                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1333                            chunkSize * sizeof(unsigned char), 1,
1334                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1335                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1336            remain = number % chunkSize;
1337            if (remain != 0)
1338                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks *
1339                            chunkSize, remain * sizeof(unsigned char), 1,
1340                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1341                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1342        }
1343        /* how much remains ? */
1344        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] - number;
1345    }
1346    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape = number;
1347    ADOLC_CURRENT_TAPE_INFOS.currOp = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1348
1349    /* init locations */
1350    number = 0;
1351    if (ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] == 1) {
1352        ADOLC_CURRENT_TAPE_INFOS.loc_file =
1353            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "rb");
1354        /* how much to read ? */
1355        number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE],
1356                ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS]);
1357        if (number != 0) {
1358            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1359            chunks = number / chunkSize;
1360            for (i = 0; i < chunks; ++i)
1361                if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1362                            chunkSize * sizeof(locint), 1,
1363                            ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1364                    fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1365            remain = number % chunkSize;
1366            if (remain != 0)
1367            if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks * chunkSize,
1368                        remain * sizeof(locint), 1,
1369                        ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1370                fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1371        }
1372        /* how much remains ? */
1373        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] - number;
1374    }
1375    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape = number;
1376
1377    /* skip stats */
1378    numLocsForStats = statSpace;
1379    while (numLocsForStats >= ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE])
1380    {
1381        get_loc_block_f();
1382        numLocsForStats -= ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1383    }
1384    ADOLC_CURRENT_TAPE_INFOS.currLoc =
1385        ADOLC_CURRENT_TAPE_INFOS.locBuffer + numLocsForStats;
1386
1387    /* init constants */
1388    number = 0;
1389    if (ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] == 1) {
1390        ADOLC_CURRENT_TAPE_INFOS.val_file =
1391            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "rb");
1392        /* how much to read ? */
1393        number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE],
1394                ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES]);
1395        if (number != 0) {
1396            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1397            chunks = number / chunkSize;
1398            for (i = 0; i < chunks; ++i)
1399                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1400                            chunkSize * sizeof(double), 1,
1401                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1402                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1403            remain = number % chunkSize;
1404            if (remain != 0)
1405                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks *
1406                            chunkSize, remain * sizeof(double), 1,
1407                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1408                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1409        }
1410        /* how much remains ? */
1411        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] - number;
1412    }
1413    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape = number;
1414    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1415}
1416
1417/****************************************************************************/
1418/* Initialize a reverse sweep. Get stats, open tapes, fill buffers, ...     */
1419/****************************************************************************/
1420void init_rev_sweep(short tag) {
1421    int i, chunks;
1422    size_t number, remain, chunkSize;
1423    ADOLC_OPENMP_THREAD_NUMBER;
1424    ADOLC_OPENMP_GET_THREAD_NUMBER;
1425
1426    /* mark possible (hard disk) tape creation */
1427    markNewTape();
1428
1429    /* make room for tapeInfos and read tape stats if necessary, keep value
1430     * stack information */
1431    openTape(tag, ADOLC_REVERSE);
1432    initTapeBuffers();
1433
1434    /* init operations */
1435    number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS];
1436    if (ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS] == 1) {
1437        ADOLC_CURRENT_TAPE_INFOS.op_file =
1438            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "rb");
1439        number = (ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] /
1440                ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE]) *
1441                ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE];
1442        fseek(ADOLC_CURRENT_TAPE_INFOS.op_file,
1443                number * sizeof(unsigned char), SEEK_SET);
1444        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] %
1445                ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE] ;
1446        if (number != 0) {
1447            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1448            chunks = number / chunkSize;
1449            for (i = 0; i < chunks; ++i)
1450                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1451                            chunkSize * sizeof(unsigned char), 1,
1452                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1453                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1454            remain = number % chunkSize;
1455            if (remain != 0)
1456                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks *
1457                            chunkSize, remain * sizeof(unsigned char), 1,
1458                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1459                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1460        }
1461    }
1462    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape =
1463        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] - number;
1464    ADOLC_CURRENT_TAPE_INFOS.currOp =
1465        ADOLC_CURRENT_TAPE_INFOS.opBuffer + number;
1466
1467    /* init locations */
1468    number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS];
1469    if (ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] == 1) {
1470        ADOLC_CURRENT_TAPE_INFOS.loc_file =
1471            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "rb");
1472        number = (ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] /
1473                ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE]) *
1474                ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1475        fseek(ADOLC_CURRENT_TAPE_INFOS.loc_file,
1476                number * sizeof(locint), SEEK_SET);
1477        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] %
1478                ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1479        if (number != 0) {
1480            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1481            chunks = number / chunkSize;
1482            for (i = 0; i < chunks; ++i)
1483                if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1484                            chunkSize * sizeof(locint), 1,
1485                            ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1486                    fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1487            remain = number % chunkSize;
1488            if (remain != 0)
1489                if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks *
1490                            chunkSize, remain * sizeof(locint), 1,
1491                            ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1492                    fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1493        }
1494    }
1495    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape =
1496        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] - number;
1497    ADOLC_CURRENT_TAPE_INFOS.currLoc =
1498        ADOLC_CURRENT_TAPE_INFOS.locBuffer + number;
1499
1500    /* init constants */
1501    number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES];
1502    if (ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] == 1) {
1503        ADOLC_CURRENT_TAPE_INFOS.val_file =
1504            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "rb");
1505        number = (ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] /
1506                ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE]) *
1507                ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1508        fseek(ADOLC_CURRENT_TAPE_INFOS.val_file,
1509                number * sizeof(double), SEEK_SET);
1510        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] %
1511                ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1512        if (number != 0) {
1513            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1514            chunks = number / chunkSize;
1515            for (i = 0; i < chunks; ++i)
1516                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1517                            chunkSize * sizeof(double), 1,
1518                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1519                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1520            remain = number % chunkSize;
1521            if (remain != 0)
1522                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks *
1523                            chunkSize, remain * sizeof(double), 1,
1524                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1525                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1526        }
1527    }
1528    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape =
1529        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] - number;
1530    ADOLC_CURRENT_TAPE_INFOS.currVal =
1531        ADOLC_CURRENT_TAPE_INFOS.valBuffer + number;
1532}
1533
1534/****************************************************************************/
1535/* Finish a forward or reverse sweep.                                       */
1536/****************************************************************************/
1537void end_sweep() {
1538    ADOLC_OPENMP_THREAD_NUMBER;
1539    ADOLC_OPENMP_GET_THREAD_NUMBER;
1540    if (ADOLC_CURRENT_TAPE_INFOS.op_file != NULL) {
1541        fclose(ADOLC_CURRENT_TAPE_INFOS.op_file);
1542        ADOLC_CURRENT_TAPE_INFOS.op_file = NULL;
1543    }
1544    if (ADOLC_CURRENT_TAPE_INFOS.loc_file != NULL) {
1545        fclose(ADOLC_CURRENT_TAPE_INFOS.loc_file);
1546        ADOLC_CURRENT_TAPE_INFOS.loc_file = NULL;
1547    }
1548    if (ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) {
1549        fclose(ADOLC_CURRENT_TAPE_INFOS.val_file);
1550        ADOLC_CURRENT_TAPE_INFOS.val_file = NULL;
1551    }
1552    if (ADOLC_CURRENT_TAPE_INFOS.deg_save > 0) releaseTape(); /* keep value stack */
1553    else releaseTape(); /* no value stack */
1554}
1555
1556/* --- Operations --- */
1557
1558/****************************************************************************/
1559/* Puts an operation into the operation buffer. Ensures that location buffer*/
1560/* and constants buffer are prepared to take the belonging stuff.           */
1561/****************************************************************************/
1562void put_op(unsigned char op) {
1563    ADOLC_OPENMP_THREAD_NUMBER;
1564    ADOLC_OPENMP_GET_THREAD_NUMBER;
1565    /* every operation writes <5 locations */
1566    if (ADOLC_CURRENT_TAPE_INFOS.currLoc + 5 > ADOLC_CURRENT_TAPE_INFOS.lastLocP1) {
1567        *(ADOLC_CURRENT_TAPE_INFOS.lastLocP1 - 1) = ADOLC_CURRENT_TAPE_INFOS.lastLocP1 -
1568                ADOLC_CURRENT_TAPE_INFOS.currLoc;
1569        put_loc_block(ADOLC_CURRENT_TAPE_INFOS.lastLocP1);
1570        /* every operation writes 1 opcode */
1571        if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1572            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1573            put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1574            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1575            ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1576        }
1577        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_int;
1578        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1579    }
1580    /* every operation writes <5 values --- 3 should be sufficient */
1581    if (ADOLC_CURRENT_TAPE_INFOS.currVal + 5 > ADOLC_CURRENT_TAPE_INFOS.lastValP1) {
1582        ADOLC_PUT_LOCINT(ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1583        put_val_block(ADOLC_CURRENT_TAPE_INFOS.lastValP1);
1584        /* every operation writes 1 opcode */
1585        if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1586            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1587            put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1588            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1589            ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1590        }
1591        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_val;
1592        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1593    }
1594    /* every operation writes 1 opcode */
1595    if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1596        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1597        put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1598        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1599        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1600    }
1601    *ADOLC_CURRENT_TAPE_INFOS.currOp = op;
1602    ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1603}
1604
1605/****************************************************************************/
1606/* Writes a block of operations onto hard disk and handles file creation,   */
1607/* removal, ...                                                             */
1608/****************************************************************************/
1609void put_op_block(unsigned char *lastOpP1) {
1610    size_t i, chunks;
1611    size_t number, remain, chunkSize;
1612    ADOLC_OPENMP_THREAD_NUMBER;
1613    ADOLC_OPENMP_GET_THREAD_NUMBER;
1614
1615    if (ADOLC_CURRENT_TAPE_INFOS.op_file == NULL) {
1616        ADOLC_CURRENT_TAPE_INFOS.op_file =
1617            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "rb");
1618        if (ADOLC_CURRENT_TAPE_INFOS.op_file != NULL) {
1619            #if defined(ADOLC_DEBUG)
1620            fprintf(DIAG_OUT, "ADOL-C debug: Old tapefile %s gets removed!\n",
1621                    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName);
1622            #endif
1623            fclose(ADOLC_CURRENT_TAPE_INFOS.op_file);
1624            ADOLC_CURRENT_TAPE_INFOS.op_file = NULL;
1625            if (remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName))
1626                fprintf(DIAG_OUT, "ADOL-C warning: "
1627                        "Unable to remove old tapefile\n");
1628            ADOLC_CURRENT_TAPE_INFOS.op_file =
1629                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "wb");
1630        } else {
1631            ADOLC_CURRENT_TAPE_INFOS.op_file =
1632                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "wb");
1633        }
1634    }
1635
1636    number = lastOpP1 - ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1637    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1638    chunks = number / chunkSize;
1639    for (i = 0; i < chunks; ++i)
1640        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.opBuffer +
1641                        i * chunkSize, chunkSize *
1642                        sizeof(unsigned char), 1,
1643                        ADOLC_CURRENT_TAPE_INFOS.op_file) ) != 1 )
1644            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1645    remain = number % chunkSize;
1646    if (remain != 0)
1647        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.opBuffer +
1648                        chunks * chunkSize, remain *
1649                        sizeof(unsigned char), 1,
1650                        ADOLC_CURRENT_TAPE_INFOS.op_file) ) != 1 )
1651            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1652    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape += number;
1653    ADOLC_CURRENT_TAPE_INFOS.currOp = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1654    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1655}
1656
1657/****************************************************************************/
1658/* Reads the next operations block into the internal buffer.                */
1659/****************************************************************************/
1660void get_op_block_f() {
1661    size_t i, chunks;
1662    size_t number, remain, chunkSize;
1663    ADOLC_OPENMP_THREAD_NUMBER;
1664    ADOLC_OPENMP_GET_THREAD_NUMBER;
1665
1666    number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE],
1667            ADOLC_CURRENT_TAPE_INFOS.numOps_Tape);
1668    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1669    chunks = number / chunkSize;
1670    for (i = 0; i < chunks; ++i)
1671        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1672                    chunkSize * sizeof(unsigned char), 1,
1673                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1674            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1675    remain = number % chunkSize;
1676    if (remain != 0)
1677        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks * chunkSize,
1678                    remain * sizeof(unsigned char), 1,
1679                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1680            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1681    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape -= remain;
1682    ADOLC_CURRENT_TAPE_INFOS.currOp = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1683}
1684
1685/****************************************************************************/
1686/* Reads the previous block of operations into the internal buffer.         */
1687/****************************************************************************/
1688void get_op_block_r() {
1689    size_t i, chunks;
1690    size_t number, remain, chunkSize;
1691    ADOLC_OPENMP_THREAD_NUMBER;
1692    ADOLC_OPENMP_GET_THREAD_NUMBER;
1693
1694    number = ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE];
1695    fseek(ADOLC_CURRENT_TAPE_INFOS.op_file, sizeof(unsigned char) *
1696            (ADOLC_CURRENT_TAPE_INFOS.numOps_Tape - number), SEEK_SET);
1697    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1698    chunks = number / chunkSize;
1699    for (i = 0; i < chunks; ++i)
1700        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1701                    chunkSize * sizeof(unsigned char), 1,
1702                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1703            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1704    remain = number % chunkSize;
1705    if (remain != 0)
1706        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks * chunkSize,
1707                    remain * sizeof(unsigned char), 1,
1708                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1709            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1710    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape -= number;
1711    ADOLC_CURRENT_TAPE_INFOS.currOp =
1712        ADOLC_CURRENT_TAPE_INFOS.opBuffer + number;
1713}
1714
1715/* --- Locations --- */
1716
1717/****************************************************************************/
1718/* Writes a block of locations onto hard disk and handles file creation,   */
1719/* removal, ...                                                             */
1720/****************************************************************************/
1721void put_loc_block(locint *lastLocP1) {
1722    size_t i, chunks;
1723    size_t number, remain, chunkSize;
1724    ADOLC_OPENMP_THREAD_NUMBER;
1725    ADOLC_OPENMP_GET_THREAD_NUMBER;
1726
1727    if (ADOLC_CURRENT_TAPE_INFOS.loc_file == NULL) {
1728        ADOLC_CURRENT_TAPE_INFOS.loc_file =
1729            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "rb");
1730        if (ADOLC_CURRENT_TAPE_INFOS.loc_file != NULL) {
1731            #if defined(ADOLC_DEBUG)
1732            fprintf(DIAG_OUT, "ADOL-C debug: Old tapefile %s gets removed!\n",
1733                    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName);
1734            #endif
1735            fclose(ADOLC_CURRENT_TAPE_INFOS.loc_file);
1736            ADOLC_CURRENT_TAPE_INFOS.loc_file = NULL;
1737            if (remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName))
1738                fprintf(DIAG_OUT, "ADOL-C warning: "
1739                        "Unable to remove old tapefile!\n");
1740            ADOLC_CURRENT_TAPE_INFOS.loc_file =
1741                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "wb");
1742        } else {
1743            ADOLC_CURRENT_TAPE_INFOS.loc_file =
1744                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "wb");
1745        }
1746    }
1747
1748    number = lastLocP1 - ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1749    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1750    chunks = number / chunkSize;
1751    for (i = 0; i < chunks; ++i)
1752        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.locBuffer +
1753                        i * chunkSize, chunkSize * sizeof(locint), 1,
1754                        ADOLC_CURRENT_TAPE_INFOS.loc_file) ) != 1)
1755            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1756    remain = number % chunkSize;
1757    if (remain != 0)
1758        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.locBuffer +
1759                        chunks * chunkSize, remain * sizeof(locint), 1,
1760                        ADOLC_CURRENT_TAPE_INFOS.loc_file) ) != 1)
1761            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1762    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape += number;
1763    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1764    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1765}
1766
1767/****************************************************************************/
1768/* Reads the next block of locations into the internal buffer.              */
1769/****************************************************************************/
1770void get_loc_block_f() {
1771    size_t i, chunks;
1772    size_t number, remain, chunkSize;
1773    ADOLC_OPENMP_THREAD_NUMBER;
1774    ADOLC_OPENMP_GET_THREAD_NUMBER;
1775
1776    number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE],
1777            ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape);
1778    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof (locint);
1779    chunks = number / chunkSize;
1780    for (i = 0; i < chunks; ++i)
1781        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1782                    chunkSize * sizeof(locint), 1,
1783                    ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1784            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1785    remain = number % chunkSize;
1786    if (remain != 0)
1787        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks * chunkSize,
1788                    remain * sizeof(locint), 1,
1789                    ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1790            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1791    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape -= number;
1792    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1793}
1794
1795/****************************************************************************/
1796/* Reads the previous block of locations into the internal buffer.          */
1797/****************************************************************************/
1798void get_loc_block_r() {
1799    size_t i, chunks;
1800    size_t number, remain, chunkSize;
1801    ADOLC_OPENMP_THREAD_NUMBER;
1802    ADOLC_OPENMP_GET_THREAD_NUMBER;
1803
1804    number = ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1805    fseek(ADOLC_CURRENT_TAPE_INFOS.loc_file, sizeof(locint) *
1806            (ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape - number), SEEK_SET);
1807    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1808    chunks = number / chunkSize;
1809    for (i = 0; i < chunks; ++i)
1810        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1811                   chunkSize * sizeof(locint), 1,
1812                   ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1813            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1814    remain = number % chunkSize;
1815    if (remain != 0)
1816        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks * chunkSize,
1817                   remain * sizeof(locint), 1,
1818                   ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1819            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1820    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape -=
1821        ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1822    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.lastLocP1 -
1823            *(ADOLC_CURRENT_TAPE_INFOS.lastLocP1 - 1);
1824}
1825
1826/* --- Values (Constants -- Real) --- */
1827
1828/****************************************************************************/
1829/* Writes a block of constants (real) onto hard disk and handles file       */
1830/* creation, removal, ...                                                   */
1831/****************************************************************************/
1832void put_vals_writeBlock(double *vals, locint numVals) {
1833    int i;
1834    ADOLC_OPENMP_THREAD_NUMBER;
1835    ADOLC_OPENMP_GET_THREAD_NUMBER;
1836
1837    for (i = 0; i < numVals; ++i) {
1838        *ADOLC_CURRENT_TAPE_INFOS.currVal = vals[i];
1839        ++ADOLC_CURRENT_TAPE_INFOS.currVal;
1840    }
1841    ADOLC_PUT_LOCINT(ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1842    put_val_block(ADOLC_CURRENT_TAPE_INFOS.lastValP1);
1843    /* every operation writes 1 opcode */
1844    if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1845        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1846        put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1847        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1848        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1849    }
1850    *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_val;
1851    ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1852}
1853
1854/****************************************************************************/
1855/* Write some constants to the buffer without disk access                   */
1856/****************************************************************************/
1857void put_vals_notWriteBlock(double *vals, locint numVals) {
1858    int i;
1859    ADOLC_OPENMP_THREAD_NUMBER;
1860    ADOLC_OPENMP_GET_THREAD_NUMBER;
1861
1862    for (i = 0; i < numVals; ++i) {
1863        *ADOLC_CURRENT_TAPE_INFOS.currVal = vals[i];
1864        ++ADOLC_CURRENT_TAPE_INFOS.currVal;
1865    }
1866}
1867
1868/****************************************************************************/
1869/* Writes a block of constants (real) onto tape and handles file creation   */
1870/* removal, ...                                                             */
1871/****************************************************************************/
1872void put_val_block(double *lastValP1) {
1873    size_t i, chunks;
1874    size_t number, remain, chunkSize;
1875    ADOLC_OPENMP_THREAD_NUMBER;
1876    ADOLC_OPENMP_GET_THREAD_NUMBER;
1877
1878    if (ADOLC_CURRENT_TAPE_INFOS.val_file == NULL) {
1879        ADOLC_CURRENT_TAPE_INFOS.val_file =
1880            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "rb");
1881        if (ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) {
1882            #if defined(ADOLC_DEBUG)
1883            fprintf(DIAG_OUT, "ADOL-C debug: Old tapefile %s gets removed!\n",
1884                    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName);
1885            #endif
1886            fclose(ADOLC_CURRENT_TAPE_INFOS.val_file);
1887            ADOLC_CURRENT_TAPE_INFOS.val_file = NULL;
1888            if (remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName))
1889                fprintf(DIAG_OUT, "ADOL-C warning: "
1890                        "Unable to remove old tapefile\n");
1891            ADOLC_CURRENT_TAPE_INFOS.val_file =
1892                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "wb");
1893        } else {
1894            ADOLC_CURRENT_TAPE_INFOS.val_file =
1895                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "wb");
1896        }
1897    }
1898
1899    number = lastValP1 - ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1900    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1901    chunks = number / chunkSize;
1902    for (i = 0; i < chunks; ++i)
1903        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.valBuffer +
1904                        i * chunkSize, chunkSize * sizeof(double), 1,
1905                        ADOLC_CURRENT_TAPE_INFOS.val_file) ) != 1)
1906            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1907    remain = number % chunkSize;
1908    if (remain != 0)
1909        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.valBuffer +
1910                        chunks * chunkSize, remain * sizeof(double), 1,
1911                        ADOLC_CURRENT_TAPE_INFOS.val_file) ) != 1)
1912            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1913    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape += number;
1914    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1915    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1916}
1917
1918/****************************************************************************/
1919/* Reads the next block of constants into the internal buffer.              */
1920/****************************************************************************/
1921void get_val_block_f() {
1922    size_t i, chunks;
1923    size_t number, remain, chunkSize;
1924    ADOLC_OPENMP_THREAD_NUMBER;
1925    ADOLC_OPENMP_GET_THREAD_NUMBER;
1926
1927    number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE],
1928            ADOLC_CURRENT_TAPE_INFOS.numVals_Tape);
1929    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof (double);
1930    chunks = number / chunkSize;
1931    for (i = 0; i < chunks; ++i)
1932        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1933                    chunkSize * sizeof(double), 1,
1934                    ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1935            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1936    remain = number % chunkSize;
1937    if (remain != 0)
1938        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks * chunkSize,
1939                    remain * sizeof(double), 1,
1940                    ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1941            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1942    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape -= number;
1943    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1944    /* get_locint_f(); value used in reverse only */
1945    ++ADOLC_CURRENT_TAPE_INFOS.currLoc;
1946}
1947
1948/****************************************************************************/
1949/* Reads the previous block of values into the internal buffer.             */
1950/****************************************************************************/
1951void get_val_block_r() {
1952    size_t i, chunks;
1953    size_t number, remain, chunkSize;
1954    locint temp;
1955    ADOLC_OPENMP_THREAD_NUMBER;
1956    ADOLC_OPENMP_GET_THREAD_NUMBER;
1957
1958    number = ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1959    fseek(ADOLC_CURRENT_TAPE_INFOS.val_file, sizeof(double) *
1960            (ADOLC_CURRENT_TAPE_INFOS.numVals_Tape - number), SEEK_SET);
1961    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1962    chunks = number / chunkSize;
1963    for (i = 0; i < chunks; ++i)
1964        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1965                   chunkSize * sizeof(double), 1,
1966                   ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1967            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1968    remain = number % chunkSize;
1969    if (remain != 0)
1970        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks * chunkSize,
1971                    remain * sizeof(double), 1,
1972                    ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1973            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1974    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape -= number;
1975    --ADOLC_CURRENT_TAPE_INFOS.currLoc;
1976    temp = *ADOLC_CURRENT_TAPE_INFOS.currLoc;
1977    ADOLC_CURRENT_TAPE_INFOS.currVal =
1978        ADOLC_CURRENT_TAPE_INFOS.lastValP1 - temp;
1979}
1980
1981/****************************************************************************/
1982/* Returns the number of free constants in the real tape. Ensures that it   */
1983/* is at least 5.                                                           */
1984/****************************************************************************/
1985locint get_val_space(void) {
1986    ADOLC_OPENMP_THREAD_NUMBER;
1987    ADOLC_OPENMP_GET_THREAD_NUMBER;
1988    if (ADOLC_CURRENT_TAPE_INFOS.lastValP1 - 5 < ADOLC_CURRENT_TAPE_INFOS.currVal) {
1989        ADOLC_PUT_LOCINT(ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1990        put_val_block(ADOLC_CURRENT_TAPE_INFOS.lastValP1);
1991        /* every operation writes 1 opcode */
1992        if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1993            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1994            put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1995            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1996            ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1997        }
1998        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_val;
1999        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
2000    }
2001    return (ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
2002}
2003
2004/****************************************************************************/
2005/* Returns a pointer to the first element of a values vector and skips the  */
2006/* vector. -- Forward Mode --                                               */
2007/****************************************************************************/
2008double *get_val_v_f(locint size) {
2009    double *temp;
2010    ADOLC_OPENMP_THREAD_NUMBER;
2011
2012    ADOLC_OPENMP_GET_THREAD_NUMBER;
2013    temp = ADOLC_CURRENT_TAPE_INFOS.currVal;
2014    ADOLC_CURRENT_TAPE_INFOS.currVal += size;
2015    return temp;
2016}
2017
2018/****************************************************************************/
2019/* Returns a pointer to the first element of a values vector and skips the  */
2020/* vector. -- Reverse Mode --                                               */
2021/****************************************************************************/
2022double *get_val_v_r(locint size) {
2023    ADOLC_OPENMP_THREAD_NUMBER;
2024    ADOLC_OPENMP_GET_THREAD_NUMBER;
2025    ADOLC_CURRENT_TAPE_INFOS.currVal -= size;
2026    return ADOLC_CURRENT_TAPE_INFOS.currVal;
2027}
2028
2029/* --- Updates / Corrections --- */
2030
2031/****************************************************************************/
2032/* Not sure what's going on here! -> vector class ?  --- kowarz             */
2033/****************************************************************************/
2034void reset_val_r(void) {
2035    ADOLC_OPENMP_THREAD_NUMBER;
2036    ADOLC_OPENMP_GET_THREAD_NUMBER;
2037    if (ADOLC_CURRENT_TAPE_INFOS.currVal == ADOLC_CURRENT_TAPE_INFOS.valBuffer)
2038        get_val_block_r();
2039}
2040
2041/****************************************************************************/
2042/* Update locations tape to remove assignments involving temp. variables.   */
2043/* e.g.  t = a + b ; y = t  =>  y = a + b                                   */
2044/****************************************************************************/
2045int upd_resloc(locint temp, locint lhs) {
2046    ADOLC_OPENMP_THREAD_NUMBER;
2047    ADOLC_OPENMP_GET_THREAD_NUMBER;
2048    if (ADOLC_CURRENT_TAPE_INFOS.currLoc - ADOLC_CURRENT_TAPE_INFOS.locBuffer < 1) return 0;
2049    if (temp == *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1)) {
2050        *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1) = lhs;
2051        return 1;
2052    }
2053    return 0;
2054}
2055
2056/****************************************************************************/
2057/* Update locations and operations tape to remove special operations inv.   */
2058/* temporary variables. e.g.  t = a * b ; y += t  =>  y += a * b            */
2059/****************************************************************************/
2060int upd_resloc_inc_prod(locint temp, locint newlhs, unsigned char newop) {
2061    ADOLC_OPENMP_THREAD_NUMBER;
2062    ADOLC_OPENMP_GET_THREAD_NUMBER;
2063    if (ADOLC_CURRENT_TAPE_INFOS.currLoc - ADOLC_CURRENT_TAPE_INFOS.locBuffer < 3) return 0;
2064    if (ADOLC_CURRENT_TAPE_INFOS.currOp - ADOLC_CURRENT_TAPE_INFOS.opBuffer < 1) return 0;
2065    if (temp == *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1)    &&
2066            mult_a_a == *(ADOLC_CURRENT_TAPE_INFOS.currOp - 1) &&
2067            /* skipping recursive case */
2068            newlhs != *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 2)  &&
2069            newlhs != *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 3)    ) {
2070        *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1) = newlhs;
2071        *(ADOLC_CURRENT_TAPE_INFOS.currOp - 1) = newop;
2072        return 1;
2073    }
2074    return 0;
2075}
2076
2077void enableBranchSwitchWarnings() {
2078    ADOLC_OPENMP_THREAD_NUMBER;
2079    ADOLC_OPENMP_GET_THREAD_NUMBER;
2080    ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = 1;
2081}
2082
2083void disableBranchSwitchWarnings() {
2084    ADOLC_OPENMP_THREAD_NUMBER;
2085    ADOLC_OPENMP_GET_THREAD_NUMBER;
2086    ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = 0;
2087}
2088
2089/****************************************************************************/
2090/*                                                                    UTILs */
2091/****************************************************************************/
2092double make_nan() {
2093    double a, b;
2094    #ifdef inf_num
2095    a = non_num;
2096    b = non_den;
2097    #endif
2098    return a / b;
2099}
2100
2101double make_inf() {
2102    double a, b;
2103    #ifdef inf_num
2104    a = inf_num;
2105    b = inf_den;
2106    #endif
2107    return a / b;
2108}
2109
2110/****************************************************************************/
2111/*                                                          DEBUG FUNCTIONS */
2112#if defined(ADOLC_HARDDEBUG)
2113
2114/*--------------------------------------------------------------------------*/
2115unsigned char get_op_f() {
2116    unsigned char temp;
2117    ADOLC_OPENMP_THREAD_NUMBER;
2118    ADOLC_OPENMP_GET_THREAD_NUMBER;
2119
2120    temp = *ADOLC_CURRENT_TAPE_INFOS.currOp;
2121    ++ADOLC_CURRENT_TAPE_INFOS.currOp;
2122    fprintf(DIAG_OUT, "f_op: %i\n", temp - '\0'); /* why -'\0' ??? kowarz */
2123    return temp;
2124}
2125
2126/*--------------------------------------------------------------------------*/
2127unsigned char get_op_r() {
2128    unsigned char temp;
2129    ADOLC_OPENMP_THREAD_NUMBER;
2130    ADOLC_OPENMP_GET_THREAD_NUMBER;
2131
2132    --ADOLC_CURRENT_TAPE_INFOS.currOp;
2133    temp = *ADOLC_CURRENT_TAPE_INFOS.currOp;
2134    fprintf(DIAG_OUT, "r_op: %i\n", temp - '\0');
2135    return temp;
2136}
2137
2138/*--------------------------------------------------------------------------*/
2139locint get_locint_f() {
2140    locint temp;
2141    ADOLC_OPENMP_THREAD_NUMBER;
2142    ADOLC_OPENMP_GET_THREAD_NUMBER;
2143
2144    temp = *ADOLC_CURRENT_TAPE_INFOS.currLoc;
2145    ++ADOLC_CURRENT_TAPE_INFOS.currLoc;
2146    fprintf(DIAG_OUT, "f_loc: %i\n", temp);
2147    return temp;
2148}
2149
2150/*--------------------------------------------------------------------------*/
2151locint get_locint_r() {
2152    unsigned char temp;
2153    ADOLC_OPENMP_THREAD_NUMBER;
2154    ADOLC_OPENMP_GET_THREAD_NUMBER;
2155
2156    --ADOLC_CURRENT_TAPE_INFOS.currLoc;
2157    temp = *ADOLC_CURRENT_TAPE_INFOS.currLoc;
2158    fprintf(DIAG_OUT, "r_loc: %i\n", temp);
2159    return temp;
2160}
2161
2162/*--------------------------------------------------------------------------*/
2163double get_val_f() {
2164    double temp;
2165    ADOLC_OPENMP_THREAD_NUMBER;
2166    ADOLC_OPENMP_GET_THREAD_NUMBER;
2167
2168    temp = *ADOLC_CURRENT_TAPE_INFOS.currVal;
2169    ++ADOLC_CURRENT_TAPE_INFOS.currVal;
2170    fprintf(DIAG_OUT, "f_val: %e\n", temp);
2171    return temp;
2172}
2173
2174/*--------------------------------------------------------------------------*/
2175double get_val_r() {
2176    double temp;
2177    ADOLC_OPENMP_THREAD_NUMBER;
2178    ADOLC_OPENMP_GET_THREAD_NUMBER;
2179
2180    --ADOLC_CURRENT_TAPE_INFOS.currVal;
2181    temp = *ADOLC_CURRENT_TAPE_INFOS.currVal;
2182    fprintf(DIAG_OUT, "r_val: %e\n", temp);
2183    return temp;
2184}
2185
2186#endif
2187
Note: See TracBrowser for help on using the repository browser.