1 /* This file provides interface functions for 'partial ' random 2 access into the PHASTA input files 3 4 Anil Karanam March 2001 */ 5 6 #include <stdlib.h> 7 #include <stdio.h> 8 #include <string.h> 9 #include <ctype.h> 10 #include <stdlib.h> 11 #include <time.h> 12 #include <math.h> 13 #include <assert.h> 14 #include "mpi.h" 15 #include "phastaIO.h" 16 #include "rdtsc.h" 17 #include <FCMangle.h> 18 #include "new_interface.h" 19 #include "phIO.h" 20 #include "syncio.h" 21 #include "posixio.h" 22 #include "streamio.h" 23 #include "common_c.h" 24 #include "tmrc.h" 25 #include "phString.h" 26 27 #ifdef intel 28 #include <winsock2.h> 29 #else 30 #include <unistd.h> 31 #include <strings.h> 32 #endif 33 34 void igetMinMaxAvg(int *ivalue, double *stats, int *statRanks) { 35 double *value = (double*)malloc(sizeof(double)); 36 *value = 1.0*(*ivalue); 37 rgetMinMaxAvg(value,stats,statRanks); 38 free(value); 39 } 40 41 void rgetMinMaxAvg(double *value, double *stats, int *statRanks) { 42 int isThisRank; 43 double sqValue = 0., sqValueAvg = 0.; 44 45 MPI_Allreduce(value,&stats[0],1,MPI_DOUBLE,MPI_MIN,MPI_COMM_WORLD); 46 isThisRank=workfc.numpe+1; 47 if(*value==stats[0]) 48 isThisRank=workfc.myrank; 49 MPI_Allreduce(&isThisRank,&statRanks[0],1,MPI_INT,MPI_MIN,MPI_COMM_WORLD); 50 51 MPI_Allreduce(value,&stats[1],1,MPI_DOUBLE,MPI_MAX,MPI_COMM_WORLD); 52 isThisRank=workfc.numpe+1; 53 if(*value==stats[1]) 54 isThisRank=workfc.myrank; 55 MPI_Allreduce(&isThisRank,&statRanks[1],1,MPI_INT,MPI_MIN,MPI_COMM_WORLD); 56 57 MPI_Allreduce(value,&stats[2],1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); 58 stats[2] /= workfc.numpe; 59 60 sqValue = (*value)*(*value); 61 MPI_Allreduce(&sqValue,&sqValueAvg,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD); 62 sqValueAvg /= workfc.numpe; 63 64 stats[3] = sqrt(sqValueAvg-stats[2]*stats[2]); 65 } 66 67 void print_mesh_stats(void) { 68 int statRanks[2]; 69 double iStats[4]; 70 71 igetMinMaxAvg(&conpar.nshg,iStats,statRanks); 72 if(workfc.myrank==workfc.master) 73 printf("nshg : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 74 igetMinMaxAvg(&conpar.numel,iStats,statRanks); 75 if(workfc.myrank==workfc.master) 76 printf("numel : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 77 igetMinMaxAvg(&conpar.numelb,iStats,statRanks); 78 if(workfc.myrank==workfc.master) 79 printf("numelb : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 80 igetMinMaxAvg(&conpar.nnz_tot,iStats,statRanks); 81 if(workfc.myrank==workfc.master) { 82 printf("nnz_tot : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 83 printf("\n"); 84 } 85 } 86 87 void print_mpi_stats(void) { 88 int statRanks[2]; 89 double iStats[4], rStats[4]; 90 91 /* NS equations*/ 92 igetMinMaxAvg(&mpistats.iISend,iStats,statRanks); 93 if(workfc.myrank==workfc.master) 94 printf("iISend : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 95 igetMinMaxAvg(&mpistats.iIRecv,iStats,statRanks); 96 if(workfc.myrank==workfc.master) 97 printf("iIRecv : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 98 igetMinMaxAvg(&mpistats.iWaitAll,iStats,statRanks); 99 if(workfc.myrank==workfc.master) 100 printf("iWtAll : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 101 igetMinMaxAvg(&mpistats.iAllR,iStats,statRanks); 102 if(workfc.myrank==workfc.master) 103 printf("iAllR : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 104 105 rgetMinMaxAvg(&mpistats.rISend,rStats,statRanks); 106 if(workfc.myrank==workfc.master) 107 printf("rISend : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 108 rgetMinMaxAvg(&mpistats.rIRecv,rStats,statRanks); 109 if(workfc.myrank==workfc.master) 110 printf("rIRecv : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 111 rgetMinMaxAvg(&mpistats.rWaitAll,rStats,statRanks); 112 if(workfc.myrank==workfc.master) 113 printf("rWtAll : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 114 rgetMinMaxAvg(&mpistats.rCommu,rStats,statRanks); 115 if(workfc.myrank==workfc.master) 116 printf("rCommu : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 117 rgetMinMaxAvg(&mpistats.rAllR,rStats,statRanks); 118 if(workfc.myrank==workfc.master) { 119 printf("rAllR : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 120 printf("\n"); 121 } 122 /* Scalars*/ 123 igetMinMaxAvg(&mpistats.iISendScal,iStats,statRanks); 124 if(workfc.myrank==workfc.master) 125 printf("iISendScal : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 126 igetMinMaxAvg(&mpistats.iIRecvScal,iStats,statRanks); 127 if(workfc.myrank==workfc.master) 128 printf("iIRecvScal : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 129 igetMinMaxAvg(&mpistats.iWaitAllScal,iStats,statRanks); 130 if(workfc.myrank==workfc.master) 131 printf("iWtAllScal : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 132 igetMinMaxAvg(&mpistats.iAllRScal,iStats,statRanks); 133 if(workfc.myrank==workfc.master) 134 printf("iAllRScal : min [%d,%d], max[%d,%d] and avg[.,%d] (rms=%d)\n",statRanks[0],(int)iStats[0],statRanks[1],(int)iStats[1],(int)iStats[2],(int)iStats[3]); 135 136 rgetMinMaxAvg(&mpistats.rISendScal,rStats,statRanks); 137 if(workfc.myrank==workfc.master) 138 printf("rISendScal : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 139 rgetMinMaxAvg(&mpistats.rIRecvScal,rStats,statRanks); 140 if(workfc.myrank==workfc.master) 141 printf("rIRecvScal : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 142 rgetMinMaxAvg(&mpistats.rWaitAllScal,rStats,statRanks); 143 if(workfc.myrank==workfc.master) 144 printf("rWtAllScal : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 145 rgetMinMaxAvg(&mpistats.rCommuScal,rStats,statRanks); 146 if(workfc.myrank==workfc.master) 147 printf("rCommuScal : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 148 rgetMinMaxAvg(&mpistats.rAllRScal,rStats,statRanks); 149 if(workfc.myrank==workfc.master) 150 printf("rAllRScal : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 151 152 153 } 154 155 void print_system_stats(double *tcorecp, double *tcorecpscal) { 156 int statRanks[2]; 157 double rStats[4]; 158 double syst_assembly, syst_solve; 159 160 /* NS equations */ 161 syst_assembly = tcorecp[0]; 162 syst_solve = tcorecp[1]; 163 164 rgetMinMaxAvg(&syst_assembly,rStats,statRanks); 165 if(workfc.myrank==workfc.master) 166 printf("Elm. form. : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 167 168 rgetMinMaxAvg(&syst_solve,rStats,statRanks); 169 if(workfc.myrank==workfc.master) 170 printf("Lin. alg. sol : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 171 172 /* Scalars */ 173 syst_assembly = tcorecpscal[0]; 174 syst_solve = tcorecpscal[1]; 175 176 rgetMinMaxAvg(&syst_assembly,rStats,statRanks); 177 if(workfc.myrank==workfc.master) 178 printf("Elm. form. Scal. : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 179 180 rgetMinMaxAvg(&syst_solve,rStats,statRanks); 181 if(workfc.myrank==workfc.master) { 182 printf("Lin. alg. sol Scal. : min [%d,%2.5f], max[%d,%2.5f] and avg[.,%2.5f] (rms=%2.5f)\n",statRanks[0],rStats[0],statRanks[1],rStats[1],rStats[2],rStats[3]); 183 printf("\n"); 184 } 185 } 186 187 188 189 void countfieldstowriterestart() 190 { 191 int nfields = 3; /*magic number, solution, time derivatives*/ 192 193 if(outpar.ivort == 1){ 194 nfields++; /*vorticity*/ 195 } 196 197 if(abs(turbvar.itwmod) != 1 && outpar.iowflux == 1) { 198 nfields++; /*instantaneous wss in bflux.f */ 199 } 200 201 /*projection vectors and pressure projection vectors (call saveLesRestart in itrdrv)*/ 202 if(incomp.ipresPrjFlag ==1) { 203 nfields = nfields +2; 204 } 205 206 /*if Print Error Indicators = true (call write_error in itrdrv)*/ 207 if(turbvar.ierrcalc == 1){ 208 nfields++; 209 } 210 211 /*if Print ybar = True (call write_field(myrank,'a','ybar',4,... in itrdrv)*/ 212 if(outpar.ioybar == 1){ 213 nfields++; /*ybar*/ 214 215 /*phase average fields*/ 216 if(outpar.nphasesincycle >0) { 217 nfields = nfields + outpar.nphasesincycle; 218 } 219 220 if(abs(turbvar.itwmod) != 1 && outpar.iowflux == 1) { 221 nfields++; /*wssbar*/ 222 } 223 224 } 225 226 if(turbvari.irans < 0) { 227 nfields++; /*dwal*/ 228 } 229 230 outpar.nsynciofieldswriterestart = nfields; 231 232 if(workfc.myrank == 0) { 233 printf("Number of fields to write in restart files: %d\n", nfields); 234 } 235 } 236 237 238 void 239 Write_Restart( int* pid, 240 int* stepno, 241 int* nshg, 242 int* numVars, 243 double* array1, 244 double* array2 ) { 245 246 const char* magic_name = "byteorder magic number"; 247 int magic_number = 362436; 248 int isize, nitems; 249 int iarray[10]; 250 int nfiles; 251 int nfields; 252 int numparts; 253 int nprocs; 254 int ione = 1; 255 double iotime = 0; 256 char filename[255]; 257 258 /* First, count the number of fields to write and store the result in*/ 259 countfieldstowriterestart(); 260 261 /* Retrieve and compute the parameters required for SyncIO*/ 262 nfiles = outpar.nsynciofiles; 263 nfields = outpar.nsynciofieldswriterestart; 264 numparts = workfc.numpe; 265 nprocs = workfc.numpe; 266 assert(numparts/nprocs == 1);/* Number of parts per proc ...*/ 267 268 bzero((void*)filename,255); 269 270 iotime = TMRC(); 271 if(outpar.output_mode == -1 ) 272 streamio_setup_write(&f_descriptor, streamio_get_r()); 273 else if(outpar.output_mode == 0 ) 274 posixio_setup(&f_descriptor, 'w'); 275 else if(outpar.output_mode > 0 ) 276 syncio_setup_write(nfiles, nfields, numparts/nfiles, &f_descriptor); 277 else 278 exit(EXIT_FAILURE); 279 phio_constructName(f_descriptor,"restart",filename); 280 phstr_appendInt(filename, *stepno); 281 phstr_appendStr(filename, "."); 282 phio_openfile(filename, f_descriptor); 283 284 field_flag=0; 285 286 /* write the magic number*/ 287 phio_writeheader(f_descriptor, magic_name, (void*)&magic_number, &ione, 288 &ione, "integer", phasta_iotype); 289 phio_writedatablock(f_descriptor, magic_name, (void*)&magic_number, 290 &ione, "integer", phasta_iotype ); 291 field_flag++; 292 293 /* Write solution field ...*/ 294 isize = (*nshg)*(*numVars); 295 nitems = 3; 296 iarray[ 0 ] = (*nshg); 297 iarray[ 1 ] = (*numVars); 298 iarray[ 2 ] = (*stepno); 299 300 phio_writeheader(f_descriptor, "solution", (void*)iarray, &nitems, 301 &isize, "double", phasta_iotype); 302 nitems = (*nshg)*(*numVars); 303 phio_writedatablock(f_descriptor, "solution", (void*)(array1), 304 &isize, "double", phasta_iotype ); 305 field_flag++; 306 307 /* Write solution field ...*/ 308 isize = (*nshg)*(*numVars); 309 nitems = 3; 310 iarray[ 0 ] = (*nshg); 311 iarray[ 1 ] = (*numVars); 312 iarray[ 2 ] = (*stepno); 313 phio_writeheader(f_descriptor, "time derivative of solution", 314 (void*)iarray, &nitems, &isize, "double", phasta_iotype); 315 nitems = (*nshg)*(*numVars); 316 phio_writedatablock(f_descriptor, "time derivative of solution", 317 (void*)(array2), &isize, "double", phasta_iotype ); 318 field_flag++; 319 320 if (field_flag==nfields){ 321 phio_closefile(f_descriptor); 322 if (*pid==0) { 323 printf("\n"); 324 } 325 } 326 iotime = TMRC() - iotime; 327 if (workfc.master == workfc.myrank) 328 printf("time to write restart (seconds) %f\n",iotime); 329 } 330 331 void 332 Write_Error( int* pid, 333 int* stepno, 334 int* nshg, 335 int* numVars, 336 double* array1 ) { 337 int isize, nitems; 338 int iarray[10]; 339 int nfields; 340 int numparts; 341 int nprocs; 342 343 (void)*pid; /*silence compiler warning*/ 344 345 nfields = outpar.nsynciofieldswriterestart; 346 numparts = workfc.numpe; 347 nprocs = workfc.numpe; 348 349 assert(numparts/nprocs == 1);/* Number of parts per proc ...*/ 350 351 field_flag++; 352 353 if(*pid==0) { 354 printf("\n"); 355 printf("The %d/%d th field to be written is 'errors'\n",field_flag,nfields); 356 } 357 358 isize = (*nshg)*(*numVars); 359 nitems = 3; 360 iarray[ 0 ] = (*nshg); 361 iarray[ 1 ] = (*numVars); 362 iarray[ 2 ] = (*stepno); 363 364 phio_writeheader(f_descriptor, "errors", (void*)iarray, &nitems, 365 &isize, "double", phasta_iotype); 366 367 phio_writedatablock(f_descriptor, "errors", (void*)array1, &isize, 368 "double", phasta_iotype ); 369 370 if (field_flag==nfields){ 371 phio_closefile(f_descriptor); 372 if (*pid==0) { 373 printf("Last field %d 'errors' finished! \n",nfields); 374 printf("\n"); 375 } 376 } 377 } 378 379 void 380 Write_Field( int *pid, 381 char* filemode, 382 char* fieldtag, 383 int* tagsize, 384 void* array, 385 char* arraytype, 386 int* nshg, 387 int* numvars, 388 int* stepno) { 389 char *fieldlabel = NULL; 390 391 int isize, nitems; 392 int iarray[10]; 393 char datatype[10]; 394 395 int nfields; 396 int numparts; 397 int nprocs; 398 399 (void)*filemode; /*silence compiler warning*/ 400 401 if(!strncmp(arraytype,"i",1)) 402 strcpy(datatype,"int"); 403 else /* default is double*/ 404 strcpy(datatype,"double"); 405 406 nfields = outpar.nsynciofieldswriterestart; 407 numparts = workfc.numpe; 408 nprocs = workfc.numpe; 409 410 assert(numparts/nprocs == 1);/* Number of parts per proc ...*/ 411 412 fieldlabel = (char *)malloc((*tagsize+1)*sizeof(char)); 413 strncpy(fieldlabel, fieldtag, *tagsize); 414 fieldlabel[*tagsize] = '\0'; 415 416 field_flag++; 417 if(*pid==0) { 418 printf("\n"); 419 printf("The %d/%d th field to be written is '%s'\n",field_flag,nfields,fieldlabel); 420 } 421 422 /* Write solution field ...*/ 423 isize = (*nshg)*(*numvars); 424 nitems = 3; 425 iarray[ 0 ] = (*nshg); 426 iarray[ 1 ] = (*numvars); 427 iarray[ 2 ] = (*stepno); 428 429 phio_writeheader(f_descriptor, fieldlabel, (void*)iarray, &nitems, 430 &isize, datatype, phasta_iotype); 431 nitems = (*nshg)*(*numvars); 432 phio_writedatablock(f_descriptor, fieldlabel, array, &isize, 433 datatype, phasta_iotype ); 434 435 if (field_flag==nfields){ 436 phio_closefile(f_descriptor); 437 if (*pid==0) { 438 printf("Last field %d '%s' finished! \n",nfields, fieldtag); 439 printf("\n"); 440 } 441 } 442 free(fieldlabel); 443 } 444 445 void 446 Write_PhAvg2( int* pid, 447 char* filemode, 448 char* fieldtag, 449 int* tagsize, 450 int* iphase, 451 int* nphasesincycle, 452 void* array, 453 char* arraytype, 454 int* nshg, 455 int* numvars, 456 int* stepno) { 457 int addtagsize=0; /* phase number is added to the name of the field*/ 458 int tagsize2 = 0; 459 char *fieldlabel = NULL; 460 char straddtagsize[10] = "\0"; 461 int isize, nitems; 462 int iarray[10]; 463 char datatype[10]; 464 int nfields; 465 int numparts; 466 int nprocs; 467 468 (void)*filemode; /*silence compiler warning*/ 469 (void)*nphasesincycle; /*silence compiler warning*/ 470 471 if(*iphase<10) 472 addtagsize=1; 473 else if(*iphase<100) 474 addtagsize=2; 475 else if(*iphase<1000) 476 addtagsize=3; 477 478 tagsize2=*tagsize+addtagsize; 479 480 fieldlabel = (char *)malloc((tagsize2+1)*sizeof(char)); 481 strncpy(fieldlabel, fieldtag, *tagsize); 482 fieldlabel[tagsize2] = '\0'; 483 484 sprintf(straddtagsize,"%d",*iphase); 485 486 if(*iphase<10) { 487 fieldlabel[tagsize2-1]=straddtagsize[0]; 488 } 489 else if(*iphase<100) { 490 fieldlabel[tagsize2-2]=straddtagsize[0]; 491 fieldlabel[tagsize2-1]=straddtagsize[1]; 492 } 493 else if(*iphase<1000) { 494 fieldlabel[tagsize2-3]=straddtagsize[0]; 495 fieldlabel[tagsize2-2]=straddtagsize[1]; 496 fieldlabel[tagsize2-1]=straddtagsize[2]; 497 } 498 499 if(!strncmp(arraytype,"i",1)) 500 strcpy(datatype,"int"); 501 else /* default is double*/ 502 strcpy(datatype,"double"); 503 504 nfields = outpar.nsynciofieldswriterestart; 505 numparts = workfc.numpe; 506 nprocs = workfc.numpe; 507 508 assert(numparts/nprocs == 1);/* Number of parts per proc ...*/ 509 510 field_flag++; 511 if(*pid==0) { 512 printf("\n"); 513 printf("The %d/%d th field to be written is '%s'\n",field_flag,nfields,fieldlabel); 514 } 515 516 /* Write solution field ...*/ 517 isize = (*nshg)*(*numvars); 518 nitems = 3; 519 iarray[ 0 ] = (*nshg); 520 iarray[ 1 ] = (*numvars); 521 iarray[ 2 ] = (*stepno); 522 phio_writeheader(f_descriptor, fieldlabel, (void*)iarray, &nitems, 523 &isize, "double", phasta_iotype); 524 nitems = (*nshg)*(*numvars); 525 phio_writedatablock(f_descriptor, fieldlabel, array, &isize, 526 "double", phasta_iotype ); 527 if (field_flag==nfields){ 528 phio_closefile(f_descriptor); 529 if (*pid==0) { 530 printf("\n"); 531 } 532 } 533 free(fieldlabel); 534 } 535