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