HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
mytime.c
Go to the documentation of this file.
1 
7 #include "decs.h"
8 
9 
10 
11 
13 int timecheck(int whichlocation, SFTYPE comptstart)
14 {
15  static SFTYPE tlasttime;
16  static long long int nsteplasttime;
17  static long long int startnstep;
18  long long int diffnstep;
19  FTYPE ftemp;
20  FILE* perfout;
21  FILE *fileit;
22  int i,ii;
23  char temps[MAXFILENAME];
24  int numzones,numcompzones;
25  int dostepout;
26  int itemp;
27 
28  FTYPE var_ete,var_wt,var_tuperhr,var_eff,var_fracdiagtime;
29  long long int var_zc,var_tzc;
30 
31  FTYPE var_lete,var_lwt,var_ltuperhr,var_leff,var_lfracdiagtime;
32  long long int var_lzc,var_ltzc;
33 
34 
35  static SFTYPE diagwalltimecumulative=0.0,localdiagwalltimecumulative=0.0;
36  SFTYPE diagwallstep;
37 
39  //
40  // BEGIN TIMING STUFF
41  //
42 #if(TIMEMETHOD==0)
43  static time_t timestart,timestop;
44  static time_t gtimestart,gtimestop,checktime;
45 
46  static time_t diagtimestart,diagtimestop;
47  static time_t diaggtimestart,diaggtimestop;
48 #elif(TIMEMETHOD==1)
49  static struct timeval timestart,timestop, gtimestart,gtimestop,checktime; GETTIMEZONETYPE tz;
50 
51  static struct timeval diagtimestart,diagtimestop, diaggtimestart,diaggtimestop; GETTIMEZONETYPE diagtz;
52 #elif((TIMEMETHOD==2)||(TIMEMETHOD==3))
53  static clock_t timestart,timestop, gtimestart,gtimestop,checktime;
54 
55  static clock_t diagtimestart,diagtimestop, diaggtimestart,diaggtimestop;
56 #endif
57  static SFTYPE walltime=0,walltimelocal=0,walltot=0;
58  // general time reports
59  static clock_t usertmstimestart,usertmstimestop,systmstimestart,systmstimestop;
60  static struct timeval wttimestart,wttimestop;
61 
62  static SFTYPE diagwalltime=0,diagwalltimelocal=0,diagwalltot=0;
63  static clock_t diagusertmstimestart,diagusertmstimestop,diagsystmstimestart,diagsystmstimestop;
64  static struct timeval diagwttimestart,diagwttimestop;
65 #if(TIMEMETHOD!=1)
66  // generic variables for other TIMEMETHOD's in order to avoid #if's below
67  GETTIMEZONETYPE tz;
68 
69  GETTIMEZONETYPE diagtz;
70 #endif
71  // END TIMING STUFF
72  //
74 
75 
76 #if(GETTIMEOFDAYPROBLEM==1)
77  // gettimeofday() needs NULL pointer for second argument on some systems
78  tz=diagtz=NULL;
79 #endif
80 
81 
82  if(myid==0){ // only report time/performance for myid==0
83 
84 
85  if(whichlocation==CHECKTIME || whichlocation==SPEEDTIME || whichlocation==STOPTIME || whichlocation==REPORTTIME){
86  diffnstep=nstep-startnstep;
87  }
88 
89 
90  if(whichlocation==INITSTARTTIME){
91  // SETUP TIME TRACKING for INIT -> COMP
92  // cannot print to ???_file files yet since not yet open
93  GETTIME(&timestart);
94  GETTIME(&gtimestart);
95  microtime(&wttimestart);
96  myustimes2(&usertmstimestart,&systmstimestart);
97  }
98  else if(whichlocation==INITSTOPTIME){
99  // get final time
100  GETTIME(&timestop);
101  microtime(&wttimestop);
102  myustimes2(&usertmstimestop,&systmstimestop);
103 
104  // running average zonecycle rate
105  walltime=(SFTYPE) DELTATIME(timestop,timestart);
106  if(walltime<1E-5) walltime=1E-5;
107 
108  fprintf(logfull_file,"#INIT WTIME: %10.2g\n",walltime*SEC2HOUR);
109 #ifndef WIN32
110  fprintf(logfull_file,"#(sec) INIT walltime: %21.15g usertime: %21.15g systime: %21.15g\n",diffmicrotime(wttimestop,wttimestart),diffmyustimes(usertmstimestop,usertmstimestart),diffmyustimes(systmstimestop,systmstimestart));
111 #endif
112 
113  }
114  else if(whichlocation==STARTTIME){
115  // SETUP TIME TRACKING
116  GETTIME(&timestart);
117  GETTIME(&gtimestart);
118  microtime(&wttimestart);
119  myustimes2(&usertmstimestart,&systmstimestart);
120  startnstep=nstep; // since don't store the above starting times upon restart, but DO restart with correct nstep/realnstep, must offset
121  diffnstep=0;
122  }
123  else if(whichlocation==STOPTIME){
124  // get final time
125  GETTIME(&timestop);
126  microtime(&wttimestop);
127  myustimes2(&usertmstimestop,&systmstimestop);
128  }
129  else if(whichlocation==DIAGSTARTTIME){
130  // SETUP DIAG TIME TRACKING
131  GETTIME(&diagtimestart);
132  GETTIME(&diaggtimestart);
133  microtime(&diagwttimestart);
134  myustimes2(&diagusertmstimestart,&diagsystmstimestart);
135  }
136  else if(whichlocation==DIAGSTOPTIME){
137  // get final (i.e. each diag() call in main.c) diag time
138  GETTIME(&diagtimestop);
139  microtime(&diagwttimestop);
140  myustimes2(&diagusertmstimestop,&diagsystmstimestop);
141 
142  // cumulative wall time for diagnostic
143  diagwallstep = (SFTYPE) DELTATIME(diagtimestop,diagtimestart);
144 
145  // total cumulative for diags
146  diagwalltimecumulative += diagwallstep;
147  // local dumulative for diags (resets every CHECKTIME call)
148  localdiagwalltimecumulative += diagwallstep;
149 
150 
151  }
152  else if(whichlocation==CHECKTIME){
153 
154 
155 
156  // check up on how many timesteps per second so can calibrate period of step, perf, and gocheck
157  if((diffnstep==1)||( (!(diffnstep%NTIMECHECK))) ){
158  // no need to synch cpus since should be close and no MPI calls used so don't require exact synch
159  //just use average time, instead of local time, to do a timestep
160  GETTIME(&checktime);
161  walltime=(SFTYPE) DELTATIME(checktime,timestart);
162  if(walltime<SMALL){
163  dualfprintf(fail_file,"Warning: walltime=%21.15g < %21.15g\n",walltime,SMALL);
164  walltime=SMALL;
165  }
166 
167  // wall time for all diag()
168  diagwalltime=diagwalltimecumulative;
169  if(diagwalltime<SMALL) diagwalltime=SMALL;
170 
171 
172  // now calibrate everything
173  NTIMECHECK=(int)((SFTYPE)(diffnstep)*DTtimecheck/walltime); // took walltime to go nsteps, so check every so steps corresponding to desired time.
174  if(DTstep!=0.0) NDTCCHECK=(int)((SFTYPE)(diffnstep)*DTstep/walltime);
175  if(DTstepdot!=0.0) NDTDOTCCHECK=(int)((SFTYPE)(diffnstep)*DTstepdot/walltime);
176  if(DTperf!=0.0) NZCCHECK=(int)((SFTYPE)(diffnstep)*DTperf/walltime);
177  if(DTgocheck!=0.0) NGOCHECK=(int)((SFTYPE)(diffnstep)*DTgocheck/walltime);
178  if(DTperfdump!=0.0) NDTPERFDUMPCHECK=(int)((SFTYPE)(diffnstep)*DTperfdump/diagwalltime);
179 
180  if(NTIMECHECK<1) NTIMECHECK=1;
181  if(NDTCCHECK<1) NDTCCHECK=1;
182  if(NDTDOTCCHECK<1) NDTDOTCCHECK=1;
183  if(NZCCHECK<1) NZCCHECK=1;
184  if(NGOCHECK<1) NGOCHECK=1;
186 
187  // DEBUG:
188  //stderrfprintf("WALLTIME: %21.15g :: %d %d %d %d %d\n",walltime,NTIMECHECK,NDTCCHECK,NDTDOTCCHECK,NZCCHECK,NGOCHECK);
189 
190  }
191 
192 
193  }
194  else if(whichlocation==SPEEDTIME){
195 
196 
197 
198  // speed check
199  // setup so can plot in sm
200  if(DOLOGPERF&&(!( (diffnstep)%NZCCHECK))){
201  GETTIME(&gtimestop);
202 
203  // running average
204  // wall time for ZCPS running average
205  walltime=(SFTYPE) DELTATIME(gtimestop,timestart);
206  if(walltime<SMALL) walltime=SMALL;
207 
208  // wall time for local zonecycle
209  walltimelocal=(SFTYPE) DELTATIME(gtimestop,gtimestart);
210  if(walltimelocal<SMALL) walltimelocal=SMALL;
211 
212  // wall time for all diag()
213  diagwalltime=(SFTYPE) (diagwalltimecumulative);
214  if(diagwalltime<SMALL) diagwalltime=SMALL;
215 
216  // local wall time for all diag()
217  diagwalltimelocal=(SFTYPE) (localdiagwalltimecumulative);
218  if(diagwalltimelocal<SMALL) diagwalltimelocal=SMALL;
219 
220 
221  for(i=1;i<=1;i++){ // don't really want perf for i==0
222  if(i==0){
223  fileit=log_file;
224  dostepout=1;
225  numzones=N1*N2*N3; // GODMARK not really right, but not used
226  numcompzones=numzones;
227  }
228  else if(i==1){
229  fileit=logperf_file;
230  dostepout=1;
231  numzones=realtotalzones;
232  numcompzones=realtotalcompzones;
233  }
234  if(dostepout){
235 
236  var_ete=((tf-t+1.0E-6)/(t-comptstart+1.0E-6)*walltime*SEC2HOUR);
237  var_wt=walltime*SEC2HOUR;
238  var_zc=(int)((FTYPE)(numzones)*(FTYPE)(diffnstep)/walltime);
239  var_tzc=(int)((FTYPE)(numcompzones)*(FTYPE)(diffnstep)/walltime);
240  var_tuperhr=((t-comptstart)/(walltime*SEC2HOUR));
241  var_eff=var_zc/((FTYPE)(numprocs)*ZCPSESTIMATE); // estimate only as good as estimate of ZCPSESTIMATE
242  // fraction of time taken by diagnostics
243  var_fracdiagtime = diagwalltime/walltime;
244 
245  var_lete=((tf-t+1.0E-6)/(t-tlasttime+1.0E-6)*walltimelocal*SEC2HOUR);
246  var_lwt=walltimelocal*SEC2HOUR;
247  var_lzc=(int)((FTYPE)(numzones)*(FTYPE)(NZCCHECK)/walltimelocal);
248  var_ltzc=(int)((FTYPE)(numcompzones)*(FTYPE)(NZCCHECK)/walltimelocal);
249  var_ltuperhr=((t-tlasttime)/(walltimelocal*SEC2HOUR));
250  var_leff=var_lzc/((FTYPE)(numprocs)*ZCPSESTIMATE); // estimate only as good as estimate of ZCPSESTIMATE
251  // fraction of time taken by diagnostics
252  var_lfracdiagtime = diagwalltimelocal/walltimelocal;
253 
254  myfprintf(fileit,"#t ete n wt zc tzc tu/hr Eff FracDiag lete ln lwt lzc ltzc ltu/hr lEff lFracDiag \n");
255  myfprintf(fileit,"%15.10g %15.10g %10ld %15.10g %10lld %10lld %10.5g %10.5g %10.5g"
256  " %15.10g %5d %15.10g %10lld %10lld %10.5g %10.5g %10.5g\n"
257  ,t
258  ,var_ete
259  ,nstep
260  ,var_wt
261  ,var_zc
262  ,var_tzc
263  ,var_tuperhr
264  ,var_eff
265  ,var_fracdiagtime
266 
267  ,var_lete
268  ,NZCCHECK
269  ,var_lwt
270  ,var_lzc
271  ,var_ltzc
272  ,var_ltuperhr
273  ,var_leff
274  ,var_lfracdiagtime
275  );
276 
277 
278  // factor by which diagnostics time should be smaller compared to non-diagnostic time
279  // For example, if choose 10.0, then diagnostics should only eat up to 10% of non-diagnostic time.
280  // This ensures that report only when diagnostics drop performance by more than 10% (just a reported fact, not a dynamically controlled feature!)
281  // Note that this only accounts for full diag() call, but not diag_flux or diag_source*. Wouldn't want to time those since timing operations would be too expensive for ACCURATE versions of those calls that are done per i,j,k.
282 #define DIAGFACTOR (10.0)
283 
284  for(ii=0;ii<NUMDUMPTYPES;ii++){
285  // Compute how many seconds, below which if logging is taking place could impact performance and so is reported to user in the perf file
286  // Compute total wall time for non-diagnostic computations: (walltimelocal-diagwalltimelocal)
287  // Then compare that to time taken by diagnostics: diagwalltimelocal
288  // Then divide by internal of checks and interval of corresponding diagnostics to see if overall will be a problem
289  // So compute: walltime(to do step without diagnostics)/dt << walltime(to do dump)/Dt
290  if(ii!=FAKEDUMPTYPE){ // ignore fake dump
291  if(ii!=RESTARTDUMPTYPE && ii!=RESTARTMETRICDUMPTYPE){// then time-based
292  if((walltimelocal-diagwalltimelocal)/(t-tlasttime) < DIAGFACTOR*diagwalltimelocal/DTdumpgen[ii]){
293  // output to perf file if that log is impacting performance
294  myfprintf(fileit,"#LOGDIAG(DTbased)!: %d : %21.15g\n",ii,diagwalltimelocal*(t-tlasttime)/(DTdumpgen[ii])/(walltimelocal-diagwalltimelocal));
295  }
296  }
297  else{// then step based
298  if((walltimelocal-diagwalltimelocal)/((FTYPE)(nstep-nsteplasttime)) < DIAGFACTOR*diagwalltimelocal/DTr){
299  // output to perf file if that log is impacting performance
300  myfprintf(fileit,"#LOGDIAG(nstepbased)!: %d : %21.15g\n",ii,diagwalltimelocal*((FTYPE)(nstep-nsteplasttime))/((FTYPE)DTr)/(walltimelocal-diagwalltimelocal));
301  }
302  }
303  }
304  }
305  // Below checks if instantaneous impact on performance (which can be ok integrated over long times as estimated by above)
306  if((walltimelocal-diagwalltimelocal) < DIAGFACTOR*diagwalltimelocal){
307  myfprintf(fileit,"#INSTANTLOGDIAG!\n");
308  }
309  // Also check total times
310  if((walltime-diagwalltime) < DIAGFACTOR*diagwalltime){
311  myfprintf(fileit,"#GLOBALLOGDIAG!\n");
312  }
313 
314  }
315  }
316  GETTIME(&gtimestart); // this restarts walltimelocal count
317  localdiagwalltimecumulative=0.0; // resets local cumulative wall time for diagnostics
318  tlasttime=t;
319  nsteplasttime=nstep;
320  }// end if output speed
321 
322 
323  if(PERFTEST){
324  GETTIME(&checktime);
325  walltime=(SFTYPE) DELTATIME(checktime,timestart);
326  if(walltime<1E-5) walltime=1E-5;
327  // setup so each turn is about the same WALLtime
328  //itemp=(int)((SFTYPE)((SFTYPE)PERFWALLTIME/(walltime/(SFTYPE)(diffnstep))));
329  // setup so each turn is same as estimated time and speed, but fixed timesteps for all runs: best for benchmark if you know ahead of time ZCPSESTIMATE, and use same value of this across all tests
330  itemp=(int)((SFTYPE)(PERFWALLTIME*ZCPSESTIMATE) /( (SFTYPE)realtotalzones) );
331  // fprintf(stdout,"itemp: %d PWT: %d ZCPS: %d realtotalzones: %d\n",itemp,PERFWALLTIME,ZCPSESTIMATE,realtotalzones);
332  if(itemp<1) itemp=1;
333  // set final time so steps to desired # of steps
334  tf=1.0*(SFTYPE)(itemp)/(SFTYPE)(diffnstep)*t;
335  stderrfprintf("PERFTEST: nstep=%ld/%d t=%15.10g/%15.10g wt=%15.10g/%15.10g\n",nstep,itemp,t,tf,walltime,(SFTYPE)itemp*(SFTYPE)walltime/(SFTYPE)nstep); fflush(stderr);
336 
337  // if(itemp>1000) itemp=1000;
338  if(diffnstep==itemp) reallaststep=1;
339  if(walltime>PERFWALLTIME) reallaststep=1;
340  // GODMARK(commented)
341  //if(diffnstep==100) reallaststep=1;
342  }
343  // GODMARK(commented)
344  // if(diffnstep==1) reallaststep=1;
345 
346 
347 
348 
349  }
350 
351 
352 
353  else if(whichlocation==REPORTTIME){
354 
355 
356 
357  if(PERFTEST){
358  sprintf(temps,"%sfinalperf%s",DATADIR,".txt") ;
359  if(!(perfout=fopen(temps,"at"))){
360  dualfprintf(fail_file,"Can't open %s\n",temps);
361  exit(1);
362  }
363  stderrfprintf( "opened: %s\n", temps);
364  }
365 
366 
367  // running average zonecycle rate
368  walltime=(SFTYPE) DELTATIME(timestop,timestart);
369  if(walltime<1E-5) walltime=1E-5;
370 
371 
372  fprintf(logfull_file,"#allproc: steps: %10ld wtime: %10.2g tzcycles: %10d t: %10.2g\n",nstep,walltime*SEC2HOUR,(int)((FTYPE)(realtotalzones)*(FTYPE)diffnstep/walltime),(t-comptstart)) ;
373 #ifndef WIN32
374  fprintf(logfull_file,"#(sec) walltime: %21.15g usertime: %21.15g systime: %21.15g\n",diffmicrotime(wttimestop,wttimestart),diffmyustimes(usertmstimestop,usertmstimestart),diffmyustimes(systmstimestop,systmstimestart));
375 #endif
376  stderrfprintf("#(sec) walltime: %21.15g usertime: %21.15g systime: %21.15g\n",diffmicrotime(wttimestop,wttimestart),diffmyustimes(usertmstimestop,usertmstimestart),diffmyustimes(systmstimestop,systmstimestart));
377 
378  if(DOLOGPERF){
379  myfprintf(logperf_file,"#done: steps: %10ld wtime: %10.2g tzcycles: %10d t: %10.2g tu/hour: %10.5g\n",nstep,walltime*SEC2HOUR,(int)((FTYPE)(realtotalzones)*(FTYPE)diffnstep/walltime),(t-comptstart),(t-comptstart)/(walltime*SEC2HOUR)) ;
380  }
381  if(PERFTEST){
382  myfprintf(perfout,"%10d\n",(int)((FTYPE)(realtotalzones)*(FTYPE)diffnstep/walltime)) ;
383  myfprintf(stderr,"perf: N3: %d N2: %d N1: %d RTZ: %d tZCPS: %d steps: %ld walltime: %15.10g\n",N3,N2,N1,realtotalzones,(int)((FTYPE)(realtotalzones)*(FTYPE)diffnstep/walltime),nstep,walltime) ;
384  fclose(perfout);
385  }
386  if(DOLOGSTEP){
387  myfprintf(logstep_file,"#done: steps: %10ld wtime: %10.2g tzcycles: %10d t: %10.2g\n",nstep,walltime*SEC2HOUR,(int)((FTYPE)(realtotalzones)*(FTYPE)diffnstep/walltime),(t-comptstart)) ;
388  }
389 
390  }
391  }// end if myid==0
392 
393 
394 
395  // global parameters of importance to all CPUs
396 #if(USEMPI)
397  if(whichlocation==SPEEDTIME && PERFTEST){
398  MPI_Bcast(&reallaststep,1,MPI_INT,MPIid[0], MPI_COMM_GRMHD);
399  }
400 #endif
401 
402  return(0);
403 
404 }
405 
406 
407 
408 
409 void mycpuclock(clock_t *time)
410 {
411  *time=clock();
412 }
413 
414 #ifndef WIN32
415 void myustimes(clock_t *time) // returns number of microseconds
416 {
417  struct tms mytimes;
418  clock_t ret;
419  long clockspersecond;
420 
421  clockspersecond=sysconf(_SC_CLK_TCK);
422  ret=times(&mytimes);
423  *time=(clock_t) (1000000.0*(SFTYPE)(mytimes.tms_utime+mytimes.tms_stime+mytimes.tms_cutime+mytimes.tms_cstime)/(SFTYPE)clockspersecond );
424 }
425 void myustimes2(clock_t *usertime,clock_t *systime) // returns number of microseconds
426 {
427  struct tms mytimes;
428  clock_t ret;
429  long clockspersecond;
430 
431  clockspersecond=sysconf(_SC_CLK_TCK);
432  ret=times(&mytimes);
433  *usertime=(clock_t) (1000000.0*(SFTYPE)(mytimes.tms_utime+mytimes.tms_stime)/(SFTYPE)clockspersecond );
434  *systime=(clock_t) (1000000.0*(SFTYPE)(mytimes.tms_cutime+mytimes.tms_cstime)/(SFTYPE)clockspersecond );
435 }
436 #else
437 void myustimes(clock_t *time) // returns number of microseconds
438 {
439 }
440 void myustimes2(clock_t *usertime,clock_t *systime) // returns number of microseconds
441 {
442 }
443 #endif
444 
445 
446 
447 #ifdef WIN32
448 
449 int gettimeofday(struct timeval *tv, struct timezone *tz)
450 {
451  FILETIME ft;
452  unsigned __int64 tmpres = 0;
453  static int tzflag;
454  if (NULL != tv)
455  {
456  GetSystemTimeAsFileTime(&ft);
457  tmpres |= ft.dwHighDateTime;
458  tmpres <<= 32;
459  tmpres |= ft.dwLowDateTime;
460  /*converting file time to unix epoch*/
461  tmpres /= 10; /*convert into microseconds*/
462  tmpres -= DELTA_EPOCH_IN_MICROSECS;
463  tv->tv_sec = (long)(tmpres / 1000000UL);
464  tv->tv_usec = (long)(tmpres % 1000000UL);
465  }
466  if (NULL != tz)
467  {
468  if (!tzflag)
469  {
470  _tzset();
471  tzflag++;
472  }
473  tz->tz_minuteswest = _timezone / 60;
474  tz->tz_dsttime = _daylight;
475  }
476  return 0;
477 }
478 
479 #endif
480 
481 
482 
483 
484 
485 
486 
490 int output_steptimedt_info(SFTYPE comptstart)
491 {
492  int i;
493  FILE *fileit;
494  int dostepout;
495  FTYPE strokecount;
496 
497  if(myid==0){ // only output step/dt info for myid==0
498 
499  if(DOLOGSTEP&&( (!(nstep%NDTDOTCCHECK)) )){
500  myfprintf(logstep_file,".");
501  }
502  // GODMARK: comptstart was tstart in pnmhd code
503  if(DOLOGSTEP&&( (!(nstep%NDTCCHECK))||(t>=tf-1.0E-7)||(t<=comptstart+1.0E-7) ) ){
504  myfprintf(logstep_file,"\n");
505  for(i=1;i<=1;i++){ // ==0 and ==2 not done since really not needed
506  if(i==0){
507  fileit=log_file;
508  dostepout=1;
509  strokecount=1.0*nstroke/(2.0*N1*N2);
510  }
511  else if(i==1){
512  fileit=logstep_file;
513  dostepout=1;
514  strokecount=1.0*nstroke/(2.0*realtotalzones);
515  }
516  else if(i==2){
517  fileit=stderr;
518  dostepout=1;
519  strokecount=1.0*nstroke/(2.0*realtotalzones);
520  }
521 
522  if(dostepout){
523  myfprintf(fileit,"#t dt cour nstep realnstep strokeperzone:\n"
524  "%21.15g %21.15g %21.15g %8ld %8ld %21.15g\n", t, dt, cour, nstep, realnstep,strokecount );
525 
526  if(i==1) myfprintf(fileit,"#"); // for "." to be commented in SM
527  }
528  }// end over files
529  }// end if outputting
530  }
531 
532  return(0);
533 }
534