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 newformat[j++] = format[i++]; 88 } 89 newformat[j] = 0; 90 PetscFunctionReturn(0); 91 } 92 93 #undef __FUNCT__ 94 #define __FUNCT__ "PetscVSNPrintf" 95 /*@C 96 PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 97 function arguments into a string using the format statement. 98 99 Input Parameters: 100 + str - location to put result 101 . len - the amount of space in str 102 + format - the PETSc format string 103 - fullLength - the amount of space in str actually used. 104 105 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 106 a recursion will occur and possible crash. 107 108 Level: developer 109 110 @*/ 111 PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) 112 { 113 char *newformat; 114 char formatbuf[8*1024]; 115 size_t oldLength,length; 116 int fullLengthInt; 117 PetscErrorCode ierr; 118 119 PetscFunctionBegin; 120 ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); 121 if (oldLength < 8*1024) { 122 newformat = formatbuf; 123 oldLength = 8*1024-1; 124 } else { 125 oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength); 126 ierr = PetscMalloc(oldLength * sizeof(char), &newformat);CHKERRQ(ierr); 127 } 128 PetscFormatConvert(format,newformat,oldLength); 129 ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr); 130 #if 0 131 if (length > len) newformat[len] = '\0'; 132 #endif 133 #if defined(PETSC_HAVE_VSNPRINTF_CHAR) 134 fullLengthInt = vsnprintf(str,len,newformat,(char*)Argp); 135 #elif defined(PETSC_HAVE_VSNPRINTF) 136 fullLengthInt = vsnprintf(str,len,newformat,Argp); 137 #elif defined(PETSC_HAVE__VSNPRINTF) 138 fullLengthInt = _vsnprintf(str,len,newformat,Argp); 139 #else 140 #error "vsnprintf not found" 141 #endif 142 if (fullLengthInt < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"vsnprintf() failed"); 143 if (fullLength) *fullLength = (size_t)fullLengthInt; 144 if (oldLength >= 8*1024) { 145 ierr = PetscFree(newformat);CHKERRQ(ierr); 146 } 147 PetscFunctionReturn(0); 148 } 149 150 #undef __FUNCT__ 151 #define __FUNCT__ "PetscVFPrintfDefault" 152 /*@C 153 PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 154 can be replaced with something that does not simply write to a file. 155 156 To use, write your own function for example, 157 $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 158 ${ 159 $ PetscErrorCode ierr; 160 $ 161 $ PetscFunctionBegin; 162 $ if (fd != stdout && fd != stderr) { handle regular files 163 $ ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr); 164 $ } else { 165 $ char buff[BIG]; 166 $ size_t length; 167 $ ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr); 168 $ now send buff to whatever stream or whatever you want 169 $ } 170 $ PetscFunctionReturn(0); 171 $} 172 then before the call to PetscInitialize() do the assignment 173 $ PetscVFPrintf = mypetscvfprintf; 174 175 Notes: For error messages this may be called by any process, for regular standard out it is 176 called only by process 0 of a given communicator 177 178 Developer Notes: this could be called by an error handler, if that happens then a recursion of the error handler may occur 179 and a crash 180 181 Level: developer 182 183 .seealso: PetscVSNPrintf(), PetscErrorPrintf() 184 185 @*/ 186 PetscErrorCode PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp) 187 { 188 char *newformat; 189 char formatbuf[8*1024]; 190 size_t oldLength; 191 PetscErrorCode ierr; 192 193 PetscFunctionBegin; 194 ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); 195 if (oldLength < 8*1024) { 196 newformat = formatbuf; 197 oldLength = 8*1024-1; 198 } else { 199 oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength); 200 ierr = PetscMalloc(oldLength * sizeof(char), &newformat);CHKERRQ(ierr); 201 } 202 ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr); 203 204 #if defined(PETSC_HAVE_VFPRINTF_CHAR) 205 vfprintf(fd,newformat,(char*)Argp); 206 #else 207 vfprintf(fd,newformat,Argp); 208 #endif 209 fflush(fd); 210 if (oldLength >= 8*1024) { 211 ierr = PetscFree(newformat);CHKERRQ(ierr); 212 } 213 PetscFunctionReturn(0); 214 } 215 216 #undef __FUNCT__ 217 #define __FUNCT__ "PetscSNPrintf" 218 /*@C 219 PetscSNPrintf - Prints to a string of given length 220 221 Not Collective 222 223 Input Parameters: 224 + str - the string to print to 225 . len - the length of str 226 . format - the usual printf() format string 227 - any arguments 228 229 Level: intermediate 230 231 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 232 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 233 @*/ 234 PetscErrorCode PetscSNPrintf(char *str,size_t len,const char format[],...) 235 { 236 PetscErrorCode ierr; 237 size_t fullLength; 238 va_list Argp; 239 240 PetscFunctionBegin; 241 va_start(Argp,format); 242 ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr); 243 PetscFunctionReturn(0); 244 } 245 246 #undef __FUNCT__ 247 #define __FUNCT__ "PetscSNPrintfCount" 248 /*@C 249 PetscSNPrintfCount - Prints to a string of given length, returns count 250 251 Not Collective 252 253 Input Parameters: 254 + str - the string to print to 255 . len - the length of str 256 . format - the usual printf() format string 257 . countused - number of characters used 258 - any arguments 259 260 Level: intermediate 261 262 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 263 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf() 264 @*/ 265 PetscErrorCode PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...) 266 { 267 PetscErrorCode ierr; 268 va_list Argp; 269 270 PetscFunctionBegin; 271 va_start(Argp,countused); 272 ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr); 273 PetscFunctionReturn(0); 274 } 275 276 /* ----------------------------------------------------------------------- */ 277 278 PrintfQueue petsc_printfqueue = 0,petsc_printfqueuebase = 0; 279 int petsc_printfqueuelength = 0; 280 FILE *petsc_printfqueuefile = PETSC_NULL; 281 282 #undef __FUNCT__ 283 #define __FUNCT__ "PetscSynchronizedPrintf" 284 /*@C 285 PetscSynchronizedPrintf - Prints synchronized output from several processors. 286 Output of the first processor is followed by that of the second, etc. 287 288 Not Collective 289 290 Input Parameters: 291 + comm - the communicator 292 - format - the usual printf() format string 293 294 Level: intermediate 295 296 Notes: 297 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 298 from all the processors to be printed. 299 300 Fortran Note: 301 The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 302 That is, you can only pass a single character string from Fortran. 303 304 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 305 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 306 @*/ 307 PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 308 { 309 PetscErrorCode ierr; 310 PetscMPIInt rank; 311 312 PetscFunctionBegin; 313 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 314 315 /* First processor prints immediately to stdout */ 316 if (!rank) { 317 va_list Argp; 318 va_start(Argp,format); 319 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 320 if (petsc_history) { 321 va_start(Argp,format); 322 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 323 } 324 va_end(Argp); 325 } else { /* other processors add to local queue */ 326 va_list Argp; 327 PrintfQueue next; 328 size_t fullLength = 8191; 329 330 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 331 if (petsc_printfqueue) { 332 petsc_printfqueue->next = next; 333 petsc_printfqueue = next; 334 petsc_printfqueue->next = 0; 335 } else petsc_printfqueuebase = petsc_printfqueue = next; 336 petsc_printfqueuelength++; 337 next->size = -1; 338 while ((PetscInt)fullLength >= next->size) { 339 next->size = fullLength+1; 340 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 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) { 401 petsc_printfqueue->next = next; 402 petsc_printfqueue = next; 403 petsc_printfqueue->next = 0; 404 } else petsc_printfqueuebase = petsc_printfqueue = next; 405 petsc_printfqueuelength++; 406 next->size = -1; 407 while ((PetscInt)fullLength >= next->size) { 408 next->size = fullLength+1; 409 ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr); 410 va_start(Argp,format); 411 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 412 ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr); 413 va_end(Argp); 414 } 415 } 416 PetscFunctionReturn(0); 417 } 418 419 #undef __FUNCT__ 420 #define __FUNCT__ "PetscSynchronizedFlush" 421 /*@ 422 PetscSynchronizedFlush - Flushes to the screen output from all processors 423 involved in previous PetscSynchronizedPrintf() calls. 424 425 Collective on MPI_Comm 426 427 Input Parameters: 428 . comm - the communicator 429 430 Level: intermediate 431 432 Notes: 433 Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with 434 different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush(). 435 436 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 437 PetscViewerASCIISynchronizedPrintf() 438 @*/ 439 PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm) 440 { 441 PetscErrorCode ierr; 442 PetscMPIInt rank,size,tag,i,j,n,dummy = 0; 443 char *message; 444 MPI_Status status; 445 FILE *fd; 446 447 PetscFunctionBegin; 448 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 449 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 450 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 451 452 /* First processor waits for messages from all other processors */ 453 if (!rank) { 454 if (petsc_printfqueuefile) fd = petsc_printfqueuefile; 455 else fd = PETSC_STDOUT; 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)) 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