1e5c89e4eSSatish Balay /* 2da81f932SPierre Jolivet Utilities routines to add simple ASCII IO capability. 3e5c89e4eSSatish Balay */ 4c6db04a5SJed Brown #include <../src/sys/fileio/mprint.h> 579c0e996SJed Brown #include <errno.h> 6e5c89e4eSSatish Balay /* 7e5c89e4eSSatish Balay If petsc_history is on, then all Petsc*Printf() results are saved 8e5c89e4eSSatish Balay if the appropriate (usually .petschistory) file. 9e5c89e4eSSatish Balay */ 1095c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history; 11e5c89e4eSSatish Balay /* 12e5c89e4eSSatish Balay Allows one to overwrite where standard out is sent. For example 135106ddf5SBarry Smith PETSC_STDOUT = fopen("/dev/ttyXX","w") will cause all standard out 14e5c89e4eSSatish Balay writes to go to terminal XX; assuming you have write permission there 15e5c89e4eSSatish Balay */ 1602c9f0b5SLisandro Dalcin FILE *PETSC_STDOUT = NULL; 17ae9b4142SLisandro Dalcin /* 18ae9b4142SLisandro Dalcin Allows one to overwrite where standard error is sent. For example 19ae9b4142SLisandro Dalcin PETSC_STDERR = fopen("/dev/ttyXX","w") will cause all standard error 20ae9b4142SLisandro Dalcin writes to go to terminal XX; assuming you have write permission there 21ae9b4142SLisandro Dalcin */ 2202c9f0b5SLisandro Dalcin FILE *PETSC_STDERR = NULL; 23b13499bfSbcordonn 24c9a19010SBarry Smith /*@C 25811af0c4SBarry Smith PetscFormatConvertGetSize - Gets the length of a string needed to hold format converted with `PetscFormatConvert()` 26811af0c4SBarry Smith 27058c9ee1SBarry Smith No Fortran Support 28c9a19010SBarry Smith 29d781fa04SBarry Smith Input Parameter: 30d781fa04SBarry Smith . format - the PETSc format string 31c9a19010SBarry Smith 32d781fa04SBarry Smith Output Parameter: 33d781fa04SBarry Smith . size - the needed length of the new format 34c9a19010SBarry Smith 35c9a19010SBarry Smith Level: developer 36c9a19010SBarry Smith 37db781477SPatrick Sanan .seealso: `PetscFormatConvert()`, `PetscVSNPrintf()`, `PetscVFPrintf()` 38c9a19010SBarry Smith @*/ 39d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvertGetSize(const char *format, size_t *size) 40d71ae5a4SJacob Faibussowitsch { 413ca90d2dSJacob Faibussowitsch size_t sz = 0; 42d781fa04SBarry Smith PetscInt i = 0; 43d781fa04SBarry Smith 44d781fa04SBarry Smith PetscFunctionBegin; 453ca90d2dSJacob Faibussowitsch PetscValidCharPointer(format, 1); 463ca90d2dSJacob Faibussowitsch PetscValidPointer(size, 2); 47d781fa04SBarry Smith while (format[i]) { 483ca90d2dSJacob Faibussowitsch if (format[i] == '%') { 493ca90d2dSJacob Faibussowitsch if (format[i + 1] == '%') { 503ca90d2dSJacob Faibussowitsch i += 2; 513ca90d2dSJacob Faibussowitsch sz += 2; 523ca90d2dSJacob Faibussowitsch continue; 533ca90d2dSJacob Faibussowitsch } 54d781fa04SBarry Smith /* Find the letter */ 559371c9d4SSatish Balay while (format[i] && (format[i] <= '9')) { 569371c9d4SSatish Balay ++i; 579371c9d4SSatish Balay ++sz; 589371c9d4SSatish Balay } 59d781fa04SBarry Smith switch (format[i]) { 603ca90d2dSJacob Faibussowitsch #if PetscDefined(USE_64BIT_INDICES) 61d71ae5a4SJacob Faibussowitsch case 'D': 62d71ae5a4SJacob Faibussowitsch sz += 2; 63d71ae5a4SJacob Faibussowitsch break; 64d781fa04SBarry Smith #endif 65d71ae5a4SJacob Faibussowitsch case 'g': 66d71ae5a4SJacob Faibussowitsch sz += 4; 67d71ae5a4SJacob Faibussowitsch default: 68d71ae5a4SJacob Faibussowitsch break; 69d781fa04SBarry Smith } 70d781fa04SBarry Smith } 713ca90d2dSJacob Faibussowitsch ++i; 723ca90d2dSJacob Faibussowitsch ++sz; 73d781fa04SBarry Smith } 743ca90d2dSJacob Faibussowitsch *size = sz + 1; /* space for NULL character */ 753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76d781fa04SBarry Smith } 77d781fa04SBarry Smith 78d781fa04SBarry Smith /*@C 79058c9ee1SBarry Smith PetscFormatConvert - converts %g to [|%g|] so that `PetscVSNPrintf()` can ensure all %g formatted numbers have a decimal point when printed. The 80058c9ee1SBarry Smith decimal point is then used by the `petscdiff` script so that differences in floating point number output is ignored in the test harness. 81d781fa04SBarry Smith 82058c9ee1SBarry Smith No Fortran Support 83811af0c4SBarry Smith 84d781fa04SBarry Smith Input Parameters: 85d781fa04SBarry Smith + format - the PETSc format string 86d781fa04SBarry Smith . newformat - the location to put the new format 87811af0c4SBarry Smith - size - the length of newformat, you can use `PetscFormatConvertGetSize()` to compute the needed size 88d781fa04SBarry Smith 89d781fa04SBarry Smith Level: developer 90d781fa04SBarry Smith 91058c9ee1SBarry Smith Note: 92058c9ee1SBarry Smith Deprecated usage also converts the %D to %d for 32 bit PETSc indices and %lld for 64 bit PETSc indices. This feature is no 93058c9ee1SBarry Smith longer used in PETSc code instead use %" PetscInt_FMT " in the format string 94058c9ee1SBarry Smith 95db781477SPatrick Sanan .seealso: `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscVFPrintf()` 96d781fa04SBarry Smith @*/ 97d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvert(const char *format, char *newformat) 98d71ae5a4SJacob Faibussowitsch { 99e5c89e4eSSatish Balay PetscInt i = 0, j = 0; 100e5c89e4eSSatish Balay 101eed5747fSBarry Smith PetscFunctionBegin; 102d781fa04SBarry Smith while (format[i]) { 1032a1ad9caSBarry Smith if (format[i] == '%' && format[i + 1] == '%') { 1042a1ad9caSBarry Smith newformat[j++] = format[i++]; 1052a1ad9caSBarry Smith newformat[j++] = format[i++]; 1062a1ad9caSBarry Smith } else if (format[i] == '%') { 1078627564fSBarry Smith if (format[i + 1] == 'g') { 1088627564fSBarry Smith newformat[j++] = '['; 1098627564fSBarry Smith newformat[j++] = '|'; 1108627564fSBarry Smith } 1117bc47156SJose Roman /* Find the letter */ 1127bc47156SJose Roman for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 1137bc47156SJose Roman switch (format[i]) { 1147bc47156SJose Roman case 'D': 1156de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 116e5c89e4eSSatish Balay newformat[j++] = 'd'; 117e5c89e4eSSatish Balay #else 118e5c89e4eSSatish Balay newformat[j++] = 'l'; 119e5c89e4eSSatish Balay newformat[j++] = 'l'; 120e5c89e4eSSatish Balay newformat[j++] = 'd'; 121e5c89e4eSSatish Balay #endif 1227bc47156SJose Roman break; 1238627564fSBarry Smith case 'g': 1248627564fSBarry Smith newformat[j++] = format[i]; 1258627564fSBarry Smith if (format[i - 1] == '%') { 1268627564fSBarry Smith newformat[j++] = '|'; 1278627564fSBarry Smith newformat[j++] = ']'; 1288627564fSBarry Smith } 1298627564fSBarry Smith break; 130d71ae5a4SJacob Faibussowitsch case 'G': 131d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%G format is no longer supported, use %%g and cast the argument to double"); 132d71ae5a4SJacob Faibussowitsch case 'F': 133d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%F format is no longer supported, use %%f and cast the argument to double"); 134d71ae5a4SJacob Faibussowitsch default: 135d71ae5a4SJacob Faibussowitsch newformat[j++] = format[i]; 136d71ae5a4SJacob Faibussowitsch break; 1377bc47156SJose Roman } 1387bc47156SJose Roman i++; 139a297a907SKarl Rupp } else newformat[j++] = format[i++]; 140e5c89e4eSSatish Balay } 141e5c89e4eSSatish Balay newformat[j] = 0; 1423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 143e5c89e4eSSatish Balay } 144e5c89e4eSSatish Balay 14514416c0eSBarry Smith #define PETSCDEFAULTBUFFERSIZE 8 * 1024 146d781fa04SBarry Smith 147c9a19010SBarry Smith /*@C 1486026c97aSBarry Smith PetscVSNPrintf - The PETSc version of `vsnprintf()`. Ensures that all `%g` formatted arguments' output contains the decimal point (which 149058c9ee1SBarry Smith is used by the test harness) 150c9a19010SBarry Smith 151c9a19010SBarry Smith Input Parameters: 152c9a19010SBarry Smith + str - location to put result 153c9a19010SBarry Smith . len - the amount of space in str 154c9a19010SBarry Smith + format - the PETSc format string 155c9a19010SBarry Smith - fullLength - the amount of space in str actually used. 156c9a19010SBarry Smith 157c9a19010SBarry Smith Level: developer 158c9a19010SBarry Smith 159058c9ee1SBarry Smith Developer Note: 160058c9ee1SBarry Smith This function may be called from an error handler, if an error occurs when it is called by the error handler than likely 161058c9ee1SBarry Smith a recursion will occur resulting in a crash of the program. 162058c9ee1SBarry Smith 1636026c97aSBarry Smith If the length of the format string `format` is on the order of `PETSCDEFAULTBUFFERSIZE` (8 * 1024 bytes), this function will call `PetscMalloc()` 164058c9ee1SBarry Smith 165058c9ee1SBarry Smith .seealso: `PetscFormatConvert()`, `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscVPrintf()` 166c9a19010SBarry Smith @*/ 167d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVSNPrintf(char *str, size_t len, const char *format, size_t *fullLength, va_list Argp) 168d71ae5a4SJacob Faibussowitsch { 169d781fa04SBarry Smith char *newformat = NULL; 17014416c0eSBarry Smith char formatbuf[PETSCDEFAULTBUFFERSIZE]; 171d781fa04SBarry Smith size_t newLength; 17214416c0eSBarry Smith int flen; 173e5c89e4eSSatish Balay 174eed5747fSBarry Smith PetscFunctionBegin; 1759566063dSJacob Faibussowitsch PetscCall(PetscFormatConvertGetSize(format, &newLength)); 17694217ebdSBarry Smith if (newLength < sizeof(formatbuf)) { 177e2135aedSMatthew Knepley newformat = formatbuf; 17894217ebdSBarry Smith newLength = sizeof(formatbuf) - 1; 179e2135aedSMatthew Knepley } else { 1809566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(newLength, &newformat)); 181e2135aedSMatthew Knepley } 1829566063dSJacob Faibussowitsch PetscCall(PetscFormatConvert(format, newformat)); 1837b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF) 184152b30f0SSatish Balay flen = vsnprintf(str, len, newformat, Argp); 185e5c89e4eSSatish Balay #else 18689b07760SSatish Balay #error "vsnprintf not found" 187e5c89e4eSSatish Balay #endif 18848a46eb9SPierre Jolivet if (newLength > sizeof(formatbuf) - 1) PetscCall(PetscFree(newformat)); 1898627564fSBarry Smith { 1908627564fSBarry Smith PetscBool foundedot; 1918627564fSBarry Smith size_t cnt = 0, ncnt = 0, leng; 1929566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 19317ca8410SBarry Smith if (leng > 4) { 1948627564fSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 1958627564fSBarry Smith if (str[cnt] == '[' && str[cnt + 1] == '|') { 196c540d043SBarry Smith flen -= 4; 1979371c9d4SSatish Balay cnt++; 1989371c9d4SSatish Balay cnt++; 1998627564fSBarry Smith foundedot = PETSC_FALSE; 2008627564fSBarry Smith for (; cnt < leng - 1; cnt++) { 2018627564fSBarry Smith if (str[cnt] == '|' && str[cnt + 1] == ']') { 2028627564fSBarry Smith cnt++; 2038627564fSBarry Smith if (!foundedot) str[ncnt++] = '.'; 2048627564fSBarry Smith ncnt--; 2058627564fSBarry Smith break; 2068627564fSBarry Smith } else { 2078627564fSBarry Smith if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 2088627564fSBarry Smith str[ncnt++] = str[cnt]; 2098627564fSBarry Smith } 2108627564fSBarry Smith } 2118627564fSBarry Smith } else { 2128627564fSBarry Smith str[ncnt] = str[cnt]; 2138627564fSBarry Smith } 2148627564fSBarry Smith ncnt++; 2158627564fSBarry Smith } 2168627564fSBarry Smith while (cnt < leng) { 2179371c9d4SSatish Balay str[ncnt] = str[cnt]; 2189371c9d4SSatish Balay ncnt++; 2199371c9d4SSatish Balay cnt++; 2208627564fSBarry Smith } 2218627564fSBarry Smith str[ncnt] = 0; 2228627564fSBarry Smith } 2238627564fSBarry Smith } 224748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 225e51f71cfSBarry Smith /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 226748e1b9dSBarry Smith { 227748e1b9dSBarry Smith size_t cnt = 0, ncnt = 0, leng; 2289566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 229748e1b9dSBarry Smith if (leng > 5) { 230748e1b9dSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 231e51f71cfSBarry Smith if (str[cnt] == 'e' && (str[cnt + 1] == '-' || str[cnt + 1] == '+') && str[cnt + 2] == '0' && str[cnt + 3] >= '0' && str[cnt + 3] <= '9' && str[cnt + 4] >= '0' && str[cnt + 4] <= '9') { 2329371c9d4SSatish Balay str[ncnt] = str[cnt]; 2339371c9d4SSatish Balay ncnt++; 2349371c9d4SSatish Balay cnt++; 2359371c9d4SSatish Balay str[ncnt] = str[cnt]; 2369371c9d4SSatish Balay ncnt++; 2379371c9d4SSatish Balay cnt++; 2389371c9d4SSatish Balay cnt++; 239e51f71cfSBarry Smith str[ncnt] = str[cnt]; 240748e1b9dSBarry Smith } else { 241748e1b9dSBarry Smith str[ncnt] = str[cnt]; 242748e1b9dSBarry Smith } 243748e1b9dSBarry Smith ncnt++; 244748e1b9dSBarry Smith } 245748e1b9dSBarry Smith while (cnt < leng) { 2469371c9d4SSatish Balay str[ncnt] = str[cnt]; 2479371c9d4SSatish Balay ncnt++; 2489371c9d4SSatish Balay cnt++; 249748e1b9dSBarry Smith } 250748e1b9dSBarry Smith str[ncnt] = 0; 251748e1b9dSBarry Smith } 252748e1b9dSBarry Smith } 253748e1b9dSBarry Smith #endif 254c540d043SBarry Smith if (fullLength) *fullLength = 1 + (size_t)flen; 2553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 256e5c89e4eSSatish Balay } 257e5c89e4eSSatish Balay 258c9a19010SBarry Smith /*@C 259c69effb2SJacob Faibussowitsch PetscFFlush - Flush a file stream 260c69effb2SJacob Faibussowitsch 261c69effb2SJacob Faibussowitsch Input Parameter: 262c69effb2SJacob Faibussowitsch . fd - The file stream handle 263c69effb2SJacob Faibussowitsch 264c69effb2SJacob Faibussowitsch Level: intermediate 265c69effb2SJacob Faibussowitsch 266c69effb2SJacob Faibussowitsch Notes: 267c69effb2SJacob Faibussowitsch For output streams (and for update streams on which the last operation was output), writes 268c69effb2SJacob Faibussowitsch any unwritten data from the stream's buffer to the associated output device. 269c69effb2SJacob Faibussowitsch 270c69effb2SJacob Faibussowitsch For input streams (and for update streams on which the last operation was input), the 271c69effb2SJacob Faibussowitsch behavior is undefined. 272c69effb2SJacob Faibussowitsch 273c69effb2SJacob Faibussowitsch If `fd` is `NULL`, all open output streams are flushed, including ones not directly 274c69effb2SJacob Faibussowitsch accessible to the program. 275c69effb2SJacob Faibussowitsch 276c69effb2SJacob Faibussowitsch .seealso: `PetscPrintf()`, `PetscFPrintf()`, `PetscVFPrintf()`, `PetscVSNPrintf()` 277c69effb2SJacob Faibussowitsch @*/ 278c69effb2SJacob Faibussowitsch PetscErrorCode PetscFFlush(FILE *fd) 279c69effb2SJacob Faibussowitsch { 280c69effb2SJacob Faibussowitsch int ret; 281c69effb2SJacob Faibussowitsch 282c69effb2SJacob Faibussowitsch PetscFunctionBegin; 283c69effb2SJacob Faibussowitsch if (fd) PetscValidPointer(fd, 1); 284c69effb2SJacob Faibussowitsch ret = fflush(fd); 285c69effb2SJacob Faibussowitsch // could also use PetscCallExternal() here, but since we can get additional error explanation 286c69effb2SJacob Faibussowitsch // from strerror() we opted for a manual check 287c69effb2SJacob Faibussowitsch PetscCheck(ret == 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "Error in fflush(): error code %d (%s)", ret, strerror(errno)); 288c69effb2SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 289c69effb2SJacob Faibussowitsch } 290c69effb2SJacob Faibussowitsch 291c69effb2SJacob Faibussowitsch /*@C 292c9a19010SBarry Smith PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 293e5c89e4eSSatish Balay can be replaced with something that does not simply write to a file. 294e5c89e4eSSatish Balay 295c9a19010SBarry Smith To use, write your own function for example, 296058c9ee1SBarry Smith .vb 297058c9ee1SBarry Smith PetscErrorCode mypetscvfprintf(FILE *fd, const char format[], va_list Argp) 298058c9ee1SBarry Smith { 299058c9ee1SBarry Smith PetscErrorCode ierr; 300058c9ee1SBarry Smith 301058c9ee1SBarry Smith PetscFunctionBegin; 302058c9ee1SBarry Smith if (fd != stdout && fd != stderr) { handle regular files 303058c9ee1SBarry Smith CHKERR(PetscVFPrintfDefault(fd,format,Argp)); 304058c9ee1SBarry Smith } else { 305058c9ee1SBarry Smith char buff[BIG]; 306058c9ee1SBarry Smith size_t length; 307058c9ee1SBarry Smith PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp)); 308058c9ee1SBarry Smith now send buff to whatever stream or whatever you want 309058c9ee1SBarry Smith } 310058c9ee1SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 311058c9ee1SBarry Smith } 312058c9ee1SBarry Smith .ve 313058c9ee1SBarry Smith then before the call to `PetscInitialize()` do the assignment `PetscVFPrintf = mypetscvfprintf`; 314058c9ee1SBarry Smith 315058c9ee1SBarry Smith Level: developer 316c9a19010SBarry Smith 317811af0c4SBarry Smith Note: 31895452b02SPatrick Sanan For error messages this may be called by any process, for regular standard out it is 319e5c89e4eSSatish Balay called only by process 0 of a given communicator 320e5c89e4eSSatish Balay 321811af0c4SBarry Smith Developer Note: 322058c9ee1SBarry Smith This could be called by an error handler, if that happens then a recursion of the error handler may occur 323058c9ee1SBarry Smith and a resulting crash 324c9a19010SBarry Smith 325c69effb2SJacob Faibussowitsch .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscFFlush()` 326c9a19010SBarry Smith @*/ 327d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char *format, va_list Argp) 328d71ae5a4SJacob Faibussowitsch { 32914416c0eSBarry Smith char str[PETSCDEFAULTBUFFERSIZE]; 33014416c0eSBarry Smith char *buff = str; 33114416c0eSBarry Smith size_t fullLength; 3321531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 33314416c0eSBarry Smith va_list Argpcopy; 3341531940fSBarry Smith #endif 3351179db26SBarry Smith 336eed5747fSBarry Smith PetscFunctionBegin; 3371531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 33814416c0eSBarry Smith va_copy(Argpcopy, Argp); 3391531940fSBarry Smith #endif 3409566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp)); 34114416c0eSBarry Smith if (fullLength > sizeof(str)) { 3429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fullLength, &buff)); 3431531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 3449566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy)); 3451531940fSBarry Smith #else 3461531940fSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines"); 3471531940fSBarry Smith #endif 34814416c0eSBarry Smith } 349*eae3dc7dSJacob Faibussowitsch #if defined(PETSC_HAVE_VA_COPY) 350*eae3dc7dSJacob Faibussowitsch va_end(Argpcopy); 351*eae3dc7dSJacob Faibussowitsch #endif 352c69effb2SJacob Faibussowitsch { 353c69effb2SJacob Faibussowitsch const int err = fprintf(fd, "%s", buff); 354c69effb2SJacob Faibussowitsch // cannot use PetscCallExternal() for fprintf since the return value is "number of 355c69effb2SJacob Faibussowitsch // characters transmitted to the output stream" on success 356c69effb2SJacob Faibussowitsch PetscCheck(err >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "fprintf() returned error code %d", err); 357c69effb2SJacob Faibussowitsch } 358c69effb2SJacob Faibussowitsch PetscCall(PetscFFlush(fd)); 35948a46eb9SPierre Jolivet if (buff != str) PetscCall(PetscFree(buff)); 3603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 361e5c89e4eSSatish Balay } 362e5c89e4eSSatish Balay 3635b5bc046SBarry Smith /*@C 3645b5bc046SBarry Smith PetscSNPrintf - Prints to a string of given length 3655b5bc046SBarry Smith 3665b5bc046SBarry Smith Not Collective 3675b5bc046SBarry Smith 3685b5bc046SBarry Smith Input Parameters: 3695b5bc046SBarry Smith + str - the string to print to 370058c9ee1SBarry Smith . len - the length of `str` 371058c9ee1SBarry Smith . format - the usual `printf()` format string 37210699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 3735b5bc046SBarry Smith 3745b5bc046SBarry Smith Level: intermediate 3755b5bc046SBarry Smith 376db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 377c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 378c69effb2SJacob Faibussowitsch `PetscVFPrintf()`, `PetscFFlush()` 3795b5bc046SBarry Smith @*/ 380d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintf(char *str, size_t len, const char format[], ...) 381d71ae5a4SJacob Faibussowitsch { 382c9a19010SBarry Smith size_t fullLength; 3835b5bc046SBarry Smith va_list Argp; 3845b5bc046SBarry Smith 3855b5bc046SBarry Smith PetscFunctionBegin; 3865b5bc046SBarry Smith va_start(Argp, format); 3879566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp)); 388*eae3dc7dSJacob Faibussowitsch va_end(Argp); 3893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3905b5bc046SBarry Smith } 3915b5bc046SBarry Smith 392257d2499SJed Brown /*@C 393058c9ee1SBarry Smith PetscSNPrintfCount - Prints to a string of given length, returns count of characters printed 394257d2499SJed Brown 395257d2499SJed Brown Not Collective 396257d2499SJed Brown 397257d2499SJed Brown Input Parameters: 398257d2499SJed Brown + str - the string to print to 399058c9ee1SBarry Smith . len - the length of `str` 400058c9ee1SBarry Smith . format - the usual `printf()` format string 40110699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 402257d2499SJed Brown 403cb398dd3SBarry Smith Output Parameter: 404058c9ee1SBarry Smith . countused - number of characters printed 405cb398dd3SBarry Smith 406257d2499SJed Brown Level: intermediate 407257d2499SJed Brown 408db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 409db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()` 410257d2499SJed Brown @*/ 411d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintfCount(char *str, size_t len, const char format[], size_t *countused, ...) 412d71ae5a4SJacob Faibussowitsch { 413257d2499SJed Brown va_list Argp; 414257d2499SJed Brown 415257d2499SJed Brown PetscFunctionBegin; 416257d2499SJed Brown va_start(Argp, countused); 4179566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, countused, Argp)); 418*eae3dc7dSJacob Faibussowitsch va_end(Argp); 4193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 420257d2499SJed Brown } 421257d2499SJed Brown 422e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */ 423e5c89e4eSSatish Balay 42402c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL; 425d30b0576SJed Brown int petsc_printfqueuelength = 0; 426e5c89e4eSSatish Balay 427*eae3dc7dSJacob Faibussowitsch static inline PetscErrorCode PetscVFPrintf_Private(MPI_Comm comm, FILE *fd, const char format[], va_list Argp) 428*eae3dc7dSJacob Faibussowitsch { 429*eae3dc7dSJacob Faibussowitsch const PetscBool tee = (PetscBool)(petsc_history && (fd != petsc_history)); 430*eae3dc7dSJacob Faibussowitsch PetscMPIInt rank; 431*eae3dc7dSJacob Faibussowitsch va_list cpy; 432*eae3dc7dSJacob Faibussowitsch 433*eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 434*eae3dc7dSJacob Faibussowitsch PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 435*eae3dc7dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 436*eae3dc7dSJacob Faibussowitsch if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS); 437*eae3dc7dSJacob Faibussowitsch // must do this before we possibly consume Argp 438*eae3dc7dSJacob Faibussowitsch if (tee) va_copy(cpy, Argp); 439*eae3dc7dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fd, format, Argp)); 440*eae3dc7dSJacob Faibussowitsch if (tee) { 441*eae3dc7dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, cpy)); 442*eae3dc7dSJacob Faibussowitsch va_end(cpy); 443*eae3dc7dSJacob Faibussowitsch } 444*eae3dc7dSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 445*eae3dc7dSJacob Faibussowitsch } 446*eae3dc7dSJacob Faibussowitsch 447*eae3dc7dSJacob Faibussowitsch static inline PetscErrorCode PetscSynchronizedFPrintf_Private(MPI_Comm comm, FILE *fp, const char format[], va_list Argp) 448*eae3dc7dSJacob Faibussowitsch { 449*eae3dc7dSJacob Faibussowitsch PetscMPIInt rank; 450*eae3dc7dSJacob Faibussowitsch va_list cpy; 451*eae3dc7dSJacob Faibussowitsch 452*eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 453*eae3dc7dSJacob Faibussowitsch PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 454*eae3dc7dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 455*eae3dc7dSJacob Faibussowitsch /* First processor prints immediately to fp */ 456*eae3dc7dSJacob Faibussowitsch if (rank == 0) { 457*eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 458*eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, fp, format, cpy)); 459*eae3dc7dSJacob Faibussowitsch va_end(cpy); 460*eae3dc7dSJacob Faibussowitsch } else { /* other processors add to local queue */ 461*eae3dc7dSJacob Faibussowitsch PrintfQueue next; 462*eae3dc7dSJacob Faibussowitsch size_t fullLength = PETSCDEFAULTBUFFERSIZE; 463*eae3dc7dSJacob Faibussowitsch 464*eae3dc7dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 465*eae3dc7dSJacob Faibussowitsch if (petsc_printfqueue) { 466*eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = next; 467*eae3dc7dSJacob Faibussowitsch petsc_printfqueue = next; 468*eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = NULL; 469*eae3dc7dSJacob Faibussowitsch } else petsc_printfqueuebase = petsc_printfqueue = next; 470*eae3dc7dSJacob Faibussowitsch petsc_printfqueuelength++; 471*eae3dc7dSJacob Faibussowitsch next->size = 0; 472*eae3dc7dSJacob Faibussowitsch next->string = NULL; 473*eae3dc7dSJacob Faibussowitsch while (fullLength >= next->size) { 474*eae3dc7dSJacob Faibussowitsch next->size = fullLength + 1; 475*eae3dc7dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 476*eae3dc7dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 477*eae3dc7dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, next->size)); 478*eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 479*eae3dc7dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, cpy)); 480*eae3dc7dSJacob Faibussowitsch va_end(cpy); 481*eae3dc7dSJacob Faibussowitsch } 482*eae3dc7dSJacob Faibussowitsch } 483*eae3dc7dSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 484*eae3dc7dSJacob Faibussowitsch } 485*eae3dc7dSJacob Faibussowitsch 486e5c89e4eSSatish Balay /*@C 487e5c89e4eSSatish Balay PetscSynchronizedPrintf - Prints synchronized output from several processors. 488e5c89e4eSSatish Balay Output of the first processor is followed by that of the second, etc. 489e5c89e4eSSatish Balay 490e5c89e4eSSatish Balay Not Collective 491e5c89e4eSSatish Balay 492e5c89e4eSSatish Balay Input Parameters: 493058c9ee1SBarry Smith + comm - the MPI communicator 4946026c97aSBarry Smith - format - the usual `printf()` format string 495e5c89e4eSSatish Balay 496e5c89e4eSSatish Balay Level: intermediate 497e5c89e4eSSatish Balay 498811af0c4SBarry Smith Note: 499811af0c4SBarry Smith REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information 500e5c89e4eSSatish Balay from all the processors to be printed. 501e5c89e4eSSatish Balay 502e5c89e4eSSatish Balay Fortran Note: 503058c9ee1SBarry Smith The call sequence is `PetscSynchronizedPrintf`(`MPI_Comm`, `character`(*), `PetscErrorCode` ierr). 504e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 505e5c89e4eSSatish Balay 506db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, 507c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 508c69effb2SJacob Faibussowitsch `PetscFFlush()` 509e5c89e4eSSatish Balay @*/ 510d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...) 511d71ae5a4SJacob Faibussowitsch { 512*eae3dc7dSJacob Faibussowitsch va_list Argp; 513e5c89e4eSSatish Balay 514e5c89e4eSSatish Balay PetscFunctionBegin; 515e5c89e4eSSatish Balay va_start(Argp, format); 516*eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 517e5c89e4eSSatish Balay va_end(Argp); 5183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 519e5c89e4eSSatish Balay } 520e5c89e4eSSatish Balay 521e5c89e4eSSatish Balay /*@C 522e5c89e4eSSatish Balay PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 523e5c89e4eSSatish Balay several processors. Output of the first processor is followed by that of the 524e5c89e4eSSatish Balay second, etc. 525e5c89e4eSSatish Balay 526e5c89e4eSSatish Balay Not Collective 527e5c89e4eSSatish Balay 528e5c89e4eSSatish Balay Input Parameters: 529058c9ee1SBarry Smith + comm - the MPI communicator 530e5c89e4eSSatish Balay . fd - the file pointer 5316026c97aSBarry Smith - format - the usual `printf()` format string 532e5c89e4eSSatish Balay 533e5c89e4eSSatish Balay Level: intermediate 534e5c89e4eSSatish Balay 535811af0c4SBarry Smith Note: 536811af0c4SBarry Smith REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information 537e5c89e4eSSatish Balay from all the processors to be printed. 538e5c89e4eSSatish Balay 539db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`, 540c69effb2SJacob Faibussowitsch `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 541c69effb2SJacob Faibussowitsch `PetscFFlush()` 542e5c89e4eSSatish Balay @*/ 543d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...) 544d71ae5a4SJacob Faibussowitsch { 545*eae3dc7dSJacob Faibussowitsch va_list Argp; 546e5c89e4eSSatish Balay 547e5c89e4eSSatish Balay PetscFunctionBegin; 548e5c89e4eSSatish Balay va_start(Argp, format); 549*eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, fp, format, Argp)); 550e5c89e4eSSatish Balay va_end(Argp); 5513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 552e5c89e4eSSatish Balay } 553e5c89e4eSSatish Balay 5540ec8b6e3SBarry Smith /*@C 555e5c89e4eSSatish Balay PetscSynchronizedFlush - Flushes to the screen output from all processors 556811af0c4SBarry Smith involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls. 557e5c89e4eSSatish Balay 558d083f849SBarry Smith Collective 559e5c89e4eSSatish Balay 560e5c89e4eSSatish Balay Input Parameters: 561058c9ee1SBarry Smith + comm - the MPI communicator 5620ec8b6e3SBarry Smith - fd - the file pointer (valid on process 0 of the communicator) 563e5c89e4eSSatish Balay 564e5c89e4eSSatish Balay Level: intermediate 565e5c89e4eSSatish Balay 566811af0c4SBarry Smith Note: 567811af0c4SBarry Smith If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with 568811af0c4SBarry Smith different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators. 569e5c89e4eSSatish Balay 570811af0c4SBarry Smith Fortran Note: 571811af0c4SBarry Smith Pass `PETSC_STDOUT` if the flush is for standard out; otherwise pass a value obtained from `PetscFOpen()` 572e50bf69fSBarry Smith 573db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`, 574db781477SPatrick Sanan `PetscViewerASCIISynchronizedPrintf()` 5750087d953SMatthew G. Knepley @*/ 576d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd) 577d71ae5a4SJacob Faibussowitsch { 57829a5cbdcSMatthew G. Knepley PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0; 5792d609e63SMatthew Knepley char *message; 580e5c89e4eSSatish Balay MPI_Status status; 581e5c89e4eSSatish Balay 582e5c89e4eSSatish Balay PetscFunctionBegin; 5839566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(comm, &comm, &tag)); 5849566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5859566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 586e5c89e4eSSatish Balay 587e5c89e4eSSatish Balay /* First processor waits for messages from all other processors */ 588dd400576SPatrick Sanan if (rank == 0) { 5890ec8b6e3SBarry Smith if (!fd) fd = PETSC_STDOUT; 590e5c89e4eSSatish Balay for (i = 1; i < size; i++) { 5919f73f8ecSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 5929566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm)); 5939566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status)); 594e5c89e4eSSatish Balay for (j = 0; j < n; j++) { 59529a5cbdcSMatthew G. Knepley PetscMPIInt size = 0; 5962d609e63SMatthew Knepley 5979566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status)); 5989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &message)); 5999566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status)); 6009566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, "%s", message)); 6019566063dSJacob Faibussowitsch PetscCall(PetscFree(message)); 602e5c89e4eSSatish Balay } 603e5c89e4eSSatish Balay } 604e5c89e4eSSatish Balay } else { /* other processors send queue to processor 0 */ 605d30b0576SJed Brown PrintfQueue next = petsc_printfqueuebase, previous; 606e5c89e4eSSatish Balay 6079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status)); 6089566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm)); 609d30b0576SJed Brown for (i = 0; i < petsc_printfqueuelength; i++) { 6109566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm)); 6119566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm)); 612e5c89e4eSSatish Balay previous = next; 613e5c89e4eSSatish Balay next = next->next; 6149566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 6159566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 616e5c89e4eSSatish Balay } 61702c9f0b5SLisandro Dalcin petsc_printfqueue = NULL; 618d30b0576SJed Brown petsc_printfqueuelength = 0; 619e5c89e4eSSatish Balay } 6209566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&comm)); 6213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 622e5c89e4eSSatish Balay } 623e5c89e4eSSatish Balay 624e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 625e5c89e4eSSatish Balay 626e5c89e4eSSatish Balay /*@C 627e5c89e4eSSatish Balay PetscFPrintf - Prints to a file, only from the first 628e5c89e4eSSatish Balay processor in the communicator. 629e5c89e4eSSatish Balay 630cf53795eSBarry Smith Not Collective; No Fortran Support 631e5c89e4eSSatish Balay 632e5c89e4eSSatish Balay Input Parameters: 633058c9ee1SBarry Smith + comm - the MPI communicator 634e5c89e4eSSatish Balay . fd - the file pointer 6356026c97aSBarry Smith - format - the usual `printf()` format string 636e5c89e4eSSatish Balay 637e5c89e4eSSatish Balay Level: intermediate 638e5c89e4eSSatish Balay 639058c9ee1SBarry Smith Developer Note: 640058c9ee1SBarry Smith This maybe, and is, called from PETSc error handlers and `PetscMallocValidate()` hence it does not use `PetscCallMPI()` which 641058c9ee1SBarry Smith could recursively restart the malloc validation. 642058c9ee1SBarry Smith 643db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 644c69effb2SJacob Faibussowitsch `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFFlush()` 645e5c89e4eSSatish Balay @*/ 646d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...) 647d71ae5a4SJacob Faibussowitsch { 648*eae3dc7dSJacob Faibussowitsch va_list Argp; 649e5c89e4eSSatish Balay 650e5c89e4eSSatish Balay PetscFunctionBegin; 651e5c89e4eSSatish Balay va_start(Argp, format); 652*eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, fd, format, Argp)); 653e5c89e4eSSatish Balay va_end(Argp); 6543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 655e5c89e4eSSatish Balay } 656e5c89e4eSSatish Balay 657e5c89e4eSSatish Balay /*@C 658e5c89e4eSSatish Balay PetscPrintf - Prints to standard out, only from the first 659eed5747fSBarry Smith processor in the communicator. Calls from other processes are ignored. 660e5c89e4eSSatish Balay 661e5c89e4eSSatish Balay Not Collective 662e5c89e4eSSatish Balay 663e5c89e4eSSatish Balay Input Parameters: 664e5c89e4eSSatish Balay + comm - the communicator 665e5c89e4eSSatish Balay - format - the usual printf() format string 666e5c89e4eSSatish Balay 667e5c89e4eSSatish Balay Level: intermediate 668e5c89e4eSSatish Balay 669811af0c4SBarry Smith Note: 670811af0c4SBarry Smith Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc. 671811af0c4SBarry Smith See the manual page for `PetscFormatConvert()` for details. 672b2706f25SRichard Tran Mills 673e5c89e4eSSatish Balay Fortran Note: 674811af0c4SBarry Smith The call sequence is `PetscPrintf`(MPI_Comm, character(*), `PetscErrorCode` ierr) from Fortran. 675e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 676e5c89e4eSSatish Balay 677c69effb2SJacob Faibussowitsch .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()`, `PetscFFlush()` 678e5c89e4eSSatish Balay @*/ 679d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...) 680d71ae5a4SJacob Faibussowitsch { 681*eae3dc7dSJacob Faibussowitsch va_list Argp; 682e5c89e4eSSatish Balay 683e5c89e4eSSatish Balay PetscFunctionBegin; 684e5c89e4eSSatish Balay va_start(Argp, format); 685*eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 686e5c89e4eSSatish Balay va_end(Argp); 6873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 688e5c89e4eSSatish Balay } 689e5c89e4eSSatish Balay 690d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...) 691d71ae5a4SJacob Faibussowitsch { 692*eae3dc7dSJacob Faibussowitsch va_list Argp; 693e5c89e4eSSatish Balay 694e5c89e4eSSatish Balay PetscFunctionBegin; 695e5c89e4eSSatish Balay va_start(Argp, format); 696*eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 697e5c89e4eSSatish Balay va_end(Argp); 6983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 699e5c89e4eSSatish Balay } 700e5c89e4eSSatish Balay 701e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 702e5c89e4eSSatish Balay 703e5c89e4eSSatish Balay /*@C 704e5c89e4eSSatish Balay PetscSynchronizedFGets - Several processors all get the same line from a file. 705e5c89e4eSSatish Balay 706d083f849SBarry Smith Collective 707e5c89e4eSSatish Balay 708e5c89e4eSSatish Balay Input Parameters: 709e5c89e4eSSatish Balay + comm - the communicator 710e5c89e4eSSatish Balay . fd - the file pointer 711e5c89e4eSSatish Balay - len - the length of the output buffer 712e5c89e4eSSatish Balay 713e5c89e4eSSatish Balay Output Parameter: 714e31d4fa4SJed Brown . string - the line read from the file, at end of file string[0] == 0 715e5c89e4eSSatish Balay 716e5c89e4eSSatish Balay Level: intermediate 717e5c89e4eSSatish Balay 718db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, 719db781477SPatrick Sanan `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()` 720e5c89e4eSSatish Balay @*/ 721d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm, FILE *fp, size_t len, char string[]) 722d71ae5a4SJacob Faibussowitsch { 723e5c89e4eSSatish Balay PetscMPIInt rank; 724e5c89e4eSSatish Balay 725e5c89e4eSSatish Balay PetscFunctionBegin; 7269566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 727*eae3dc7dSJacob Faibussowitsch if (rank != 0) PetscFunctionReturn(PETSC_SUCCESS); 728*eae3dc7dSJacob Faibussowitsch if (!fgets(string, len, fp)) { 729e31d4fa4SJed Brown string[0] = 0; 73008401ef6SPierre Jolivet PetscCheck(feof(fp), PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 731047b9c12SMatthew G Knepley } 7329566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(string, len, MPI_BYTE, 0, comm)); 7333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 734e5c89e4eSSatish Balay } 735238ccf28SShri Abhyankar 7368c74ee41SBarry Smith /*@C 7378c74ee41SBarry Smith PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 7388c74ee41SBarry Smith 7398c74ee41SBarry Smith Input Parameters: 7408c74ee41SBarry Smith . format - the PETSc format string 7418c74ee41SBarry Smith 7428c74ee41SBarry Smith Level: developer 7438c74ee41SBarry Smith 7448c74ee41SBarry Smith @*/ 745d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatStrip(char *format) 746d71ae5a4SJacob Faibussowitsch { 7478c74ee41SBarry Smith size_t loc1 = 0, loc2 = 0; 7488c74ee41SBarry Smith 7498c74ee41SBarry Smith PetscFunctionBegin; 7508c74ee41SBarry Smith while (format[loc2]) { 7518c74ee41SBarry Smith if (format[loc2] == '%') { 7528c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7538c74ee41SBarry Smith while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 7548c74ee41SBarry Smith } 7558c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7568c74ee41SBarry Smith } 7573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7588c74ee41SBarry Smith } 7598c74ee41SBarry Smith 760d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[]) 761d71ae5a4SJacob Faibussowitsch { 7621b5687a1SBarry Smith PetscInt i; 7631b5687a1SBarry Smith size_t left, count; 7641b5687a1SBarry Smith char *p; 7651b5687a1SBarry Smith 7661b5687a1SBarry Smith PetscFunctionBegin; 7671b5687a1SBarry Smith for (i = 0, p = buf, left = len; i < n; i++) { 7689566063dSJacob Faibussowitsch PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i])); 76908401ef6SPierre Jolivet PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer"); 7701b5687a1SBarry Smith left -= count; 7711b5687a1SBarry Smith p += count - 1; 7721b5687a1SBarry Smith *p++ = ' '; 7731b5687a1SBarry Smith } 7741b5687a1SBarry Smith p[i ? 0 : -1] = 0; 7753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7761b5687a1SBarry Smith } 777