HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
dumpgen.c
Go to the documentation of this file.
1 #include "decs.h"
2 
10 
11 
12 int dump_gen(int readwrite, long dump_cnt, int bintxt, int whichdump, MPI_Datatype datatype, char *fileprefix, char *fileformat, char *filesuffix, int (*headerfun) (int whichdump, int whichdumpversion, int numcolumns, int bintxt, FILE*headerptr),int (*setgetcontent) (int i, int j, int k, MPI_Datatype datatype, void*setbuf))
13 {
14  int i = 0, j = 0, k = 0, l = 0, col = 0;
15  FILE **fpp;
16  char dfnam[MAXFILENAME]={'\0'};
17  char dfnamreal[MAXFILENAME]={'\0'};
18  char localfileformat[MAXFILENAME]={'\0'};
19  void *jonio;
20  static void *writebuf; // must be static so ROMIO non-blocking has permenant pointer address for this
21  char truemyidtxt[MAXFILENAME]={'\0'};
22  char filerw[MAXFILENAME]={'\0'};
23  FILE *headerptr;
24  int numfiles,coliter;
25  void *setbuf;
26  int sizeofdatatype;
27  int romiocloopend;
28  int headerbintxt;
29  int dumpbintxt;
30  fpos_t headerendpos;
31  long int uptodatabytesize;
32  int binextension;
33  int checkstatus;
34  int gopastlinebreak(FILE *stream);
35  int whichdumpversion;
36 
37 
38 
39  // see if want to only do ROMIO finish-up when doing MPIVERSION>=2
40  if(whichdump==FAKEDUMPTYPE){
41  // only writebufptr and which realy used, so just ignore other values
42  // -1 indicates separate finish romio call, so that next call to mpiio_final() will not think some new file is ready to be finished.
43  mpiio_final(0, 0, NULL, 0, MPICOMBINEROMIO, NULL, -1, 0, NULL, &writebuf);
44  // done with finishing-up prior ROMIO combine if using ROMIO
45  return(0);
46  }
47 
48 
50  //
51  // setup file format for header and dump
52  //
54 
55  if(readwrite==READFILE){
56  strcpy(filerw,"rb"); //atch
57  //if(bintxt==BINARYOUTPUT)
58  //else strcpy(filerw,"rt");
59  }
60  else if(readwrite==WRITEFILE){
61  strcpy(filerw,"wb"); //atch
62  //if(bintxt==BINARYOUTPUT) strcpy(filerw,"w");
63  //else strcpy(filerw,"wt");
64  }
65 
66  if(bintxt==BINARYOUTPUT) headerbintxt=dumpbintxt=BINARYOUTPUT;
67  else if(bintxt==TEXTOUTPUT) headerbintxt=dumpbintxt=TEXTOUTPUT;
68  else if(bintxt==MIXEDOUTPUT){
69  headerbintxt=TEXTOUTPUT;
70  dumpbintxt=BINARYOUTPUT;
71  }
72 
73 
74 
75  numcolumns=dnumcolumns[whichdump];
76  whichdumpversion=dnumversion[whichdump];
77  docolsplit=DOCOLSPLIT[whichdump]; // docolsplit global var for now
78 
79 
81  //
82  // See if enough HD space
83  //
85 
86  if(mpicombine){
87  if(dumpbintxt==BINARYOUTPUT){
88  if(myid==0) isenoughfreespace((unsigned long long)(sizeof(FTYPE))*(unsigned long long)numcolumns*(unsigned long long)(totalsize[1])*(unsigned long long)(totalsize[2])*(unsigned long long)(totalsize[3]) );
89  else isenoughfreespace(0);
90  }
91  else{// text
92  if(myid==0) isenoughfreespace((unsigned long long)(22)*(unsigned long long)numcolumns*(unsigned long long)(totalsize[1])*(unsigned long long)(totalsize[2])*(unsigned long long)(totalsize[3]) );
93  else isenoughfreespace(0);
94  }
95  }
96  else{
97  if(dumpbintxt==BINARYOUTPUT){
98  isenoughfreespace((unsigned long long)(sizeof(FTYPE))*(unsigned long long)numcolumns*(unsigned long long)(N1)*(unsigned long long)(N2)*(unsigned long long)(N3) );
99  }
100  else{// text
101  isenoughfreespace((unsigned long long)(21)*(unsigned long long)numcolumns*(unsigned long long)(N1)*(unsigned long long)(N2)*(unsigned long long)(N3) );
102  }
103  }
104 
105 
107  //
108  // Allocate memory for setting up setbuf
109  //
111 
112  sizeofdatatype=getsizeofdatatype(datatype);
113  setbuf=malloc(numcolumns*sizeofdatatype);
114  if(setbuf==NULL){
115  dualfprintf(fail_file,"cannot allocate memory to setbuf in %s %s with numcolumns=%d and sizeofdatatype=%d\n",fileprefix,filesuffix,numcolumns,sizeofdatatype);
116  myexit(927656247);
117  }
118 
119 
120  // trifprintf("numcolumns=%d sizeofdatatype=%d setbuf=%d total=%d\n",numcolumns,sizeofdatatype,setbuf,numcolumns*sizeofdatatype);
121 
123  //
124  // Set up DOCOLSPLIT for normal and ROMIO loop
125  //
127 
128 
129 
130  if(docolsplit){
131  numfiles=numcolumns;
132  if(mpicombine&&USEMPI&&USEROMIO) romiocloopend=numfiles;
133  else romiocloopend=1;
134  }
135  else{
136  numfiles=1;
137  romiocloopend=1;
138  }
139 
140 
142  //
143  // Define file output and open it
144  //
146 
147  // say whether .bin is allowed or not if binary
148  if(fileprefix[0]=='i') binextension=0; // images don't need binary extension
149  else binextension=1;
150 
151 
152  // sometimes all CPUs need to know filename (e.g. ROMIO)
153  // setup file suffix
154  if((dumpbintxt==BINARYOUTPUT)&&(binextension)){
155  if(USEMPI&&(mpicombine==0)&&(numprocs>1)) sprintf(truemyidtxt,".bin.%04d",myid);
156  else strcpy(truemyidtxt,".bin");
157  }
158  else{
159  if(USEMPI&&(mpicombine==0)&&(numprocs>1)) sprintf(truemyidtxt,".%04d",myid);
160  else strcpy(truemyidtxt,"");
161  }
162 
163  // setup filename
164  if(dump_cnt>=0){
165  strcpy(localfileformat,"%s");
166  strcat(localfileformat,fileformat);
167  strcat(localfileformat,"%s");
168  strcat(localfileformat,"%s");
169  sprintf(dfnam, localfileformat, fileprefix, dump_cnt, filesuffix, truemyidtxt);
170  }
171  else{ // then no file number wanted (i.e. for gdump())
172  sprintf(dfnam, "%s%s%s", fileprefix, filesuffix, truemyidtxt);
173  }
174 
175 
176 
178  //
179  // open files, or open files for header if mpicombine==1, which for mpicombine==1 gets reopened later by MPI routines
180  //
182 
183  checkstatus=0; // no error so far
184  int problemloadingfile=0;
185  if((USEMPI&&(myid==0)&&(mpicombine==1))||(mpicombine==0)){// for mpicombine==1 even with ROMIO, real filename and header not needed
186 
187  // only one CPU does header if mpicombine==1, header+dump done in all CPUs if mpicombine==0
188  // create files for each column, or each column's header if mpicombine==1
189  if((fpp=(FILE**)malloc(sizeof(FILE*)*numfiles))==NULL){
190  dualfprintf(fail_file,"couldn't open fpp in dump()\n");
191  myexit(836565474);
192  }// now fpp[i] indexes a list of file pointers
193 
194 
195  // setup each file corresponding to each column
196  COLLOOP(coliter){
197  if(docolsplit&&(numfiles>1)){
198  sprintf(dfnamreal,"%s-col%04d",dfnam,coliter);
199  }
200  else strcpy(dfnamreal,dfnam);
201 
202  if ((fpp[coliter] = fopen(dfnamreal, filerw)) == NULL) {
203  dualfprintf(fail_file, "error opening %s %s (fullname=%s) file\n",fileprefix,filesuffix,dfnamreal);
204  dualfprintf(fail_file, "Check if disk full or have correct permissions\n");
205  problemloadingfile=1;
206  }
207  }// end COLLOOP
208  }// end if myid or mpicombine==0 (split the loop so that can check for file existence first)
209 
210 
211  // need to broadcast whether got all files or had problem
212 #if(USEMPI)
213  MPI_Bcast(&problemloadingfile,1,MPI_INT,MPIid[0], MPI_COMM_GRMHD);
214 #endif
215  if(problemloadingfile){
216  // indicate failure, but one may wish to set some defaults if no file, so don't hard fail.
217  return(FILENOTFOUND);
218  }
219 
220 
221 
222  checkstatus=0; // no error so far
223  if((USEMPI&&(myid==0)&&(mpicombine==1))||(mpicombine==0)){// for mpicombine==1 even with ROMIO, real filename and header not needed
224  // setup each file corresponding to each column
225  COLLOOP(coliter){
226 
228  //
229  // read or write header: header is read/written in whatever style chosen to the top of each dump file created
230  //
232  if(headerfun!=NULL){
233  headerfun(whichdump,whichdumpversion,numcolumns,headerbintxt,fpp[coliter]); // outputs header to each column file (or just one file, or all CPU files, etc.)
234  }
235 
237  //
238  // check that file one is reading is in right format (no need to check writing format)
239  // assumed puts stream back to location before entered function
240  //
242  if(readwrite==READFILE){
243  checkstatus=check_fileformat(readwrite, bintxt, whichdump, numcolumns, docolsplit, mpicombine, sizeofdatatype, fpp[coliter]);
244  }
245 
246  // deal with transition between header and data
247  if(readwrite==READFILE){
248  if(bintxt==TEXTOUTPUT || bintxt==MIXEDOUTPUT){
249  if(headerfun!=NULL){
250  // now move past \n
251  if(gopastlinebreak(fpp[coliter])) checkstatus=1;
252  }
253  }
254  }
255  // get position that would start real data
256  uptodatabytesize=ftell(fpp[coliter]);
257 
258 
259  }
260 
261  // don't close if mpicombine==0, since used in a moment, else mpicombine==1 it's reopened by MPI routines
262  if(USEMPI&&(myid==0)&&(mpicombine==1)) COLLOOP(coliter) fclose(fpp[coliter]); // will get reopened later by MPI routines
263 
264 
265  }
266 
267 
268 
269  // need to broadcast the header size to other CPUs for ROMIO
270 #if(USEMPI&&USEROMIO)
271  MPI_Bcast(&uptodatabytesize,1,MPI_LONG,MPIid[0], MPI_COMM_GRMHD);
272 #endif
273 
274 
276  //
277  // Check file format status
278  //
279  //
281  if(failed==0) failed=checkstatus;
282  error_check(ERRORCODEBELOWCLEANFINISH+100); // number should be >ERRORCODEBELOWCLEANFINISH for myexit to avoid dumping
283 
284 
285 
286 
288  //
289  // loop over columns for per-column buffer ROMIO dump
290  //
291  //
293 
294 
295  ROMIOCOLLOOP(romiocoliter) { // only loop if mpicombine&&USEMPI&&USEROMIO&&docolsplit==1
296  if(romiocloopend>1) trifprintf("romiocoliter=%d of romiocloopend=%d\n",romiocoliter,romiocloopend);
297 
298 
299 
300  // setup MPI buffer if mpicombine==1
301  if( mpicombine == 0 ) { // then one file per CPU if USEMPI or just normal file writing on 1CPU
302  writebuf=NULL;
303  }
304  else mpiio_init(dumpbintxt,sortedoutput, fpp, uptodatabytesize, readwrite, dfnam, numcolumns, datatype, &jonio, &writebuf);
305  // if USEROMIO==1 then numcolumns interpreted properly for docolsplit
306 
307 
308  if(readwrite==READFILE){
310  //
311  // read DUMP
312  //
314 
315  if (mpicombine == 1) {
316 #if(USEMPI)
317  mpiio_seperate(binaryoutput,sortedoutput, STAGE1, numcolumns, datatype, fpp, jonio, writebuf);
318 #endif
319  }
320  }
321 
322 
323 
325  //
326  // DUMP LOOP
327  //
329 
330 
331 
332  if(readwrite==READFILE){
333  BUFFERINIT0;
334  DUMPGENLOOP { // diagnostic loop
335  // buffer init starts the parallel index
336  BUFFERINIT;
337  // initialize to 0th column
338  COLINIT;
339 
341  //
342  // READFILE
343  //
345  if((mpicombine)&&(truempicombinetype==MPICOMBINEMINMEM)) mpiio_minmem(READFILE,whichdump,i,j,k,dumpbintxt,sortedoutput,numcolumns,datatype, fpp,jonio,writebuf);
346 
347 
348  // read all at once
349  myfread(dumpbintxt,datatype,setbuf,0,numcolumns,i,j,k,fpp,writebuf);
350 
351  // check
352  if(nextbuf!=numcolumns){
353  dualfprintf(fail_file,"Number of columns (numcolumns=%d) isn't equal to number of columns/buffers attempted (nextbuf=%lld)\n",numcolumns,nextbuf);
354  myexit(932736466);
355  }
356 
357  // get the content of 1 row
358  setgetcontent(i,j,k,datatype,setbuf);
359 
360  // check
361  if(nextcol!=numcolumns){
362  dualfprintf(fail_file,"Number of columns (numcolumns=%d) isn't equal to number of columns attempted (nextcol=%d)\n",numcolumns,nextcol);
363  myexit(836745613);
364  }
365  }// end DUMPGENLOOP
366  }// end readwrite==READFILE
367  else if(readwrite==WRITEFILE){
368  BUFFERINIT0;
369  DUMPGENLOOP { // diagnostic loop
370 
371 
372 
373  // buffer init starts the parallel index
374  BUFFERINIT;
375  // initialize to 0th column
376  COLINIT;
378  //
379  // WRITEFILE
380  //
382 
383  // set the content of 1 row
384  setgetcontent(i,j,k,datatype,setbuf);
385 
386  // check
387  if(nextcol!=numcolumns){
388  dualfprintf(fail_file,"Number of columns (numcolumns=%d) isn't equal to number of columns attempted (nextcol=%d)\n",numcolumns,nextcol);
389  myexit(19785566);
390  }
391 
392  // write all at once
393  myfwrite(dumpbintxt,datatype,setbuf,0,numcolumns,i,j,k,fpp,writebuf);
394 
395 
396  // check
397  if(nextbuf!=numcolumns){
398  dualfprintf(fail_file,"Number of columns (numcolumns=%d) isn't equal to number of columns/buffers attempted (nextbuf=%d)\n",numcolumns,nextbuf);
399  myexit(94675455);
400  }
401 
402 
403  // finish up this row
404  if((mpicombine==0)&&(dumpbintxt==TEXTOUTPUT)) COLLOOP(coliter) fprintf(fpp[coliter],"\n");
405  if((mpicombine)&&(truempicombinetype==MPICOMBINEMINMEM)) mpiio_minmem(WRITEFILE,whichdump,i,j,k,dumpbintxt,sortedoutput,numcolumns,datatype, fpp, jonio,writebuf);
406 
407 
408 
409  }// end DUMPGENLOOP
410  }//end readwrite==WRITEFILE
411 
412 
413 
414 
416  //
417  // Close dump file and write/close file if mpicombine==1
418  //
420 
421 
422  if (mpicombine == 0){
423  COLLOOP(coliter) if (fpp[coliter] != NULL) fclose(fpp[coliter]);
424  }
425  else{
426 #if(USEMPI)
427  if(readwrite==WRITEFILE) mpiio_combine(dumpbintxt, sortedoutput, numcolumns, datatype, fpp, jonio, writebuf);
428  else if(readwrite==READFILE) mpiio_seperate(binaryoutput,sortedoutput, STAGE2, numcolumns, datatype, fpp, jonio, writebuf);
429 #endif
430  }
431 
432  }// end column loop for ROMIO&&docolsplit
433 
434 
435 
436  // free the set/get buffer
437  if(setbuf!=NULL) free(setbuf);
438 
439 
440 
441  return (0);
442 }
443 
444 
445 
446 
447 
448 
449 
450 
451 
480 int header1_gen(int accessmemory, int readwrite, int bintxt, int bcasthead, void *ptr, size_t size, char *format, size_t nmemb, MPI_Datatype datatype, FILE *stream)
481 {
482  void *ptrlocal;
483  //
484  unsigned char *ptr1;
485  float *ptr4;
486  double *ptr8;
487  long double *ptr16;
488  int *ptr4i;
489  long *ptr4l;
490  long long int *ptr8i;
491  //
492  unsigned char var1;
493  float var4;
494  double var8;
495  long double var16;
496  int var4i;
497  long var4l;
498  long long int var8i;
499  //
500  char formatwithspace[MAXFILENAME]; // really format length, not file name
501  size_t ii;
502  char largedumbspace[200]; // GODMARK: Should be larger than long doubles
503  int jj;
504 
505 
506  if(accessmemory){
507  ptrlocal=ptr;
508  }
509  else{
510 
511  // emulates argument passing to this function through assignment of pointers
512  var1=0;
513  var4=0.0;
514  var8=0.0;
515  var16=0.0;
516  var4i=0;
517  var4l=0;
518  var8i=0;
519 
520  if (datatype == MPI_UNSIGNED_CHAR) ptrlocal = (unsigned char *) &var1;
521  else if (datatype == MPI_FLOAT) ptrlocal = (float *) &var4;
522  else if (datatype == MPI_DOUBLE) ptrlocal = (double *) &var8;
523  else if (datatype == MPI_LONG_DOUBLE) ptrlocal = (long double *) &var16;
524  else if (datatype == MPI_INT) ptrlocal = (int *) &var4i;
525  else if (datatype == MPI_LONG) ptrlocal = (long *) &var4l;
526  else if (datatype == MPI_LONG_LONG_INT) ptrlocal = (long long int *) &var8i;
527  else{
528  dualfprintf(fail_file,"No such datatype=%d\n",datatype);
529  myexit(76293623);
530  }
531 
532  }
533 
534 
535 
537  //
538  // resolve data type as necessary for fprintf
539  //
541  if (datatype == MPI_UNSIGNED_CHAR) ptr1 = (unsigned char *) ptrlocal;
542  else if (datatype == MPI_FLOAT) ptr4 = (float *) ptrlocal;
543  else if (datatype == MPI_DOUBLE) ptr8 = (double *) ptrlocal;
544  else if (datatype == MPI_LONG_DOUBLE) ptr16 = (long double *) ptrlocal;
545  else if (datatype == MPI_INT) ptr4i = (int *) ptrlocal;
546  else if (datatype == MPI_LONG) ptr4l = (long *) ptrlocal;
547  else if (datatype == MPI_LONG_LONG_INT) ptr8i = (long long int *) ptrlocal;
548  else{
549  dualfprintf(fail_file,"No such datatype=%d\n",datatype);
550  myexit(76293623);
551  }
552 
553 
554 
555 
556  if(readwrite==READHEAD){
557 
558  if(bintxt==BINARYOUTPUT){
559  if(accessmemory) fread(ptrlocal,size,nmemb,stream);
560  else{
561  for(ii=0;ii<nmemb;ii++){
562  fread(ptrlocal,size,1,stream); // just repeatedly fill same dummy space
563  }
564  }
565  }
566  else if(bintxt==TEXTOUTPUT || bintxt==MIXEDOUTPUT){
567 
568  for(ii=0;ii<nmemb;ii++){
569 
570  if(accessmemory) jj=ii;
571  else jj=0; // repeatedly read into same dummy space
572 
573  if (datatype == MPI_UNSIGNED_CHAR) fscanf(stream,format,&ptr1[jj]);
574  else if (datatype == MPI_FLOAT) fscanf(stream,format,&ptr4[jj]);
575  else if (datatype == MPI_DOUBLE) fscanf(stream,format,&ptr8[jj]);
576  else if (datatype == MPI_LONG_DOUBLE) fscanf(stream,format,&ptr16[jj]);
577  else if (datatype == MPI_INT) fscanf(stream,format,&ptr4i[jj]);
578  else if (datatype == MPI_LONG) fscanf(stream,format,&ptr4l[jj]);
579  else if (datatype == MPI_LONG_LONG_INT) fscanf(stream,format,&ptr8i[jj]);
580  else{
581  dualfprintf(fail_file,"No such datatype=%d\n",datatype);
582  myexit(40968321);
583  }
584  }
585  }
586  else{
587  dualfprintf(fail_file,"No such bintxt=%d in readwrite=%d\n",bintxt,readwrite);
588  myexit(249684962);
589  }
590 
591  }
592  else if(readwrite==WRITEHEAD){
593 
594  if(bintxt==BINARYOUTPUT){
595  if(accessmemory) fwrite(ptrlocal,size,nmemb,stream);
596  else{
597  for(ii=0;ii<nmemb;ii++){
598  fwrite(ptrlocal,size,1,stream); // repeatedly write from same dummy space (value=0)
599  }
600  }
601  }
602  else if(bintxt==TEXTOUTPUT || bintxt==MIXEDOUTPUT){
603  sprintf(formatwithspace,"%s ",format);
604 
605  for(ii=0;ii<nmemb;ii++){
606 
607  if(accessmemory) jj=ii;
608  else jj=0; // repeatedly read into same dummy space
609 
610  if (datatype == MPI_UNSIGNED_CHAR) fprintf(stream,formatwithspace,ptr1[jj]);
611  else if (datatype == MPI_FLOAT) fprintf(stream,formatwithspace,ptr4[jj]);
612  else if (datatype == MPI_DOUBLE) fprintf(stream,formatwithspace,ptr8[jj]);
613  else if (datatype == MPI_LONG_DOUBLE) fprintf(stream,formatwithspace,ptr16[jj]);
614  else if (datatype == MPI_INT) fprintf(stream,formatwithspace,ptr4i[jj]);
615  else if (datatype == MPI_LONG) fprintf(stream,formatwithspace,ptr4l[jj]);
616  else if (datatype == MPI_LONG_LONG_INT) fprintf(stream,formatwithspace,ptr8i[jj]);
617  else{
618  dualfprintf(fail_file,"No such datatype=%d\n",datatype);
619  myexit(98346834);
620  }
621  }
622  }
623  else{
624  dualfprintf(fail_file,"No such bintxt=%d in readwrite=%d\n",bintxt,readwrite);
625  myexit(24934963);
626  }
627 
628  }
629  else if(readwrite==NOTHINGHEAD){
630  if(!bcasthead){
631  dualfprintf(fail_file,"Entered header1_gen() with nothing do to\n");
632  myexit(24672672);
633  }
634  }
635  else{
636  dualfprintf(fail_file,"Entered header1_gen() with nothing do to version2\n");
637  myexit(24672673);
638  }
639 
640 
641 
642 
643  // assume only broadcast when reading header information
644  // only do if accessing memory (not dummy memory)
645  if(bcasthead && accessmemory){
646  // bintxt doesn't matter
647  // assume root=MPIid[0] and MPI_COMM_GRMHD
648 #if(USEMPI)
649  MPI_Bcast(ptr, (int)nmemb, datatype, MPIid[0], MPI_COMM_GRMHD);
650 #endif
651 
652  }
653 
654 
655 
656  // return(0); // indicates no failure
657  return(nmemb);
658 
659 }
660 
661 
662 
663 
664 
665 
667 int check_fileformat(int readwrite, int bintxt, int whichdump, int numcolumnsvar, int docolsplitvar, int mpicombinevar, int sizeofdatatype, FILE *stream)
668 {
669  long onlyheaderbytesize;
670  long uptodatabytesize;
671  long withintransitionbytesize;
672  long totalbytesize;
673  //
674  int truenumcolumns;
675  long long int datawordnumber;
676  long long int totaldatasize;
677  long long int wordtotal;
678  long long int badwordtotal;
679  long long int databytesize;
680  long long int fullheaderbytesize;
681  int get_word_count(long long int databytesize, long long int *wordtotal, FILE *stream);
682  unsigned char mychar;
683  int gopastlinebreak(FILE *stream);
684 
685 
686  // get position of stream, which indicates size of header in bytes
687  onlyheaderbytesize=ftell(stream);
688 
689 
690  // find transition between header and data
691  if(readwrite==READFILE){
692  if(bintxt==TEXTOUTPUT || bintxt==MIXEDOUTPUT){
693  gopastlinebreak(stream);
694  }
695  }
696  // up to and including '\n' minus just beyond header
697  // will be same as onlyheaderbytesize if nothing between header and data or if binary
698  uptodatabytesize=ftell(stream);
699 
700  // get number of bytes up to first \n
701  if(readwrite==READFILE){
702  if(bintxt==TEXTOUTPUT || bintxt==MIXEDOUTPUT){
703  fseek(stream,0,SEEK_SET);
704  gopastlinebreak(stream);
705  }
706  }
707  fullheaderbytesize=ftell(stream);
708 
709 
710  // see if header is really up to first \n and not multiple \n
711  if(fullheaderbytesize!=uptodatabytesize){
712  dualfprintf(fail_file,"restart read found \\n mismatch: fullheaderbytesize=%lld uptodatabytesize=%lld\n",fullheaderbytesize,uptodatabytesize);
713  return(1);
714  }
715 
716 
717 
718  // go back to where was before getting up to first \n
719  fseek(stream,uptodatabytesize,SEEK_SET);
720 
721  // byte size of transition region
722  withintransitionbytesize = uptodatabytesize - onlyheaderbytesize;
723 
724  // DEBUG:
725  // dualfprintf(fail_file,"onlyheaderbytesize=%ld uptodatabytesize=%ld withintransitionbytesize=%ld\n",onlyheaderbytesize,uptodatabytesize,withintransitionbytesize);
726 
727 
728  // go to end of file
729  fseek(stream,0,SEEK_END);
730  // get byte size
731  totalbytesize=ftell(stream);
732 
733 
734  // get bytes in data region
735  databytesize = totalbytesize-uptodatabytesize;
736 
737 
738  // determine number of columns within a file
739  if(docolsplitvar) truenumcolumns=1;
740  else truenumcolumns=numcolumnsvar;
741 
742  // determine number of words in data section
743  if(mpicombinevar) datawordnumber=totalsize[1]*totalsize[2]*totalsize[3]*truenumcolumns;
744  else datawordnumber=N1*N2*N3*truenumcolumns;
745 
746  // determine total bytes in data section
747  totaldatasize=datawordnumber*sizeofdatatype;
748 
749 
750 
751 
752 
753 
754  // only have checks for this case so far
755  if(readwrite==READFILE && whichdump==RESTARTDUMPTYPE){
756 
757 
759  //
760  // Check header
761  //
763  if(bintxt==TEXTOUTPUT || bintxt==MIXEDOUTPUT){
764 
765  // first start back where ended header that will be first byte of data section
766  fseek(stream,onlyheaderbytesize,SEEK_SET);
767 
768  // get word count from onlyheaderbytesize up to '\n'
769  get_word_count(withintransitionbytesize, &badwordtotal, stream);
770 
771  if(badwordtotal>0){
772  dualfprintf(fail_file,"restart read found extra words (badwordtotal=%lld) in header or could be that reading of header passed into data section\n",badwordtotal);
773  return(1);
774  }
775 
776  }
777 
778 
779 
781  //
782  // Check data
783  //
785  if(bintxt==BINARYOUTPUT || bintxt==MIXEDOUTPUT){
786  // header is binary for BINARYOUTPUT and text for MIXEDOUTPUT
787  // data is binary
788 
789  // just check that data section is right size
790  // this is easier since data section has a single data type unlike header
791  // header has to be right size for this to work out
792  if(databytesize != totaldatasize){
793  dualfprintf(fail_file,"restart read binary header/data found databytesize=%d and totaldatasize=%d\n",databytesize,totaldatasize);
794  return(1);
795  }
796 
797 
798  }
799  else if(bintxt==TEXTOUTPUT){
800  // header is text
801  // data is text
802 
803  // in this case we don't grab \n just treating it as space and counting words as normal. This is a more strict test that restart file is in correct format
804 
805  // for data as text could count words somehow (using wc and system) but many clusters don't allow system()
806  // so have to do it manually
807 
808  // first start back where ended header that will be first byte of data section
809  // don't use uptodatabytesize since want to catch errors in word count (want data to be exactly expected word count -- this checks that header is not too long)
810  //fseek(stream,onlyheaderbytesize,SEEK_SET);
811  fseek(stream,uptodatabytesize,SEEK_SET); //ATCH: otherwise, would miss the last word in dump file since databytesize definition uses uptodatabytesize as data start pos
812 
813  // get word count
814  get_word_count(databytesize, &wordtotal, stream);
815 
816 
817  if(wordtotal!=datawordnumber){
818  dualfprintf(fail_file,"restart read text data found wordtotal=%lld while datawordnumber=%lld\n",wordtotal,datawordnumber);
819  dualfprintf(fail_file,"onlyheaderbytesize=%lld ,totalbytesize=%lld,databytesize=%lld,truenumcolumns=%lld,datawordnumber=%lld,totaldatasize=%lld\n",onlyheaderbytesize,totalbytesize,databytesize,truenumcolumns,datawordnumber,totaldatasize);
820  return(1);
821  }
822 
823 
824  }
825  }
826 
828  //
829  // whatever we did to the stream, put it back to just after header function called
830  //
832  fseek(stream,onlyheaderbytesize,SEEK_SET);
833 
834 
835  return(0);
836 
837 }
838 
839 
840 
842 int gopastlinebreak(FILE *stream)
843 {
844  int mychar;
845 
846  // then need to grab up to '\n'
847  while(1){
848  mychar=fgetc(stream);
849  if(mychar=='\n' || mychar=='\r') break;
850  if(feof(stream)){
851  dualfprintf(fail_file,"Reached end of file while seeking \\n or \\r in header\n");
852  return(1);
853  }
854  }
855 
856  return(0);
857 }
858 
860 int get_word_count(long long int databytesize, long long int *wordtotal, FILE *stream)
861 {
862  unsigned char mychar;
863  int wordchar,spacechar;
864  long long int i;
865  int thischarisword;
866 
867 
868 
869  // now run through text data section
870  // a word is defined as some characters not including space, \n, \r, etc. and being bounded at least on one side by such characters
871  wordchar=0;
872  spacechar=0;
873  *wordtotal=0;
874  // go through each byte
875  for(i=0;i<databytesize;i++){
876  // read-in a byte (character) at a time
877  mychar=(unsigned char)fgetc(stream);
878 
879 
880  if(feof(stream)){
881  dualfprintf(fail_file,"Something is wrong with databytesize or loop since databytesize=%lld but found EOF\n",databytesize);
882  return(1);
883  }
884 
885  thischarisword=-1;
886  if(mychar=='\n' || mychar=='\r' || mychar==' ' || mychar=='\t' || mychar=='\v'){
887  // then got word-break (delimiter) type character
888  spacechar++;
889  thischarisword=0;
890  }
891  else{
892  wordchar++;
893  thischarisword=1;
894  }
895 
896 
897  // check for word at start
898  if(i==0 && wordchar==1 && thischarisword){
899  // then detected new word appearing and this is what we are counting (instead of ends of words)
900  (*wordtotal)++;
901  }
902 
903  // check for word entering as "space word"
904  if(wordchar==1 && spacechar>0 && thischarisword){
905  // this defines presence of word we just entered
906  (*wordtotal)++;
907 
908  // reset spacechar
909  spacechar=0;
910  }
911 
912  // reset wordchar if within space region
913  if(spacechar>0){
914  wordchar=0;
915  }
916 
917  // DEBUG:
918  // dualfprintf(fail_file,"i=%lld mychar=%c spacechar=%d wordchar=%d wordtotal=%lld\n",i,mychar,spacechar,wordchar,*wordtotal);
919 
920 
921  }// end over all bytes
922 
923 
924  return(0);
925 }