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