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