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

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

get rid of strdup, it is in POSIX but not in ISO standard

so we can compile using -std=c99 and -std=c++11

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

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