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