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