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