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

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

do not segfault if trace_off is called before trace_on

segfault is bad, even though a user doing this is clearly brain-dead.

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

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