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

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

Allow reading octal and hexadecimal numbers in .adolcrc

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

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