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 /*@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 PetscInt i = 0; 41 42 PetscFunctionBegin; 43 *size = 0; 44 while (format[i]) { 45 if (format[i] == '%' && format[i+1] == '%') { 46 i++; i++; *size += 2; 47 } else if (format[i] == '%') { 48 /* Find the letter */ 49 for (; format[i] && format[i] <= '9'; i++,(*size += 1)); 50 switch (format[i]) { 51 case 'D': 52 #if defined(PETSC_USE_64BIT_INDICES) 53 *size += 2; 54 #endif 55 break; 56 case 'g': 57 *size += 4; 58 break; 59 default: 60 break; 61 } 62 *size += 1; 63 i++; 64 } else { 65 i++; 66 *size += 1; 67 } 68 } 69 *size += 1; /* space for NULL character */ 70 PetscFunctionReturn(0); 71 } 72 73 /*@C 74 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 75 converts %g to [|%g|] so that PetscVSNPrintf() can easily insure all %g formatted numbers have a decimal point when printed. 76 77 Input Parameters: 78 + format - the PETSc format string 79 . newformat - the location to put the new format 80 - size - the length of newformat, you can use PetscFormatConvertGetSize() to compute the needed size 81 82 Note: this exists so we can have the same code when PetscInt is either int or long long int 83 84 Level: developer 85 86 .seealso: PetscFormatConvertGetSize(), PetscVSNPrintf(), PetscVFPrintf() 87 88 @*/ 89 PetscErrorCode PetscFormatConvert(const char *format,char *newformat) 90 { 91 PetscInt i = 0, j = 0; 92 93 PetscFunctionBegin; 94 while (format[i]) { 95 if (format[i] == '%' && format[i+1] == '%') { 96 newformat[j++] = format[i++]; 97 newformat[j++] = format[i++]; 98 } else if (format[i] == '%') { 99 if (format[i+1] == 'g') { 100 newformat[j++] = '['; 101 newformat[j++] = '|'; 102 } 103 /* Find the letter */ 104 for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 105 switch (format[i]) { 106 case 'D': 107 #if !defined(PETSC_USE_64BIT_INDICES) 108 newformat[j++] = 'd'; 109 #else 110 newformat[j++] = 'l'; 111 newformat[j++] = 'l'; 112 newformat[j++] = 'd'; 113 #endif 114 break; 115 case 'g': 116 newformat[j++] = format[i]; 117 if (format[i-1] == '%') { 118 newformat[j++] = '|'; 119 newformat[j++] = ']'; 120 } 121 break; 122 case 'G': 123 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%G format is no longer supported, use %%g and cast the argument to double"); 124 break; 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 break; 128 default: 129 newformat[j++] = format[i]; 130 break; 131 } 132 i++; 133 } else newformat[j++] = format[i++]; 134 } 135 newformat[j] = 0; 136 PetscFunctionReturn(0); 137 } 138 139 #define PETSCDEFAULTBUFFERSIZE 8*1024 140 141 /*@C 142 PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 143 function arguments into a string using the format statement. 144 145 Input Parameters: 146 + str - location to put result 147 . len - the amount of space in str 148 + format - the PETSc format string 149 - fullLength - the amount of space in str actually used. 150 151 Developer Notes: 152 this function may be called from an error handler, if an error occurs when it is called by the error handler than likely 153 a recursion will occur and possible crash. 154 155 Level: developer 156 157 .seealso: PetscVSNPrintf(), PetscErrorPrintf(), PetscVPrintf() 158 159 @*/ 160 PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) 161 { 162 char *newformat = NULL; 163 char formatbuf[PETSCDEFAULTBUFFERSIZE]; 164 size_t newLength; 165 PetscErrorCode ierr; 166 int flen; 167 168 PetscFunctionBegin; 169 ierr = PetscFormatConvertGetSize(format,&newLength);CHKERRQ(ierr); 170 if (newLength < PETSCDEFAULTBUFFERSIZE) { 171 newformat = formatbuf; 172 newLength = PETSCDEFAULTBUFFERSIZE-1; 173 } else { 174 ierr = PetscMalloc1(newLength, &newformat);CHKERRQ(ierr); 175 } 176 ierr = PetscFormatConvert(format,newformat);CHKERRQ(ierr); 177 #if defined(PETSC_HAVE_VSNPRINTF) 178 flen = vsnprintf(str,len,newformat,Argp); 179 #else 180 #error "vsnprintf not found" 181 #endif 182 if (fullLength) *fullLength = 1 + (size_t) flen; 183 if (newLength > PETSCDEFAULTBUFFERSIZE-1) { 184 ierr = PetscFree(newformat);CHKERRQ(ierr); 185 } 186 { 187 PetscBool foundedot; 188 size_t cnt = 0,ncnt = 0,leng; 189 ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); 190 if (leng > 4) { 191 for (cnt=0; cnt<leng-4; cnt++) { 192 if (str[cnt] == '[' && str[cnt+1] == '|'){ 193 cnt++; cnt++; 194 foundedot = PETSC_FALSE; 195 for (; cnt<leng-1; cnt++) { 196 if (str[cnt] == '|' && str[cnt+1] == ']'){ 197 cnt++; 198 if (!foundedot) str[ncnt++] = '.'; 199 ncnt--; 200 break; 201 } else { 202 if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 203 str[ncnt++] = str[cnt]; 204 } 205 } 206 } else { 207 str[ncnt] = str[cnt]; 208 } 209 ncnt++; 210 } 211 while (cnt < leng) { 212 str[ncnt] = str[cnt]; ncnt++; cnt++; 213 } 214 str[ncnt] = 0; 215 } 216 } 217 #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 218 /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 219 { 220 size_t cnt = 0,ncnt = 0,leng; 221 ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); 222 if (leng > 5) { 223 for (cnt=0; cnt<leng-4; cnt++) { 224 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') { 225 str[ncnt] = str[cnt]; ncnt++; cnt++; 226 str[ncnt] = str[cnt]; ncnt++; cnt++; cnt++; 227 str[ncnt] = str[cnt]; 228 } else { 229 str[ncnt] = str[cnt]; 230 } 231 ncnt++; 232 } 233 while (cnt < leng) { 234 str[ncnt] = str[cnt]; ncnt++; cnt++; 235 } 236 str[ncnt] = 0; 237 } 238 } 239 #endif 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);CHKERRQ(ierr); 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 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 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 = 0,petsc_printfqueuebase = 0; 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 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 403 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 404 405 /* First processor prints immediately to stdout */ 406 if (!rank) { 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 = 0; 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 = PetscMemzero(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 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 471 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 472 473 /* First processor prints immediately to fp */ 474 if (!rank) { 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 = 0; 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 = PetscMemzero(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 on MPI_Comm 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);CHKERRQ(ierr); 541 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 542 543 /* First processor waits for messages from all other processors */ 544 if (!rank) { 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);CHKERRQ(ierr); 549 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(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);CHKERRQ(ierr); 554 ierr = PetscMalloc1(size, &message);CHKERRQ(ierr); 555 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(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);CHKERRQ(ierr); 564 ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 565 for (i=0; i<petsc_printfqueuelength; i++) { 566 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 567 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(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 = 0; 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 Concepts: printing^in parallel 599 Concepts: printf^in parallel 600 601 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 602 PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 603 @*/ 604 PetscErrorCode PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 605 { 606 PetscErrorCode ierr; 607 PetscMPIInt rank; 608 609 PetscFunctionBegin; 610 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 611 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 612 if (!rank) { 613 va_list Argp; 614 va_start(Argp,format); 615 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 616 if (petsc_history && (fd !=petsc_history)) { 617 va_start(Argp,format); 618 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 619 } 620 va_end(Argp); 621 } 622 PetscFunctionReturn(0); 623 } 624 625 /*@C 626 PetscPrintf - Prints to standard out, only from the first 627 processor in the communicator. Calls from other processes are ignored. 628 629 Not Collective 630 631 Input Parameters: 632 + comm - the communicator 633 - format - the usual printf() format string 634 635 Level: intermediate 636 637 Fortran Note: 638 The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 639 That is, you can only pass a single character string from Fortran. 640 641 Concepts: printing^in parallel 642 Concepts: printf^in parallel 643 644 .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 645 @*/ 646 PetscErrorCode PetscPrintf(MPI_Comm comm,const char format[],...) 647 { 648 PetscErrorCode ierr; 649 PetscMPIInt rank; 650 651 PetscFunctionBegin; 652 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 653 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 654 if (!rank) { 655 va_list Argp; 656 va_start(Argp,format); 657 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 658 if (petsc_history) { 659 va_start(Argp,format); 660 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 661 } 662 va_end(Argp); 663 } 664 PetscFunctionReturn(0); 665 } 666 667 /* ---------------------------------------------------------------------------------------*/ 668 /*@C 669 PetscHelpPrintf - All PETSc help messages are passing through this function. You can change how help messages are printed by 670 replacinng it with something that does not simply write to a stdout. 671 672 To use, write your own function for example, 673 $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....) 674 ${ 675 $ PetscFunctionReturn(0); 676 $} 677 then before the call to PetscInitialize() do the assignment 678 $ PetscHelpPrintf = mypetschelpprintf; 679 680 Note: the default routine used is called PetscHelpPrintfDefault(). 681 682 Level: developer 683 684 .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf() 685 @*/ 686 PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 687 { 688 PetscErrorCode ierr; 689 PetscMPIInt rank; 690 691 PetscFunctionBegin; 692 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 693 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 694 if (!rank) { 695 va_list Argp; 696 va_start(Argp,format); 697 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 698 if (petsc_history) { 699 va_start(Argp,format); 700 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 701 } 702 va_end(Argp); 703 } 704 PetscFunctionReturn(0); 705 } 706 707 /* ---------------------------------------------------------------------------------------*/ 708 709 710 /*@C 711 PetscSynchronizedFGets - Several processors all get the same line from a file. 712 713 Collective on MPI_Comm 714 715 Input Parameters: 716 + comm - the communicator 717 . fd - the file pointer 718 - len - the length of the output buffer 719 720 Output Parameter: 721 . string - the line read from the file, at end of file string[0] == 0 722 723 Level: intermediate 724 725 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 726 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 727 728 @*/ 729 PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[]) 730 { 731 PetscErrorCode ierr; 732 PetscMPIInt rank; 733 734 PetscFunctionBegin; 735 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 736 737 if (!rank) { 738 char *ptr = fgets(string, len, fp); 739 740 if (!ptr) { 741 string[0] = 0; 742 if (!feof(fp)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 743 } 744 } 745 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 746 PetscFunctionReturn(0); 747 } 748 749 #if defined(PETSC_HAVE_CLOSURES) 750 int (^SwiftClosure)(const char*) = 0; 751 752 PetscErrorCode PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp) 753 { 754 PetscErrorCode ierr; 755 756 PetscFunctionBegin; 757 if (fd != stdout && fd != stderr) { /* handle regular files */ 758 ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr); 759 } else { 760 size_t length; 761 char buff[PETSCDEFAULTBUFFERSIZE]; 762 763 ierr = PetscVSNPrintf(buf,size(buff),format,&length,Argp);CHKERRQ(ierr); 764 ierr = SwiftClosure(buff);CHKERRQ(ierr); 765 } 766 PetscFunctionReturn(0); 767 } 768 769 /* 770 Provide a Swift function that processes all the PETSc calls to PetscVFPrintf() 771 */ 772 PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*)) 773 { 774 PetscVFPrintf = PetscVFPrintfToString; 775 SwiftClosure = closure; 776 return 0; 777 } 778 #endif 779 780 #if defined(PETSC_HAVE_MATLAB_ENGINE) 781 #include <mex.h> 782 PetscErrorCode PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp) 783 { 784 PetscErrorCode ierr; 785 786 PetscFunctionBegin; 787 if (fd != stdout && fd != stderr) { /* handle regular files */ 788 ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr); 789 } else { 790 size_t length; 791 char buff[length]; 792 793 ierr = PetscVSNPrintf(buff,sizeof(buff),format,&length,Argp);CHKERRQ(ierr); 794 mexPrintf("%s",buff); 795 } 796 PetscFunctionReturn(0); 797 } 798 #endif 799 800 /*@C 801 PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 802 803 Input Parameters: 804 . format - the PETSc format string 805 806 Level: developer 807 808 @*/ 809 PetscErrorCode PetscFormatStrip(char *format) 810 { 811 size_t loc1 = 0, loc2 = 0; 812 813 PetscFunctionBegin; 814 while (format[loc2]) { 815 if (format[loc2] == '%') { 816 format[loc1++] = format[loc2++]; 817 while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 818 } 819 format[loc1++] = format[loc2++]; 820 } 821 PetscFunctionReturn(0); 822 } 823 824 PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[]) 825 { 826 PetscErrorCode ierr; 827 PetscInt i; 828 size_t left,count; 829 char *p; 830 831 PetscFunctionBegin; 832 for (i=0,p=buf,left=len; i<n; i++) { 833 ierr = PetscSNPrintfCount(p,left,fmt,&count,(double)x[i]);CHKERRQ(ierr); 834 if (count >= left) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer"); 835 left -= count; 836 p += count-1; 837 *p++ = ' '; 838 } 839 p[i ? 0 : -1] = 0; 840 PetscFunctionReturn(0); 841 } 842