source: CIVL/examples/compare/provesa/ADFirstAidKit/debugAD.c@ a389857

main test-branch
Last change on this file since a389857 was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 27.4 KB
Line 
1#include <string.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <errno.h>
7#include "debugAD.h"
8
9extern void pushreal8(double x) ;
10extern void popreal8(double *x) ;
11extern void pushinteger4(int x) ;
12extern void popinteger4(int *x) ;
13
14/* The "call stack" used by debugging to
15 * keep track of the position in the call tree */
16typedef struct _DBAD_CallStackElem {
17 char *funcname ;
18 int deltadepth ;
19 int code ;
20 struct _DBAD_CallStackElem *context ;
21} DBAD_CallStackElem ;
22
23static DBAD_CallStackElem dbad_topContext ;
24static DBAD_CallStackElem *dbad_callStack ;
25static int dbad_calltracedepth = 1 ;
26
27static int dbad_mode, dbad_phase, dbad_nberrors ;
28static int dbad_trace = 0 ;
29static int dbad_nocommunication = 0 ;
30static FILE *dbad_file ;
31static double dbad_almostzero, dbad_errormax, dbad_ddeps = 1.e-6 ;
32static double dbad_seed = 0.137 ;
33static double dbad_currentSeed = 0.0 ;
34static double dbad_condensed_dd, dbad_condensed_tgt, dbad_condensed_adj ;
35static double dbad_refsum, dbad_nextrefsum ;
36static double dbad_coeff = 1.0 ;
37static double dbad_sum = 0.0 ;
38
39void dbad_pushCallFrame(char* unitname, int deltadepth, int forcetraced) {
40 DBAD_CallStackElem *newCallLevel = (DBAD_CallStackElem*)malloc(sizeof(DBAD_CallStackElem)) ;
41 newCallLevel->funcname = (char*)malloc(100) ;
42 sprintf(newCallLevel->funcname, "%s", unitname) ;
43 newCallLevel->deltadepth = (dbad_calltracedepth>0?1-deltadepth:0) ;
44 dbad_calltracedepth -= newCallLevel->deltadepth ;
45 // forcing mechanism:
46 if (forcetraced>0 && forcetraced>dbad_calltracedepth) {
47 newCallLevel->deltadepth -= (forcetraced-dbad_calltracedepth) ;
48 dbad_calltracedepth = forcetraced ;
49 }
50 newCallLevel->code = 0 ;
51 newCallLevel->context = dbad_callStack ;
52 dbad_callStack = newCallLevel ;
53}
54
55void dbad_popCallFrame() {
56 dbad_calltracedepth += dbad_callStack->deltadepth ;
57 DBAD_CallStackElem *newCallLevel = dbad_callStack->context ;
58 free(dbad_callStack->funcname) ;
59 free(dbad_callStack) ;
60 dbad_callStack = newCallLevel ;
61}
62
63int dbad_debughere(int forcetraced) {
64 return (dbad_calltracedepth>0 || forcetraced) ;
65}
66
67int dbad_debugabove() {
68 return (dbad_calltracedepth+dbad_callStack->deltadepth)>0 ;
69}
70
71int dbad_callstacksize() {
72 DBAD_CallStackElem *incallstack = dbad_callStack ;
73 int depth = 1 ;
74 while (incallstack) {++depth ; incallstack=incallstack->context ;}
75 return depth ;
76}
77
78void dbad_resetCondensors() {
79 dbad_currentSeed = 0.0 ;
80 dbad_condensed_dd = 0.0 ;
81 dbad_condensed_tgt = 0.0 ;
82 dbad_condensed_adj = 0.0 ;
83}
84
85double dbad_nextRandom() {
86 dbad_currentSeed += dbad_seed ;
87 if (dbad_currentSeed>1.0) dbad_currentSeed-=1.0 ;
88 return dbad_currentSeed ;
89}
90
91void dbad_ddcheckvarname(char* varname) {
92 char ddvarname[40] ;
93 int ret = fscanf(dbad_file, " %s\n", ddvarname) ;
94 if (strcmp(varname, ddvarname)!=0) {
95 printf("Control mismatch, expecting a variable named \"%s\", got \"%s\"\n",varname,ddvarname) ;
96 exit(0) ;
97 }
98}
99
100//TODO: detect NaNs and if so, set *areNaNs :
101void dbad_ddpicktwo8(double var, double *varwr, FILE *dbad_file, double *ddvar, int *areNaNs) {
102 FILE *wrfile ;
103 int ret ;
104 wrfile = fopen("ddwrfile", "w") ;
105 fprintf(wrfile, "%24.16e", var) ;
106 freopen("ddwrfile", "r", wrfile) ;
107 ret = fscanf(wrfile," %lf",varwr) ;
108 fclose(wrfile) ;
109 ret = fscanf(dbad_file," %lf\n", ddvar) ;
110}
111
112void dbad_display_location(char *placename) {
113 int i ;
114 char* enclosproc = dbad_callStack->funcname ;
115 for (i=dbad_callstacksize() ; i>0 ; --i) printf(" ") ;
116 printf(" AT:%s OF %s\n", placename, enclosproc) ;
117}
118
119//###################### DEBUG OF TANGENT ##############################
120
121void debug_tgt_init(double epsilon, double ezero, double errmax, double seed) {
122 dbad_mode = 1 ;
123 dbad_ddeps = epsilon ;
124 dbad_almostzero = ezero ;
125 dbad_errormax = errmax ;
126 dbad_seed = seed ;
127 dbad_topContext.funcname = "TESTED CODE\0" ;
128 dbad_topContext.deltadepth = 0 ;
129 dbad_topContext.code = 0 ;
130 dbad_calltracedepth = 1 ;
131 dbad_callStack = &dbad_topContext ;
132 char* phase = getenv("DBAD_PHASE") ;
133 if (phase==NULL) {
134 printf("Please set DBAD_PHASE environment variable to 1 (perturbed), 2 (tangent), or 0 (no debug)\n") ;
135 exit(0) ;
136 } else if (strcmp(phase,"0")==0) {
137 dbad_phase = 0 ;
138 } else if (strcmp(phase,"1")==0) {
139 dbad_phase = 1 ;
140 } else if (strcmp(phase,"2")==0) {
141 dbad_phase = 2 ;
142 } else if (strcmp(phase,"-1")==0) {
143 dbad_phase = 1 ;
144 dbad_trace = 1 ;
145 } else if (strcmp(phase,"-2")==0) {
146 dbad_phase = 2 ;
147 dbad_trace = 1 ;
148 } else {
149 printf("DBAD_PHASE environment variable must be set to 1 or 2 (or 0 for no debug)\n") ;
150 exit(0) ;
151 }
152 if (dbad_trace) {
153 printf("INTERNAL TESTS, epsilon=%7.1e, zero=%7.1e, errmax=%4.1f%\n", epsilon, ezero, errmax) ;
154 printf("===========================================================\n") ;
155 }
156 if (dbad_phase==1) {
157 printf("Starting TGT test, phase one, epsilon=%7.1e, zero=%7.1e, errmax=%4.1f%, seed=%7.1e\n",
158 epsilon, ezero, errmax, seed) ;
159 printf("===========================================================\n") ;
160 dbad_resetCondensors() ;
161 mkfifo("/tmp/DBAD_fifo", S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH | S_IRWXU | S_IRWXO) ;
162 dbad_file = fopen("/tmp/DBAD_fifo", "a") ;
163 if (dbad_file==NULL) {
164 char errbuf[20] ;
165 strerror_r(errno, errbuf, 20) ;
166 printf("FIFO ERROR %i: %s OR %s\n",errno,strerror(errno),errbuf) ;
167 exit(0) ;
168 }
169 } else if (dbad_phase==2) {
170 printf("Starting TGT test, phase two, epsilon=%7.1e, zero=%7.1e, errmax=%4.1f%, seed=%7.1e\n",
171 epsilon, ezero, errmax, seed) ;
172 printf("===========================================================\n") ;
173 dbad_resetCondensors() ;
174 dbad_file = fopen("/tmp/DBAD_fifo", "r") ;
175 }
176}
177
178void debug_tgt_call(char* unitname, int deltadepth, int forcetraced) {
179 if (dbad_trace) {
180 printf("call_ %s deltadepth:%i forcetraced:%i\n", unitname, deltadepth, forcetraced) ;
181 }
182 if (dbad_phase!=0) {
183 dbad_pushCallFrame(unitname, deltadepth, forcetraced) ;
184 }
185}
186
187void debug_tgt_exit() {
188 if (dbad_trace) {
189 printf("exit_\n") ;
190 }
191 if (dbad_phase!=0) {
192 dbad_popCallFrame() ;
193 }
194 dbad_resetCondensors() ;
195}
196
197int debug_tgt_here(char* placename, int forcetraced) {
198 if (dbad_trace) {
199 printf("here_?? %s forcetraced:%i\n", placename, forcetraced) ;
200 printf(" will return %i\n", (dbad_phase==0?0:dbad_debughere(forcetraced))) ;
201 }
202 if (dbad_phase==0) return 0 ;
203 return dbad_debughere(forcetraced) ;
204}
205
206void debug_tgt_initreal8(char* varname, double *indep, double *indepd) {
207 *indepd = dbad_nextRandom() ;
208 if (dbad_phase==1)
209 *indep = (*indep)+dbad_ddeps*(*indepd) ;
210 if (dbad_trace)
211 printf("initreal8_ of %s: %24.16e //%24.16e\n", varname, *indep, *indepd) ;
212}
213
214void debug_tgt_initreal8array(char* varname, double *indep, double *indepd, int length) {
215 int i ;
216 for (i=0 ; i<length ; ++i) {
217 indepd[i] = dbad_nextRandom() ;
218 }
219 if (dbad_phase==1) {
220 for (i=0 ; i<length ; ++i) {
221 indep[i] = indep[i]+dbad_ddeps*indepd[i] ;
222 }
223 }
224 if (dbad_trace) {
225 printf("initreal8array_ of %s, length=%i:\n", varname, length) ;
226 for (i=0 ; i<length ; ++i)
227 printf(" %i:%24.16e //%24.16e",i,indep[i],indepd[i]) ;
228 printf("\n") ;
229 }
230}
231
232void debug_tgt_concludereal8(char* varname, double dep, double depd) {
233 double depb = dbad_nextRandom() ;
234 if (dbad_trace) {
235 printf("concludereal8_ %s %24.16e //%24.16e\n", varname, dep, depd) ;
236 }
237 if (dbad_phase==1) {
238 fprintf(dbad_file, "%s\n", varname) ;
239 fprintf(dbad_file, "%24.16e\n", dep) ;
240 } else if (dbad_phase==2) {
241 double ddvar, dd, diff, varwr, maxabs, absvard, absdd, absvardmdd ;
242 int areNaNs = 0;
243 dbad_ddcheckvarname(varname) ;
244 dbad_ddpicktwo8(dep, &varwr, dbad_file, &ddvar, &areNaNs) ;
245 if (!areNaNs) {
246 dd = (ddvar-varwr)/dbad_ddeps ;
247 absvard = (depd>=0.0?depd:-depd) ;
248 absdd = (dd>=0.0?dd:-dd) ;
249 maxabs = (absvard>absdd?absvard:absdd) ;
250 absvardmdd = depd-dd ;
251 if (absvardmdd<0.0) absvardmdd=-absvardmdd ;
252 diff = (absvardmdd*100.0)/ maxabs ;
253 if (diff>dbad_errormax) {
254 printf("Result variable %s sum: %24.16e (ad)%5.2f% DIFF WITH (dd)%24.16e\n",
255 varname,depd,diff,dd) ;
256 }
257 dbad_condensed_dd += dd*depb;
258 dbad_condensed_tgt += depd*depb;
259 } else {
260 printf("Variable %s has NaNs\n", varname) ;
261 }
262 }
263}
264
265void debug_tgt_concludereal8array(char* varname, double *dep, double *depd, int length) {
266 if (dbad_trace) {
267 printf("concludereal8array_ %s[%i]:", varname, length) ;
268 }
269 if (dbad_phase==1) {
270 fprintf(dbad_file, "%s\n", varname) ;
271 } else if (dbad_phase==2) {
272 dbad_ddcheckvarname(varname) ;
273 }
274 int i ;
275 double depb ;
276 for (i=0 ; i<length ; ++i) {
277 depb = dbad_nextRandom() ;
278 if (dbad_trace) {
279 printf(" %i:%24.16e //%24.16e",i,dep[i],depd[i]) ;
280 }
281 if (dbad_phase==1) {
282 fprintf(dbad_file, "%24.16e\n", dep[i]) ;
283 } else if (dbad_phase==2) {
284 double ddvar, dd, diff, varwr, maxabs, absvard, absdd, absvardmdd ;
285 int areNaNs = 0;
286 dbad_ddpicktwo8(dep[i], &varwr, dbad_file, &ddvar, &areNaNs) ;
287 if (!areNaNs) {
288 dd = (ddvar-varwr)/dbad_ddeps ;
289 absvard = (depd[i]>=0.0?depd[i]:-depd[i]) ;
290 absdd = (dd>=0.0?dd:-dd) ;
291 maxabs = (absvard>absdd?absvard:absdd) ;
292 absvardmdd = depd[i]-dd ;
293 if (absvardmdd<0.0) absvardmdd=-absvardmdd ;
294 diff = (absvardmdd*100.0)/ maxabs ;
295 if (diff>dbad_errormax) {
296 printf("Result variable %s[%i] sum: %24.16e (ad)%5.2f% DIFF WITH (dd)%24.16e\n",
297 varname,i,depd[i],diff,dd) ;
298 }
299 dbad_condensed_dd += dd*depb;
300 dbad_condensed_tgt += depd[i]*depb;
301 } else {
302 printf("Variable %s[%i] has NaNs\n", varname, i) ;
303 }
304 }
305 }
306 if (dbad_trace) {
307 printf("\n") ;
308 }
309}
310
311void debug_tgt_conclude() {
312 printf("===========================================================\n") ;
313 if (dbad_trace) {
314 printf(" condensed result %24.16e //%24.16e",dbad_condensed_tgt,dbad_condensed_dd) ;
315 }
316 if (dbad_phase==2) {
317 double abstgt, absdd, maxabs, abserror, diff ;
318 abstgt = (dbad_condensed_tgt>=0.0?dbad_condensed_tgt:-dbad_condensed_tgt) ;
319 absdd = (dbad_condensed_dd>=0.0?dbad_condensed_dd:-dbad_condensed_dd) ;
320 maxabs = (abstgt>absdd?abstgt:absdd) ;
321 abserror = dbad_condensed_tgt-dbad_condensed_dd ;
322 if (abserror<0.0) abserror=-abserror ;
323 diff = (abserror*100.0)/ maxabs ;
324 printf("[seed:%7.1e] Condensed tangent : %24.16e (ad)%5.2f% DIFF WITH (dd)%24.16e\n",
325 dbad_seed,dbad_condensed_tgt,diff,dbad_condensed_dd) ;
326 }
327}
328
329void debug_tgt_real8(char *varname, double var, double vard) {
330 if (dbad_phase==1) {
331 fprintf(dbad_file, "%s\n", varname) ;
332 fprintf(dbad_file, "%24.16e\n", var) ;
333 } else if (dbad_phase==2) {
334 double ddvar, dd, diff, varwr, maxabs, absvard, absdd, absvardmdd ;
335 int areNaNs = 0 ;
336 dbad_ddcheckvarname(varname) ;
337 dbad_ddpicktwo8(var, &varwr, dbad_file, &ddvar, &areNaNs) ;
338 if (!areNaNs || dbad_trace) {
339 dd = (ddvar-varwr)/dbad_ddeps ;
340 absvard = (vard>=0.0?vard:-vard) ;
341 absdd = (dd>=0.0?dd:-dd) ;
342 if (absvard>dbad_almostzero || absdd>dbad_almostzero || dbad_trace) {
343 maxabs = (absvard>absdd?absvard:absdd) ;
344 absvardmdd = vard-dd ;
345 if (absvardmdd<0.0) absvardmdd=-absvardmdd ;
346 diff = (absvardmdd*100.0)/maxabs ;
347 if (dbad_trace) {
348 printf("%s v-eps:%24.16e v-loc:%24.16e ->(dd)%24.16e=?=(ad)%24.16e %5.1f%\n",
349 varname,ddvar,varwr,dd,vard,diff) ;
350 } else if (diff>dbad_errormax) {
351 printf("%s: %24.16e (ad) %5.1f% DIFF WITH (dd) %24.16e\n",
352 varname, vard, diff, dd) ;
353 }
354 }
355 }
356 }
357}
358
359void debug_tgt_real8array(char *varname, double* var, double* vard, int length) {
360 int i ;
361 if (dbad_phase==1) {
362 fprintf(dbad_file, "%s\n", varname) ;
363 for (i=0 ; i<length ; ++i) {
364 fprintf(dbad_file, "%24.16e\n", var[i]) ;
365 }
366 } else if (dbad_phase==2) {
367 double ddvar, dd, diff, varwr, maxabs, absvard, absdd, absvardmdd ;
368 int areNaNs = 0 ;
369 double vardbuf[10], ddbuf[10] ;
370 double varepsbuf[10], varlocbuf[10] ;
371 int indexbuf[10] ;
372 dbad_ddcheckvarname(varname) ;
373 int ibuf = 0;
374 int printedheader = 0 ;
375 for (i=0 ; i<length ; ++i) {
376 dbad_ddpicktwo8(var[i],&varwr,dbad_file,&ddvar,&areNaNs) ;
377 if (!areNaNs || dbad_trace) {
378 dd = (ddvar-varwr)/dbad_ddeps ;
379 absvard = (vard[i]>=0.0?vard[i]:-vard[i]) ;
380 absdd = (dd>=0.0?dd:-dd) ;
381 if (absvard>dbad_almostzero || absdd>dbad_almostzero || dbad_trace) {
382 maxabs = (absvard>absdd?absvard:absdd) ;
383 absvardmdd = vard[i]-dd ;
384 if (absvardmdd<0.0) absvardmdd=-absvardmdd ;
385 diff = (absvardmdd*100.0)/maxabs ;
386 if (dbad_trace) {
387 vardbuf[ibuf] = vard[i] ;
388 varepsbuf[ibuf] = ddvar ;
389 varlocbuf[ibuf] = varwr ;
390 ddbuf[ibuf] = dd ;
391 indexbuf[ibuf] = i ;
392 ++ibuf ;
393 } else if (diff>dbad_errormax) {
394 vardbuf[ibuf] = vard[i] ;
395 ddbuf[ibuf] = dd ;
396 indexbuf[ibuf] = i ;
397 ++ibuf ;
398 }
399 }
400 }
401 if (ibuf>=10 || (i==length-1 && ibuf>0)) {
402 int j ;
403 if (!printedheader) {
404 printf("%s:\n", varname) ;
405 printedheader = 1 ;
406 }
407 printf(" ") ;
408 for (j=0 ; j<ibuf ; ++j)
409 printf(" %4i->%11.4e", indexbuf[j], vardbuf[j]) ;
410 printf("\n ") ;
411 for (j=0 ; j<ibuf ; ++j)
412 printf(" (eps)%12.5e", varepsbuf[j]) ;
413 printf("\n ") ;
414 for (j=0 ; j<ibuf ; ++j)
415 printf(" (loc)%12.5e", varlocbuf[j]) ;
416 printf("\n ") ;
417 for (j=0 ; j<ibuf ; ++j)
418 printf(" (dd:)%11.4e", ddbuf[j]) ;
419 printf("\n") ;
420 ibuf = 0 ;
421 }
422 }
423 }
424}
425
426void debug_tgt_display(char *placename) {
427 if (dbad_trace) {
428 printf("display_ %s\n", placename) ;
429 }
430 if (dbad_phase==2) {
431 dbad_display_location(placename) ;
432 }
433}
434
435//############## DEBUG OF ADJOINT, FIRST SWEEP: ADJOINT RUN ################
436
437void debug_bwd_init(double ezero, double errmax, double seed) {
438 dbad_mode = -1 ;
439 dbad_phase = 1 ;
440 dbad_almostzero = ezero ;
441 dbad_errormax = errmax ;
442 dbad_seed = seed ;
443 dbad_topContext.funcname = "TESTED CODE\0" ;
444 dbad_topContext.deltadepth = 0 ;
445 dbad_topContext.code = 0 ;
446 dbad_calltracedepth = 1 ;
447 dbad_callStack = &dbad_topContext ;
448 char* phase = getenv("DBAD_PHASE") ;
449 if (phase==NULL) {
450 printf("Please set DBAD_PHASE environment variable to 0 (no debug), 1 (sendToTgt), -1 (plusTraces)\n") ;
451 dbad_phase = 1 ;
452 } else if (strcmp(phase,"0")==0) {
453 dbad_phase = 1 ;
454 dbad_nocommunication = 1 ;
455 } else if (strcmp(phase,"1")==0) {
456 dbad_phase = 1 ;
457 } else if (strcmp(phase,"-1")==0) {
458 dbad_phase = 1 ;
459 dbad_trace = 1 ;
460 } else {
461 printf("DBAD_PHASE environment variable must be set to 1 or -1 (or 0 for no debug)\n") ;
462 exit(0) ;
463 }
464 printf("Starting ADJ test, phase one (bwd), zero=%7.1e, errmax=%4.1f%, seed=%7.1e\n", ezero, errmax, seed) ;
465 printf("===========================================================\n") ;
466 if (dbad_nocommunication) {
467 dbad_file = NULL ;
468 printf("FIFO COMMUNICATION TURNED OFF !\n") ;
469 } else {
470 mkfifo("/tmp/DBAD_fifo", S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH | S_IRWXU | S_IRWXO) ;
471 dbad_file = fopen("/tmp/DBAD_fifo", "a") ;
472 if (dbad_file==NULL) {
473 char errbuf[20] ;
474 strerror_r(errno, errbuf, 20) ;
475 printf("FIFO ERROR %i: %s OR %s\n",errno,strerror(errno),errbuf) ;
476 exit(0) ;
477 }
478 }
479 dbad_resetCondensors() ;
480}
481
482void debug_bwd_call(char *funcname, int deltadepth) {
483 dbad_pushCallFrame(funcname, deltadepth, 0) ;
484}
485
486void debug_bwd_exit() {
487 if (dbad_debugabove()) {
488 if (dbad_nocommunication) {
489 printf("debugAD would send (%i %s)\n", (dbad_debughere(0)?2:-2), dbad_callStack->funcname) ;
490 } else {
491 fprintf(dbad_file, "%i\n", (dbad_debughere(0)?2:-2)) ;
492 fprintf(dbad_file, "%s\n", dbad_callStack->funcname) ;
493 }
494 }
495 dbad_popCallFrame() ;
496}
497
498int debug_bwd_here(char* placename) {
499 dbad_resetCondensors() ;
500 return debug_tgt_here(placename, 0) ;
501}
502
503//############## DEBUG OF ADJOINT, SECOND SWEEP: TANGENT RUN ################
504
505void debug_fwd_init(double ezero, double errmax, double seed) {
506 dbad_mode = -1 ;
507 dbad_phase = 2 ;
508 dbad_almostzero = ezero ;
509 dbad_errormax = errmax ;
510 dbad_seed = seed ;
511 dbad_topContext.funcname = "TESTED CODE\0" ;
512 dbad_topContext.deltadepth = 0 ;
513 dbad_topContext.code = 0 ;
514 dbad_calltracedepth = 1 ;
515 dbad_callStack = &dbad_topContext ;
516 char* phase = getenv("DBAD_PHASE") ;
517 if (phase==NULL) {
518 printf("Please set DBAD_PHASE environment variable to 0 (no debug), 2 (readFromAdj), -2 (plusTraces)\n") ;
519 dbad_phase = 2 ;
520 } else if (strcmp(phase,"0")==0) {
521 dbad_phase = 2 ;
522 dbad_nocommunication = 1 ;
523 } else if (strcmp(phase,"2")==0) {
524 dbad_phase = 2 ;
525 } else if (strcmp(phase,"-2")==0) {
526 dbad_phase = 2 ;
527 dbad_trace = 1 ;
528 } else {
529 printf("DBAD_PHASE environment variable must be set to 2 or -2 (or 0 for no debug)\n") ;
530 exit(0) ;
531 }
532 dbad_nberrors = 0 ;
533 printf("Starting ADJ test, phase two (fwd), zero=%7.1e, errmax=%4.1f%, seed=%7.1e\n", ezero, errmax, seed) ;
534 printf("===========================================================\n") ;
535 if (dbad_nocommunication) {
536 dbad_file = NULL ;
537 printf("FIFO COMMUNICATION TURNED OFF !\n") ;
538 } else {
539 dbad_file = fopen("/tmp/DBAD_fifo", "r") ;
540 dbad_resetCondensors() ;
541 /* Convention on the meaning of labels:
542 -1 -> a debug point, skipped
543 0 -> a debug point, traced but no associated value.
544 1 -> a debug point, traced, with an associated value.
545 -2 -> a call, skipped
546 2 -> a call, traced
547 */
548 int ret=0 ;
549 int label ;
550 char placename[40] ;
551 double value ;
552 while (1) {
553 ret = fscanf(dbad_file, "%i\n", &label) ;
554 if (ret!=1) break ;
555 ret = fscanf(dbad_file, "%s\n", placename) ;
556 if (label==1) {
557 ret = fscanf(dbad_file, "%lf\n", &value) ;
558 pushreal8(value) ;
559 }
560 pushcharacterarray(placename, 40) ;
561 pushinteger4(label) ;
562 }
563 }
564}
565
566void debug_fwd_call(char *funcname) {
567 int label ;
568 char funcnamefrom[40] ;
569 char funcnamehere[40] ;
570 // In the special debug^2 case, on the 2nd phase (tangent) of the debugAdj, with DBAD_PHASE=0,
571 // push the call frame but do essentially nothing!
572 if (dbad_debughere(0) && !(dbad_nocommunication && dbad_phase==2)) {
573 popinteger4(&label) ;
574 if (label!=2 && label!=-2) {
575 printf("Control mismatch, expecting a trace (-2or2) from %s bwd call exit, got %i\n",funcname,label) ;
576 exit(0) ;
577 }
578 popcharacterarray(funcnamefrom, 40) ;
579 sprintf(funcnamehere,"%s",funcname) ;
580 if (strcmp(funcnamefrom,funcnamehere)!=0) {
581 printf("Control mismatch, expecting a call to %s, got %s\n",funcnamehere,funcnamefrom) ;
582 exit(0) ;
583 }
584 dbad_pushCallFrame(funcname, 0, 0) ;
585 if (label==2) { // then the call is traced:
586 dbad_callStack->deltadepth += (dbad_calltracedepth-1) ;
587 dbad_calltracedepth = 1 ;
588 } else { // then label==-2: the call is not traced:
589 dbad_callStack->deltadepth += dbad_calltracedepth ;
590 dbad_calltracedepth = 0 ;
591 }
592 } else {
593 dbad_pushCallFrame(funcname, 0, 0) ;
594 }
595}
596
597void debug_fwd_exit() {
598 dbad_popCallFrame() ;
599}
600
601int debug_fwd_here(char* placename) {
602 // In the special debug^2 case, on the 2nd phase (tangent) of the debugAdj, with DBAD_PHASE=0,
603 // never go into the derivative manipulation body, except to st the inputs at the very "start"
604 // and to print the result at the very "end".
605 if (dbad_nocommunication && dbad_phase==2) {
606 if (strcmp(placename,"end")==0 || strcmp(placename,"start")==0)
607 return 1 ;
608 else
609 return 0 ;
610 } else {
611 if (dbad_debughere(0)) {
612 int label ;
613 char placenamefrom[40] ;
614 char placenamehere[40] ;
615 dbad_resetCondensors() ;
616 popinteger4(&label) ;
617 if (label!=1 && label!=-1 && label!=0) {
618 printf("Control mismatch, expecting a trace (-1or0or1) from place %s, got %i\n",placename,label) ;
619 exit(0) ;
620 }
621 popcharacterarray(placenamefrom, 40) ;
622 sprintf(placenamehere,"%s",placename) ;
623 if (strcmp(placenamefrom,placenamehere)!=0) {
624 printf("Control mismatch, expecting place %s, got %s\n",placenamehere,placenamefrom) ;
625 exit(0) ;
626 }
627 if (label==1) {
628 popreal8(&dbad_nextrefsum) ;
629 }
630 return label!=-1 ;
631 } else {
632 return 0 ;
633 }
634 }
635}
636
637//############## DEBUG OF ADJOINT, FOR BOTH SWEEPS: ################
638
639void debug_adj_rwreal8(double *vard) {
640 double varb = dbad_nextRandom() ;
641 dbad_condensed_adj += varb*(*vard) ;
642 *vard = varb ;
643}
644
645/** Although at present this routine doesn't modify its argument,
646 * we still expect a reference, just in case, and for consistency
647 * with debug_adj_wreal8() */
648void debug_adj_rreal8(double *vard) {
649 double varb = dbad_nextRandom() ;
650 dbad_condensed_adj += varb*(*vard) ;
651}
652
653void debug_adj_wreal8(double *vard) {
654 *vard = dbad_nextRandom() ;
655}
656
657void debug_adj_rwreal8array(double *vard, int length) {
658 int i ;
659 if (vard)
660 for (i=0 ; i<length ; ++i)
661 debug_adj_rwreal8(&(vard[i])) ;
662}
663
664void debug_adj_rreal8array(double *vard, int length) {
665 int i ;
666 if (vard)
667 for (i=0 ; i<length ; ++i)
668 debug_adj_rreal8(&(vard[i])) ;
669}
670
671void debug_adj_wreal8array(double *vard, int length) {
672 int i ;
673 if (vard)
674 for (i=0 ; i<length ; ++i)
675 debug_adj_wreal8(&(vard[i])) ;
676}
677
678void debug_adj_rwdisplay(char *placename, int indent) {
679 debug_adj_rdisplay(placename, indent) ;
680 if (dbad_phase==2)
681 dbad_refsum = dbad_nextrefsum ;
682}
683
684void debug_adj_rdisplay(char *placename, int indent) {
685 if (dbad_phase==1) {
686 if (dbad_nocommunication) {
687 printf("debugAD would send (1 %s %24.16e)\n", placename, dbad_condensed_adj) ;
688 } else {
689 fprintf(dbad_file, "1\n") ;
690 fprintf(dbad_file, "%s\n", placename) ;
691 fprintf(dbad_file, "%24.16e\n", dbad_condensed_adj) ;
692 }
693 } else if (dbad_phase==2) {
694 // In the special debug^2 case, on the 2nd phase (tangent) of the debugAdj, with DBAD_PHASE=0,
695 // debug_adj_wdisplay is called ony on the "end" location. Print the tangent result:
696 if (dbad_nocommunication) {
697 printf("Condensed tangent result is %24.16e\n", dbad_condensed_adj) ;
698 } else {
699 double absref = (dbad_refsum>=0.0?dbad_refsum:-dbad_refsum) ;
700 double absadj = (dbad_condensed_adj>=0.0?dbad_condensed_adj:-dbad_condensed_adj) ;
701 double absdiff = dbad_refsum - dbad_condensed_adj ;
702 if (absdiff<0.0) absdiff = -absdiff ;
703 double reldiff = (absdiff*200.0)/(absref+absadj) ;
704 if (reldiff>dbad_errormax) {
705 printf(" %5.1f% DIFFERENCE!! tgt:%24.16e adj:%24.16e\n",
706 reldiff, dbad_condensed_adj, dbad_refsum) ;
707 ++dbad_nberrors ;
708 } else if (strcmp(placename,"end")==0 && dbad_nberrors==0) {
709 // When we are at end and no errors were found, always show the compared values
710 printf(" difference is just %7.3f% between tgt:%24.16e and adj:%24.16e\n",
711 reldiff, dbad_condensed_adj, dbad_refsum) ;
712 }
713 if (indent==0) dbad_display_location(placename) ;
714 }
715 }
716 dbad_resetCondensors() ;
717}
718
719void debug_adj_wdisplay(char *placename, int indent) {
720 if (dbad_phase==1) {
721 if (dbad_nocommunication) {
722 printf("debugAD would send (0 %s)\n", placename) ;
723 } else {
724 fprintf(dbad_file, "0\n") ;
725 fprintf(dbad_file, "%s\n", placename) ;
726 }
727 } else if (dbad_phase==2) {
728 if (indent==0) dbad_display_location(placename) ;
729 dbad_refsum = dbad_nextrefsum ;
730 }
731 dbad_resetCondensors() ;
732}
733
734void debug_adj_skip(char *placename) {
735 if (dbad_phase==1 && dbad_debughere(0)) {
736 if (dbad_nocommunication) {
737 printf("debugAD would send (-1 %s)\n", placename) ;
738 } else {
739 fprintf(dbad_file, "-1\n") ;
740 fprintf(dbad_file, "%s\n", placename) ;
741 }
742 }
743}
744
745void debug_adj_conclude() {
746 if (dbad_phase==2) {
747 if (!dbad_nocommunication) {
748 // In the special debug^2 case, on the 2nd phase (tangent) of the debugAdj, with DBAD_PHASE=0,
749 // don't claim that any testing has been done!! but show the expected condensed tangent:
750 printf("End of ADJ test, %i error(s) found.\n", dbad_nberrors) ;
751 printf("===========================================================\n") ;
752 }
753 }
754}
755
756/* void debug_adj_show() { */
757/* printf("Present sum %24.16e, current seed is %f (%f)\n", dbad_condensed_adj, dbad_currentSeed, dbad_seed) ; */
758/* } */
759
760//############## INTERFACE PROCEDURES CALLED FROM FORTRAN ################
761
762void debug_tgt_init_(double *epsilon, double *ezero, double *errmax, double *seed) {
763 debug_tgt_init(*epsilon, *ezero, *errmax, *seed) ;
764}
765
766void debug_tgt_call_(char* unitname, int *deltadepth, int *forcetraced) {
767 debug_tgt_call(unitname, *deltadepth, *forcetraced) ;
768}
769
770void debug_tgt_exit_() {
771 debug_tgt_exit() ;
772}
773
774int debug_tgt_here_(char* placename, int *forcetraced) {
775 return debug_tgt_here(placename, *forcetraced) ;
776}
777
778void debug_tgt_initreal8_(char* varname, double *indep, double *indepd) {
779 debug_tgt_initreal8(varname, indep, indepd) ;
780}
781
782void debug_tgt_initreal8array_(char* varname, double *indep, double *indepd, int *length) {
783 debug_tgt_initreal8array(varname, indep, indepd, *length) ;
784}
785
786void debug_tgt_concludereal8_(char* varname, double *dep, double *depd) {
787 debug_tgt_concludereal8(varname, *dep, *depd) ;
788}
789
790void debug_tgt_concludereal8array_(char* varname, double *dep, double *depd, int *length) {
791 debug_tgt_concludereal8array(varname, dep, depd, *length) ;
792}
793
794void debug_tgt_conclude_() {
795 debug_tgt_conclude() ;
796}
797
798void debug_tgt_real8_(char *varname, double *var, double *vard) {
799 debug_tgt_real8(varname, *var, *vard) ;
800}
801
802void debug_tgt_real8array_(char *varname, double* var, double* vard, int *length) {
803 debug_tgt_real8array(varname, var, vard, *length) ;
804}
805
806void debug_tgt_display_(char *placename) {
807 debug_tgt_display(placename) ;
808}
809
810void debug_bwd_init_(double *ezero, double *errmax, double *seed) {
811 debug_bwd_init(*ezero, *errmax, *seed) ;
812}
813
814void debug_bwd_call_(char *funcname, int *deltadepth) {
815 debug_bwd_call(funcname, *deltadepth) ;
816}
817
818void debug_bwd_exit_() {
819 debug_bwd_exit() ;
820}
821
822int debug_bwd_here_(char* placename) {
823 return debug_bwd_here(placename) ;
824}
825
826void debug_fwd_init_(double *ezero, double *errmax, double *seed) {
827 debug_fwd_init(*ezero, *errmax, *seed) ;
828}
829
830void debug_fwd_call_(char *funcname) {
831 debug_fwd_call(funcname) ;
832}
833
834void debug_fwd_exit_() {
835 debug_fwd_exit() ;
836}
837
838int debug_fwd_here_(char* placename) {
839 return debug_fwd_here(placename) ;
840}
841
842void debug_adj_rwreal8_(double *vard) {
843 debug_adj_rwreal8(vard) ;
844}
845
846void debug_adj_rreal8_(double *vard) {
847 debug_adj_rreal8(vard) ;
848}
849
850void debug_adj_wreal8_(double *vard) {
851 debug_adj_wreal8(vard) ;
852}
853
854void debug_adj_rwreal8array_(double *vard, int *length) {
855 debug_adj_rwreal8array(vard, *length) ;
856}
857
858void debug_adj_rreal8array_(double *vard, int *length) {
859 debug_adj_rreal8array(vard, *length) ;
860}
861
862void debug_adj_wreal8array_(double *vard, int *length) {
863 debug_adj_wreal8array(vard, *length) ;
864}
865
866void debug_adj_rwdisplay_(char *placename, int *indent) {
867 debug_adj_rwdisplay(placename, *indent) ;
868}
869
870void debug_adj_rdisplay_(char *placename, int *indent) {
871 debug_adj_rdisplay(placename, *indent) ;
872}
873
874void debug_adj_wdisplay_(char *placename, int *indent) {
875 debug_adj_wdisplay(placename, *indent) ;
876}
877
878void debug_adj_skip_(char* placename) {
879 debug_adj_skip(placename) ;
880}
881
882void debug_adj_conclude_() {
883 debug_adj_conclude() ;
884}
Note: See TracBrowser for help on using the repository browser.