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 PETSC_INTERN 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 = NULL; 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 = NULL; 23 24 /*@C 25 PetscFormatConvertGetSize - Gets the length of a string needed to hold format converted with PetscFormatConvert() 26 27 Input Parameter: 28 . format - the PETSc format string 29 30 Output Parameter: 31 . size - the needed length of the new format 32 33 Level: developer 34 35 .seealso: PetscFormatConvert(), PetscVSNPrintf(), PetscVFPrintf() 36 37 @*/ 38 PetscErrorCode PetscFormatConvertGetSize(const char *format,size_t *size) 39 { 40 size_t sz = 0; 41 PetscInt i = 0; 42 43 PetscFunctionBegin; 44 PetscValidCharPointer(format,1); 45 PetscValidPointer(size,2); 46 while (format[i]) { 47 if (format[i] == '%') { 48 if (format[i+1] == '%') { 49 i += 2; 50 sz += 2; 51 continue; 52 } 53 /* Find the letter */ 54 while (format[i] && (format[i] <= '9')) {++i;++sz;} 55 switch (format[i]) { 56 #if PetscDefined(USE_64BIT_INDICES) 57 case 'D': 58 sz += 2; 59 break; 60 #endif 61 case 'g': 62 sz += 4; 63 default: 64 break; 65 } 66 } 67 ++i; 68 ++sz; 69 } 70 *size = sz+1; /* space for NULL character */ 71 PetscFunctionReturn(0); 72 } 73 74 /*@C 75 PetscFormatConvert - Takes a PETSc format string and converts the %D to %d for 32 bit PETSc indices and %lld for 64 bit PETSc indices. Also 76 converts %g to [|%g|] so that PetscVSNPrintf() can easily insure all %g formatted numbers have a decimal point when printed. 77 78 Input Parameters: 79 + format - the PETSc format string 80 . newformat - the location to put the new format 81 - size - the length of newformat, you can use PetscFormatConvertGetSize() to compute the needed size 82 83 Note: this exists so we can have the same code when PetscInt is either int or long long int 84 85 Level: developer 86 87 .seealso: PetscFormatConvertGetSize(), PetscVSNPrintf(), PetscVFPrintf() 88 89 @*/ 90 PetscErrorCode PetscFormatConvert(const char *format,char *newformat) 91 { 92 PetscInt i = 0, j = 0; 93 94 PetscFunctionBegin; 95 while (format[i]) { 96 if (format[i] == '%' && format[i+1] == '%') { 97 newformat[j++] = format[i++]; 98 newformat[j++] = format[i++]; 99 } else if (format[i] == '%') { 100 if (format[i+1] == 'g') { 101 newformat[j++] = '['; 102 newformat[j++] = '|'; 103 } 104 /* Find the letter */ 105 for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 106 switch (format[i]) { 107 case 'D': 108 #if !defined(PETSC_USE_64BIT_INDICES) 109 newformat[j++] = 'd'; 110 #else 111 newformat[j++] = 'l'; 112 newformat[j++] = 'l'; 113 newformat[j++] = 'd'; 114 #endif 115 break; 116 case 'g': 117 newformat[j++] = format[i]; 118 if (format[i-1] == '%') { 119 newformat[j++] = '|'; 120 newformat[j++] = ']'; 121 } 122 break; 123 case 'G': 124 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%G format is no longer supported, use %%g and cast the argument to double"); 125 case 'F': 126 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%F format is no longer supported, use %%f and cast the argument to double"); 127 default: 128 newformat[j++] = format[i]; 129 break; 130 } 131 i++; 132 } else newformat[j++] = format[i++]; 133 } 134 newformat[j] = 0; 135 PetscFunctionReturn(0); 136 } 137 138 #define PETSCDEFAULTBUFFERSIZE 8*1024 139 140 /*@C 141 PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 142 function arguments into a string using the format statement. 143 144 Input Parameters: 145 + str - location to put result 146 . len - the amount of space in str 147 + format - the PETSc format string 148 - fullLength - the amount of space in str actually used. 149 150 Developer Notes: 151 this function may be called from an error handler, if an error occurs when it is called by the error handler than likely 152 a recursion will occur and possible crash. 153 154 Level: developer 155 156 .seealso: PetscVSNPrintf(), PetscErrorPrintf(), PetscVPrintf() 157 158 @*/ 159 PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) 160 { 161 char *newformat = NULL; 162 char formatbuf[PETSCDEFAULTBUFFERSIZE]; 163 size_t newLength; 164 PetscErrorCode ierr; 165 int flen; 166 167 PetscFunctionBegin; 168 ierr = PetscFormatConvertGetSize(format,&newLength);CHKERRQ(ierr); 169 if (newLength < PETSCDEFAULTBUFFERSIZE) { 170 newformat = formatbuf; 171 newLength = PETSCDEFAULTBUFFERSIZE-1; 172 } else { 173 ierr = PetscMalloc1(newLength, &newformat);CHKERRQ(ierr); 174 } 175 ierr = PetscFormatConvert(format,newformat);CHKERRQ(ierr); 176 #if defined(PETSC_HAVE_VSNPRINTF) 177 flen = vsnprintf(str,len,newformat,Argp); 178 #else 179 #error "vsnprintf not found" 180 #endif 181 if (newLength > PETSCDEFAULTBUFFERSIZE-1) { 182 ierr = PetscFree(newformat);CHKERRQ(ierr); 183 } 184 { 185 PetscBool foundedot; 186 size_t cnt = 0,ncnt = 0,leng; 187 ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); 188 if (leng > 4) { 189 for (cnt=0; cnt<leng-4; cnt++) { 190 if (str[cnt] == '[' && str[cnt+1] == '|') { 191 flen -= 4; 192 cnt++; cnt++; 193 foundedot = PETSC_FALSE; 194 for (; cnt<leng-1; cnt++) { 195 if (str[cnt] == '|' && str[cnt+1] == ']') { 196 cnt++; 197 if (!foundedot) str[ncnt++] = '.'; 198 ncnt--; 199 break; 200 } else { 201 if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 202 str[ncnt++] = str[cnt]; 203 } 204 } 205 } else { 206 str[ncnt] = str[cnt]; 207 } 208 ncnt++; 209 } 210 while (cnt < leng) { 211 str[ncnt] = str[cnt]; ncnt++; cnt++; 212 } 213 str[ncnt] = 0; 214 } 215 } 216 #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 217 /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 218 { 219 size_t cnt = 0,ncnt = 0,leng; 220 ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); 221 if (leng > 5) { 222 for (cnt=0; cnt<leng-4; cnt++) { 223 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') { 224 str[ncnt] = str[cnt]; ncnt++; cnt++; 225 str[ncnt] = str[cnt]; ncnt++; cnt++; cnt++; 226 str[ncnt] = str[cnt]; 227 } else { 228 str[ncnt] = str[cnt]; 229 } 230 ncnt++; 231 } 232 while (cnt < leng) { 233 str[ncnt] = str[cnt]; ncnt++; cnt++; 234 } 235 str[ncnt] = 0; 236 } 237 } 238 #endif 239 if (fullLength) *fullLength = 1 + (size_t) flen; 240 PetscFunctionReturn(0); 241 } 242 243 /*@C 244 PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 245 can be replaced with something that does not simply write to a file. 246 247 To use, write your own function for example, 248 $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 249 ${ 250 $ PetscErrorCode ierr; 251 $ 252 $ PetscFunctionBegin; 253 $ if (fd != stdout && fd != stderr) { handle regular files 254 $ ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr); 255 $ } else { 256 $ char buff[BIG]; 257 $ size_t length; 258 $ ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr); 259 $ now send buff to whatever stream or whatever you want 260 $ } 261 $ PetscFunctionReturn(0); 262 $} 263 then before the call to PetscInitialize() do the assignment 264 $ PetscVFPrintf = mypetscvfprintf; 265 266 Notes: 267 For error messages this may be called by any process, for regular standard out it is 268 called only by process 0 of a given communicator 269 270 Developer Notes: 271 this could be called by an error handler, if that happens then a recursion of the error handler may occur 272 and a crash 273 274 Level: developer 275 276 .seealso: PetscVSNPrintf(), PetscErrorPrintf() 277 278 @*/ 279 PetscErrorCode PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp) 280 { 281 char str[PETSCDEFAULTBUFFERSIZE]; 282 char *buff = str; 283 size_t fullLength; 284 PetscErrorCode ierr; 285 #if defined(PETSC_HAVE_VA_COPY) 286 va_list Argpcopy; 287 #endif 288 289 PetscFunctionBegin; 290 #if defined(PETSC_HAVE_VA_COPY) 291 va_copy(Argpcopy,Argp); 292 #endif 293 ierr = PetscVSNPrintf(str,sizeof(str),format,&fullLength,Argp);CHKERRQ(ierr); 294 if (fullLength > sizeof(str)) { 295 ierr = PetscMalloc1(fullLength,&buff);CHKERRQ(ierr); 296 #if defined(PETSC_HAVE_VA_COPY) 297 ierr = PetscVSNPrintf(buff,fullLength,format,NULL,Argpcopy);CHKERRQ(ierr); 298 #else 299 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"C89 does not support va_copy() hence cannot print long strings with PETSc printing routines"); 300 #endif 301 } 302 fprintf(fd,"%s",buff); 303 fflush(fd); 304 if (buff != str) { 305 ierr = PetscFree(buff);CHKERRQ(ierr); 306 } 307 PetscFunctionReturn(0); 308 } 309 310 /*@C 311 PetscSNPrintf - Prints to a string of given length 312 313 Not Collective 314 315 Input Parameters: 316 + str - the string to print to 317 . len - the length of str 318 . format - the usual printf() format string 319 - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 320 321 Level: intermediate 322 323 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 324 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscVFPrintf() 325 @*/ 326 PetscErrorCode PetscSNPrintf(char *str,size_t len,const char format[],...) 327 { 328 PetscErrorCode ierr; 329 size_t fullLength; 330 va_list Argp; 331 332 PetscFunctionBegin; 333 va_start(Argp,format); 334 ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr); 335 PetscFunctionReturn(0); 336 } 337 338 /*@C 339 PetscSNPrintfCount - Prints to a string of given length, returns count 340 341 Not Collective 342 343 Input Parameters: 344 + str - the string to print to 345 . len - the length of str 346 . format - the usual printf() format string 347 - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 348 349 Output Parameter: 350 . countused - number of characters used 351 352 Level: intermediate 353 354 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 355 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf(), PetscVFPrintf() 356 @*/ 357 PetscErrorCode PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...) 358 { 359 PetscErrorCode ierr; 360 va_list Argp; 361 362 PetscFunctionBegin; 363 va_start(Argp,countused); 364 ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr); 365 PetscFunctionReturn(0); 366 } 367 368 /* ----------------------------------------------------------------------- */ 369 370 PrintfQueue petsc_printfqueue = NULL,petsc_printfqueuebase = NULL; 371 int petsc_printfqueuelength = 0; 372 373 /*@C 374 PetscSynchronizedPrintf - Prints synchronized output from several processors. 375 Output of the first processor is followed by that of the second, etc. 376 377 Not Collective 378 379 Input Parameters: 380 + comm - the communicator 381 - format - the usual printf() format string 382 383 Level: intermediate 384 385 Notes: 386 REQUIRES a call to PetscSynchronizedFlush() by all the processes after the completion of the calls to PetscSynchronizedPrintf() for the information 387 from all the processors to be printed. 388 389 Fortran Note: 390 The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 391 That is, you can only pass a single character string from Fortran. 392 393 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 394 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 395 @*/ 396 PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 397 { 398 PetscErrorCode ierr; 399 PetscMPIInt rank; 400 401 PetscFunctionBegin; 402 PetscCheckFalse(comm == MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 403 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 404 405 /* First processor prints immediately to stdout */ 406 if (rank == 0) { 407 va_list Argp; 408 va_start(Argp,format); 409 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 410 if (petsc_history) { 411 va_start(Argp,format); 412 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 413 } 414 va_end(Argp); 415 } else { /* other processors add to local queue */ 416 va_list Argp; 417 PrintfQueue next; 418 size_t fullLength = PETSCDEFAULTBUFFERSIZE; 419 420 ierr = PetscNew(&next);CHKERRQ(ierr); 421 if (petsc_printfqueue) { 422 petsc_printfqueue->next = next; 423 petsc_printfqueue = next; 424 petsc_printfqueue->next = NULL; 425 } else petsc_printfqueuebase = petsc_printfqueue = next; 426 petsc_printfqueuelength++; 427 next->size = -1; 428 next->string = NULL; 429 while ((PetscInt)fullLength >= next->size) { 430 next->size = fullLength+1; 431 ierr = PetscFree(next->string);CHKERRQ(ierr); 432 ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr); 433 va_start(Argp,format); 434 ierr = PetscArrayzero(next->string,next->size);CHKERRQ(ierr); 435 ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr); 436 va_end(Argp); 437 } 438 } 439 PetscFunctionReturn(0); 440 } 441 442 /*@C 443 PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 444 several processors. Output of the first processor is followed by that of the 445 second, etc. 446 447 Not Collective 448 449 Input Parameters: 450 + comm - the communicator 451 . fd - the file pointer 452 - format - the usual printf() format string 453 454 Level: intermediate 455 456 Notes: 457 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 458 from all the processors to be printed. 459 460 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 461 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 462 463 @*/ 464 PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm,FILE *fp,const char format[],...) 465 { 466 PetscErrorCode ierr; 467 PetscMPIInt rank; 468 469 PetscFunctionBegin; 470 PetscCheckFalse(comm == MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 471 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 472 473 /* First processor prints immediately to fp */ 474 if (rank == 0) { 475 va_list Argp; 476 va_start(Argp,format); 477 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 478 if (petsc_history && (fp !=petsc_history)) { 479 va_start(Argp,format); 480 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 481 } 482 va_end(Argp); 483 } else { /* other processors add to local queue */ 484 va_list Argp; 485 PrintfQueue next; 486 size_t fullLength = PETSCDEFAULTBUFFERSIZE; 487 488 ierr = PetscNew(&next);CHKERRQ(ierr); 489 if (petsc_printfqueue) { 490 petsc_printfqueue->next = next; 491 petsc_printfqueue = next; 492 petsc_printfqueue->next = NULL; 493 } else petsc_printfqueuebase = petsc_printfqueue = next; 494 petsc_printfqueuelength++; 495 next->size = -1; 496 next->string = NULL; 497 while ((PetscInt)fullLength >= next->size) { 498 next->size = fullLength+1; 499 ierr = PetscFree(next->string);CHKERRQ(ierr); 500 ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr); 501 va_start(Argp,format); 502 ierr = PetscArrayzero(next->string,next->size);CHKERRQ(ierr); 503 ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr); 504 va_end(Argp); 505 } 506 } 507 PetscFunctionReturn(0); 508 } 509 510 /*@C 511 PetscSynchronizedFlush - Flushes to the screen output from all processors 512 involved in previous PetscSynchronizedPrintf()/PetscSynchronizedFPrintf() calls. 513 514 Collective 515 516 Input Parameters: 517 + comm - the communicator 518 - fd - the file pointer (valid on process 0 of the communicator) 519 520 Level: intermediate 521 522 Notes: 523 If PetscSynchronizedPrintf() and/or PetscSynchronizedFPrintf() are called with 524 different MPI communicators there must be an intervening call to PetscSynchronizedFlush() between the calls with different MPI communicators. 525 526 From Fortran pass PETSC_STDOUT if the flush is for standard out; otherwise pass a value obtained from PetscFOpen() 527 528 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 529 PetscViewerASCIISynchronizedPrintf() 530 @*/ 531 PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm,FILE *fd) 532 { 533 PetscErrorCode ierr; 534 PetscMPIInt rank,size,tag,i,j,n = 0,dummy = 0; 535 char *message; 536 MPI_Status status; 537 538 PetscFunctionBegin; 539 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 540 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 541 ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 542 543 /* First processor waits for messages from all other processors */ 544 if (rank == 0) { 545 if (!fd) fd = PETSC_STDOUT; 546 for (i=1; i<size; i++) { 547 /* to prevent a flood of messages to process zero, request each message separately */ 548 ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRMPI(ierr); 549 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRMPI(ierr); 550 for (j=0; j<n; j++) { 551 PetscMPIInt size = 0; 552 553 ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRMPI(ierr); 554 ierr = PetscMalloc1(size, &message);CHKERRQ(ierr); 555 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRMPI(ierr); 556 ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr); 557 ierr = PetscFree(message);CHKERRQ(ierr); 558 } 559 } 560 } else { /* other processors send queue to processor 0 */ 561 PrintfQueue next = petsc_printfqueuebase,previous; 562 563 ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRMPI(ierr); 564 ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRMPI(ierr); 565 for (i=0; i<petsc_printfqueuelength; i++) { 566 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRMPI(ierr); 567 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRMPI(ierr); 568 previous = next; 569 next = next->next; 570 ierr = PetscFree(previous->string);CHKERRQ(ierr); 571 ierr = PetscFree(previous);CHKERRQ(ierr); 572 } 573 petsc_printfqueue = NULL; 574 petsc_printfqueuelength = 0; 575 } 576 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 577 PetscFunctionReturn(0); 578 } 579 580 /* ---------------------------------------------------------------------------------------*/ 581 582 /*@C 583 PetscFPrintf - Prints to a file, only from the first 584 processor in the communicator. 585 586 Not Collective 587 588 Input Parameters: 589 + comm - the communicator 590 . fd - the file pointer 591 - format - the usual printf() format string 592 593 Level: intermediate 594 595 Fortran Note: 596 This routine is not supported in Fortran. 597 598 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 599 PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 600 @*/ 601 PetscErrorCode PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 602 { 603 PetscErrorCode ierr; 604 PetscMPIInt rank; 605 606 PetscFunctionBegin; 607 PetscCheckFalse(comm == MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 608 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 609 if (rank == 0) { 610 va_list Argp; 611 va_start(Argp,format); 612 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 613 if (petsc_history && (fd !=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 /*@C 623 PetscPrintf - Prints to standard out, only from the first 624 processor in the communicator. Calls from other processes are ignored. 625 626 Not Collective 627 628 Input Parameters: 629 + comm - the communicator 630 - format - the usual printf() format string 631 632 Level: intermediate 633 634 Notes: 635 PetscPrintf() supports some format specifiers that are unique to PETSc. 636 See the manual page for PetscFormatConvert() for details. 637 638 Fortran Note: 639 The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 640 That is, you can only pass a single character string from Fortran. 641 642 .seealso: PetscFPrintf(), PetscSynchronizedPrintf(), PetscFormatConvert() 643 @*/ 644 PetscErrorCode PetscPrintf(MPI_Comm comm,const char format[],...) 645 { 646 PetscErrorCode ierr; 647 PetscMPIInt rank; 648 649 PetscFunctionBegin; 650 PetscCheckFalse(comm == MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 651 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 652 if (rank == 0) { 653 va_list Argp; 654 va_start(Argp,format); 655 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 656 if (petsc_history) { 657 va_start(Argp,format); 658 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 659 } 660 va_end(Argp); 661 } 662 PetscFunctionReturn(0); 663 } 664 665 PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 666 { 667 PetscErrorCode ierr; 668 PetscMPIInt rank; 669 670 PetscFunctionBegin; 671 PetscCheckFalse(comm == MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 672 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 673 if (rank == 0) { 674 va_list Argp; 675 va_start(Argp,format); 676 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 677 if (petsc_history) { 678 va_start(Argp,format); 679 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 680 } 681 va_end(Argp); 682 } 683 PetscFunctionReturn(0); 684 } 685 686 /* ---------------------------------------------------------------------------------------*/ 687 688 /*@C 689 PetscSynchronizedFGets - Several processors all get the same line from a file. 690 691 Collective 692 693 Input Parameters: 694 + comm - the communicator 695 . fd - the file pointer 696 - len - the length of the output buffer 697 698 Output Parameter: 699 . string - the line read from the file, at end of file string[0] == 0 700 701 Level: intermediate 702 703 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 704 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 705 706 @*/ 707 PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[]) 708 { 709 PetscErrorCode ierr; 710 PetscMPIInt rank; 711 712 PetscFunctionBegin; 713 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 714 715 if (rank == 0) { 716 char *ptr = fgets(string, len, fp); 717 718 if (!ptr) { 719 string[0] = 0; 720 PetscCheckFalse(!feof(fp),PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 721 } 722 } 723 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRMPI(ierr); 724 PetscFunctionReturn(0); 725 } 726 727 #if defined(PETSC_HAVE_CLOSURE) 728 int (^SwiftClosure)(const char*) = 0; 729 730 PetscErrorCode PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp) 731 { 732 PetscErrorCode ierr; 733 734 PetscFunctionBegin; 735 if (fd != stdout && fd != stderr) { /* handle regular files */ 736 ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr); 737 } else { 738 size_t length; 739 char buff[PETSCDEFAULTBUFFERSIZE]; 740 741 ierr = PetscVSNPrintf(buff,sizeof(buff),format,&length,Argp);CHKERRQ(ierr); 742 ierr = SwiftClosure(buff);CHKERRQ(ierr); 743 } 744 PetscFunctionReturn(0); 745 } 746 747 /* 748 Provide a Swift function that processes all the PETSc calls to PetscVFPrintf() 749 */ 750 PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*)) 751 { 752 PetscVFPrintf = PetscVFPrintfToString; 753 SwiftClosure = closure; 754 return 0; 755 } 756 #endif 757 758 /*@C 759 PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 760 761 Input Parameters: 762 . format - the PETSc format string 763 764 Level: developer 765 766 @*/ 767 PetscErrorCode PetscFormatStrip(char *format) 768 { 769 size_t loc1 = 0, loc2 = 0; 770 771 PetscFunctionBegin; 772 while (format[loc2]) { 773 if (format[loc2] == '%') { 774 format[loc1++] = format[loc2++]; 775 while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 776 } 777 format[loc1++] = format[loc2++]; 778 } 779 PetscFunctionReturn(0); 780 } 781 782 PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[]) 783 { 784 PetscErrorCode ierr; 785 PetscInt i; 786 size_t left,count; 787 char *p; 788 789 PetscFunctionBegin; 790 for (i=0,p=buf,left=len; i<n; i++) { 791 ierr = PetscSNPrintfCount(p,left,fmt,&count,(double)x[i]);CHKERRQ(ierr); 792 PetscCheckFalse(count >= left,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer"); 793 left -= count; 794 p += count-1; 795 *p++ = ' '; 796 } 797 p[i ? 0 : -1] = 0; 798 PetscFunctionReturn(0); 799 } 800