1 /* 2 Utilites routines to add simple ASCII IO capability. 3 */ 4 #include <../src/sys/fileio/mprint.h> 5 #include <errno.h> 6 /* 7 If petsc_history is on, then all Petsc*Printf() results are saved 8 if the appropriate (usually .petschistory) file. 9 */ 10 extern FILE *petsc_history; 11 /* 12 Allows one to overwrite where standard out is sent. For example 13 PETSC_STDOUT = fopen("/dev/ttyXX","w") will cause all standard out 14 writes to go to terminal XX; assuming you have write permission there 15 */ 16 FILE *PETSC_STDOUT = 0; 17 /* 18 Allows one to overwrite where standard error is sent. For example 19 PETSC_STDERR = fopen("/dev/ttyXX","w") will cause all standard error 20 writes to go to terminal XX; assuming you have write permission there 21 */ 22 FILE *PETSC_STDERR = 0; 23 24 /* 25 Return the maximum expected new size of the format 26 */ 27 #define PETSC_MAX_LENGTH_FORMAT(l) (l+l/8) 28 29 #undef __FUNCT__ 30 #define __FUNCT__ "PetscFormatConvert" 31 /*@C 32 PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string 33 34 Input Parameters: 35 + format - the PETSc format string 36 . newformat - the location to put the standard C format string values 37 - size - the length of newformat 38 39 Note: this exists so we can have the same code when PetscInt is either int or long long and PetscScalar is either __float128, double, or float 40 41 Level: developer 42 43 @*/ 44 PetscErrorCode PetscFormatConvert(const char *format,char *newformat,size_t size) 45 { 46 PetscInt i = 0,j = 0; 47 48 PetscFunctionBegin; 49 while (format[i] && j < (PetscInt)size-1) { 50 if (format[i] == '%' && format[i+1] == '%') { 51 newformat[j++] = format[i++]; 52 newformat[j++] = format[i++]; 53 } else if (format[i] == '%') { 54 if (format[i+1] == 'g') { 55 newformat[j++] = '['; 56 newformat[j++] = '|'; 57 } 58 /* Find the letter */ 59 for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 60 switch (format[i]) { 61 case 'D': 62 #if !defined(PETSC_USE_64BIT_INDICES) 63 newformat[j++] = 'd'; 64 #else 65 newformat[j++] = 'l'; 66 newformat[j++] = 'l'; 67 newformat[j++] = 'd'; 68 #endif 69 break; 70 case 'g': 71 newformat[j++] = format[i]; 72 if (format[i-1] == '%') { 73 newformat[j++] = '|'; 74 newformat[j++] = ']'; 75 } 76 break; 77 case 'G': 78 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%G format is no longer supported, use %%g and cast the argument to double"); 79 break; 80 case 'F': 81 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%F format is no longer supported, use %%f and cast the argument to double"); 82 break; 83 default: 84 newformat[j++] = format[i]; 85 break; 86 } 87 i++; 88 } else newformat[j++] = format[i++]; 89 } 90 newformat[j] = 0; 91 PetscFunctionReturn(0); 92 } 93 94 #undef __FUNCT__ 95 #define __FUNCT__ "PetscVSNPrintf" 96 /*@C 97 PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 98 function arguments into a string using the format statement. 99 100 Input Parameters: 101 + str - location to put result 102 . len - the amount of space in str 103 + format - the PETSc format string 104 - fullLength - the amount of space in str actually used. 105 106 Developer Notes: this function may be called from an error handler, if an error occurs when it is called by the error handler than likely 107 a recursion will occur and possible crash. 108 109 Level: developer 110 111 @*/ 112 PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) 113 { 114 char *newformat; 115 char formatbuf[8*1024]; 116 size_t oldLength,length; 117 PetscErrorCode ierr; 118 119 PetscFunctionBegin; 120 ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); 121 if (oldLength < 8*1024) { 122 newformat = formatbuf; 123 oldLength = 8*1024-1; 124 } else { 125 oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength); 126 ierr = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr); 127 } 128 ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr); 129 ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr); 130 #if 0 131 if (length > len) newformat[len] = '\0'; 132 #endif 133 #if defined(PETSC_HAVE_VSNPRINTF_CHAR) 134 (void) vsnprintf(str,len,newformat,(char*)Argp); 135 #elif defined(PETSC_HAVE_VSNPRINTF) 136 (void) vsnprintf(str,len,newformat,Argp); 137 #elif defined(PETSC_HAVE__VSNPRINTF) 138 (void) _vsnprintf(str,len,newformat,Argp); 139 #else 140 #error "vsnprintf not found" 141 #endif 142 if (oldLength >= 8*1024) { 143 ierr = PetscFree(newformat);CHKERRQ(ierr); 144 } 145 { 146 PetscBool foundedot; 147 size_t cnt = 0,ncnt = 0,leng; 148 ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); 149 if (leng > 4) { 150 for (cnt=0; cnt<leng-4; cnt++) { 151 if (str[cnt] == '[' && str[cnt+1] == '|'){ 152 cnt++; cnt++; 153 foundedot = PETSC_FALSE; 154 for (; cnt<leng-1; cnt++) { 155 if (str[cnt] == '|' && str[cnt+1] == ']'){ 156 cnt++; 157 if (!foundedot) str[ncnt++] = '.'; 158 ncnt--; 159 break; 160 } else { 161 if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 162 str[ncnt++] = str[cnt]; 163 } 164 } 165 } else { 166 str[ncnt] = str[cnt]; 167 } 168 ncnt++; 169 } 170 while (cnt < leng) { 171 str[ncnt] = str[cnt]; ncnt++; cnt++; 172 } 173 str[ncnt] = 0; 174 } 175 } 176 #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 177 /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 178 { 179 size_t cnt = 0,ncnt = 0,leng; 180 ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); 181 if (leng > 5) { 182 for (cnt=0; cnt<leng-4; cnt++) { 183 if (str[cnt] == 'e' && (str[cnt+1] == '-' || str[cnt+1] == '+') && str[cnt+2] == '0' && str[cnt+3] >= '0' && str[cnt+3] <= '9' && str[cnt+4] >= '0' && str[cnt+4] <= '9') { 184 str[ncnt] = str[cnt]; ncnt++; cnt++; 185 str[ncnt] = str[cnt]; ncnt++; cnt++; cnt++; 186 str[ncnt] = str[cnt]; 187 } else { 188 str[ncnt] = str[cnt]; 189 } 190 ncnt++; 191 } 192 while (cnt < leng) { 193 str[ncnt] = str[cnt]; ncnt++; cnt++; 194 } 195 str[ncnt] = 0; 196 } 197 } 198 #endif 199 if (fullLength) { 200 ierr = PetscStrlen(str,fullLength);CHKERRQ(ierr); 201 } 202 PetscFunctionReturn(0); 203 } 204 205 #undef __FUNCT__ 206 #define __FUNCT__ "PetscVFPrintfDefault" 207 /*@C 208 PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 209 can be replaced with something that does not simply write to a file. 210 211 To use, write your own function for example, 212 $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 213 ${ 214 $ PetscErrorCode ierr; 215 $ 216 $ PetscFunctionBegin; 217 $ if (fd != stdout && fd != stderr) { handle regular files 218 $ ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr); 219 $ } else { 220 $ char buff[BIG]; 221 $ size_t length; 222 $ ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr); 223 $ now send buff to whatever stream or whatever you want 224 $ } 225 $ PetscFunctionReturn(0); 226 $} 227 then before the call to PetscInitialize() do the assignment 228 $ PetscVFPrintf = mypetscvfprintf; 229 230 Notes: For error messages this may be called by any process, for regular standard out it is 231 called only by process 0 of a given communicator 232 233 Developer Notes: this could be called by an error handler, if that happens then a recursion of the error handler may occur 234 and a crash 235 236 Level: developer 237 238 .seealso: PetscVSNPrintf(), PetscErrorPrintf() 239 240 @*/ 241 PetscErrorCode PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp) 242 { 243 char str[8*1024]; 244 PetscErrorCode ierr; 245 246 PetscFunctionBegin; 247 ierr = PetscVSNPrintf(str,sizeof(str),format,NULL,Argp);CHKERRQ(ierr); 248 fprintf(fd,"%s",str);CHKERRQ(ierr); 249 fflush(fd); 250 PetscFunctionReturn(0); 251 } 252 253 #undef __FUNCT__ 254 #define __FUNCT__ "PetscSNPrintf" 255 /*@C 256 PetscSNPrintf - Prints to a string of given length 257 258 Not Collective 259 260 Input Parameters: 261 + str - the string to print to 262 . len - the length of str 263 . format - the usual printf() format string 264 - any arguments 265 266 Level: intermediate 267 268 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 269 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 270 @*/ 271 PetscErrorCode PetscSNPrintf(char *str,size_t len,const char format[],...) 272 { 273 PetscErrorCode ierr; 274 size_t fullLength; 275 va_list Argp; 276 277 PetscFunctionBegin; 278 va_start(Argp,format); 279 ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr); 280 PetscFunctionReturn(0); 281 } 282 283 #undef __FUNCT__ 284 #define __FUNCT__ "PetscSNPrintfCount" 285 /*@C 286 PetscSNPrintfCount - Prints to a string of given length, returns count 287 288 Not Collective 289 290 Input Parameters: 291 + str - the string to print to 292 . len - the length of str 293 . format - the usual printf() format string 294 . countused - number of characters used 295 - any arguments 296 297 Level: intermediate 298 299 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 300 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf() 301 @*/ 302 PetscErrorCode PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...) 303 { 304 PetscErrorCode ierr; 305 va_list Argp; 306 307 PetscFunctionBegin; 308 va_start(Argp,countused); 309 ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr); 310 PetscFunctionReturn(0); 311 } 312 313 /* ----------------------------------------------------------------------- */ 314 315 PrintfQueue petsc_printfqueue = 0,petsc_printfqueuebase = 0; 316 int petsc_printfqueuelength = 0; 317 318 #undef __FUNCT__ 319 #define __FUNCT__ "PetscSynchronizedPrintf" 320 /*@C 321 PetscSynchronizedPrintf - Prints synchronized output from several processors. 322 Output of the first processor is followed by that of the second, etc. 323 324 Not Collective 325 326 Input Parameters: 327 + comm - the communicator 328 - format - the usual printf() format string 329 330 Level: intermediate 331 332 Notes: 333 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 334 from all the processors to be printed. 335 336 Fortran Note: 337 The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 338 That is, you can only pass a single character string from Fortran. 339 340 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 341 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 342 @*/ 343 PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 344 { 345 PetscErrorCode ierr; 346 PetscMPIInt rank; 347 348 PetscFunctionBegin; 349 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 350 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 351 352 /* First processor prints immediately to stdout */ 353 if (!rank) { 354 va_list Argp; 355 va_start(Argp,format); 356 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 357 if (petsc_history) { 358 va_start(Argp,format); 359 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 360 } 361 va_end(Argp); 362 } else { /* other processors add to local queue */ 363 va_list Argp; 364 PrintfQueue next; 365 size_t fullLength = 8191; 366 367 ierr = PetscNew(&next);CHKERRQ(ierr); 368 if (petsc_printfqueue) { 369 petsc_printfqueue->next = next; 370 petsc_printfqueue = next; 371 petsc_printfqueue->next = 0; 372 } else petsc_printfqueuebase = petsc_printfqueue = next; 373 petsc_printfqueuelength++; 374 next->size = -1; 375 while ((PetscInt)fullLength >= next->size) { 376 next->size = fullLength+1; 377 378 ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr); 379 va_start(Argp,format); 380 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 381 ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr); 382 va_end(Argp); 383 } 384 } 385 PetscFunctionReturn(0); 386 } 387 388 #undef __FUNCT__ 389 #define __FUNCT__ "PetscSynchronizedFPrintf" 390 /*@C 391 PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 392 several processors. Output of the first processor is followed by that of the 393 second, etc. 394 395 Not Collective 396 397 Input Parameters: 398 + comm - the communicator 399 . fd - the file pointer 400 - format - the usual printf() format string 401 402 Level: intermediate 403 404 Notes: 405 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 406 from all the processors to be printed. 407 408 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 409 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 410 411 @*/ 412 PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm,FILE *fp,const char format[],...) 413 { 414 PetscErrorCode ierr; 415 PetscMPIInt rank; 416 417 PetscFunctionBegin; 418 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 419 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 420 421 /* First processor prints immediately to fp */ 422 if (!rank) { 423 va_list Argp; 424 va_start(Argp,format); 425 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 426 if (petsc_history && (fp !=petsc_history)) { 427 va_start(Argp,format); 428 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 429 } 430 va_end(Argp); 431 } else { /* other processors add to local queue */ 432 va_list Argp; 433 PrintfQueue next; 434 size_t fullLength = 8191; 435 ierr = PetscNew(&next);CHKERRQ(ierr); 436 if (petsc_printfqueue) { 437 petsc_printfqueue->next = next; 438 petsc_printfqueue = next; 439 petsc_printfqueue->next = 0; 440 } else petsc_printfqueuebase = petsc_printfqueue = next; 441 petsc_printfqueuelength++; 442 next->size = -1; 443 while ((PetscInt)fullLength >= next->size) { 444 next->size = fullLength+1; 445 ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr); 446 va_start(Argp,format); 447 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 448 ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr); 449 va_end(Argp); 450 } 451 } 452 PetscFunctionReturn(0); 453 } 454 455 #undef __FUNCT__ 456 #define __FUNCT__ "PetscSynchronizedFlush" 457 /*@C 458 PetscSynchronizedFlush - Flushes to the screen output from all processors 459 involved in previous PetscSynchronizedPrintf() calls. 460 461 Collective on MPI_Comm 462 463 Input Parameters: 464 + comm - the communicator 465 - fd - the file pointer (valid on process 0 of the communicator) 466 467 Level: intermediate 468 469 Notes: 470 Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with 471 different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush(). 472 473 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 474 PetscViewerASCIISynchronizedPrintf() 475 @*/ 476 PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm,FILE *fd) 477 { 478 PetscErrorCode ierr; 479 PetscMPIInt rank,size,tag,i,j,n = 0,dummy = 0; 480 char *message; 481 MPI_Status status; 482 483 PetscFunctionBegin; 484 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 485 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 486 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 487 488 /* First processor waits for messages from all other processors */ 489 if (!rank) { 490 if (!fd) fd = PETSC_STDOUT; 491 for (i=1; i<size; i++) { 492 /* to prevent a flood of messages to process zero, request each message separately */ 493 ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr); 494 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 495 for (j=0; j<n; j++) { 496 PetscMPIInt size = 0; 497 498 ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 499 ierr = PetscMalloc1(size, &message);CHKERRQ(ierr); 500 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr); 501 ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr); 502 ierr = PetscFree(message);CHKERRQ(ierr); 503 } 504 } 505 } else { /* other processors send queue to processor 0 */ 506 PrintfQueue next = petsc_printfqueuebase,previous; 507 508 ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr); 509 ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 510 for (i=0; i<petsc_printfqueuelength; i++) { 511 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 512 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr); 513 previous = next; 514 next = next->next; 515 ierr = PetscFree(previous->string);CHKERRQ(ierr); 516 ierr = PetscFree(previous);CHKERRQ(ierr); 517 } 518 petsc_printfqueue = 0; 519 petsc_printfqueuelength = 0; 520 } 521 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 522 PetscFunctionReturn(0); 523 } 524 525 /* ---------------------------------------------------------------------------------------*/ 526 527 #undef __FUNCT__ 528 #define __FUNCT__ "PetscFPrintf" 529 /*@C 530 PetscFPrintf - Prints to a file, only from the first 531 processor in the communicator. 532 533 Not Collective 534 535 Input Parameters: 536 + comm - the communicator 537 . fd - the file pointer 538 - format - the usual printf() format string 539 540 Level: intermediate 541 542 Fortran Note: 543 This routine is not supported in Fortran. 544 545 Concepts: printing^in parallel 546 Concepts: printf^in parallel 547 548 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 549 PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 550 @*/ 551 PetscErrorCode PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 552 { 553 PetscErrorCode ierr; 554 PetscMPIInt rank; 555 556 PetscFunctionBegin; 557 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 558 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 559 if (!rank) { 560 va_list Argp; 561 va_start(Argp,format); 562 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 563 if (petsc_history && (fd !=petsc_history)) { 564 va_start(Argp,format); 565 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 566 } 567 va_end(Argp); 568 } 569 PetscFunctionReturn(0); 570 } 571 572 #undef __FUNCT__ 573 #define __FUNCT__ "PetscPrintf" 574 /*@C 575 PetscPrintf - Prints to standard out, only from the first 576 processor in the communicator. Calls from other processes are ignored. 577 578 Not Collective 579 580 Input Parameters: 581 + comm - the communicator 582 - format - the usual printf() format string 583 584 Level: intermediate 585 586 Fortran Note: 587 The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 588 That is, you can only pass a single character string from Fortran. 589 590 Concepts: printing^in parallel 591 Concepts: printf^in parallel 592 593 .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 594 @*/ 595 PetscErrorCode PetscPrintf(MPI_Comm comm,const char format[],...) 596 { 597 PetscErrorCode ierr; 598 PetscMPIInt rank; 599 600 PetscFunctionBegin; 601 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 602 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 603 if (!rank) { 604 va_list Argp; 605 va_start(Argp,format); 606 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 607 if (petsc_history) { 608 va_start(Argp,format); 609 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 610 } 611 va_end(Argp); 612 } 613 PetscFunctionReturn(0); 614 } 615 616 /* ---------------------------------------------------------------------------------------*/ 617 #undef __FUNCT__ 618 #define __FUNCT__ "PetscHelpPrintfDefault" 619 /*@C 620 PetscHelpPrintf - All PETSc help messages are passing through this function. You can change how help messages are printed by 621 replacinng it with something that does not simply write to a stdout. 622 623 To use, write your own function for example, 624 $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....) 625 ${ 626 $ PetscFunctionReturn(0); 627 $} 628 then before the call to PetscInitialize() do the assignment 629 $ PetscHelpPrintf = mypetschelpprintf; 630 631 Note: the default routine used is called PetscHelpPrintfDefault(). 632 633 Level: developer 634 635 .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf() 636 @*/ 637 PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 638 { 639 PetscErrorCode ierr; 640 PetscMPIInt rank; 641 642 PetscFunctionBegin; 643 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 644 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 645 if (!rank) { 646 va_list Argp; 647 va_start(Argp,format); 648 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 649 if (petsc_history) { 650 va_start(Argp,format); 651 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 652 } 653 va_end(Argp); 654 } 655 PetscFunctionReturn(0); 656 } 657 658 /* ---------------------------------------------------------------------------------------*/ 659 660 661 #undef __FUNCT__ 662 #define __FUNCT__ "PetscSynchronizedFGets" 663 /*@C 664 PetscSynchronizedFGets - Several processors all get the same line from a file. 665 666 Collective on MPI_Comm 667 668 Input Parameters: 669 + comm - the communicator 670 . fd - the file pointer 671 - len - the length of the output buffer 672 673 Output Parameter: 674 . string - the line read from the file, at end of file string[0] == 0 675 676 Level: intermediate 677 678 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 679 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 680 681 @*/ 682 PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[]) 683 { 684 PetscErrorCode ierr; 685 PetscMPIInt rank; 686 687 PetscFunctionBegin; 688 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 689 690 if (!rank) { 691 char *ptr = fgets(string, len, fp); 692 693 if (!ptr) { 694 string[0] = 0; 695 if (!feof(fp)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 696 } 697 } 698 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 699 PetscFunctionReturn(0); 700 } 701 702 #if defined(PETSC_HAVE_CLOSURES) 703 int (^SwiftClosure)(const char*) = 0; 704 705 #undef __FUNCT__ 706 #define __FUNCT__ "PetscVFPrintfToString" 707 PetscErrorCode PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp) 708 { 709 PetscErrorCode ierr; 710 711 PetscFunctionBegin; 712 if (fd != stdout && fd != stderr) { /* handle regular files */ 713 ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr); 714 } else { 715 size_t len=8*1024,length; 716 char buf[len]; 717 718 ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr); 719 ierr = SwiftClosure(buf);CHKERRQ(ierr); 720 } 721 PetscFunctionReturn(0); 722 } 723 724 /* 725 Provide a Swift function that processes all the PETSc calls to PetscVFPrintf() 726 */ 727 PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*)) 728 { 729 PetscVFPrintf = PetscVFPrintfToString; 730 SwiftClosure = closure; 731 return 0; 732 } 733 #endif 734 735 #if defined(PETSC_HAVE_MATLAB_ENGINE) 736 #include <mex.h> 737 #undef __FUNCT__ 738 #define __FUNCT__ "PetscVFPrintf_Matlab" 739 PetscErrorCode PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp) 740 { 741 PetscErrorCode ierr; 742 743 PetscFunctionBegin; 744 if (fd != stdout && fd != stderr) { /* handle regular files */ 745 ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr); 746 } else { 747 size_t len=8*1024,length; 748 char buf[len]; 749 750 ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr); 751 mexPrintf("%s",buf); 752 } 753 PetscFunctionReturn(0); 754 } 755 #endif 756 757 #undef __FUNCT__ 758 #define __FUNCT__ "PetscFormatStrip" 759 /*@C 760 PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 761 762 Input Parameters: 763 . format - the PETSc format string 764 765 Level: developer 766 767 @*/ 768 PetscErrorCode PetscFormatStrip(char *format) 769 { 770 size_t loc1 = 0, loc2 = 0; 771 772 PetscFunctionBegin; 773 while (format[loc2]) { 774 if (format[loc2] == '%') { 775 format[loc1++] = format[loc2++]; 776 while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 777 } 778 format[loc1++] = format[loc2++]; 779 } 780 PetscFunctionReturn(0); 781 } 782 783