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 PetscFunctionReturn(0); 349 } 350 351 #undef __FUNCT__ 352 #define __FUNCT__ "PetscSynchronizedFPrintf" 353 /*@C 354 PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 355 several processors. Output of the first processor is followed by that of the 356 second, etc. 357 358 Not Collective 359 360 Input Parameters: 361 + comm - the communicator 362 . fd - the file pointer 363 - format - the usual printf() format string 364 365 Level: intermediate 366 367 Notes: 368 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 369 from all the processors to be printed. 370 371 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 372 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 373 374 @*/ 375 PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...) 376 { 377 PetscErrorCode ierr; 378 PetscMPIInt rank; 379 380 PetscFunctionBegin; 381 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 382 383 /* First processor prints immediately to fp */ 384 if (!rank) { 385 va_list Argp; 386 va_start(Argp,format); 387 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 388 petsc_printfqueuefile = fp; 389 if (petsc_history && (fp !=petsc_history)) { 390 va_start(Argp,format); 391 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 392 } 393 va_end(Argp); 394 } else { /* other processors add to local queue */ 395 va_list Argp; 396 PrintfQueue next; 397 size_t fullLength = 8191; 398 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 399 if (petsc_printfqueue) {petsc_printfqueue->next = next; petsc_printfqueue = next; petsc_printfqueue->next = 0;} 400 else {petsc_printfqueuebase = petsc_printfqueue = next;} 401 petsc_printfqueuelength++; 402 next->size = -1; 403 while ((PetscInt)fullLength >= next->size) { 404 next->size = fullLength+1; 405 ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr); 406 va_start(Argp,format); 407 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 408 ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr); 409 va_end(Argp); 410 } 411 } 412 PetscFunctionReturn(0); 413 } 414 415 #undef __FUNCT__ 416 #define __FUNCT__ "PetscSynchronizedFlush" 417 /*@ 418 PetscSynchronizedFlush - Flushes to the screen output from all processors 419 involved in previous PetscSynchronizedPrintf() calls. 420 421 Collective on MPI_Comm 422 423 Input Parameters: 424 . comm - the communicator 425 426 Level: intermediate 427 428 Notes: 429 Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with 430 different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush(). 431 432 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 433 PetscViewerASCIISynchronizedPrintf() 434 @*/ 435 PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm) 436 { 437 PetscErrorCode ierr; 438 PetscMPIInt rank,size,tag,i,j,n,dummy = 0; 439 char *message; 440 MPI_Status status; 441 FILE *fd; 442 443 PetscFunctionBegin; 444 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 445 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 446 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 447 448 /* First processor waits for messages from all other processors */ 449 if (!rank) { 450 if (petsc_printfqueuefile) { 451 fd = petsc_printfqueuefile; 452 } else { 453 fd = PETSC_STDOUT; 454 } 455 for (i=1; i<size; i++) { 456 /* to prevent a flood of messages to process zero, request each message separately */ 457 ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr); 458 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 459 for (j=0; j<n; j++) { 460 PetscMPIInt size; 461 462 ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 463 ierr = PetscMalloc(size * sizeof(char), &message);CHKERRQ(ierr); 464 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr); 465 ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr); 466 ierr = PetscFree(message);CHKERRQ(ierr); 467 } 468 } 469 petsc_printfqueuefile = PETSC_NULL; 470 } else { /* other processors send queue to processor 0 */ 471 PrintfQueue next = petsc_printfqueuebase,previous; 472 473 ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr); 474 ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 475 for (i=0; i<petsc_printfqueuelength; i++) { 476 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 477 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr); 478 previous = next; 479 next = next->next; 480 ierr = PetscFree(previous->string);CHKERRQ(ierr); 481 ierr = PetscFree(previous);CHKERRQ(ierr); 482 } 483 petsc_printfqueue = 0; 484 petsc_printfqueuelength = 0; 485 } 486 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 487 PetscFunctionReturn(0); 488 } 489 490 /* ---------------------------------------------------------------------------------------*/ 491 492 #undef __FUNCT__ 493 #define __FUNCT__ "PetscFPrintf" 494 /*@C 495 PetscFPrintf - Prints to a file, only from the first 496 processor in the communicator. 497 498 Not Collective 499 500 Input Parameters: 501 + comm - the communicator 502 . fd - the file pointer 503 - format - the usual printf() format string 504 505 Level: intermediate 506 507 Fortran Note: 508 This routine is not supported in Fortran. 509 510 Concepts: printing^in parallel 511 Concepts: printf^in parallel 512 513 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 514 PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 515 @*/ 516 PetscErrorCode PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 517 { 518 PetscErrorCode ierr; 519 PetscMPIInt rank; 520 521 PetscFunctionBegin; 522 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 523 if (!rank) { 524 va_list Argp; 525 va_start(Argp,format); 526 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 527 if (petsc_history && (fd !=petsc_history)) { 528 va_start(Argp,format); 529 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 530 } 531 va_end(Argp); 532 } 533 PetscFunctionReturn(0); 534 } 535 536 #undef __FUNCT__ 537 #define __FUNCT__ "PetscPrintf" 538 /*@C 539 PetscPrintf - Prints to standard out, only from the first 540 processor in the communicator. Calls from other processes are ignored. 541 542 Not Collective 543 544 Input Parameters: 545 + comm - the communicator 546 - format - the usual printf() format string 547 548 Level: intermediate 549 550 Fortran Note: 551 The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 552 That is, you can only pass a single character string from Fortran. 553 554 Concepts: printing^in parallel 555 Concepts: printf^in parallel 556 557 .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 558 @*/ 559 PetscErrorCode PetscPrintf(MPI_Comm comm,const char format[],...) 560 { 561 PetscErrorCode ierr; 562 PetscMPIInt rank; 563 564 PetscFunctionBegin; 565 if (!comm) comm = PETSC_COMM_WORLD; 566 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 567 if (!rank) { 568 va_list Argp; 569 va_start(Argp,format); 570 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 571 if (petsc_history) { 572 va_start(Argp,format); 573 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 574 } 575 va_end(Argp); 576 } 577 PetscFunctionReturn(0); 578 } 579 580 /* ---------------------------------------------------------------------------------------*/ 581 #undef __FUNCT__ 582 #define __FUNCT__ "PetscHelpPrintfDefault" 583 /*@C 584 PetscHelpPrintf - All PETSc help messages are passing through this function. You can change how help messages are printed by 585 replacinng it with something that does not simply write to a stdout. 586 587 To use, write your own function for example, 588 $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....) 589 ${ 590 $ PetscFunctionReturn(0); 591 $} 592 then before the call to PetscInitialize() do the assignment 593 $ PetscHelpPrintf = mypetschelpprintf; 594 595 Note: the default routine used is called PetscHelpPrintfDefault(). 596 597 Level: developer 598 599 .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf() 600 @*/ 601 PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 602 { 603 PetscErrorCode ierr; 604 PetscMPIInt rank; 605 606 PetscFunctionBegin; 607 if (!comm) comm = PETSC_COMM_WORLD; 608 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 609 if (!rank) { 610 va_list Argp; 611 va_start(Argp,format); 612 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 613 if (petsc_history) { 614 va_start(Argp,format); 615 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 616 } 617 va_end(Argp); 618 } 619 PetscFunctionReturn(0); 620 } 621 622 /* ---------------------------------------------------------------------------------------*/ 623 624 625 #undef __FUNCT__ 626 #define __FUNCT__ "PetscSynchronizedFGets" 627 /*@C 628 PetscSynchronizedFGets - Several processors all get the same line from a file. 629 630 Collective on MPI_Comm 631 632 Input Parameters: 633 + comm - the communicator 634 . fd - the file pointer 635 - len - the length of the output buffer 636 637 Output Parameter: 638 . string - the line read from the file 639 640 Level: intermediate 641 642 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 643 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 644 645 @*/ 646 PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[]) 647 { 648 PetscErrorCode ierr; 649 PetscMPIInt rank; 650 651 PetscFunctionBegin; 652 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 653 654 if (!rank) { 655 char *ptr = fgets(string, len, fp); 656 657 if (!ptr) { 658 if (feof(fp)) { 659 len = 0; 660 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 661 } 662 } 663 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 664 PetscFunctionReturn(0); 665 } 666 667 #if defined(PETSC_HAVE_MATLAB_ENGINE) 668 #include <mex.h> 669 #undef __FUNCT__ 670 #define __FUNCT__ "PetscVFPrintf_Matlab" 671 PetscErrorCode PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp) 672 { 673 PetscErrorCode ierr; 674 675 PetscFunctionBegin; 676 if (fd != stdout && fd != stderr) { /* handle regular files */ 677 ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr); 678 } else { 679 size_t len=8*1024,length; 680 char buf[len]; 681 682 ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr); 683 mexPrintf("%s",buf); 684 } 685 PetscFunctionReturn(0); 686 } 687 #endif 688 689 #undef __FUNCT__ 690 #define __FUNCT__ "PetscFormatStrip" 691 /*@C 692 PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 693 694 Input Parameters: 695 . format - the PETSc format string 696 697 Level: developer 698 699 @*/ 700 PetscErrorCode PetscFormatStrip(char *format) 701 { 702 size_t loc1 = 0, loc2 = 0; 703 704 PetscFunctionBegin; 705 while (format[loc2]) { 706 if (format[loc2] == '%') { 707 format[loc1++] = format[loc2++]; 708 while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 709 } 710 format[loc1++] = format[loc2++]; 711 } 712 PetscFunctionReturn(0); 713 } 714 715