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