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