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

Last change on this file since 708 was 704, checked in by kulshres, 3 years ago

spelling

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