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_SCALAR_INT) 59 newformat[j++] = 'd'; 60 #elif !defined(PETSC_USE_SCALAR_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 (void)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 va_start(Argp,format); 278 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 279 } 280 va_end(Argp); 281 } else { /* other processors add to local queue */ 282 va_list Argp; 283 PrintfQueue next; 284 int fullLength = 8191; 285 286 ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr); 287 if (queue) {queue->next = next; queue = next; queue->next = 0;} 288 else {queuebase = queue = next;} 289 queuelength++; 290 next->size = -1; 291 while(fullLength >= next->size) { 292 next->size = fullLength+1; 293 ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr); 294 va_start(Argp,format); 295 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 296 ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr); 297 va_end(Argp); 298 } 299 } 300 301 PetscFunctionReturn(0); 302 } 303 304 #undef __FUNCT__ 305 #define __FUNCT__ "PetscSynchronizedFPrintf" 306 /*@C 307 PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 308 several processors. Output of the first processor is followed by that of the 309 second, etc. 310 311 Not Collective 312 313 Input Parameters: 314 + comm - the communicator 315 . fd - the file pointer 316 - format - the usual printf() format string 317 318 Level: intermediate 319 320 Notes: 321 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 322 from all the processors to be printed. 323 324 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 325 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 326 327 @*/ 328 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...) 329 { 330 PetscErrorCode ierr; 331 PetscMPIInt rank; 332 333 PetscFunctionBegin; 334 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 335 336 /* First processor prints immediately to fp */ 337 if (!rank) { 338 va_list Argp; 339 va_start(Argp,format); 340 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 341 queuefile = fp; 342 if (petsc_history && (fp !=petsc_history)) { 343 va_start(Argp,format); 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 && (fd !=petsc_history)) { 478 va_start(Argp,format); 479 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 480 } 481 va_end(Argp); 482 } 483 PetscFunctionReturn(0); 484 } 485 486 #undef __FUNCT__ 487 #define __FUNCT__ "PetscPrintf" 488 /*@C 489 PetscPrintf - Prints to standard out, only from the first 490 processor in the communicator. 491 492 Not Collective 493 494 Input Parameters: 495 + comm - the communicator 496 - format - the usual printf() format string 497 498 Level: intermediate 499 500 Fortran Note: 501 The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 502 That is, you can only pass a single character string from Fortran. 503 504 Notes: %A is replace with %g unless the value is < 1.e-12 when it is 505 replaced with < 1.e-12 506 507 Concepts: printing^in parallel 508 Concepts: printf^in parallel 509 510 .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 511 @*/ 512 PetscErrorCode PETSC_DLLEXPORT PetscPrintf(MPI_Comm comm,const char format[],...) 513 { 514 PetscErrorCode ierr; 515 PetscMPIInt rank; 516 size_t len; 517 char *nformat,*sub1,*sub2; 518 PetscReal value; 519 520 PetscFunctionBegin; 521 if (!comm) comm = PETSC_COMM_WORLD; 522 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 523 if (!rank) { 524 va_list Argp; 525 va_start(Argp,format); 526 527 ierr = PetscStrstr(format,"%A",&sub1);CHKERRQ(ierr); 528 if (sub1) { 529 ierr = PetscStrstr(format,"%",&sub2);CHKERRQ(ierr); 530 if (sub1 != sub2) SETERRQ(PETSC_ERR_ARG_WRONG,"%%A format must be first in format string"); 531 ierr = PetscStrlen(format,&len);CHKERRQ(ierr); 532 ierr = PetscMalloc((len+16)*sizeof(char),&nformat);CHKERRQ(ierr); 533 ierr = PetscStrcpy(nformat,format);CHKERRQ(ierr); 534 ierr = PetscStrstr(nformat,"%",&sub2);CHKERRQ(ierr); 535 sub2[0] = 0; 536 value = (double)va_arg(Argp,double); 537 if (PetscAbsReal(value) < 1.e-12) { 538 ierr = PetscStrcat(nformat,"< 1.e-12");CHKERRQ(ierr); 539 } else { 540 ierr = PetscStrcat(nformat,"%g");CHKERRQ(ierr); 541 va_end(Argp); 542 va_start(Argp,format); 543 } 544 ierr = PetscStrcat(nformat,sub1+2);CHKERRQ(ierr); 545 } else { 546 nformat = (char*)format; 547 } 548 ierr = (*PetscVFPrintf)(PETSC_STDOUT,nformat,Argp);CHKERRQ(ierr); 549 if (petsc_history) { 550 va_start(Argp,format); 551 ierr = (*PetscVFPrintf)(petsc_history,nformat,Argp);CHKERRQ(ierr); 552 } 553 va_end(Argp); 554 if (sub1) {ierr = PetscFree(nformat);CHKERRQ(ierr);} 555 } 556 PetscFunctionReturn(0); 557 } 558 559 /* ---------------------------------------------------------------------------------------*/ 560 #undef __FUNCT__ 561 #define __FUNCT__ "PetscHelpPrintfDefault" 562 PetscErrorCode PETSC_DLLEXPORT PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 563 { 564 PetscErrorCode ierr; 565 PetscMPIInt rank; 566 567 PetscFunctionBegin; 568 if (!comm) comm = PETSC_COMM_WORLD; 569 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 570 if (!rank) { 571 va_list Argp; 572 va_start(Argp,format); 573 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 574 if (petsc_history) { 575 va_start(Argp,format); 576 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 577 } 578 va_end(Argp); 579 } 580 PetscFunctionReturn(0); 581 } 582 583 /* ---------------------------------------------------------------------------------------*/ 584 585 586 #undef __FUNCT__ 587 #define __FUNCT__ "PetscSynchronizedFGets" 588 /*@C 589 PetscSynchronizedFGets - Several processors all get the same line from a file. 590 591 Collective on MPI_Comm 592 593 Input Parameters: 594 + comm - the communicator 595 . fd - the file pointer 596 - len - the length of the output buffer 597 598 Output Parameter: 599 . string - the line read from the file 600 601 Level: intermediate 602 603 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 604 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 605 606 @*/ 607 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[]) 608 { 609 PetscErrorCode ierr; 610 PetscMPIInt rank; 611 612 PetscFunctionBegin; 613 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 614 615 if (!rank) { 616 fgets(string,len,fp); 617 } 618 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 619 PetscFunctionReturn(0); 620 } 621