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