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