1 2 /* 3 Utilites routines to add simple ASCII IO capability. 4 */ 5 #include "../src/sys/fileio/mprint.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 Used to output to Zope 25 */ 26 FILE *PETSC_ZOPEFD = 0; 27 28 #undef __FUNCT__ 29 #define __FUNCT__ "PetscFormatConvert" 30 /*@C 31 PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string 32 33 Input Parameters: 34 + format - the PETSc format string 35 . newformat - the location to put the standard C format string values 36 - size - the length of newformat 37 38 Note: this exists so we can have the same code when PetscInt is either int or long long and PetscScalar is either double or float 39 40 Level: developer 41 42 @*/ 43 PetscErrorCode PetscFormatConvert(const char *format,char *newformat,size_t size) 44 { 45 PetscInt i = 0,j = 0; 46 47 while (format[i] && i < (PetscInt)size-1) { 48 if (format[i] == '%' && format[i+1] == 'D') { 49 newformat[j++] = '%'; 50 #if !defined(PETSC_USE_64BIT_INDICES) 51 newformat[j++] = 'd'; 52 #else 53 newformat[j++] = 'l'; 54 newformat[j++] = 'l'; 55 newformat[j++] = 'd'; 56 #endif 57 i += 2; 58 } else if (format[i] == '%' && format[i+1] >= '1' && format[i+1] <= '9' && format[i+2] == 'D') { 59 newformat[j++] = '%'; 60 newformat[j++] = format[i+1]; 61 #if !defined(PETSC_USE_64BIT_INDICES) 62 newformat[j++] = 'd'; 63 #else 64 newformat[j++] = 'l'; 65 newformat[j++] = 'l'; 66 newformat[j++] = 'd'; 67 #endif 68 i += 3; 69 } else if (format[i] == '%' && format[i+1] == 'G') { 70 newformat[j++] = '%'; 71 #if defined(PETSC_USE_SCALAR_INT) 72 newformat[j++] = 'd'; 73 #elif !defined(PETSC_USE_SCALAR_LONG_DOUBLE) 74 newformat[j++] = 'g'; 75 #else 76 newformat[j++] = 'L'; 77 newformat[j++] = 'g'; 78 #endif 79 i += 2; 80 }else { 81 newformat[j++] = format[i++]; 82 } 83 } 84 newformat[j] = 0; 85 return 0; 86 } 87 88 #undef __FUNCT__ 89 #define __FUNCT__ "PetscVSNPrintf" 90 /*@C 91 PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 92 function arguments into a string using the format statement. 93 94 Input Parameters: 95 + str - location to put result 96 . len - the amount of space in str 97 + format - the PETSc format string 98 - fullLength - the amount of space in str actually used. 99 100 Note: No error handling because may be called by error handler 101 102 Level: developer 103 104 @*/ 105 PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) 106 { 107 /* no malloc since may be called by error handler */ 108 char *newformat; 109 char formatbuf[8*1024]; 110 size_t oldLength,length; 111 PetscErrorCode ierr; 112 113 ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); 114 if (oldLength < 8*1024) { 115 newformat = formatbuf; 116 } else { 117 ierr = PetscMalloc((oldLength+1) * sizeof(char), &newformat);CHKERRQ(ierr); 118 } 119 PetscFormatConvert(format,newformat,oldLength+1); 120 ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr); 121 #if 0 122 if (length > len) { 123 newformat[len] = '\0'; 124 } 125 #endif 126 #if defined(PETSC_HAVE_VSNPRINTF_CHAR) 127 *fullLength = vsnprintf(str,len,newformat,(char *)Argp); 128 #elif defined(PETSC_HAVE_VSNPRINTF) 129 *fullLength = vsnprintf(str,len,newformat,Argp); 130 #elif defined(PETSC_HAVE__VSNPRINTF) 131 *fullLength = _vsnprintf(str,len,newformat,Argp); 132 #else 133 #error "vsnprintf not found" 134 #endif 135 if (oldLength >= 8*1024) { 136 ierr = PetscFree(newformat);CHKERRQ(ierr); 137 } 138 return 0; 139 } 140 141 #undef __FUNCT__ 142 #define __FUNCT__ "PetscZopeLog" 143 PetscErrorCode PetscZopeLog(const char *format,va_list Argp) 144 { 145 /* no malloc since may be called by error handler */ 146 char newformat[8*1024]; 147 char log[8*1024]; 148 char logstart[] = " <<<log>>>"; 149 size_t len,formatlen; 150 151 PetscFormatConvert(format,newformat,8*1024); 152 PetscStrlen(logstart, &len); 153 PetscMemcpy(log, logstart, len); 154 PetscStrlen(newformat, &formatlen); 155 PetscMemcpy(&(log[len]), newformat, formatlen); 156 if (PETSC_ZOPEFD){ 157 #if defined(PETSC_HAVE_VFPRINTF_CHAR) 158 vfprintf(PETSC_ZOPEFD,log,(char *)Argp); 159 #else 160 vfprintf(PETSC_ZOPEFD,log,Argp); 161 #endif 162 fflush(PETSC_ZOPEFD); 163 } 164 return 0; 165 } 166 167 #undef __FUNCT__ 168 #define __FUNCT__ "PetscVFPrintfDefault" 169 /*@C 170 PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 171 can be replaced with something that does not simply write to a file. 172 173 To use, write your own function for example, 174 $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 175 ${ 176 $ PetscErrorCode ierr; 177 $ 178 $ PetscFunctionBegin; 179 $ if (fd != stdout && fd != stderr) { handle regular files 180 $ ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERR(ierr); 181 $ } else { 182 $ char buff[BIG]; 183 $ size_t length; 184 $ ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr); 185 $ now send buff to whatever stream or whatever you want 186 $ } 187 $ PetscFunctionReturn(0); 188 $} 189 then before the call to PetscInitialize() do the assignment 190 $ PetscVFPrintf = mypetscvfprintf; 191 192 Notes: For error messages this may be called by any process, for regular standard out it is 193 called only by process 0 of a given communicator 194 195 No error handling because may be called by error handler 196 197 Level: developer 198 199 .seealso: PetscVSNPrintf(), PetscErrorPrintf() 200 201 @*/ 202 PetscErrorCode PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp) 203 { 204 /* no malloc since may be called by error handler (assume no long messages in errors) */ 205 char *newformat; 206 char formatbuf[8*1024]; 207 size_t oldLength; 208 209 PetscStrlen(format, &oldLength); 210 if (oldLength < 8*1024) { 211 newformat = formatbuf; 212 } else { 213 (void)PetscMalloc((oldLength+1) * sizeof(char), &newformat); 214 } 215 PetscFormatConvert(format,newformat,oldLength+1); 216 217 #if defined(PETSC_HAVE_VFPRINTF_CHAR) 218 vfprintf(fd,newformat,(char *)Argp); 219 #else 220 vfprintf(fd,newformat,Argp); 221 #endif 222 fflush(fd); 223 if (oldLength >= 8*1024) { 224 (void)PetscFree(newformat); 225 } 226 return 0; 227 } 228 229 #undef __FUNCT__ 230 #define __FUNCT__ "PetscSNPrintf" 231 /*@C 232 PetscSNPrintf - Prints to a string of given length 233 234 Not Collective 235 236 Input Parameters: 237 + str - the string to print to 238 . len - the length of str 239 . format - the usual printf() format string 240 - any arguments 241 242 Level: intermediate 243 244 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 245 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 246 @*/ 247 PetscErrorCode PetscSNPrintf(char *str,size_t len,const char format[],...) 248 { 249 PetscErrorCode ierr; 250 size_t fullLength; 251 va_list Argp; 252 253 PetscFunctionBegin; 254 va_start(Argp,format); 255 ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr); 256 PetscFunctionReturn(0); 257 } 258 259 /* ----------------------------------------------------------------------- */ 260 261 PrintfQueue queue = 0,queuebase = 0; 262 int queuelength = 0; 263 FILE *queuefile = PETSC_NULL; 264 265 #undef __FUNCT__ 266 #define __FUNCT__ "PetscSynchronizedPrintf" 267 /*@C 268 PetscSynchronizedPrintf - Prints synchronized output from several processors. 269 Output of the first processor is followed by that of the second, etc. 270 271 Not Collective 272 273 Input Parameters: 274 + comm - the communicator 275 - format - the usual printf() format string 276 277 Level: intermediate 278 279 Notes: 280 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 281 from all the processors to be printed. 282 283 Fortran Note: 284 The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 285 That is, you can only pass a single character string from Fortran. 286 287 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 288 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 289 @*/ 290 PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 291 { 292 PetscErrorCode ierr; 293 PetscMPIInt rank; 294 295 PetscFunctionBegin; 296 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 297 298 /* First processor prints immediately to stdout */ 299 if (!rank) { 300 va_list Argp; 301 va_start(Argp,format); 302 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 303 if (petsc_history) { 304 va_start(Argp,format); 305 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 306 } 307 va_end(Argp); 308 } else { /* other processors add to local queue */ 309 va_list Argp; 310 PrintfQueue next; 311 size_t fullLength = 8191; 312 313 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 314 if (queue) {queue->next = next; queue = next; queue->next = 0;} 315 else {queuebase = queue = next;} 316 queuelength++; 317 next->size = -1; 318 while((PetscInt)fullLength >= next->size) { 319 next->size = fullLength+1; 320 ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr); 321 va_start(Argp,format); 322 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 323 ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr); 324 va_end(Argp); 325 } 326 } 327 328 PetscFunctionReturn(0); 329 } 330 331 #undef __FUNCT__ 332 #define __FUNCT__ "PetscSynchronizedFPrintf" 333 /*@C 334 PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 335 several processors. Output of the first processor is followed by that of the 336 second, etc. 337 338 Not Collective 339 340 Input Parameters: 341 + comm - the communicator 342 . fd - the file pointer 343 - format - the usual printf() format string 344 345 Level: intermediate 346 347 Notes: 348 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 349 from all the processors to be printed. 350 351 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 352 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 353 354 @*/ 355 PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...) 356 { 357 PetscErrorCode ierr; 358 PetscMPIInt rank; 359 360 PetscFunctionBegin; 361 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 362 363 /* First processor prints immediately to fp */ 364 if (!rank) { 365 va_list Argp; 366 va_start(Argp,format); 367 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 368 queuefile = fp; 369 if (petsc_history && (fp !=petsc_history)) { 370 va_start(Argp,format); 371 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 372 } 373 va_end(Argp); 374 } else { /* other processors add to local queue */ 375 va_list Argp; 376 PrintfQueue next; 377 size_t fullLength = 8191; 378 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 379 if (queue) {queue->next = next; queue = next; queue->next = 0;} 380 else {queuebase = queue = next;} 381 queuelength++; 382 next->size = -1; 383 while((PetscInt)fullLength >= next->size) { 384 next->size = fullLength+1; 385 ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr); 386 va_start(Argp,format); 387 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 388 ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr); 389 va_end(Argp); 390 } 391 } 392 PetscFunctionReturn(0); 393 } 394 395 #undef __FUNCT__ 396 #define __FUNCT__ "PetscSynchronizedFlush" 397 /*@ 398 PetscSynchronizedFlush - Flushes to the screen output from all processors 399 involved in previous PetscSynchronizedPrintf() calls. 400 401 Collective on MPI_Comm 402 403 Input Parameters: 404 . comm - the communicator 405 406 Level: intermediate 407 408 Notes: 409 Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with 410 different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush(). 411 412 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 413 PetscViewerASCIISynchronizedPrintf() 414 @*/ 415 PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm) 416 { 417 PetscErrorCode ierr; 418 PetscMPIInt rank,size,tag,i,j,n,dummy = 0; 419 char *message; 420 MPI_Status status; 421 FILE *fd; 422 423 PetscFunctionBegin; 424 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 425 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 426 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 427 428 /* First processor waits for messages from all other processors */ 429 if (!rank) { 430 if (queuefile) { 431 fd = queuefile; 432 } else { 433 fd = PETSC_STDOUT; 434 } 435 for (i=1; i<size; i++) { 436 /* to prevent a flood of messages to process zero, request each message separately */ 437 ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr); 438 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 439 for (j=0; j<n; j++) { 440 PetscMPIInt size; 441 442 ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 443 ierr = PetscMalloc(size * sizeof(char), &message);CHKERRQ(ierr); 444 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr); 445 ierr = PetscFPrintf(comm,fd,"%s",message); 446 ierr = PetscFree(message);CHKERRQ(ierr); 447 } 448 } 449 queuefile = PETSC_NULL; 450 } else { /* other processors send queue to processor 0 */ 451 PrintfQueue next = queuebase,previous; 452 453 ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr); 454 ierr = MPI_Send(&queuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 455 for (i=0; i<queuelength; i++) { 456 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 457 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr); 458 previous = next; 459 next = next->next; 460 ierr = PetscFree(previous->string);CHKERRQ(ierr); 461 ierr = PetscFree(previous);CHKERRQ(ierr); 462 } 463 queue = 0; 464 queuelength = 0; 465 } 466 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 467 PetscFunctionReturn(0); 468 } 469 470 /* ---------------------------------------------------------------------------------------*/ 471 472 #undef __FUNCT__ 473 #define __FUNCT__ "PetscFPrintf" 474 /*@C 475 PetscFPrintf - Prints to a file, only from the first 476 processor in the communicator. 477 478 Not Collective 479 480 Input Parameters: 481 + comm - the communicator 482 . fd - the file pointer 483 - format - the usual printf() format string 484 485 Level: intermediate 486 487 Fortran Note: 488 This routine is not supported in Fortran. 489 490 Concepts: printing^in parallel 491 Concepts: printf^in parallel 492 493 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 494 PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 495 @*/ 496 PetscErrorCode PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 497 { 498 PetscErrorCode ierr; 499 PetscMPIInt rank; 500 501 PetscFunctionBegin; 502 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 503 if (!rank) { 504 va_list Argp; 505 va_start(Argp,format); 506 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 507 if (petsc_history && (fd !=petsc_history)) { 508 va_start(Argp,format); 509 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 510 } 511 va_end(Argp); 512 } 513 PetscFunctionReturn(0); 514 } 515 516 #undef __FUNCT__ 517 #define __FUNCT__ "PetscPrintf" 518 /*@C 519 PetscPrintf - Prints to standard out, only from the first 520 processor in the communicator. 521 522 Not Collective 523 524 Input Parameters: 525 + comm - the communicator 526 - format - the usual printf() format string 527 528 Level: intermediate 529 530 Fortran Note: 531 The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 532 That is, you can only pass a single character string from Fortran. 533 534 Notes: The %A format specifier is special. It assumes an argument of type PetscReal 535 and is replaced with %G unless the absolute value is < 1.e-12 when it is replaced 536 with "< 1.e-12" (1.e-6 for single precision). 537 538 Concepts: printing^in parallel 539 Concepts: printf^in parallel 540 541 .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 542 @*/ 543 PetscErrorCode PetscPrintf(MPI_Comm comm,const char format[],...) 544 { 545 PetscErrorCode ierr; 546 PetscMPIInt rank; 547 size_t len; 548 char *nformat,*sub1,*sub2; 549 PetscReal value; 550 551 PetscFunctionBegin; 552 if (!comm) comm = PETSC_COMM_WORLD; 553 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 554 if (!rank) { 555 va_list Argp; 556 va_start(Argp,format); 557 558 ierr = PetscStrstr(format,"%A",&sub1);CHKERRQ(ierr); 559 if (sub1) { 560 ierr = PetscStrstr(format,"%",&sub2);CHKERRQ(ierr); 561 if (sub1 != sub2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"%%A format must be first in format string"); 562 ierr = PetscStrlen(format,&len);CHKERRQ(ierr); 563 ierr = PetscMalloc((len+16)*sizeof(char),&nformat);CHKERRQ(ierr); 564 ierr = PetscStrcpy(nformat,format);CHKERRQ(ierr); 565 ierr = PetscStrstr(nformat,"%",&sub2);CHKERRQ(ierr); 566 sub2[0] = 0; 567 value = va_arg(Argp,double); 568 #if defined(PETSC_USE_SCALAR_SINGLE) 569 if (PetscAbsReal(value) < 1.e-6) { 570 ierr = PetscStrcat(nformat,"< 1.e-6");CHKERRQ(ierr); 571 #else 572 if (PetscAbsReal(value) < 1.e-12) { 573 ierr = PetscStrcat(nformat,"< 1.e-12");CHKERRQ(ierr); 574 #endif 575 } else { 576 ierr = PetscStrcat(nformat,"%G");CHKERRQ(ierr); 577 va_end(Argp); 578 va_start(Argp,format); 579 } 580 ierr = PetscStrcat(nformat,sub1+2);CHKERRQ(ierr); 581 } else { 582 nformat = (char*)format; 583 } 584 ierr = (*PetscVFPrintf)(PETSC_STDOUT,nformat,Argp);CHKERRQ(ierr); 585 if (petsc_history) { 586 va_start(Argp,format); 587 ierr = (*PetscVFPrintf)(petsc_history,nformat,Argp);CHKERRQ(ierr); 588 } 589 va_end(Argp); 590 if (sub1) {ierr = PetscFree(nformat);CHKERRQ(ierr);} 591 } 592 PetscFunctionReturn(0); 593 } 594 595 /* ---------------------------------------------------------------------------------------*/ 596 #undef __FUNCT__ 597 #define __FUNCT__ "PetscHelpPrintfDefault" 598 /*@C 599 PetscHelpPrintf - All PETSc help messages are passing through this function. You can change how help messages are printed by 600 replacinng it with something that does not simply write to a stdout. 601 602 To use, write your own function for example, 603 $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....) 604 ${ 605 $ PetscFunctionReturn(0); 606 $} 607 then before the call to PetscInitialize() do the assignment 608 $ PetscHelpPrintf = mypetschelpprintf; 609 610 Note: the default routine used is called PetscHelpPrintfDefault(). 611 612 Level: developer 613 614 .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf() 615 @*/ 616 PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 617 { 618 PetscErrorCode ierr; 619 PetscMPIInt rank; 620 621 PetscFunctionBegin; 622 if (!comm) comm = PETSC_COMM_WORLD; 623 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 624 if (!rank) { 625 va_list Argp; 626 va_start(Argp,format); 627 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 628 if (petsc_history) { 629 va_start(Argp,format); 630 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 631 } 632 va_end(Argp); 633 } 634 PetscFunctionReturn(0); 635 } 636 637 /* ---------------------------------------------------------------------------------------*/ 638 639 640 #undef __FUNCT__ 641 #define __FUNCT__ "PetscSynchronizedFGets" 642 /*@C 643 PetscSynchronizedFGets - Several processors all get the same line from a file. 644 645 Collective on MPI_Comm 646 647 Input Parameters: 648 + comm - the communicator 649 . fd - the file pointer 650 - len - the length of the output buffer 651 652 Output Parameter: 653 . string - the line read from the file 654 655 Level: intermediate 656 657 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 658 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 659 660 @*/ 661 PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[]) 662 { 663 PetscErrorCode ierr; 664 PetscMPIInt rank; 665 666 PetscFunctionBegin; 667 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 668 669 if (!rank) { 670 (void) fgets(string,len,fp); /* Not very useful error behavior, but what is desired behavior for attempt to read at EOF? */ 671 } 672 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 673 PetscFunctionReturn(0); 674 } 675 676 #if defined(PETSC_HAVE_MATLAB_ENGINE) 677 #include "mex.h" 678 #undef __FUNCT__ 679 #define __FUNCT__ "PetscVFPrintf_Matlab" 680 PetscErrorCode PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp) 681 { 682 PetscErrorCode ierr; 683 684 PetscFunctionBegin; 685 if (fd != stdout && fd != stderr) { /* handle regular files */ 686 ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERRQ(ierr); 687 } else { 688 size_t len=8*1024,length; 689 char buf[len]; 690 691 ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr); 692 mexPrintf("%s",buf); 693 } 694 PetscFunctionReturn(0); 695 } 696 #endif 697