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