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 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 .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(MPI_Comm, 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