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