1 #define PETSC_DLL 2 /* 3 Utilites routines to add simple ASCII IO capability. 4 */ 5 #include "src/sys/fileio/mprint.h" 6 #include "petscconfiginfo.h" 7 /* 8 If petsc_history is on, then all Petsc*Printf() results are saved 9 if the appropriate (usually .petschistory) file. 10 */ 11 extern FILE *petsc_history; 12 /* 13 Allows one to overwrite where standard out is sent. For example 14 PETSC_STDOUTPUT = fopen("/dev/ttyXX","w") will cause all standard out 15 writes to go to terminal XX; assuming you have write permission there 16 */ 17 FILE *PETSC_STDOUT = 0; 18 19 #undef __FUNCT__ 20 #define __FUNCT__ "PetscFormatConvert" 21 PetscErrorCode PETSC_DLLEXPORT PetscFormatConvert(const char *format,char *newformat) 22 { 23 PetscInt i = 0,j = 0; 24 25 while (format[i] && i < 8*1024-1) { 26 if (format[i] == '%' && format[i+1] == 'D') { 27 newformat[j++] = '%'; 28 #if defined(PETSC_USE_32BIT_INT) 29 newformat[j++] = 'd'; 30 #else 31 newformat[j++] = 'l'; 32 newformat[j++] = 'l'; 33 newformat[j++] = 'd'; 34 #endif 35 i += 2; 36 } else if (format[i] == '%' && format[i+1] >= '1' && format[i+1] <= '9' && format[i+2] == 'D') { 37 newformat[j++] = '%'; 38 newformat[j++] = format[i+1]; 39 #if defined(PETSC_USE_32BIT_INT) 40 newformat[j++] = 'd'; 41 #else 42 newformat[j++] = 'l'; 43 newformat[j++] = 'l'; 44 newformat[j++] = 'd'; 45 #endif 46 i += 3; 47 }else { 48 newformat[j++] = format[i++]; 49 } 50 } 51 newformat[j] = 0; 52 return 0; 53 } 54 55 #undef __FUNCT__ 56 #define __FUNCT__ "PetscVSNPrintf" 57 /* 58 No error handling because may be called by error handler 59 */ 60 PetscErrorCode PETSC_DLLEXPORT PetscVSNPrintf(char *str,size_t len,const char *format,va_list Argp) 61 { 62 /* no malloc since may be called by error handler */ 63 char newformat[8*1024]; 64 65 PetscFormatConvert(format,newformat); 66 #if defined(PETSC_HAVE_VPRINTF_CHAR) 67 vsprintf(str,newformat,(char *)Argp); 68 #else 69 vsprintf(str,newformat,Argp); 70 #endif 71 return 0; 72 } 73 74 #undef __FUNCT__ 75 #define __FUNCT__ "PetscVFPrintf" 76 /* 77 All PETSc standard out and error messages are sent through this function; so, in theory, this can 78 can be replaced with something that does not simply write to a file. 79 80 Note: For error messages this may be called by a process, for regular standard out it is 81 called only by process 0 of a given communicator 82 83 No error handling because may be called by error handler 84 */ 85 PetscErrorCode PETSC_DLLEXPORT PetscVFPrintf(FILE *fd,const char *format,va_list Argp) 86 { 87 /* no malloc since may be called by error handler */ 88 char newformat[8*1024]; 89 90 PetscFormatConvert(format,newformat); 91 #if defined(PETSC_HAVE_VPRINTF_CHAR) 92 vfprintf(fd,newformat,(char *)Argp); 93 #else 94 vfprintf(fd,newformat,Argp); 95 fflush(fd); 96 #endif 97 return 0; 98 } 99 100 /* ----------------------------------------------------------------------- */ 101 102 PrintfQueue queue = 0,queuebase = 0; 103 int queuelength = 0; 104 FILE *queuefile = PETSC_NULL; 105 106 #undef __FUNCT__ 107 #define __FUNCT__ "PetscSynchronizedPrintf" 108 /*@C 109 PetscSynchronizedPrintf - Prints synchronized output from several processors. 110 Output of the first processor is followed by that of the second, etc. 111 112 Not Collective 113 114 Input Parameters: 115 + comm - the communicator 116 - format - the usual printf() format string 117 118 Level: intermediate 119 120 Notes: 121 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 122 from all the processors to be printed. 123 124 Fortran Note: 125 The call sequence is PetscSynchronizedPrintf(PetscViewer, character(*), PetscErrorCode ierr) from Fortran. 126 That is, you can only pass a single character string from Fortran. 127 128 The length of the formatted message cannot exceed QUEUESTRINGSIZE characters. 129 130 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 131 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 132 @*/ 133 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 134 { 135 PetscErrorCode ierr; 136 PetscMPIInt rank; 137 138 PetscFunctionBegin; 139 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 140 141 /* First processor prints immediately to stdout */ 142 if (!rank) { 143 va_list Argp; 144 va_start(Argp,format); 145 ierr = PetscVFPrintf(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 146 if (petsc_history) { 147 ierr = PetscVFPrintf(petsc_history,format,Argp);CHKERRQ(ierr); 148 } 149 va_end(Argp); 150 } else { /* other processors add to local queue */ 151 va_list Argp; 152 PrintfQueue next; 153 154 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 155 if (queue) {queue->next = next; queue = next; queue->next = 0;} 156 else {queuebase = queue = next;} 157 queuelength++; 158 va_start(Argp,format); 159 ierr = PetscMemzero(next->string,QUEUESTRINGSIZE);CHKERRQ(ierr); 160 ierr = PetscVSNPrintf(next->string,QUEUESTRINGSIZE,format,Argp);CHKERRQ(ierr); 161 va_end(Argp); 162 } 163 164 PetscFunctionReturn(0); 165 } 166 167 #undef __FUNCT__ 168 #define __FUNCT__ "PetscSynchronizedFPrintf" 169 /*@C 170 PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 171 several processors. Output of the first processor is followed by that of the 172 second, etc. 173 174 Not Collective 175 176 Input Parameters: 177 + comm - the communicator 178 . fd - the file pointer 179 - format - the usual printf() format string 180 181 Level: intermediate 182 183 Notes: 184 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 185 from all the processors to be printed. 186 187 The length of the formatted message cannot exceed QUEUESTRINGSIZE characters. 188 189 Contributed by: Matthew Knepley 190 191 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 192 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 193 194 @*/ 195 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...) 196 { 197 PetscErrorCode ierr; 198 PetscMPIInt rank; 199 200 PetscFunctionBegin; 201 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 202 203 /* First processor prints immediately to fp */ 204 if (!rank) { 205 va_list Argp; 206 va_start(Argp,format); 207 ierr = PetscVFPrintf(fp,format,Argp);CHKERRQ(ierr); 208 queuefile = fp; 209 if (petsc_history) { 210 ierr = PetscVFPrintf(petsc_history,format,Argp);CHKERRQ(ierr); 211 } 212 va_end(Argp); 213 } else { /* other processors add to local queue */ 214 va_list Argp; 215 PrintfQueue next; 216 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 217 if (queue) {queue->next = next; queue = next; queue->next = 0;} 218 else {queuebase = queue = next;} 219 queuelength++; 220 va_start(Argp,format); 221 ierr = PetscMemzero(next->string,QUEUESTRINGSIZE);CHKERRQ(ierr); 222 ierr = PetscVSNPrintf(next->string,QUEUESTRINGSIZE,format,Argp);CHKERRQ(ierr); 223 va_end(Argp); 224 } 225 PetscFunctionReturn(0); 226 } 227 228 #undef __FUNCT__ 229 #define __FUNCT__ "PetscSynchronizedFlush" 230 /*@ 231 PetscSynchronizedFlush - Flushes to the screen output from all processors 232 involved in previous PetscSynchronizedPrintf() calls. 233 234 Collective on MPI_Comm 235 236 Input Parameters: 237 . comm - the communicator 238 239 Level: intermediate 240 241 Notes: 242 Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with 243 different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush(). 244 245 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 246 PetscViewerASCIISynchronizedPrintf() 247 @*/ 248 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFlush(MPI_Comm comm) 249 { 250 PetscErrorCode ierr; 251 PetscMPIInt rank,size,tag,i,j,n; 252 char message[QUEUESTRINGSIZE]; 253 MPI_Status status; 254 FILE *fd; 255 256 PetscFunctionBegin; 257 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 258 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 259 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 260 261 /* First processor waits for messages from all other processors */ 262 if (!rank) { 263 if (queuefile) { 264 fd = queuefile; 265 } else { 266 fd = PETSC_STDOUT; 267 } 268 for (i=1; i<size; i++) { 269 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 270 for (j=0; j<n; j++) { 271 ierr = MPI_Recv(message,QUEUESTRINGSIZE,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr); 272 ierr = PetscFPrintf(comm,fd,"%s",message); 273 } 274 } 275 queuefile = PETSC_NULL; 276 } else { /* other processors send queue to processor 0 */ 277 PrintfQueue next = queuebase,previous; 278 279 ierr = MPI_Send(&queuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 280 for (i=0; i<queuelength; i++) { 281 ierr = MPI_Send(next->string,QUEUESTRINGSIZE,MPI_CHAR,0,tag,comm);CHKERRQ(ierr); 282 previous = next; 283 next = next->next; 284 ierr = PetscFree(previous);CHKERRQ(ierr); 285 } 286 queue = 0; 287 queuelength = 0; 288 } 289 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 290 PetscFunctionReturn(0); 291 } 292 293 /* ---------------------------------------------------------------------------------------*/ 294 295 #undef __FUNCT__ 296 #define __FUNCT__ "PetscFPrintf" 297 /*@C 298 PetscFPrintf - Prints to a file, only from the first 299 processor in the communicator. 300 301 Not Collective 302 303 Input Parameters: 304 + comm - the communicator 305 . fd - the file pointer 306 - format - the usual printf() format string 307 308 Level: intermediate 309 310 Fortran Note: 311 This routine is not supported in Fortran. 312 313 Concepts: printing^in parallel 314 Concepts: printf^in parallel 315 316 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 317 PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 318 @*/ 319 PetscErrorCode PETSC_DLLEXPORT PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 320 { 321 PetscErrorCode ierr; 322 PetscMPIInt rank; 323 324 PetscFunctionBegin; 325 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 326 if (!rank) { 327 va_list Argp; 328 va_start(Argp,format); 329 ierr = PetscVFPrintf(fd,format,Argp);CHKERRQ(ierr); 330 if (petsc_history) { 331 ierr = PetscVFPrintf(petsc_history,format,Argp);CHKERRQ(ierr); 332 } 333 va_end(Argp); 334 } 335 PetscFunctionReturn(0); 336 } 337 338 #undef __FUNCT__ 339 #define __FUNCT__ "PetscPrintf" 340 /*@C 341 PetscPrintf - Prints to standard out, only from the first 342 processor in the communicator. 343 344 Not Collective 345 346 Input Parameters: 347 + comm - the communicator 348 - format - the usual printf() format string 349 350 Level: intermediate 351 352 Fortran Note: 353 The call sequence is PetscPrintf(PetscViewer, character(*), PetscErrorCode ierr) from Fortran. 354 That is, you can only pass a single character string from Fortran. 355 356 Notes: %A is replace with %g unless the value is < 1.e-12 when it is 357 replaced with < 1.e-12 358 359 Concepts: printing^in parallel 360 Concepts: printf^in parallel 361 362 .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 363 @*/ 364 PetscErrorCode PETSC_DLLEXPORT PetscPrintf(MPI_Comm comm,const char format[],...) 365 { 366 PetscErrorCode ierr; 367 PetscMPIInt rank; 368 size_t len; 369 char *nformat,*sub1,*sub2; 370 PetscReal value; 371 372 PetscFunctionBegin; 373 if (!comm) comm = PETSC_COMM_WORLD; 374 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 375 if (!rank) { 376 va_list Argp; 377 va_start(Argp,format); 378 379 ierr = PetscStrstr(format,"%A",&sub1);CHKERRQ(ierr); 380 if (sub1) { 381 ierr = PetscStrstr(format,"%",&sub2);CHKERRQ(ierr); 382 if (sub1 != sub2) SETERRQ(PETSC_ERR_ARG_WRONG,"%%A format must be first in format string"); 383 ierr = PetscStrlen(format,&len);CHKERRQ(ierr); 384 ierr = PetscMalloc((len+16)*sizeof(char),&nformat);CHKERRQ(ierr); 385 ierr = PetscStrcpy(nformat,format);CHKERRQ(ierr); 386 ierr = PetscStrstr(nformat,"%",&sub2);CHKERRQ(ierr); 387 sub2[0] = 0; 388 value = (double)va_arg(Argp,double); 389 if (PetscAbsReal(value) < 1.e-12) { 390 ierr = PetscStrcat(nformat,"< 1.e-12");CHKERRQ(ierr); 391 } else { 392 ierr = PetscStrcat(nformat,"%g");CHKERRQ(ierr); 393 va_end(Argp); 394 va_start(Argp,format); 395 } 396 ierr = PetscStrcat(nformat,sub1+2);CHKERRQ(ierr); 397 } else { 398 nformat = (char*)format; 399 } 400 ierr = PetscVFPrintf(PETSC_STDOUT,nformat,Argp);CHKERRQ(ierr); 401 if (petsc_history) { 402 ierr = PetscVFPrintf(petsc_history,nformat,Argp);CHKERRQ(ierr); 403 } 404 va_end(Argp); 405 if (sub1) {ierr = PetscFree(nformat);CHKERRQ(ierr);} 406 } 407 PetscFunctionReturn(0); 408 } 409 410 /* ---------------------------------------------------------------------------------------*/ 411 #undef __FUNCT__ 412 #define __FUNCT__ "PetscHelpPrintfDefault" 413 PetscErrorCode PETSC_DLLEXPORT PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 414 { 415 PetscErrorCode ierr; 416 PetscMPIInt rank; 417 418 PetscFunctionBegin; 419 if (!comm) comm = PETSC_COMM_WORLD; 420 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 421 if (!rank) { 422 va_list Argp; 423 va_start(Argp,format); 424 ierr = PetscVFPrintf(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 425 if (petsc_history) { 426 ierr = PetscVFPrintf(petsc_history,format,Argp);CHKERRQ(ierr); 427 } 428 va_end(Argp); 429 } 430 PetscFunctionReturn(0); 431 } 432 433 /* ---------------------------------------------------------------------------------------*/ 434 435 static char arch[10],hostname[64],username[16],pname[PETSC_MAX_PATH_LEN],date[64]; 436 static PetscTruth PetscErrorPrintfInitializeCalled = PETSC_FALSE; 437 438 #undef __FUNCT__ 439 #define __FUNCT__ "PetscErrorPrintfInitialize" 440 /* 441 Initializes arch, hostname, username,date so that system calls do NOT need 442 to be made during the error handler. 443 */ 444 PetscErrorCode PETSC_DLLEXPORT PetscErrorPrintfInitialize() 445 { 446 PetscErrorCode ierr; 447 448 PetscFunctionBegin; 449 ierr = PetscGetArchType(arch,10);CHKERRQ(ierr); 450 ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr); 451 ierr = PetscGetUserName(username,16);CHKERRQ(ierr); 452 ierr = PetscGetProgramName(pname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 453 ierr = PetscGetDate(date,64);CHKERRQ(ierr); 454 PetscErrorPrintfInitializeCalled = PETSC_TRUE; 455 PetscFunctionReturn(0); 456 } 457 458 459 #undef __FUNCT__ 460 #define __FUNCT__ "PetscErrorPrintfDefault" 461 PetscErrorCode PETSC_DLLEXPORT PetscErrorPrintfDefault(const char format[],...) 462 { 463 va_list Argp; 464 static PetscTruth PetscErrorPrintfCalled = PETSC_FALSE; 465 static PetscTruth InPetscErrorPrintfDefault = PETSC_FALSE; 466 static FILE *fd; 467 char version[256]; 468 PetscErrorCode ierr; 469 470 /* 471 InPetscErrorPrintfDefault is used to prevent the error handler called (potentially) 472 from PetscSleep(), PetscGetArchName(), ... below from printing its own error message. 473 */ 474 475 /* 476 This function does not call PetscFunctionBegin and PetscFunctionReturn() because 477 it may be called by PetscStackView(). 478 479 This function does not do error checking because it is called by the error handlers. 480 */ 481 482 if (!PetscErrorPrintfCalled) { 483 PetscTruth use_stderr; 484 485 PetscErrorPrintfCalled = PETSC_TRUE; 486 InPetscErrorPrintfDefault = PETSC_TRUE; 487 488 PetscOptionsHasName(PETSC_NULL,"-error_output_stderr",&use_stderr); 489 if (use_stderr) { 490 fd = stderr; 491 } else { 492 fd = PETSC_STDOUT; 493 } 494 495 /* 496 On the SGI machines and Cray T3E, if errors are generated "simultaneously" by 497 different processors, the messages are printed all jumbled up; to try to 498 prevent this we have each processor wait based on their rank 499 */ 500 #if defined(PETSC_CAN_SLEEP_AFTER_ERROR) 501 { 502 PetscMPIInt rank; 503 if (PetscGlobalRank > 8) rank = 8; else rank = PetscGlobalRank; 504 PetscSleep(rank); 505 } 506 #endif 507 508 ierr = PetscGetVersion(&version);CHKERRQ(ierr); 509 510 PetscFPrintf(PETSC_COMM_SELF,fd,"------------------------------------------------------------------------\n"); 511 PetscFPrintf(PETSC_COMM_SELF,fd,"%s\n",version); 512 PetscFPrintf(PETSC_COMM_SELF,fd,"See docs/changes/index.html for recent updates.\n"); 513 PetscFPrintf(PETSC_COMM_SELF,fd,"See docs/faq.html for hints about trouble shooting.\n"); 514 PetscFPrintf(PETSC_COMM_SELF,fd,"See docs/index.html for manual pages.\n"); 515 PetscFPrintf(PETSC_COMM_SELF,fd,"------------------------------------------------------------------------\n"); 516 if (PetscErrorPrintfInitializeCalled) { 517 PetscFPrintf(PETSC_COMM_SELF,fd,"%s on a %s named %s by %s %s\n",pname,arch,hostname,username,date); 518 } 519 PetscFPrintf(PETSC_COMM_SELF,fd,"Libraries linked from %s\n",PETSC_LIB_DIR); 520 PetscFPrintf(PETSC_COMM_SELF,fd,"Configure run at %s\n",petscconfigureruntime); 521 PetscFPrintf(PETSC_COMM_SELF,fd,"Configure options %s\n",petscconfigureoptions); 522 PetscFPrintf(PETSC_COMM_SELF,fd,"------------------------------------------------------------------------\n"); 523 InPetscErrorPrintfDefault = PETSC_FALSE; 524 } 525 526 if (!InPetscErrorPrintfDefault) { 527 PetscFPrintf(PETSC_COMM_SELF,fd,"[%d]PETSC ERROR: ",PetscGlobalRank); 528 va_start(Argp,format); 529 PetscVFPrintf(fd,format,Argp); 530 va_end(Argp); 531 } 532 return 0; 533 } 534 535 #undef __FUNCT__ 536 #define __FUNCT__ "PetscSynchronizedFGets" 537 /*@C 538 PetscSynchronizedFGets - Several processors all get the same line from a file. 539 540 Collective on MPI_Comm 541 542 Input Parameters: 543 + comm - the communicator 544 . fd - the file pointer 545 - len - the length of the output buffer 546 547 Output Parameter: 548 . string - the line read from the file 549 550 Level: intermediate 551 552 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 553 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 554 555 @*/ 556 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[]) 557 { 558 PetscErrorCode ierr; 559 PetscMPIInt rank; 560 561 PetscFunctionBegin; 562 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 563 564 if (!rank) { 565 fgets(string,len,fp); 566 } 567 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 568 PetscFunctionReturn(0); 569 } 570