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

Last change on this file since 467 was 467, checked in by kulshres, 7 years ago

declaration of loc2 moved up

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

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