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

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

Throw a std::exception instead of calling exit()

based on branch 'adolcerror' of https://github.com/b45ch1/adol-c

Suggested-by: Sebastian Walter <sebastian.walter@…>
Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

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