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