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_VPRINTF_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_VPRINTF_CHAR) 135 vfprintf(PETSC_ZOPEFD,log,(char *)Argp); 136 #else 137 vfprintf(PETSC_ZOPEFD,log,Argp); 138 fflush(PETSC_ZOPEFD); 139 #endif 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_VPRINTF_CHAR) 181 vfprintf(PETSC_ZOPEFD,newformat,(char *)s); 182 #else 183 vfprintf(PETSC_ZOPEFD,newformat,s); 184 fflush(PETSC_ZOPEFD); 185 #endif 186 } 187 188 #if defined(PETSC_HAVE_VPRINTF_CHAR) 189 vfprintf(fd,newformat,(char *)Argp); 190 #else 191 vfprintf(fd,newformat,Argp); 192 fflush(fd); 193 #endif 194 if (oldLength >= 8*1024) { 195 if (PetscFree(newformat)) {}; 196 } 197 return 0; 198 } 199 200 #undef __FUNCT__ 201 #define __FUNCT__ "PetscSNPrintf" 202 /*@C 203 PetscSNPrintf - Prints to a string of given length 204 205 Not Collective 206 207 Input Parameters: 208 + str - the string to print to 209 . len - the length of str 210 . format - the usual printf() format string 211 - any arguments 212 213 Level: intermediate 214 215 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 216 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 217 @*/ 218 PetscErrorCode PETSC_DLLEXPORT PetscSNPrintf(char *str,size_t len,const char format[],...) 219 { 220 PetscErrorCode ierr; 221 int fullLength; 222 va_list Argp; 223 224 PetscFunctionBegin; 225 va_start(Argp,format); 226 ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr); 227 PetscFunctionReturn(0); 228 } 229 230 /* ----------------------------------------------------------------------- */ 231 232 PrintfQueue queue = 0,queuebase = 0; 233 int queuelength = 0; 234 FILE *queuefile = PETSC_NULL; 235 236 #undef __FUNCT__ 237 #define __FUNCT__ "PetscSynchronizedPrintf" 238 /*@C 239 PetscSynchronizedPrintf - Prints synchronized output from several processors. 240 Output of the first processor is followed by that of the second, etc. 241 242 Not Collective 243 244 Input Parameters: 245 + comm - the communicator 246 - format - the usual printf() format string 247 248 Level: intermediate 249 250 Notes: 251 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 252 from all the processors to be printed. 253 254 Fortran Note: 255 The call sequence is PetscSynchronizedPrintf(PetscViewer, character(*), PetscErrorCode ierr) from Fortran. 256 That is, you can only pass a single character string from Fortran. 257 258 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 259 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 260 @*/ 261 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 262 { 263 PetscErrorCode ierr; 264 PetscMPIInt rank; 265 266 PetscFunctionBegin; 267 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 268 269 /* First processor prints immediately to stdout */ 270 if (!rank) { 271 va_list Argp; 272 va_start(Argp,format); 273 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 274 if (petsc_history) { 275 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 276 } 277 va_end(Argp); 278 } else { /* other processors add to local queue */ 279 va_list Argp; 280 PrintfQueue next; 281 int fullLength = 8191; 282 283 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 284 if (queue) {queue->next = next; queue = next; queue->next = 0;} 285 else {queuebase = queue = next;} 286 queuelength++; 287 next->size = -1; 288 while(fullLength >= next->size) { 289 next->size = fullLength+1; 290 ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr); 291 va_start(Argp,format); 292 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 293 ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr); 294 va_end(Argp); 295 } 296 } 297 298 PetscFunctionReturn(0); 299 } 300 301 #undef __FUNCT__ 302 #define __FUNCT__ "PetscSynchronizedFPrintf" 303 /*@C 304 PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 305 several processors. Output of the first processor is followed by that of the 306 second, etc. 307 308 Not Collective 309 310 Input Parameters: 311 + comm - the communicator 312 . fd - the file pointer 313 - format - the usual printf() format string 314 315 Level: intermediate 316 317 Notes: 318 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 319 from all the processors to be printed. 320 321 Contributed by: Matthew Knepley 322 323 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 324 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 325 326 @*/ 327 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...) 328 { 329 PetscErrorCode ierr; 330 PetscMPIInt rank; 331 332 PetscFunctionBegin; 333 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 334 335 /* First processor prints immediately to fp */ 336 if (!rank) { 337 va_list Argp; 338 va_start(Argp,format); 339 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 340 queuefile = fp; 341 if (petsc_history) { 342 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 343 } 344 va_end(Argp); 345 } else { /* other processors add to local queue */ 346 va_list Argp; 347 PrintfQueue next; 348 int fullLength = 8191; 349 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 350 if (queue) {queue->next = next; queue = next; queue->next = 0;} 351 else {queuebase = queue = next;} 352 queuelength++; 353 next->size = -1; 354 while(fullLength >= next->size) { 355 next->size = fullLength+1; 356 ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr); 357 va_start(Argp,format); 358 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 359 ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr); 360 va_end(Argp); 361 } 362 } 363 PetscFunctionReturn(0); 364 } 365 366 #undef __FUNCT__ 367 #define __FUNCT__ "PetscSynchronizedFlush" 368 /*@ 369 PetscSynchronizedFlush - Flushes to the screen output from all processors 370 involved in previous PetscSynchronizedPrintf() calls. 371 372 Collective on MPI_Comm 373 374 Input Parameters: 375 . comm - the communicator 376 377 Level: intermediate 378 379 Notes: 380 Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with 381 different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush(). 382 383 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 384 PetscViewerASCIISynchronizedPrintf() 385 @*/ 386 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFlush(MPI_Comm comm) 387 { 388 PetscErrorCode ierr; 389 PetscMPIInt rank,size,tag,i,j,n; 390 char *message; 391 MPI_Status status; 392 FILE *fd; 393 394 PetscFunctionBegin; 395 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 396 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 397 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 398 399 /* First processor waits for messages from all other processors */ 400 if (!rank) { 401 if (queuefile) { 402 fd = queuefile; 403 } else { 404 fd = PETSC_STDOUT; 405 } 406 for (i=1; i<size; i++) { 407 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 408 for (j=0; j<n; j++) { 409 int size; 410 411 ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 412 ierr = PetscMalloc(size * sizeof(char), &message);CHKERRQ(ierr); 413 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr); 414 ierr = PetscFPrintf(comm,fd,"%s",message); 415 ierr = PetscFree(message);CHKERRQ(ierr); 416 } 417 } 418 queuefile = PETSC_NULL; 419 } else { /* other processors send queue to processor 0 */ 420 PrintfQueue next = queuebase,previous; 421 422 ierr = MPI_Send(&queuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 423 for (i=0; i<queuelength; i++) { 424 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 425 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr); 426 previous = next; 427 next = next->next; 428 ierr = PetscFree(previous->string);CHKERRQ(ierr); 429 ierr = PetscFree(previous);CHKERRQ(ierr); 430 } 431 queue = 0; 432 queuelength = 0; 433 } 434 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 435 PetscFunctionReturn(0); 436 } 437 438 /* ---------------------------------------------------------------------------------------*/ 439 440 #undef __FUNCT__ 441 #define __FUNCT__ "PetscFPrintf" 442 /*@C 443 PetscFPrintf - Prints to a file, only from the first 444 processor in the communicator. 445 446 Not Collective 447 448 Input Parameters: 449 + comm - the communicator 450 . fd - the file pointer 451 - format - the usual printf() format string 452 453 Level: intermediate 454 455 Fortran Note: 456 This routine is not supported in Fortran. 457 458 Concepts: printing^in parallel 459 Concepts: printf^in parallel 460 461 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 462 PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 463 @*/ 464 PetscErrorCode PETSC_DLLEXPORT PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 465 { 466 PetscErrorCode ierr; 467 PetscMPIInt rank; 468 469 PetscFunctionBegin; 470 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 471 if (!rank) { 472 va_list Argp; 473 va_start(Argp,format); 474 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 475 if (petsc_history) { 476 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 477 } 478 va_end(Argp); 479 } 480 PetscFunctionReturn(0); 481 } 482 483 #undef __FUNCT__ 484 #define __FUNCT__ "PetscPrintf" 485 /*@C 486 PetscPrintf - Prints to standard out, only from the first 487 processor in the communicator. 488 489 Not Collective 490 491 Input Parameters: 492 + comm - the communicator 493 - format - the usual printf() format string 494 495 Level: intermediate 496 497 Fortran Note: 498 The call sequence is PetscPrintf(PetscViewer, character(*), PetscErrorCode ierr) from Fortran. 499 That is, you can only pass a single character string from Fortran. 500 501 Notes: %A is replace with %g unless the value is < 1.e-12 when it is 502 replaced with < 1.e-12 503 504 Concepts: printing^in parallel 505 Concepts: printf^in parallel 506 507 .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 508 @*/ 509 PetscErrorCode PETSC_DLLEXPORT PetscPrintf(MPI_Comm comm,const char format[],...) 510 { 511 PetscErrorCode ierr; 512 PetscMPIInt rank; 513 size_t len; 514 char *nformat,*sub1,*sub2; 515 PetscReal value; 516 517 PetscFunctionBegin; 518 if (!comm) comm = PETSC_COMM_WORLD; 519 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 520 if (!rank) { 521 va_list Argp; 522 va_start(Argp,format); 523 524 ierr = PetscStrstr(format,"%A",&sub1);CHKERRQ(ierr); 525 if (sub1) { 526 ierr = PetscStrstr(format,"%",&sub2);CHKERRQ(ierr); 527 if (sub1 != sub2) SETERRQ(PETSC_ERR_ARG_WRONG,"%%A format must be first in format string"); 528 ierr = PetscStrlen(format,&len);CHKERRQ(ierr); 529 ierr = PetscMalloc((len+16)*sizeof(char),&nformat);CHKERRQ(ierr); 530 ierr = PetscStrcpy(nformat,format);CHKERRQ(ierr); 531 ierr = PetscStrstr(nformat,"%",&sub2);CHKERRQ(ierr); 532 sub2[0] = 0; 533 value = (double)va_arg(Argp,double); 534 if (PetscAbsReal(value) < 1.e-12) { 535 ierr = PetscStrcat(nformat,"< 1.e-12");CHKERRQ(ierr); 536 } else { 537 ierr = PetscStrcat(nformat,"%g");CHKERRQ(ierr); 538 va_end(Argp); 539 va_start(Argp,format); 540 } 541 ierr = PetscStrcat(nformat,sub1+2);CHKERRQ(ierr); 542 } else { 543 nformat = (char*)format; 544 } 545 ierr = (*PetscVFPrintf)(PETSC_STDOUT,nformat,Argp);CHKERRQ(ierr); 546 if (petsc_history) { 547 ierr = (*PetscVFPrintf)(petsc_history,nformat,Argp);CHKERRQ(ierr); 548 } 549 va_end(Argp); 550 if (sub1) {ierr = PetscFree(nformat);CHKERRQ(ierr);} 551 } 552 PetscFunctionReturn(0); 553 } 554 555 /* ---------------------------------------------------------------------------------------*/ 556 #undef __FUNCT__ 557 #define __FUNCT__ "PetscHelpPrintfDefault" 558 PetscErrorCode PETSC_DLLEXPORT PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 559 { 560 PetscErrorCode ierr; 561 PetscMPIInt rank; 562 563 PetscFunctionBegin; 564 if (!comm) comm = PETSC_COMM_WORLD; 565 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 566 if (!rank) { 567 va_list Argp; 568 va_start(Argp,format); 569 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 570 if (petsc_history) { 571 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 572 } 573 va_end(Argp); 574 } 575 PetscFunctionReturn(0); 576 } 577 578 /* ---------------------------------------------------------------------------------------*/ 579 580 581 #undef __FUNCT__ 582 #define __FUNCT__ "PetscSynchronizedFGets" 583 /*@C 584 PetscSynchronizedFGets - Several processors all get the same line from a file. 585 586 Collective on MPI_Comm 587 588 Input Parameters: 589 + comm - the communicator 590 . fd - the file pointer 591 - len - the length of the output buffer 592 593 Output Parameter: 594 . string - the line read from the file 595 596 Level: intermediate 597 598 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 599 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 600 601 @*/ 602 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[]) 603 { 604 PetscErrorCode ierr; 605 PetscMPIInt rank; 606 607 PetscFunctionBegin; 608 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 609 610 if (!rank) { 611 fgets(string,len,fp); 612 } 613 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 614 PetscFunctionReturn(0); 615 } 616