source: stable/2.4/ADOL-C/src/taping.c @ 397

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

Merge branch '2.3.x_ISSM' into svn

This introduces the new externally differentiated functions API

From: Jean Utke <utke@…>

Please see comments in ADOL-C/include/adolc/externfcts.h for details

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

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