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

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

get rid of warning on older gcc using fprintf without format

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

  • Property svn:keywords set to Author Date Id Revision
File size: 92.9 KB
Line 
1/*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File:     taping.c
4 Revision: $Id: taping.c 208 2011-04-08 10:47:32Z 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 suplied 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, *end = NULL;
409    long int number = 0;
410    char *path = NULL;
411    int defdirsize = strlen(TAPE_DIR PATHSEPARATOR);
412    tapeBaseNames[0] = strdup(
413        TAPE_DIR PATHSEPARATOR ADOLC_LOCATIONS_NAME);
414    tapeBaseNames[1] = strdup(
415        TAPE_DIR PATHSEPARATOR ADOLC_VALUES_NAME);
416    tapeBaseNames[2] = strdup(
417        TAPE_DIR PATHSEPARATOR ADOLC_OPERATIONS_NAME);
418    tapeBaseNames[3] = strdup(
419        TAPE_DIR PATHSEPARATOR ADOLC_TAYLORS_NAME);
420
421    ADOLC_OPENMP_THREAD_NUMBER;
422    ADOLC_OPENMP_GET_THREAD_NUMBER;
423
424    ADOLC_GLOBAL_TAPE_VARS.operationBufferSize = OBUFSIZE;
425    ADOLC_GLOBAL_TAPE_VARS.locationBufferSize = LBUFSIZE;
426    ADOLC_GLOBAL_TAPE_VARS.valueBufferSize = VBUFSIZE;
427    ADOLC_GLOBAL_TAPE_VARS.taylorBufferSize = TBUFSIZE;
428    ADOLC_GLOBAL_TAPE_VARS.maxNumberTaylorBuffers = TBUFNUM;
429    if ((configFile = fopen(".adolcrc", "r")) != NULL) {
430        fprintf(DIAG_OUT, "\nFile .adolcrc found! => Try to parse it!\n");
431        fprintf(DIAG_OUT, "****************************************\n");
432        while (fgets(inputLine, ADOLC_LINE_LENGTH + 1, configFile) == inputLine) {
433            if (strlen(inputLine) == ADOLC_LINE_LENGTH &&
434                    inputLine[ADOLC_LINE_LENGTH - 1] != 0xA) {
435                fprintf(DIAG_OUT, "ADOL-C warning: Input line in .adolcrc exceeds"
436                        " %d characters!\n", ADOLC_LINE_LENGTH);
437                fprintf(DIAG_OUT, "                => Parsing aborted!!\n");
438                break;
439            }
440            pos1 = strchr(inputLine, '"');
441            pos2 = NULL;
442            pos3 = NULL;
443            pos4 = NULL;
444            if (pos1 != NULL) {
445                pos2 = strchr(pos1 + 1, '"');
446                if (pos2 != NULL) {
447                    pos3 = strchr(pos2 + 1, '"');
448                    if (pos3 != NULL) pos4 = strchr(pos3 + 1, '"');
449                }
450            }
451            if (pos4 == NULL) {
452                if (pos1 != NULL)
453                    fprintf(DIAG_OUT, "ADOL-C warning: Malformed input line "
454                            "in .adolcrc ignored!\n");
455            } else {
456                number = strtol(pos3 + 1, &end, 10);
457                if (end == (pos3 + 1)) {
458                    *pos2 = 0;
459                    *pos4 = 0;
460                    if (strcmp(pos1 + 1, "TAPE_DIR") == 0) {
461                        struct stat st;
462                        int err;
463                        path = pos3 + 1;
464                        err = stat(path,&st);
465                        if (err == 0 && S_ISDIR(st.st_mode)) {
466                            int pathlen, pathseplen, namelen[4];
467                            int i;
468                            pathlen=strlen(path);
469                            pathseplen=strlen(PATHSEPARATOR);
470                            for(i = 0; i < 4; i++)
471                                namelen[i] = strlen(tapeBaseNames[i]);
472                            clearTapeBaseNames();
473                            for(i = 0; i < 4; i++) {
474                                char *currpos;
475                                int fnamelen;
476                                tapeBaseNames[i] = (char*)calloc(namelen[i] - defdirsize + pathlen + pathseplen + 1, sizeof(char));
477                                currpos = tapeBaseNames[i];
478                                strncpy(currpos,path,pathlen);
479                                currpos += pathlen;
480                                strncpy(currpos,PATHSEPARATOR,pathseplen);
481                                currpos += pathseplen;
482                                switch (i) {
483                                case 0:
484                                    fnamelen = strlen(ADOLC_LOCATIONS_NAME);
485                                    strncpy(currpos,ADOLC_LOCATIONS_NAME,fnamelen);
486                                    break;
487                                case 1:
488                                    fnamelen = strlen(ADOLC_VALUES_NAME);
489                                    strncpy(currpos,ADOLC_VALUES_NAME,fnamelen);
490                                    break;
491                                case 2:
492                                    fnamelen = strlen(ADOLC_OPERATIONS_NAME);
493                                    strncpy(currpos,ADOLC_OPERATIONS_NAME,fnamelen);
494                                    break;
495                                case 3:
496                                    fnamelen = strlen(ADOLC_TAYLORS_NAME);
497                                    strncpy(currpos,ADOLC_TAYLORS_NAME,fnamelen);
498                                    break;
499                                }
500                                currpos += fnamelen;
501                                *currpos = '\0';
502                            }
503                            fprintf(DIAG_OUT, "ADOL-C info: using TAPE_DIR %s for all disk bound tapes\n",path);
504                        } else
505                            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);
506                    }
507                    else 
508                        fprintf(DIAG_OUT, "ADOL-C warning: Unable to parse number in "
509                                ".adolcrc!\n");
510                } else {
511                    *pos2 = 0;
512                    *pos4 = 0;
513                    if (strcmp(pos1 + 1, "OBUFSIZE") == 0) {
514                        ADOLC_GLOBAL_TAPE_VARS.operationBufferSize = (locint)number;
515                        fprintf(DIAG_OUT, "Found operation buffer size: %u\n",
516                                (locint)number);
517                    } else if (strcmp(pos1 + 1, "LBUFSIZE") == 0) {
518                        ADOLC_GLOBAL_TAPE_VARS.locationBufferSize = (locint)number;
519                        fprintf(DIAG_OUT, "Found location buffer size: %u\n",
520                                (locint)number);
521                    } else if (strcmp(pos1 + 1, "VBUFSIZE") == 0) {
522                        ADOLC_GLOBAL_TAPE_VARS.valueBufferSize = (locint)number;
523                        fprintf(DIAG_OUT, "Found value buffer size: %u\n",
524                                (locint)number);
525                    } else if (strcmp(pos1 + 1, "TBUFSIZE") == 0) {
526                        ADOLC_GLOBAL_TAPE_VARS.taylorBufferSize = (locint)number;
527                        fprintf(DIAG_OUT, "Found taylor buffer size: %u\n",
528                                (locint)number);
529                    } else if (strcmp(pos1 + 1, "TBUFNUM") == 0) {
530                        ADOLC_GLOBAL_TAPE_VARS.maxNumberTaylorBuffers = (int)number;
531                        fprintf(DIAG_OUT, "Found maximal number of taylor buffers: "
532                                "%d\n", (int)number);
533                    } else {
534                        fprintf(DIAG_OUT, "ADOL-C warning: Unable to parse "
535                                "parameter name in .adolcrc!\n");
536                    }
537                }
538            }
539        }
540        fprintf(DIAG_OUT, "****************************************\n\n");
541        fclose(configFile);
542    }
543    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
544}
545
546/****************************************************************************/
547/****************************************************************************/
548/* VALUE STACK FUNCTIONS                                                    */
549/****************************************************************************/
550/****************************************************************************/
551
552static unsigned int numTBuffersInUse = 0;
553
554/* record all existing adoubles on the tape
555 * - intended to be used in start_trace only */
556void take_stock() {
557    locint space_left, loc = 0;
558    double *vals;
559    size_t vals_left;
560    ADOLC_OPENMP_THREAD_NUMBER;
561
562    ADOLC_OPENMP_GET_THREAD_NUMBER;
563    space_left  = get_val_space(); /* remaining space in const. tape buffer */
564    vals_left = ADOLC_GLOBAL_TAPE_VARS.storeSize;
565    vals      = ADOLC_GLOBAL_TAPE_VARS.store;
566   
567    /* if we have adoubles in use */
568    if (ADOLC_GLOBAL_TAPE_VARS.numLives > 0) {
569    /* fill the current values (real) tape buffer and write it to disk
570     * - do this as long as buffer can be fully filled */
571    while (space_left < vals_left) {
572        put_op(take_stock_op);
573        ADOLC_PUT_LOCINT(space_left);
574        ADOLC_PUT_LOCINT(loc);
575        put_vals_writeBlock(vals, space_left);
576        vals      += space_left;
577        vals_left -= space_left;
578        loc       += space_left;
579        space_left = get_val_space();
580    }
581    /* store the remaining adouble values to the values tape buffer
582     * -> no write to disk necessary */
583    if (vals_left > 0) {
584        put_op(take_stock_op);
585        ADOLC_PUT_LOCINT(vals_left);
586        ADOLC_PUT_LOCINT(loc);
587        put_vals_notWriteBlock(vals, vals_left);
588    }
589    }
590    ADOLC_CURRENT_TAPE_INFOS.traceFlag = 1;
591}
592
593/****************************************************************************/
594/* record all remaining live variables on the value stack tape              */
595/* - turns off trace_flag                                                   */
596/* - intended to be used in stop_trace only                                 */
597/****************************************************************************/
598locint keep_stock() {
599    ADOLC_OPENMP_THREAD_NUMBER;
600    ADOLC_OPENMP_GET_THREAD_NUMBER;
601    /* if we have adoubles in use */
602    if (ADOLC_GLOBAL_TAPE_VARS.numLives > 0) {
603        locint loc2 = ADOLC_GLOBAL_TAPE_VARS.storeSize - 1;
604
605        /* special signal -> all alive adoubles recorded on the end of the
606         * value stack -> special handling at the beginning of reverse */
607        put_op(death_not);
608        ADOLC_PUT_LOCINT(1);    /* lowest loc */
609        ADOLC_PUT_LOCINT(loc2); /* highest loc */
610
611        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape += ADOLC_GLOBAL_TAPE_VARS.storeSize - 1;
612        /* now really do it if keepTaylors ist set */
613        if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors) {
614            do {
615                ADOLC_WRITE_SCAYLOR(ADOLC_GLOBAL_TAPE_VARS.store[loc2]);
616            } while (--loc2 > 0);
617        }
618    }
619    ADOLC_CURRENT_TAPE_INFOS.traceFlag = 0;
620    return ADOLC_GLOBAL_TAPE_VARS.storeSize;
621}
622
623
624/****************************************************************************/
625/* Set up statics for writing taylor data                                   */
626/****************************************************************************/
627void taylor_begin(uint bufferSize, double **Tg, int degreeSave) {
628    ADOLC_OPENMP_THREAD_NUMBER;
629    ADOLC_OPENMP_GET_THREAD_NUMBER;
630    if (ADOLC_CURRENT_TAPE_INFOS.tayBuffer != NULL) {
631        #     if defined(ADOLC_DEBUG)
632            fprintf(DIAG_OUT, "\nADOL-C warning: !!! Taylor information for tape %d"
633                    " found that will be overwritten !!!\n\n",
634                    ADOLC_CURRENT_TAPE_INFOS.tapeID);
635        #     endif
636        taylor_close(0);
637    } else { /* check if new buffer is allowed */
638        if (numTBuffersInUse == ADOLC_GLOBAL_TAPE_VARS.maxNumberTaylorBuffers)
639            fail(ADOLC_TAPING_TO_MANY_TAYLOR_BUFFERS);
640        ++numTBuffersInUse;
641        if (ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.tay_fileName == NULL)
642            ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.tay_fileName =
643                createFileName(ADOLC_CURRENT_TAPE_INFOS.tapeID, TAYLORS_TAPE);
644    }
645
646    /* initial setups */
647    ADOLC_CURRENT_TAPE_INFOS.dpp_T = Tg;
648    if (ADOLC_CURRENT_TAPE_INFOS.tayBuffer != NULL)
649        free(ADOLC_CURRENT_TAPE_INFOS.tayBuffer);
650    ADOLC_CURRENT_TAPE_INFOS.tayBuffer = (revreal *)
651            malloc(sizeof(revreal) * bufferSize);
652    if (ADOLC_CURRENT_TAPE_INFOS.tayBuffer == NULL)
653        fail(ADOLC_TAPING_TBUFFER_ALLOCATION_FAILED);
654    ADOLC_CURRENT_TAPE_INFOS.deg_save = degreeSave;
655    if (degreeSave >= 0 ) ADOLC_CURRENT_TAPE_INFOS.keepTaylors = 1;
656    ADOLC_CURRENT_TAPE_INFOS.currTay = ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
657    ADOLC_CURRENT_TAPE_INFOS.lastTayP1 = ADOLC_CURRENT_TAPE_INFOS.currTay + bufferSize;
658    ADOLC_CURRENT_TAPE_INFOS.inUse = 1;
659
660    ADOLC_CURRENT_TAPE_INFOS.numTays_Tape = 0;
661}
662
663/****************************************************************************/
664/* Close the taylor file, reset data.                                       */
665/****************************************************************************/
666void taylor_close(uint buffer) {
667    ADOLC_OPENMP_THREAD_NUMBER;
668    ADOLC_OPENMP_GET_THREAD_NUMBER;
669
670    if (buffer == 0) {
671        /* enforces failure of reverse => retaping */
672        ADOLC_CURRENT_TAPE_INFOS.deg_save = -1;
673        if (ADOLC_CURRENT_TAPE_INFOS.tay_file != NULL) {
674            fclose(ADOLC_CURRENT_TAPE_INFOS.tay_file);
675            remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.tay_fileName);
676            ADOLC_CURRENT_TAPE_INFOS.tay_file = NULL;
677        }
678        return;
679    }
680
681    if (ADOLC_CURRENT_TAPE_INFOS.tay_file != NULL) {
682        if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors)
683            put_tay_block(ADOLC_CURRENT_TAPE_INFOS.currTay);
684    } else {
685        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape =
686            ADOLC_CURRENT_TAPE_INFOS.currTay -
687            ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
688    }
689    ADOLC_CURRENT_TAPE_INFOS.lastTayBlockInCore = 1;
690    ADOLC_CURRENT_TAPE_INFOS.stats[TAY_STACK_SIZE] =
691        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape;
692
693    /* keep track of the Ind/Dep counts of the taylor stack */
694    ADOLC_CURRENT_TAPE_INFOS.tay_numInds =
695        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_INDEPENDENTS];
696    ADOLC_CURRENT_TAPE_INFOS.tay_numDeps =
697        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_DEPENDENTS];
698
699    #if defined(ADOLC_DEBUG)
700    if (ADOLC_CURRENT_TAPE_INFOS.tay_file != NULL)
701        fprintf(DIAG_OUT, "\n ADOL-C debug: Taylor file of length %d bytes "
702                "completed\n",
703                (int)(ADOLC_CURRENT_TAPE_INFOS.numTays_Tape*sizeof(revreal)));
704    else
705        fprintf(DIAG_OUT, "\n ADOL-C debug: Taylor array of length %d bytes "
706                "completed\n",
707                (int)(ADOLC_CURRENT_TAPE_INFOS.numTays_Tape*sizeof(revreal)));
708    #endif
709}
710
711/****************************************************************************/
712/* Initializes a reverse sweep.                                             */
713/****************************************************************************/
714void taylor_back (short tag, int* dep, int* ind, int* degree) {
715    int i, chunks;
716    size_t number, remain, chunkSize;
717    ADOLC_OPENMP_THREAD_NUMBER;
718    ADOLC_OPENMP_GET_THREAD_NUMBER;
719
720    /* this should be removed soon since values can be accessed via         */
721    /* ADOLC_CURRENT_TAPE_INFOS directly                                    */
722    *dep    = ADOLC_CURRENT_TAPE_INFOS.tay_numDeps;
723    *ind    = ADOLC_CURRENT_TAPE_INFOS.tay_numInds;
724    *degree = ADOLC_CURRENT_TAPE_INFOS.deg_save;
725
726    if (ADOLC_CURRENT_TAPE_INFOS.tayBuffer == NULL)
727        fail(ADOLC_REVERSE_NO_TAYLOR_STACK);
728    ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber =
729        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape /
730        ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE];
731    number = ADOLC_CURRENT_TAPE_INFOS.numTays_Tape %
732           ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE];
733    ADOLC_CURRENT_TAPE_INFOS.currTay =
734        ADOLC_CURRENT_TAPE_INFOS.tayBuffer + number;
735    if (ADOLC_CURRENT_TAPE_INFOS.lastTayBlockInCore != 1) {
736        if ( fseek(ADOLC_CURRENT_TAPE_INFOS.tay_file,
737                sizeof(revreal) *
738                ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber *
739                ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE],
740                SEEK_SET)
741                == -1 ) fail(ADOLC_EVAL_SEEK_VALUE_STACK);
742        chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(revreal);
743        chunks = number / chunkSize;
744        for (i = 0; i < chunks; ++i)
745            if ((failAdditionalInfo1 =
746                        fread(ADOLC_CURRENT_TAPE_INFOS.tayBuffer +
747                            i * chunkSize, chunkSize * sizeof(revreal), 1,
748                            ADOLC_CURRENT_TAPE_INFOS.tay_file)) != 1)
749                fail(ADOLC_TAPING_FATAL_IO_ERROR);
750        remain = number % chunkSize;
751        if (remain != 0)
752            if ((failAdditionalInfo1 =
753                        fread(ADOLC_CURRENT_TAPE_INFOS.tayBuffer +
754                            chunks * chunkSize, remain * sizeof(revreal), 1,
755                            ADOLC_CURRENT_TAPE_INFOS.tay_file)) != 1)
756                fail(ADOLC_TAPING_FATAL_IO_ERROR);
757    }
758    --ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber;
759}
760
761/****************************************************************************/
762/* Writes the block of size depth of taylor coefficients from point loc to  */
763/* the taylor buffer. If the buffer is filled, then it is written to the    */
764/* taylor tape.                                                             */
765/****************************************************************************/
766void write_taylor(locint loc, int keep) {
767    revreal *i;
768    double *T;
769    ADOLC_OPENMP_THREAD_NUMBER;
770
771    ADOLC_OPENMP_GET_THREAD_NUMBER;
772    T = ADOLC_CURRENT_TAPE_INFOS.dpp_T[loc];
773
774    /* write data to buffer and put buffer to disk as long as data remain in
775     * the T-buffer => don't create an empty value stack buffer! */
776    while (ADOLC_CURRENT_TAPE_INFOS.currTay + keep > ADOLC_CURRENT_TAPE_INFOS.lastTayP1) {
777        for (i = ADOLC_CURRENT_TAPE_INFOS.currTay; i < ADOLC_CURRENT_TAPE_INFOS.lastTayP1; ++i) {
778            *i = (revreal) * T;
779            /* In this assignment the precision will be sacrificed if the type
780             * revreal is defined as float. */
781            ++T;
782        }
783        keep -= ADOLC_CURRENT_TAPE_INFOS.lastTayP1 - ADOLC_CURRENT_TAPE_INFOS.currTay;
784        put_tay_block(ADOLC_CURRENT_TAPE_INFOS.lastTayP1);
785    }
786
787    for (i = ADOLC_CURRENT_TAPE_INFOS.currTay; i < ADOLC_CURRENT_TAPE_INFOS.currTay + keep; ++i) {
788        *i = (revreal) * T;
789        /* In this assignment the precision will be sacrificed
790         * if the type revreal is defined as float. */
791        ++T;
792    }
793    ADOLC_CURRENT_TAPE_INFOS.currTay += keep;
794}
795
796/****************************************************************************/
797/* Writes the block of size depth of taylor coefficients from point loc to  */
798/* the taylor buffer.  If the buffer is filled, then it is written to the   */
799/* taylor tape.                                                             */
800/*--------------------------------------------------------------------------*/
801void write_taylors(locint loc, int keep, int degree, int numDir) {
802    int i, j;
803    double *T;
804    ADOLC_OPENMP_THREAD_NUMBER;
805
806    ADOLC_OPENMP_GET_THREAD_NUMBER;
807    T = ADOLC_CURRENT_TAPE_INFOS.dpp_T[loc];
808
809    for (j = 0; j < numDir; ++j) {
810        for (i = 0; i < keep; ++i) {
811            if (ADOLC_CURRENT_TAPE_INFOS.currTay == ADOLC_CURRENT_TAPE_INFOS.lastTayP1)
812                put_tay_block(ADOLC_CURRENT_TAPE_INFOS.lastTayP1);
813            *ADOLC_CURRENT_TAPE_INFOS.currTay = (revreal) * T;
814            /* The precision will be sacrificed if the type
815             * revreal is defined as float. */
816            ++ADOLC_CURRENT_TAPE_INFOS.currTay;
817            ++T;
818        }
819/*        for (i = keep; i < degree; ++i) ++T;*/
820        if (degree > keep)
821            T += degree - keep;
822    }
823}
824
825/****************************************************************************/
826/* Write_scaylors writes # size elements from x to the taylor buffer.       */
827/****************************************************************************/
828void write_scaylors(revreal *x, uint size) {
829    revreal *i;
830    uint j = 0;
831    ADOLC_OPENMP_THREAD_NUMBER;
832    ADOLC_OPENMP_GET_THREAD_NUMBER;
833
834    /* write data to buffer and put buffer to disk as long as data remain in
835     * the x-buffer => don't create an empty value stack buffer! */
836    while (ADOLC_CURRENT_TAPE_INFOS.currTay + size > ADOLC_CURRENT_TAPE_INFOS.lastTayP1) {
837        for (i = ADOLC_CURRENT_TAPE_INFOS.currTay; i < ADOLC_CURRENT_TAPE_INFOS.lastTayP1; ++i) {
838            *i = x[j];
839            ++j;
840        }
841        size -= ADOLC_CURRENT_TAPE_INFOS.lastTayP1 - ADOLC_CURRENT_TAPE_INFOS.currTay;
842        put_tay_block(ADOLC_CURRENT_TAPE_INFOS.lastTayP1);
843    }
844
845    for (i = ADOLC_CURRENT_TAPE_INFOS.currTay; i < ADOLC_CURRENT_TAPE_INFOS.tayBuffer + size; ++i) {
846        *ADOLC_CURRENT_TAPE_INFOS.currTay = x[j];
847        ++j;
848    }
849    ADOLC_CURRENT_TAPE_INFOS.currTay += size;
850}
851
852/****************************************************************************/
853/* Writes the value stack buffer onto hard disk.                            */
854/****************************************************************************/
855void put_tay_block(revreal *lastTayP1) {
856    int i, chunks;
857    size_t number, remain, chunkSize;
858    ADOLC_OPENMP_THREAD_NUMBER;
859    ADOLC_OPENMP_GET_THREAD_NUMBER;
860
861    if (ADOLC_CURRENT_TAPE_INFOS.tay_file == NULL) {
862        ADOLC_CURRENT_TAPE_INFOS.tay_file =
863            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.tay_fileName, "w+b");
864        if (ADOLC_CURRENT_TAPE_INFOS.tay_file == NULL)
865            fail(ADOLC_TAPING_TAYLOR_OPEN_FAILED);
866    }
867    number = lastTayP1 - ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
868    if (number != 0) {
869        chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(revreal);
870        chunks = number / chunkSize;
871        for (i = 0; i < chunks; ++i)
872            if ((failAdditionalInfo1 =
873                    fwrite(ADOLC_CURRENT_TAPE_INFOS.tayBuffer + i *
874                            chunkSize, chunkSize * sizeof(revreal), 1,
875                            ADOLC_CURRENT_TAPE_INFOS.tay_file) ) != 1)
876                fail(ADOLC_TAPING_FATAL_IO_ERROR);
877        remain = number % chunkSize;
878        if (remain != 0)
879            if ((failAdditionalInfo1 =
880                    fwrite(ADOLC_CURRENT_TAPE_INFOS.tayBuffer + chunks *
881                            chunkSize, remain * sizeof(revreal), 1,
882                            ADOLC_CURRENT_TAPE_INFOS.tay_file) ) != 1)
883                fail(ADOLC_TAPING_FATAL_IO_ERROR);
884        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape += number;
885    }
886    ADOLC_CURRENT_TAPE_INFOS.currTay = ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
887    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
888}
889
890/****************************************************************************/
891/* Puts a block of taylor coefficients from the value stack buffer to the   */
892/* taylor buffer. --- Higher Order Scalar                                   */
893/****************************************************************************/
894void get_taylors(locint loc, int degree) {
895    int j;
896    revreal *i;
897    revreal *T;
898    ADOLC_OPENMP_THREAD_NUMBER;
899
900    ADOLC_OPENMP_GET_THREAD_NUMBER;
901    T = ADOLC_CURRENT_TAPE_INFOS.rpp_T[loc] + degree;
902
903    /* As long as all values from the taylor stack buffer will be used copy
904     * them into the taylor buffer and load the next (previous) buffer. */
905    while (ADOLC_CURRENT_TAPE_INFOS.currTay - degree < ADOLC_CURRENT_TAPE_INFOS.tayBuffer) {
906        for ( i = ADOLC_CURRENT_TAPE_INFOS.currTay - 1;
907                i >= ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
908                --i ) {
909            --T;
910            *T = *i;
911        }
912        degree -= ADOLC_CURRENT_TAPE_INFOS.currTay - ADOLC_CURRENT_TAPE_INFOS.tayBuffer;
913        get_tay_block_r();
914    }
915
916    /* Copy the remaining values from the stack into the buffer ... */
917    for (j = 0; j < degree; ++j) {
918        --ADOLC_CURRENT_TAPE_INFOS.currTay;
919        --T;
920        *T = *ADOLC_CURRENT_TAPE_INFOS.currTay;
921    }
922}
923
924/****************************************************************************/
925/* Puts a block of taylor coefficients from the value stack buffer to the   */
926/* taylor buffer. --- Higher Order Vector                                   */
927/****************************************************************************/
928void get_taylors_p(locint loc, int degree, int numDir) {
929    int i, j;
930    revreal *T;
931    ADOLC_OPENMP_THREAD_NUMBER;
932
933    ADOLC_OPENMP_GET_THREAD_NUMBER;
934    T = ADOLC_CURRENT_TAPE_INFOS.rpp_T[loc] + degree * numDir;
935
936    /* update the directions except the base point parts */
937    for (j = 0; j < numDir; ++j) {
938        for (i = 1; i < degree; ++i) {
939            if (ADOLC_CURRENT_TAPE_INFOS.currTay == ADOLC_CURRENT_TAPE_INFOS.tayBuffer)
940                get_tay_block_r();
941            --ADOLC_CURRENT_TAPE_INFOS.currTay;
942            --T;
943            *T = *ADOLC_CURRENT_TAPE_INFOS.currTay;
944        }
945        --T; /* skip the base point part */
946    }
947    /* now update the base point parts */
948    --ADOLC_CURRENT_TAPE_INFOS.currTay;
949    for (i = 0; i < numDir; ++i) {
950        *T = *ADOLC_CURRENT_TAPE_INFOS.currTay;
951        T += degree;
952    }
953}
954
955/****************************************************************************/
956/* Gets the next (previous block) of the value stack                        */
957/****************************************************************************/
958void get_tay_block_r() {
959    int i, chunks;
960    size_t number, remain, chunkSize;
961    ADOLC_OPENMP_THREAD_NUMBER;
962    ADOLC_OPENMP_GET_THREAD_NUMBER;
963
964    ADOLC_CURRENT_TAPE_INFOS.lastTayBlockInCore = 0;
965    number = ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE];
966    if ( fseek(ADOLC_CURRENT_TAPE_INFOS.tay_file, sizeof(revreal) *
967                ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber * number, SEEK_SET)
968            == -1 )
969        fail(ADOLC_EVAL_SEEK_VALUE_STACK);
970    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(revreal);
971    chunks = number / chunkSize;
972    for (i = 0; i < chunks; ++i)
973        if ((failAdditionalInfo1 = fread(ADOLC_CURRENT_TAPE_INFOS.tayBuffer +
974                        i * chunkSize, chunkSize * sizeof(revreal), 1,
975                        ADOLC_CURRENT_TAPE_INFOS.tay_file)) != 1)
976            fail(ADOLC_TAPING_FATAL_IO_ERROR);
977    remain = number % chunkSize;
978    if (remain != 0)
979        if ((failAdditionalInfo1 = fread(ADOLC_CURRENT_TAPE_INFOS.tayBuffer +
980                        chunks * chunkSize, remain * sizeof(revreal), 1,
981                        ADOLC_CURRENT_TAPE_INFOS.tay_file)) != 1)
982            fail(ADOLC_TAPING_FATAL_IO_ERROR);
983    ADOLC_CURRENT_TAPE_INFOS.currTay = ADOLC_CURRENT_TAPE_INFOS.lastTayP1;
984    --ADOLC_CURRENT_TAPE_INFOS.nextBufferNumber;
985}
986
987
988/****************************************************************************/
989/****************************************************************************/
990/* NON-VALUE-STACK FUNCTIONS                                                */
991/****************************************************************************/
992/****************************************************************************/
993
994void initTapeBuffers() {
995    ADOLC_OPENMP_THREAD_NUMBER;
996    ADOLC_OPENMP_GET_THREAD_NUMBER;
997
998    if (ADOLC_CURRENT_TAPE_INFOS.opBuffer == NULL)
999        ADOLC_CURRENT_TAPE_INFOS.opBuffer = (unsigned char *)
1000                malloc(ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE] *
1001                       sizeof(unsigned char));
1002    if (ADOLC_CURRENT_TAPE_INFOS.locBuffer == NULL)
1003        ADOLC_CURRENT_TAPE_INFOS.locBuffer = (locint *)
1004                malloc(ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE] * sizeof(locint));
1005    if (ADOLC_CURRENT_TAPE_INFOS.valBuffer == NULL)
1006        ADOLC_CURRENT_TAPE_INFOS.valBuffer = (double *)
1007                malloc(ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE] * sizeof(double));
1008    if ( ADOLC_CURRENT_TAPE_INFOS.opBuffer  == NULL ||
1009            ADOLC_CURRENT_TAPE_INFOS.locBuffer == NULL ||
1010            ADOLC_CURRENT_TAPE_INFOS.valBuffer == NULL )
1011        fail(ADOLC_TAPING_BUFFER_ALLOCATION_FAILED);
1012    ADOLC_CURRENT_TAPE_INFOS.lastOpP1 = ADOLC_CURRENT_TAPE_INFOS.opBuffer +
1013            ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE];
1014    ADOLC_CURRENT_TAPE_INFOS.lastLocP1 = ADOLC_CURRENT_TAPE_INFOS.locBuffer +
1015            ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1016    ADOLC_CURRENT_TAPE_INFOS.lastValP1 = ADOLC_CURRENT_TAPE_INFOS.valBuffer +
1017            ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1018}
1019
1020/****************************************************************************/
1021/* start_trace: (part of trace_on)                                          */
1022/* Initialization for the taping process. Does buffer allocation, sets      */
1023/* files names, and calls appropriate setup routines.                       */
1024/****************************************************************************/
1025void start_trace() {
1026    int i, space;
1027    ADOLC_OPENMP_THREAD_NUMBER;
1028    ADOLC_OPENMP_GET_THREAD_NUMBER;
1029
1030    initTapeBuffers();
1031    ADOLC_CURRENT_TAPE_INFOS.currOp  = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1032    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1033    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1034
1035    /* Put operation denoting the start_of_the tape */
1036    put_op(start_of_tape);
1037
1038    /* Leave space for the stats */
1039    space = STAT_SIZE * sizeof(uint) + sizeof(ADOLC_ID);
1040    if (space > statSpace * sizeof(locint))
1041        fail(ADOLC_MORE_STAT_SPACE_REQUIRED);
1042    for (i = 0; i < statSpace; ++i) ADOLC_PUT_LOCINT(0);
1043
1044    /* initialize value stack if necessary */
1045    if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors)
1046        taylor_begin(ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE], NULL, 0);
1047
1048    /* mark possible (hard disk) tape creation */
1049    markNewTape();
1050}
1051
1052/****************************************************************************/
1053/* Stop Tracing.  Clean up, and turn off trace_flag.                        */
1054/****************************************************************************/
1055void stop_trace(int flag) {
1056    ADOLC_OPENMP_THREAD_NUMBER;
1057    ADOLC_OPENMP_GET_THREAD_NUMBER;
1058    put_op(end_of_tape);        /* Mark end of tape. */
1059
1060    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_INDEPENDENTS] =
1061        ADOLC_CURRENT_TAPE_INFOS.numInds;
1062    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_DEPENDENTS] =
1063        ADOLC_CURRENT_TAPE_INFOS.numDeps;
1064    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_MAX_LIVES] =
1065        ADOLC_GLOBAL_TAPE_VARS.storeSize;
1066
1067    taylor_close(ADOLC_CURRENT_TAPE_INFOS.stats[TAY_BUFFER_SIZE]);
1068
1069    /* The taylor stack size base estimation results in a doubled taylor count
1070     * if we tape with keep (taylors counted in adouble.cpp/avector.cpp and
1071     * "keep_stock" even if not written and a second time when actually
1072     * written by "put_tay_block"). Correction follows here. */
1073    if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors != 0 &&
1074            ADOLC_CURRENT_TAPE_INFOS.tay_file != NULL)
1075    {
1076        ADOLC_CURRENT_TAPE_INFOS.stats[TAY_STACK_SIZE] /= 2;
1077        ADOLC_CURRENT_TAPE_INFOS.numTays_Tape /= 2;
1078    }
1079
1080    close_tape(flag); /* closes the tape, files up stats, and writes the
1081                         tape stats to the integer tape */
1082}
1083
1084/****************************************************************************/
1085/* Close open tapes, update stats and clean up.                             */
1086/****************************************************************************/
1087void close_tape(int flag) {
1088    ADOLC_OPENMP_THREAD_NUMBER;
1089    ADOLC_OPENMP_GET_THREAD_NUMBER;
1090    /* finish operations tape, close it, update stats */
1091    if (flag != 0 || ADOLC_CURRENT_TAPE_INFOS.op_file != NULL) {
1092        if (ADOLC_CURRENT_TAPE_INFOS.currOp !=
1093                ADOLC_CURRENT_TAPE_INFOS.opBuffer)
1094        {
1095            put_op_block(ADOLC_CURRENT_TAPE_INFOS.currOp);
1096        }
1097        if (ADOLC_CURRENT_TAPE_INFOS.op_file != NULL)
1098            fclose(ADOLC_CURRENT_TAPE_INFOS.op_file);
1099        ADOLC_CURRENT_TAPE_INFOS.op_file = NULL;
1100        ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS] = 1;
1101        free(ADOLC_CURRENT_TAPE_INFOS.opBuffer);
1102        ADOLC_CURRENT_TAPE_INFOS.opBuffer = NULL;
1103    } else ADOLC_CURRENT_TAPE_INFOS.numOps_Tape =
1104        ADOLC_CURRENT_TAPE_INFOS.currOp - ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1105    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] =
1106        ADOLC_CURRENT_TAPE_INFOS.numOps_Tape;
1107
1108    /* finish constants tape, close it, update stats */
1109    if (flag != 0 || ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) {
1110        if (ADOLC_CURRENT_TAPE_INFOS.currVal !=
1111                ADOLC_CURRENT_TAPE_INFOS.valBuffer)
1112        {
1113            put_val_block(ADOLC_CURRENT_TAPE_INFOS.currVal);
1114        }
1115        if (ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) 
1116            fclose(ADOLC_CURRENT_TAPE_INFOS.val_file);
1117        ADOLC_CURRENT_TAPE_INFOS.val_file = NULL;
1118        ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] = 1;
1119        free(ADOLC_CURRENT_TAPE_INFOS.valBuffer);
1120        ADOLC_CURRENT_TAPE_INFOS.valBuffer = NULL;
1121    } else ADOLC_CURRENT_TAPE_INFOS.numVals_Tape =
1122        ADOLC_CURRENT_TAPE_INFOS.currVal - ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1123    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] =
1124        ADOLC_CURRENT_TAPE_INFOS.numVals_Tape;
1125
1126    /* finish locations tape, update and write tape stats, close tape */
1127    if (flag != 0 || ADOLC_CURRENT_TAPE_INFOS.loc_file != NULL) {
1128        if (ADOLC_CURRENT_TAPE_INFOS.currLoc !=
1129                ADOLC_CURRENT_TAPE_INFOS.locBuffer)
1130        {
1131            put_loc_block(ADOLC_CURRENT_TAPE_INFOS.currLoc);
1132        }
1133        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] =
1134            ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape;
1135        ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] = 1;
1136        /* write tape stats */
1137        fseek(ADOLC_CURRENT_TAPE_INFOS.loc_file, 0, 0);
1138        fwrite(&adolc_id, sizeof(ADOLC_ID), 1,
1139                ADOLC_CURRENT_TAPE_INFOS.loc_file);
1140        fwrite(ADOLC_CURRENT_TAPE_INFOS.stats, STAT_SIZE * sizeof(uint), 1,
1141               ADOLC_CURRENT_TAPE_INFOS.loc_file);
1142        fclose(ADOLC_CURRENT_TAPE_INFOS.loc_file);
1143        ADOLC_CURRENT_TAPE_INFOS.loc_file = NULL;
1144        free(ADOLC_CURRENT_TAPE_INFOS.locBuffer);
1145        ADOLC_CURRENT_TAPE_INFOS.locBuffer = NULL;
1146    } else ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape  =
1147        ADOLC_CURRENT_TAPE_INFOS.currLoc - ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1148    ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] =
1149        ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape;
1150}
1151
1152/****************************************************************************/
1153/* Free all resources used by a tape before overwriting the tape.           */
1154/****************************************************************************/
1155void freeTapeResources(TapeInfos *tapeInfos) {
1156    free(tapeInfos->opBuffer);
1157    tapeInfos->opBuffer = NULL;
1158    free(tapeInfos->locBuffer);
1159    tapeInfos->locBuffer = NULL;
1160    free(tapeInfos->valBuffer);
1161    tapeInfos->valBuffer = NULL;
1162    if (tapeInfos->tayBuffer != NULL) {
1163        free(tapeInfos->tayBuffer);
1164        tapeInfos->tayBuffer = NULL;
1165        --numTBuffersInUse;
1166    }
1167    if (tapeInfos->op_file != NULL) {
1168        fclose(tapeInfos->op_file);
1169        tapeInfos->op_file = NULL;
1170    }
1171    if (tapeInfos->loc_file != NULL) {
1172        fclose(tapeInfos->loc_file);
1173        tapeInfos->loc_file = NULL;
1174    }
1175    if (tapeInfos->val_file != NULL) {
1176        fclose(tapeInfos->val_file);
1177        tapeInfos->val_file = NULL;
1178    }
1179    if (tapeInfos->tay_file != NULL) {
1180        fclose(tapeInfos->tay_file);
1181        tapeInfos->tay_file = NULL;
1182    }
1183}
1184
1185/****************************************************************************/
1186/* Tapestats:                                                               */
1187/* Returns statistics on the tape tag with following meaning:               */
1188/* tape_stat[0] = # of independent variables.                               */
1189/* tape_stat[1] = # of dependent variables.                                 */
1190/* tape_stat[2] = max # of live variables.                                  */
1191/* tape_stat[3] = value stack size.                                         */
1192/* tape_stat[4] = buffer size (# of chars, # of doubles, # of locints)      */
1193/* tape_stat[5] = # of operations.                                          */
1194/* tape_stat[6] = operation file access flag (1 = file in use, 0 otherwise) */
1195/* tape_stat[7] = # of saved locations.                                     */
1196/* tape_stat[8] = location file access flag (1 = file in use, 0 otherwise)  */
1197/* tape_stat[9] = # of saved constant values.                               */
1198/* tape_stat[10]= value file access flag (1 = file in use, 0 otherwise)     */
1199/****************************************************************************/
1200void tapestats(short tag, int *tape_stats) {
1201    int i;
1202    TapeInfos *tapeInfos;
1203
1204    /* get the tapeInfos for tag */
1205    tapeInfos = getTapeInfos(tag);
1206    /* copy stats to the users field */
1207    for (i = 0; i < STAT_SIZE; ++i)
1208        tape_stats[i] = tapeInfos->stats[i];
1209}
1210
1211/****************************************************************************/
1212/* An all-in-one tape stats printing routine.                               */
1213/****************************************************************************/
1214void printTapeStats(FILE *stream, short tag) {
1215    int stats[STAT_SIZE];
1216
1217    tapestats(tag, (int *)&stats);
1218    fprintf(stream, "\n*** TAPE STATS (tape %d) **********\n", (int)tag);
1219    fprintf(stream, "Number of independents: %10d\n", stats[NUM_INDEPENDENTS]);
1220    fprintf(stream, "Number of dependents:   %10d\n", stats[NUM_DEPENDENTS]);
1221    fprintf(stream, "\n");
1222    fprintf(stream, "Max # of live adoubles: %10d\n", stats[NUM_MAX_LIVES]);
1223    fprintf(stream, "Taylor stack size:      %10d\n", stats[TAY_STACK_SIZE]);
1224    fprintf(stream, "\n");
1225    fprintf(stream, "Number of operations:   %10d\n", stats[NUM_OPERATIONS]);
1226    fprintf(stream, "Number of locations:    %10d\n", stats[NUM_LOCATIONS]);
1227    fprintf(stream, "Number of values:       %10d\n", stats[NUM_VALUES]);
1228    fprintf(stream, "\n");
1229    fprintf(stream, "Operation file written: %10d\n", stats[OP_FILE_ACCESS]);
1230    fprintf(stream, "Location file written:  %10d\n", stats[LOC_FILE_ACCESS]);
1231    fprintf(stream, "Value file written:     %10d\n", stats[VAL_FILE_ACCESS]);
1232    fprintf(stream, "\n");
1233    fprintf(stream, "Operation buffer size:  %10d\n", stats[OP_BUFFER_SIZE]);
1234    fprintf(stream, "Location buffer size:   %10d\n", stats[LOC_BUFFER_SIZE]);
1235    fprintf(stream, "Value buffer size:      %10d\n", stats[VAL_BUFFER_SIZE]);
1236    fprintf(stream, "Taylor buffer size:     %10d\n", stats[TAY_BUFFER_SIZE]);
1237    fprintf(stream, "\n");
1238    fprintf(stream, "Operation type size:    %10d\n",
1239            (int)sizeof(unsigned char));
1240    fprintf(stream, "Location type size:     %10d\n", (int)sizeof(locint));
1241    fprintf(stream, "Value type size:        %10d\n", (int)sizeof(double));
1242    fprintf(stream, "Taylor type size:       %10d\n", (int)sizeof(revreal));
1243    fprintf(stream, "**********************************\n\n");
1244}
1245
1246/****************************************************************************/
1247/* Does the actual reading from the hard disk into the stats buffer         */
1248/****************************************************************************/
1249void read_tape_stats(TapeInfos *tapeInfos) {
1250    FILE *loc_file;
1251    int tapeVersion, limitVersion;
1252    ADOLC_ID tape_ADOLC_ID;
1253
1254    if (tapeInfos->inUse != 0 && tapeInfos->tapingComplete == 0) return;
1255
1256    limitVersion = 100 * ADOLC_NEW_TAPE_VERSION    +
1257            10 * ADOLC_NEW_TAPE_SUBVERSION +
1258            1  * ADOLC_NEW_TAPE_PATCHLEVEL ;
1259
1260    if ((loc_file = fopen(tapeInfos->pTapeInfos.loc_fileName, "rb")) == NULL)
1261        fail(ADOLC_INTEGER_TAPE_FOPEN_FAILED);
1262    if (fread(&tape_ADOLC_ID, sizeof(ADOLC_ID), 1, loc_file) != 1)
1263        fail(ADOLC_INTEGER_TAPE_FREAD_FAILED);
1264    if (fread(tapeInfos->stats, STAT_SIZE * sizeof(uint), 1, loc_file) != 1)
1265        fail(ADOLC_INTEGER_TAPE_FREAD_FAILED);
1266
1267    failAdditionalInfo1 = tapeInfos->tapeID;
1268    tapeVersion = 100 * tape_ADOLC_ID.adolc_ver +
1269            10 * tape_ADOLC_ID.adolc_sub +
1270            1  * tape_ADOLC_ID.adolc_lvl ;
1271    if (tapeVersion < limitVersion) fail(ADOLC_TAPE_TO_OLD);
1272
1273    if (tape_ADOLC_ID.locint_size != adolc_id.locint_size) {
1274        failAdditionalInfo1 = tape_ADOLC_ID.locint_size;
1275        failAdditionalInfo2 = adolc_id.locint_size;
1276        fail(ADOLC_WRONG_LOCINT_SIZE);
1277    }
1278
1279    fclose(loc_file);
1280    tapeInfos->tapingComplete = 1;
1281}
1282
1283/****************************************************************************/
1284/* Initialize a forward sweep. Get stats, open tapes, fill buffers, ...     */
1285/****************************************************************************/
1286void init_for_sweep(short tag) {
1287    int i = 0, chunks, numLocsForStats;
1288    size_t number, remain, chunkSize;
1289    ADOLC_OPENMP_THREAD_NUMBER;
1290    ADOLC_OPENMP_GET_THREAD_NUMBER;
1291
1292    /* mark possible (hard disk) tape creation */
1293    markNewTape();
1294
1295    /* make room for tapeInfos and read tape stats if necessary, keep value
1296     * stack information */
1297    openTape(tag, ADOLC_FORWARD);
1298    initTapeBuffers();
1299
1300    /* init operations */
1301    number = 0;
1302    if (ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS] == 1) {
1303        ADOLC_CURRENT_TAPE_INFOS.op_file =
1304            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "rb");
1305        /* how much to read ? */
1306        number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE],
1307                ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS]);
1308        if (number != 0) {
1309            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1310            chunks = number / chunkSize;
1311            for (i = 0; i < chunks; ++i)
1312                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1313                            chunkSize * sizeof(unsigned char), 1,
1314                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1315                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1316            remain = number % chunkSize;
1317            if (remain != 0)
1318                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks *
1319                            chunkSize, remain * sizeof(unsigned char), 1,
1320                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1321                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1322        }
1323        /* how much remains ? */
1324        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] - number;
1325    }
1326    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape = number;
1327    ADOLC_CURRENT_TAPE_INFOS.currOp = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1328
1329    /* init locations */
1330    number = 0;
1331    if (ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] == 1) {
1332        ADOLC_CURRENT_TAPE_INFOS.loc_file =
1333            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "rb");
1334        /* how much to read ? */
1335        number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE],
1336                ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS]);
1337        if (number != 0) {
1338            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1339            chunks = number / chunkSize;
1340            for (i = 0; i < chunks; ++i)
1341                if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1342                            chunkSize * sizeof(locint), 1,
1343                            ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1344                    fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1345            remain = number % chunkSize;
1346            if (remain != 0)
1347            if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks * chunkSize,
1348                        remain * sizeof(locint), 1,
1349                        ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1350                fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1351        }
1352        /* how much remains ? */
1353        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] - number;
1354    }
1355    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape = number;
1356
1357    /* skip stats */
1358    numLocsForStats = statSpace;
1359    while (numLocsForStats >= ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE])
1360    {
1361        get_loc_block_f();
1362        numLocsForStats -= ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1363    }
1364    ADOLC_CURRENT_TAPE_INFOS.currLoc =
1365        ADOLC_CURRENT_TAPE_INFOS.locBuffer + numLocsForStats;
1366
1367    /* init constants */
1368    number = 0;
1369    if (ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] == 1) {
1370        ADOLC_CURRENT_TAPE_INFOS.val_file =
1371            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "rb");
1372        /* how much to read ? */
1373        number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE],
1374                ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES]);
1375        if (number != 0) {
1376            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1377            chunks = number / chunkSize;
1378            for (i = 0; i < chunks; ++i)
1379                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1380                            chunkSize * sizeof(double), 1,
1381                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1382                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1383            remain = number % chunkSize;
1384            if (remain != 0)
1385                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks *
1386                            chunkSize, remain * sizeof(double), 1,
1387                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1388                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1389        }
1390        /* how much remains ? */
1391        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] - number;
1392    }
1393    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape = number;
1394    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1395}
1396
1397/****************************************************************************/
1398/* Initialize a reverse sweep. Get stats, open tapes, fill buffers, ...     */
1399/****************************************************************************/
1400void init_rev_sweep(short tag) {
1401    int i, chunks;
1402    size_t number, remain, chunkSize;
1403    ADOLC_OPENMP_THREAD_NUMBER;
1404    ADOLC_OPENMP_GET_THREAD_NUMBER;
1405
1406    /* mark possible (hard disk) tape creation */
1407    markNewTape();
1408
1409    /* make room for tapeInfos and read tape stats if necessary, keep value
1410     * stack information */
1411    openTape(tag, ADOLC_REVERSE);
1412    initTapeBuffers();
1413
1414    /* init operations */
1415    number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS];
1416    if (ADOLC_CURRENT_TAPE_INFOS.stats[OP_FILE_ACCESS] == 1) {
1417        ADOLC_CURRENT_TAPE_INFOS.op_file =
1418            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "rb");
1419        number = (ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] /
1420                ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE]) *
1421                ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE];
1422        fseek(ADOLC_CURRENT_TAPE_INFOS.op_file,
1423                number * sizeof(unsigned char), SEEK_SET);
1424        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] %
1425                ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE] ;
1426        if (number != 0) {
1427            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1428            chunks = number / chunkSize;
1429            for (i = 0; i < chunks; ++i)
1430                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1431                            chunkSize * sizeof(unsigned char), 1,
1432                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1433                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1434            remain = number % chunkSize;
1435            if (remain != 0)
1436                if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks *
1437                            chunkSize, remain * sizeof(unsigned char), 1,
1438                            ADOLC_CURRENT_TAPE_INFOS.op_file) != 1 )
1439                    fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1440        }
1441    }
1442    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape =
1443        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_OPERATIONS] - number;
1444    ADOLC_CURRENT_TAPE_INFOS.currOp =
1445        ADOLC_CURRENT_TAPE_INFOS.opBuffer + number;
1446
1447    /* init locations */
1448    number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS];
1449    if (ADOLC_CURRENT_TAPE_INFOS.stats[LOC_FILE_ACCESS] == 1) {
1450        ADOLC_CURRENT_TAPE_INFOS.loc_file =
1451            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "rb");
1452        number = (ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] /
1453                ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE]) *
1454                ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1455        fseek(ADOLC_CURRENT_TAPE_INFOS.loc_file,
1456                number * sizeof(locint), SEEK_SET);
1457        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] %
1458                ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1459        if (number != 0) {
1460            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1461            chunks = number / chunkSize;
1462            for (i = 0; i < chunks; ++i)
1463                if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1464                            chunkSize * sizeof(locint), 1,
1465                            ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1466                    fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1467            remain = number % chunkSize;
1468            if (remain != 0)
1469                if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks *
1470                            chunkSize, remain * sizeof(locint), 1,
1471                            ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1 )
1472                    fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1473        }
1474    }
1475    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape =
1476        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_LOCATIONS] - number;
1477    ADOLC_CURRENT_TAPE_INFOS.currLoc =
1478        ADOLC_CURRENT_TAPE_INFOS.locBuffer + number;
1479
1480    /* init constants */
1481    number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES];
1482    if (ADOLC_CURRENT_TAPE_INFOS.stats[VAL_FILE_ACCESS] == 1) {
1483        ADOLC_CURRENT_TAPE_INFOS.val_file =
1484            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "rb");
1485        number = (ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] /
1486                ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE]) *
1487                ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1488        fseek(ADOLC_CURRENT_TAPE_INFOS.val_file,
1489                number * sizeof(double), SEEK_SET);
1490        number = ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] %
1491                ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1492        if (number != 0) {
1493            chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1494            chunks = number / chunkSize;
1495            for (i = 0; i < chunks; ++i)
1496                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1497                            chunkSize * sizeof(double), 1,
1498                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1499                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1500            remain = number % chunkSize;
1501            if (remain != 0)
1502                if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks *
1503                            chunkSize, remain * sizeof(double), 1,
1504                            ADOLC_CURRENT_TAPE_INFOS.val_file) != 1 )
1505                    fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1506        }
1507    }
1508    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape =
1509        ADOLC_CURRENT_TAPE_INFOS.stats[NUM_VALUES] - number;
1510    ADOLC_CURRENT_TAPE_INFOS.currVal =
1511        ADOLC_CURRENT_TAPE_INFOS.valBuffer + number;
1512}
1513
1514/****************************************************************************/
1515/* Finish a forward or reverse sweep.                                       */
1516/****************************************************************************/
1517void end_sweep() {
1518    ADOLC_OPENMP_THREAD_NUMBER;
1519    ADOLC_OPENMP_GET_THREAD_NUMBER;
1520    if (ADOLC_CURRENT_TAPE_INFOS.op_file != NULL) {
1521        fclose(ADOLC_CURRENT_TAPE_INFOS.op_file);
1522        ADOLC_CURRENT_TAPE_INFOS.op_file = NULL;
1523    }
1524    if (ADOLC_CURRENT_TAPE_INFOS.loc_file != NULL) {
1525        fclose(ADOLC_CURRENT_TAPE_INFOS.loc_file);
1526        ADOLC_CURRENT_TAPE_INFOS.loc_file = NULL;
1527    }
1528    if (ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) {
1529        fclose(ADOLC_CURRENT_TAPE_INFOS.val_file);
1530        ADOLC_CURRENT_TAPE_INFOS.val_file = NULL;
1531    }
1532    if (ADOLC_CURRENT_TAPE_INFOS.deg_save > 0) releaseTape(); /* keep value stack */
1533    else releaseTape(); /* no value stack */
1534}
1535
1536/* --- Operations --- */
1537
1538/****************************************************************************/
1539/* Puts an operation into the operation buffer. Ensures that location buffer*/
1540/* and constants buffer are prepared to take the belonging stuff.           */
1541/****************************************************************************/
1542void put_op(unsigned char op) {
1543    ADOLC_OPENMP_THREAD_NUMBER;
1544    ADOLC_OPENMP_GET_THREAD_NUMBER;
1545    /* every operation writes <5 locations */
1546    if (ADOLC_CURRENT_TAPE_INFOS.currLoc + 5 > ADOLC_CURRENT_TAPE_INFOS.lastLocP1) {
1547        *(ADOLC_CURRENT_TAPE_INFOS.lastLocP1 - 1) = ADOLC_CURRENT_TAPE_INFOS.lastLocP1 -
1548                ADOLC_CURRENT_TAPE_INFOS.currLoc;
1549        put_loc_block(ADOLC_CURRENT_TAPE_INFOS.lastLocP1);
1550        /* every operation writes 1 opcode */
1551        if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1552            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1553            put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1554            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1555            ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1556        }
1557        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_int;
1558        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1559    }
1560    /* every operation writes <5 values --- 3 should be sufficient */
1561    if (ADOLC_CURRENT_TAPE_INFOS.currVal + 5 > ADOLC_CURRENT_TAPE_INFOS.lastValP1) {
1562        ADOLC_PUT_LOCINT(ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1563        put_val_block(ADOLC_CURRENT_TAPE_INFOS.lastValP1);
1564        /* every operation writes 1 opcode */
1565        if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1566            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1567            put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1568            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1569            ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1570        }
1571        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_val;
1572        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1573    }
1574    /* every operation writes 1 opcode */
1575    if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1576        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1577        put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1578        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1579        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1580    }
1581    *ADOLC_CURRENT_TAPE_INFOS.currOp = op;
1582    ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1583}
1584
1585/****************************************************************************/
1586/* Writes a block of operations onto hard disk and handles file creation,   */
1587/* removal, ...                                                             */
1588/****************************************************************************/
1589void put_op_block(unsigned char *lastOpP1) {
1590    int i, chunks;
1591    size_t number, remain, chunkSize;
1592    ADOLC_OPENMP_THREAD_NUMBER;
1593    ADOLC_OPENMP_GET_THREAD_NUMBER;
1594
1595    if (ADOLC_CURRENT_TAPE_INFOS.op_file == NULL) {
1596        ADOLC_CURRENT_TAPE_INFOS.op_file =
1597            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "rb");
1598        if (ADOLC_CURRENT_TAPE_INFOS.op_file != NULL) {
1599            #if defined(ADOLC_DEBUG)
1600            fprintf(DIAG_OUT, "ADOL-C debug: Old tapefile %s gets removed!\n",
1601                    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName);
1602            #endif
1603            fclose(ADOLC_CURRENT_TAPE_INFOS.op_file);
1604            ADOLC_CURRENT_TAPE_INFOS.op_file = NULL;
1605            if (remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName))
1606                fprintf(DIAG_OUT, "ADOL-C warning: "
1607                        "Unable to remove old tapefile\n");
1608            ADOLC_CURRENT_TAPE_INFOS.op_file =
1609                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "wb");
1610        } else {
1611            ADOLC_CURRENT_TAPE_INFOS.op_file =
1612                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.op_fileName, "wb");
1613        }
1614    }
1615
1616    number = lastOpP1 - ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1617    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1618    chunks = number / chunkSize;
1619    for (i = 0; i < chunks; ++i)
1620        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.opBuffer +
1621                        i * chunkSize, chunkSize *
1622                        sizeof(unsigned char), 1,
1623                        ADOLC_CURRENT_TAPE_INFOS.op_file) ) != 1 )
1624            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1625    remain = number % chunkSize;
1626    if (remain != 0)
1627        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.opBuffer +
1628                        chunks * chunkSize, remain *
1629                        sizeof(unsigned char), 1,
1630                        ADOLC_CURRENT_TAPE_INFOS.op_file) ) != 1 )
1631            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1632    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape += number;
1633    ADOLC_CURRENT_TAPE_INFOS.currOp = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1634    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1635}
1636
1637/****************************************************************************/
1638/* Reads the next operations block into the internal buffer.                */
1639/****************************************************************************/
1640void get_op_block_f() {
1641    int i, chunks;
1642    size_t number, remain, chunkSize;
1643    ADOLC_OPENMP_THREAD_NUMBER;
1644    ADOLC_OPENMP_GET_THREAD_NUMBER;
1645
1646    number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE],
1647            ADOLC_CURRENT_TAPE_INFOS.numOps_Tape);
1648    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1649    chunks = number / chunkSize;
1650    for (i = 0; i < chunks; ++i)
1651        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1652                    chunkSize * sizeof(unsigned char), 1,
1653                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1654            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1655    remain = number % chunkSize;
1656    if (remain != 0)
1657        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks * chunkSize,
1658                    remain * sizeof(unsigned char), 1,
1659                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1660            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1661    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape -= remain;
1662    ADOLC_CURRENT_TAPE_INFOS.currOp = ADOLC_CURRENT_TAPE_INFOS.opBuffer;
1663}
1664
1665/****************************************************************************/
1666/* Reads the previous block of operations into the internal buffer.         */
1667/****************************************************************************/
1668void get_op_block_r() {
1669    int i, chunks;
1670    size_t number, remain, chunkSize;
1671    ADOLC_OPENMP_THREAD_NUMBER;
1672    ADOLC_OPENMP_GET_THREAD_NUMBER;
1673
1674    number = ADOLC_CURRENT_TAPE_INFOS.stats[OP_BUFFER_SIZE];
1675    fseek(ADOLC_CURRENT_TAPE_INFOS.op_file, sizeof(unsigned char) *
1676            (ADOLC_CURRENT_TAPE_INFOS.numOps_Tape - number), SEEK_SET);
1677    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(unsigned char);
1678    chunks = number / chunkSize;
1679    for (i = 0; i < chunks; ++i)
1680        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + i * chunkSize,
1681                    chunkSize * sizeof(unsigned char), 1,
1682                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1683            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1684    remain = number % chunkSize;
1685    if (remain != 0)
1686        if (fread(ADOLC_CURRENT_TAPE_INFOS.opBuffer + chunks * chunkSize,
1687                    remain * sizeof(unsigned char), 1,
1688                    ADOLC_CURRENT_TAPE_INFOS.op_file) != 1)
1689            fail(ADOLC_EVAL_OP_TAPE_READ_FAILED);
1690    ADOLC_CURRENT_TAPE_INFOS.numOps_Tape -= number;
1691    ADOLC_CURRENT_TAPE_INFOS.currOp =
1692        ADOLC_CURRENT_TAPE_INFOS.opBuffer + number;
1693}
1694
1695/* --- Locations --- */
1696
1697/****************************************************************************/
1698/* Writes a block of locations onto hard disk and handles file creation,   */
1699/* removal, ...                                                             */
1700/****************************************************************************/
1701void put_loc_block(locint *lastLocP1) {
1702    int i, chunks;
1703    size_t number, remain, chunkSize;
1704    ADOLC_OPENMP_THREAD_NUMBER;
1705    ADOLC_OPENMP_GET_THREAD_NUMBER;
1706
1707    if (ADOLC_CURRENT_TAPE_INFOS.loc_file == NULL) {
1708        ADOLC_CURRENT_TAPE_INFOS.loc_file =
1709            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "rb");
1710        if (ADOLC_CURRENT_TAPE_INFOS.loc_file != NULL) {
1711            #if defined(ADOLC_DEBUG)
1712            fprintf(DIAG_OUT, "ADOL-C debug: Old tapefile %s gets removed!\n",
1713                    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName);
1714            #endif
1715            fclose(ADOLC_CURRENT_TAPE_INFOS.loc_file);
1716            ADOLC_CURRENT_TAPE_INFOS.loc_file = NULL;
1717            if (remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName))
1718                fprintf(DIAG_OUT, "ADOL-C warning: "
1719                        "Unable to remove old tapefile!\n");
1720            ADOLC_CURRENT_TAPE_INFOS.loc_file =
1721                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "wb");
1722        } else {
1723            ADOLC_CURRENT_TAPE_INFOS.loc_file =
1724                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.loc_fileName, "wb");
1725        }
1726    }
1727
1728    number = lastLocP1 - ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1729    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1730    chunks = number / chunkSize;
1731    for (i = 0; i < chunks; ++i)
1732        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.locBuffer +
1733                        i * chunkSize, chunkSize * sizeof(locint), 1,
1734                        ADOLC_CURRENT_TAPE_INFOS.loc_file) ) != 1)
1735            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1736    remain = number % chunkSize;
1737    if (remain != 0)
1738        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.locBuffer +
1739                        chunks * chunkSize, remain * sizeof(locint), 1,
1740                        ADOLC_CURRENT_TAPE_INFOS.loc_file) ) != 1)
1741            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1742    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape += number;
1743    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1744    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1745}
1746
1747/****************************************************************************/
1748/* Reads the next block of locations into the internal buffer.              */
1749/****************************************************************************/
1750void get_loc_block_f() {
1751    int i, chunks;
1752    size_t number, remain, chunkSize;
1753    ADOLC_OPENMP_THREAD_NUMBER;
1754    ADOLC_OPENMP_GET_THREAD_NUMBER;
1755
1756    number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE],
1757            ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape);
1758    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof (locint);
1759    chunks = number / chunkSize;
1760    for (i = 0; i < chunks; ++i)
1761        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1762                    chunkSize * sizeof(locint), 1,
1763                    ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1764            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1765    remain = number % chunkSize;
1766    if (remain != 0)
1767        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks * chunkSize,
1768                    remain * sizeof(locint), 1,
1769                    ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1770            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1771    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape -= number;
1772    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.locBuffer;
1773}
1774
1775/****************************************************************************/
1776/* Reads the previous block of locations into the internal buffer.          */
1777/****************************************************************************/
1778void get_loc_block_r() {
1779    int i, chunks;
1780    size_t number, remain, chunkSize;
1781    ADOLC_OPENMP_THREAD_NUMBER;
1782    ADOLC_OPENMP_GET_THREAD_NUMBER;
1783
1784    number = ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1785    fseek(ADOLC_CURRENT_TAPE_INFOS.loc_file, sizeof(locint) *
1786            (ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape - number), SEEK_SET);
1787    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(locint);
1788    chunks = number / chunkSize;
1789    for (i = 0; i < chunks; ++i)
1790        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + i * chunkSize,
1791                   chunkSize * sizeof(locint), 1,
1792                   ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1793            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1794    remain = number % chunkSize;
1795    if (remain != 0)
1796        if (fread(ADOLC_CURRENT_TAPE_INFOS.locBuffer + chunks * chunkSize,
1797                   remain * sizeof(locint), 1,
1798                   ADOLC_CURRENT_TAPE_INFOS.loc_file) != 1)
1799            fail(ADOLC_EVAL_LOC_TAPE_READ_FAILED);
1800    ADOLC_CURRENT_TAPE_INFOS.numLocs_Tape -=
1801        ADOLC_CURRENT_TAPE_INFOS.stats[LOC_BUFFER_SIZE];
1802    ADOLC_CURRENT_TAPE_INFOS.currLoc = ADOLC_CURRENT_TAPE_INFOS.lastLocP1 -
1803            *(ADOLC_CURRENT_TAPE_INFOS.lastLocP1 - 1);
1804}
1805
1806/* --- Values (Constants -- Real) --- */
1807
1808/****************************************************************************/
1809/* Writes a block of constants (real) onto hard disk and handles file       */
1810/* creation, removal, ...                                                   */
1811/****************************************************************************/
1812void put_vals_writeBlock(double *vals, locint numVals) {
1813    int i;
1814    ADOLC_OPENMP_THREAD_NUMBER;
1815    ADOLC_OPENMP_GET_THREAD_NUMBER;
1816
1817    for (i = 0; i < numVals; ++i) {
1818        *ADOLC_CURRENT_TAPE_INFOS.currVal = vals[i];
1819        ++ADOLC_CURRENT_TAPE_INFOS.currVal;
1820    }
1821    ADOLC_PUT_LOCINT(ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1822    put_val_block(ADOLC_CURRENT_TAPE_INFOS.lastValP1);
1823    /* every operation writes 1 opcode */
1824    if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1825        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1826        put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1827        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1828        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1829    }
1830    *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_val;
1831    ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1832}
1833
1834/****************************************************************************/
1835/* Write some constants to the buffer without disk access                   */
1836/****************************************************************************/
1837void put_vals_notWriteBlock(double *vals, locint numVals) {
1838    int i;
1839    ADOLC_OPENMP_THREAD_NUMBER;
1840    ADOLC_OPENMP_GET_THREAD_NUMBER;
1841
1842    for (i = 0; i < numVals; ++i) {
1843        *ADOLC_CURRENT_TAPE_INFOS.currVal = vals[i];
1844        ++ADOLC_CURRENT_TAPE_INFOS.currVal;
1845    }
1846}
1847
1848/****************************************************************************/
1849/* Writes a block of constants (real) onto tape and handles file creation   */
1850/* removal, ...                                                             */
1851/****************************************************************************/
1852void put_val_block(double *lastValP1) {
1853    int i, chunks;
1854    size_t number, remain, chunkSize;
1855    ADOLC_OPENMP_THREAD_NUMBER;
1856    ADOLC_OPENMP_GET_THREAD_NUMBER;
1857
1858    if (ADOLC_CURRENT_TAPE_INFOS.val_file == NULL) {
1859        ADOLC_CURRENT_TAPE_INFOS.val_file =
1860            fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "rb");
1861        if (ADOLC_CURRENT_TAPE_INFOS.val_file != NULL) {
1862            #if defined(ADOLC_DEBUG)
1863            fprintf(DIAG_OUT, "ADOL-C debug: Old tapefile %s gets removed!\n",
1864                    ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName);
1865            #endif
1866            fclose(ADOLC_CURRENT_TAPE_INFOS.val_file);
1867            ADOLC_CURRENT_TAPE_INFOS.val_file = NULL;
1868            if (remove(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName))
1869                fprintf(DIAG_OUT, "ADOL-C warning: "
1870                        "Unable to remove old tapefile\n");
1871            ADOLC_CURRENT_TAPE_INFOS.val_file =
1872                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "wb");
1873        } else {
1874            ADOLC_CURRENT_TAPE_INFOS.val_file =
1875                fopen(ADOLC_CURRENT_TAPE_INFOS.pTapeInfos.val_fileName, "wb");
1876        }
1877    }
1878
1879    number = lastValP1 - ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1880    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1881    chunks = number / chunkSize;
1882    for (i = 0; i < chunks; ++i)
1883        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.valBuffer +
1884                        i * chunkSize, chunkSize * sizeof(double), 1,
1885                        ADOLC_CURRENT_TAPE_INFOS.val_file) ) != 1)
1886            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1887    remain = number % chunkSize;
1888    if (remain != 0)
1889        if ((failAdditionalInfo1 = fwrite(ADOLC_CURRENT_TAPE_INFOS.valBuffer +
1890                        chunks * chunkSize, remain * sizeof(double), 1,
1891                        ADOLC_CURRENT_TAPE_INFOS.val_file) ) != 1)
1892            fail(ADOLC_TAPING_FATAL_IO_ERROR);
1893    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape += number;
1894    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1895    ADOLC_OPENMP_RESTORE_THREAD_NUMBER;
1896}
1897
1898/****************************************************************************/
1899/* Reads the next block of constants into the internal buffer.              */
1900/****************************************************************************/
1901void get_val_block_f() {
1902    int i, chunks;
1903    size_t number, remain, chunkSize;
1904    ADOLC_OPENMP_THREAD_NUMBER;
1905    ADOLC_OPENMP_GET_THREAD_NUMBER;
1906
1907    number = MIN_ADOLC(ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE],
1908            ADOLC_CURRENT_TAPE_INFOS.numVals_Tape);
1909    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof (double);
1910    chunks = number / chunkSize;
1911    for (i = 0; i < chunks; ++i)
1912        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1913                    chunkSize * sizeof(double), 1,
1914                    ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1915            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1916    remain = number % chunkSize;
1917    if (remain != 0)
1918        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks * chunkSize,
1919                    remain * sizeof(double), 1,
1920                    ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1921            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1922    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape -= number;
1923    ADOLC_CURRENT_TAPE_INFOS.currVal = ADOLC_CURRENT_TAPE_INFOS.valBuffer;
1924    /* get_locint_f(); value used in reverse only */
1925    ++ADOLC_CURRENT_TAPE_INFOS.currLoc;
1926}
1927
1928/****************************************************************************/
1929/* Reads the previous block of values into the internal buffer.             */
1930/****************************************************************************/
1931void get_val_block_r() {
1932    int i, chunks;
1933    size_t number, remain, chunkSize;
1934    locint temp;
1935    ADOLC_OPENMP_THREAD_NUMBER;
1936    ADOLC_OPENMP_GET_THREAD_NUMBER;
1937
1938    number = ADOLC_CURRENT_TAPE_INFOS.stats[VAL_BUFFER_SIZE];
1939    fseek(ADOLC_CURRENT_TAPE_INFOS.val_file, sizeof(double) *
1940            (ADOLC_CURRENT_TAPE_INFOS.numVals_Tape - number), SEEK_SET);
1941    chunkSize = ADOLC_IO_CHUNK_SIZE / sizeof(double);
1942    chunks = number / chunkSize;
1943    for (i = 0; i < chunks; ++i)
1944        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + i * chunkSize,
1945                   chunkSize * sizeof(double), 1,
1946                   ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1947            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1948    remain = number % chunkSize;
1949    if (remain != 0)
1950        if (fread(ADOLC_CURRENT_TAPE_INFOS.valBuffer + chunks * chunkSize,
1951                    remain * sizeof(double), 1,
1952                    ADOLC_CURRENT_TAPE_INFOS.val_file) != 1)
1953            fail(ADOLC_EVAL_VAL_TAPE_READ_FAILED);
1954    ADOLC_CURRENT_TAPE_INFOS.numVals_Tape -= number;
1955    --ADOLC_CURRENT_TAPE_INFOS.currLoc;
1956    temp = *ADOLC_CURRENT_TAPE_INFOS.currLoc;
1957    ADOLC_CURRENT_TAPE_INFOS.currVal =
1958        ADOLC_CURRENT_TAPE_INFOS.lastValP1 - temp;
1959}
1960
1961/****************************************************************************/
1962/* Returns the number of free constants in the real tape. Ensures that it   */
1963/* is at least 5.                                                           */
1964/****************************************************************************/
1965locint get_val_space(void) {
1966    ADOLC_OPENMP_THREAD_NUMBER;
1967    ADOLC_OPENMP_GET_THREAD_NUMBER;
1968    if (ADOLC_CURRENT_TAPE_INFOS.lastValP1 - 5 < ADOLC_CURRENT_TAPE_INFOS.currVal) {
1969        ADOLC_PUT_LOCINT(ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1970        put_val_block(ADOLC_CURRENT_TAPE_INFOS.lastValP1);
1971        /* every operation writes 1 opcode */
1972        if (ADOLC_CURRENT_TAPE_INFOS.currOp + 1 == ADOLC_CURRENT_TAPE_INFOS.lastOpP1) {
1973            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1974            put_op_block(ADOLC_CURRENT_TAPE_INFOS.lastOpP1);
1975            *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_op;
1976            ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1977        }
1978        *ADOLC_CURRENT_TAPE_INFOS.currOp = end_of_val;
1979        ++ADOLC_CURRENT_TAPE_INFOS.currOp;
1980    }
1981    return (ADOLC_CURRENT_TAPE_INFOS.lastValP1 - ADOLC_CURRENT_TAPE_INFOS.currVal);
1982}
1983
1984/****************************************************************************/
1985/* Returns a pointer to the first element of a values vector and skips the  */
1986/* vector. -- Forward Mode --                                               */
1987/****************************************************************************/
1988double *get_val_v_f(locint size) {
1989    double *temp;
1990    ADOLC_OPENMP_THREAD_NUMBER;
1991
1992    ADOLC_OPENMP_GET_THREAD_NUMBER;
1993    temp = ADOLC_CURRENT_TAPE_INFOS.currVal;
1994    ADOLC_CURRENT_TAPE_INFOS.currVal += size;
1995    return temp;
1996}
1997
1998/****************************************************************************/
1999/* Returns a pointer to the first element of a values vector and skips the  */
2000/* vector. -- Reverse Mode --                                               */
2001/****************************************************************************/
2002double *get_val_v_r(locint size) {
2003    ADOLC_OPENMP_THREAD_NUMBER;
2004    ADOLC_OPENMP_GET_THREAD_NUMBER;
2005    ADOLC_CURRENT_TAPE_INFOS.currVal -= size;
2006    return ADOLC_CURRENT_TAPE_INFOS.currVal;
2007}
2008
2009/* --- Updates / Corrections --- */
2010
2011/****************************************************************************/
2012/* Not sure what's going on here! -> vector class ?  --- kowarz             */
2013/****************************************************************************/
2014void reset_val_r(void) {
2015    ADOLC_OPENMP_THREAD_NUMBER;
2016    ADOLC_OPENMP_GET_THREAD_NUMBER;
2017    if (ADOLC_CURRENT_TAPE_INFOS.currVal == ADOLC_CURRENT_TAPE_INFOS.valBuffer)
2018        get_val_block_r();
2019}
2020
2021/****************************************************************************/
2022/* Update locations tape to remove assignments involving temp. variables.   */
2023/* e.g.  t = a + b ; y = t  =>  y = a + b                                   */
2024/****************************************************************************/
2025int upd_resloc(locint temp, locint lhs) {
2026    ADOLC_OPENMP_THREAD_NUMBER;
2027    ADOLC_OPENMP_GET_THREAD_NUMBER;
2028    if (ADOLC_CURRENT_TAPE_INFOS.currLoc - ADOLC_CURRENT_TAPE_INFOS.locBuffer < 1) return 0;
2029    if (temp == *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1)) {
2030        *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1) = lhs;
2031        return 1;
2032    }
2033    return 0;
2034}
2035
2036/****************************************************************************/
2037/* Update locations and operations tape to remove special operations inv.   */
2038/* temporary variables. e.g.  t = a * b ; y += t  =>  y += a * b            */
2039/****************************************************************************/
2040int upd_resloc_inc_prod(locint temp, locint newlhs, unsigned char newop) {
2041    ADOLC_OPENMP_THREAD_NUMBER;
2042    ADOLC_OPENMP_GET_THREAD_NUMBER;
2043    if (ADOLC_CURRENT_TAPE_INFOS.currLoc - ADOLC_CURRENT_TAPE_INFOS.locBuffer < 3) return 0;
2044    if (ADOLC_CURRENT_TAPE_INFOS.currOp - ADOLC_CURRENT_TAPE_INFOS.opBuffer < 1) return 0;
2045    if (temp == *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1)    &&
2046            mult_a_a == *(ADOLC_CURRENT_TAPE_INFOS.currOp - 1) &&
2047            /* skipping recursive case */
2048            newlhs != *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 2)  &&
2049            newlhs != *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 3)    ) {
2050        *(ADOLC_CURRENT_TAPE_INFOS.currLoc - 1) = newlhs;
2051        *(ADOLC_CURRENT_TAPE_INFOS.currOp - 1) = newop;
2052        return 1;
2053    }
2054    return 0;
2055}
2056
2057void enableBranchSwitchWarnings() {
2058    ADOLC_OPENMP_THREAD_NUMBER;
2059    ADOLC_OPENMP_GET_THREAD_NUMBER;
2060    ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = 1;
2061}
2062
2063void disableBranchSwitchWarnings() {
2064    ADOLC_OPENMP_THREAD_NUMBER;
2065    ADOLC_OPENMP_GET_THREAD_NUMBER;
2066    ADOLC_GLOBAL_TAPE_VARS.branchSwitchWarning = 0;
2067}
2068
2069/****************************************************************************/
2070/*                                                                    UTILs */
2071/****************************************************************************/
2072double make_nan() {
2073    double a, b;
2074    #ifdef inf_num
2075    a = non_num;
2076    b = non_den;
2077    #endif
2078    return a / b;
2079}
2080
2081double make_inf() {
2082    double a, b;
2083    #ifdef inf_num
2084    a = inf_num;
2085    b = inf_den;
2086    #endif
2087    return a / b;
2088}
2089
2090/****************************************************************************/
2091/*                                                          DEBUG FUNCTIONS */
2092#if defined(ADOLC_HARDDEBUG)
2093
2094/*--------------------------------------------------------------------------*/
2095unsigned char get_op_f() {
2096    unsigned char temp;
2097    ADOLC_OPENMP_THREAD_NUMBER;
2098    ADOLC_OPENMP_GET_THREAD_NUMBER;
2099
2100    temp = *ADOLC_CURRENT_TAPE_INFOS.currOp;
2101    ++ADOLC_CURRENT_TAPE_INFOS.currOp;
2102    fprintf(DIAG_OUT, "f_op: %i\n", temp - '\0'); /* why -'\0' ??? kowarz */
2103    return temp;
2104}
2105
2106/*--------------------------------------------------------------------------*/
2107unsigned char get_op_r() {
2108    unsigned char temp;
2109    ADOLC_OPENMP_THREAD_NUMBER;
2110    ADOLC_OPENMP_GET_THREAD_NUMBER;
2111
2112    --ADOLC_CURRENT_TAPE_INFOS.currOp;
2113    temp = *ADOLC_CURRENT_TAPE_INFOS.currOp;
2114    fprintf(DIAG_OUT, "r_op: %i\n", temp - '\0');
2115    return temp;
2116}
2117
2118/*--------------------------------------------------------------------------*/
2119locint get_locint_f() {
2120    locint temp;
2121    ADOLC_OPENMP_THREAD_NUMBER;
2122    ADOLC_OPENMP_GET_THREAD_NUMBER;
2123
2124    temp = *ADOLC_CURRENT_TAPE_INFOS.currLoc;
2125    ++ADOLC_CURRENT_TAPE_INFOS.currLoc;
2126    fprintf(DIAG_OUT, "f_loc: %i\n", temp);
2127    return temp;
2128}
2129
2130/*--------------------------------------------------------------------------*/
2131locint get_locint_r() {
2132    unsigned char temp;
2133    ADOLC_OPENMP_THREAD_NUMBER;
2134    ADOLC_OPENMP_GET_THREAD_NUMBER;
2135
2136    --ADOLC_CURRENT_TAPE_INFOS.currLoc;
2137    temp = *ADOLC_CURRENT_TAPE_INFOS.currLoc;
2138    fprintf(DIAG_OUT, "r_loc: %i\n", temp);
2139    return temp;
2140}
2141
2142/*--------------------------------------------------------------------------*/
2143double get_val_f() {
2144    double temp;
2145    ADOLC_OPENMP_THREAD_NUMBER;
2146    ADOLC_OPENMP_GET_THREAD_NUMBER;
2147
2148    temp = *ADOLC_CURRENT_TAPE_INFOS.currVal;
2149    ++ADOLC_CURRENT_TAPE_INFOS.currVal;
2150    fprintf(DIAG_OUT, "f_val: %e\n", temp);
2151    return temp;
2152}
2153
2154/*--------------------------------------------------------------------------*/
2155double get_val_r() {
2156    double temp;
2157    ADOLC_OPENMP_THREAD_NUMBER;
2158    ADOLC_OPENMP_GET_THREAD_NUMBER;
2159
2160    --ADOLC_CURRENT_TAPE_INFOS.currVal;
2161    temp = *ADOLC_CURRENT_TAPE_INFOS.currVal;
2162    fprintf(DIAG_OUT, "r_val: %e\n", temp);
2163    return temp;
2164}
2165
2166#endif
2167
Note: See TracBrowser for help on using the repository browser.