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 25*21532e8aSBarry Smith PetscFormatConvertGetSize - Gets the length of a string needed to hold data converted with `PetscFormatConvert()` based on the format 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 86811af0c4SBarry Smith - size - the length of newformat, you can use `PetscFormatConvertGetSize()` to compute the needed size 87d781fa04SBarry Smith 88*21532e8aSBarry Smith Output Parameter: 89*21532e8aSBarry Smith . newformat - the new format 90*21532e8aSBarry Smith 91d781fa04SBarry Smith Level: developer 92d781fa04SBarry Smith 93058c9ee1SBarry Smith Note: 94*21532e8aSBarry Smith Deprecated usage also converts the `%D` to `%d` for 32 bit PETSc indices and to `%lld` for 64 bit PETSc indices. This feature is no 95058c9ee1SBarry Smith longer used in PETSc code instead use %" PetscInt_FMT " in the format string 96058c9ee1SBarry Smith 97db781477SPatrick Sanan .seealso: `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscVFPrintf()` 98d781fa04SBarry Smith @*/ 99d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvert(const char *format, char *newformat) 100d71ae5a4SJacob Faibussowitsch { 101e5c89e4eSSatish Balay PetscInt i = 0, j = 0; 102e5c89e4eSSatish Balay 103eed5747fSBarry Smith PetscFunctionBegin; 104d781fa04SBarry Smith while (format[i]) { 1052a1ad9caSBarry Smith if (format[i] == '%' && format[i + 1] == '%') { 1062a1ad9caSBarry Smith newformat[j++] = format[i++]; 1072a1ad9caSBarry Smith newformat[j++] = format[i++]; 1082a1ad9caSBarry Smith } else if (format[i] == '%') { 1098627564fSBarry Smith if (format[i + 1] == 'g') { 1108627564fSBarry Smith newformat[j++] = '['; 1118627564fSBarry Smith newformat[j++] = '|'; 1128627564fSBarry Smith } 1137bc47156SJose Roman /* Find the letter */ 1147bc47156SJose Roman for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 1157bc47156SJose Roman switch (format[i]) { 1167bc47156SJose Roman case 'D': 1176de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 118e5c89e4eSSatish Balay newformat[j++] = 'd'; 119e5c89e4eSSatish Balay #else 120e5c89e4eSSatish Balay newformat[j++] = 'l'; 121e5c89e4eSSatish Balay newformat[j++] = 'l'; 122e5c89e4eSSatish Balay newformat[j++] = 'd'; 123e5c89e4eSSatish Balay #endif 1247bc47156SJose Roman break; 1258627564fSBarry Smith case 'g': 1268627564fSBarry Smith newformat[j++] = format[i]; 1278627564fSBarry Smith if (format[i - 1] == '%') { 1288627564fSBarry Smith newformat[j++] = '|'; 1298627564fSBarry Smith newformat[j++] = ']'; 1308627564fSBarry Smith } 1318627564fSBarry Smith break; 132d71ae5a4SJacob Faibussowitsch case 'G': 133d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%G format is no longer supported, use %%g and cast the argument to double"); 134d71ae5a4SJacob Faibussowitsch case 'F': 135d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%F format is no longer supported, use %%f and cast the argument to double"); 136d71ae5a4SJacob Faibussowitsch default: 137d71ae5a4SJacob Faibussowitsch newformat[j++] = format[i]; 138d71ae5a4SJacob Faibussowitsch break; 1397bc47156SJose Roman } 1407bc47156SJose Roman i++; 141a297a907SKarl Rupp } else newformat[j++] = format[i++]; 142e5c89e4eSSatish Balay } 143e5c89e4eSSatish Balay newformat[j] = 0; 1443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 145e5c89e4eSSatish Balay } 146e5c89e4eSSatish Balay 14714416c0eSBarry Smith #define PETSCDEFAULTBUFFERSIZE 8 * 1024 148d781fa04SBarry Smith 149c9a19010SBarry Smith /*@C 1506026c97aSBarry Smith PetscVSNPrintf - The PETSc version of `vsnprintf()`. Ensures that all `%g` formatted arguments' output contains the decimal point (which 151058c9ee1SBarry Smith is used by the test harness) 152c9a19010SBarry Smith 153c9a19010SBarry Smith Input Parameters: 154c9a19010SBarry Smith + str - location to put result 155*21532e8aSBarry Smith . len - the length of `str` 156*21532e8aSBarry Smith - format - the PETSc format string 157*21532e8aSBarry Smith 158*21532e8aSBarry Smith Output Parameter: 159*21532e8aSBarry Smith . fullLength - the amount of space in `str` actually used. 160c9a19010SBarry Smith 161c9a19010SBarry Smith Level: developer 162c9a19010SBarry Smith 163058c9ee1SBarry Smith Developer Note: 164058c9ee1SBarry Smith This function may be called from an error handler, if an error occurs when it is called by the error handler than likely 165058c9ee1SBarry Smith a recursion will occur resulting in a crash of the program. 166058c9ee1SBarry Smith 167*21532e8aSBarry Smith If the length of the format string `format` is on the order of `PETSCDEFAULTBUFFERSIZE` (8 * 1024 bytes) or larger, this function will call `PetscMalloc()` 168058c9ee1SBarry Smith 169058c9ee1SBarry Smith .seealso: `PetscFormatConvert()`, `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscVPrintf()` 170c9a19010SBarry Smith @*/ 171d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVSNPrintf(char *str, size_t len, const char *format, size_t *fullLength, va_list Argp) 172d71ae5a4SJacob Faibussowitsch { 173d781fa04SBarry Smith char *newformat = NULL; 17414416c0eSBarry Smith char formatbuf[PETSCDEFAULTBUFFERSIZE]; 175d781fa04SBarry Smith size_t newLength; 17614416c0eSBarry Smith int flen; 177e5c89e4eSSatish Balay 178eed5747fSBarry Smith PetscFunctionBegin; 1799566063dSJacob Faibussowitsch PetscCall(PetscFormatConvertGetSize(format, &newLength)); 18094217ebdSBarry Smith if (newLength < sizeof(formatbuf)) { 181e2135aedSMatthew Knepley newformat = formatbuf; 18294217ebdSBarry Smith newLength = sizeof(formatbuf) - 1; 183e2135aedSMatthew Knepley } else { 1849566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(newLength, &newformat)); 185e2135aedSMatthew Knepley } 1869566063dSJacob Faibussowitsch PetscCall(PetscFormatConvert(format, newformat)); 1877b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF) 188152b30f0SSatish Balay flen = vsnprintf(str, len, newformat, Argp); 189e5c89e4eSSatish Balay #else 19089b07760SSatish Balay #error "vsnprintf not found" 191e5c89e4eSSatish Balay #endif 19248a46eb9SPierre Jolivet if (newLength > sizeof(formatbuf) - 1) PetscCall(PetscFree(newformat)); 1938627564fSBarry Smith { 1948627564fSBarry Smith PetscBool foundedot; 1958627564fSBarry Smith size_t cnt = 0, ncnt = 0, leng; 1969566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 19717ca8410SBarry Smith if (leng > 4) { 1988627564fSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 1998627564fSBarry Smith if (str[cnt] == '[' && str[cnt + 1] == '|') { 200c540d043SBarry Smith flen -= 4; 2019371c9d4SSatish Balay cnt++; 2029371c9d4SSatish Balay cnt++; 2038627564fSBarry Smith foundedot = PETSC_FALSE; 2048627564fSBarry Smith for (; cnt < leng - 1; cnt++) { 2058627564fSBarry Smith if (str[cnt] == '|' && str[cnt + 1] == ']') { 2068627564fSBarry Smith cnt++; 2078627564fSBarry Smith if (!foundedot) str[ncnt++] = '.'; 2088627564fSBarry Smith ncnt--; 2098627564fSBarry Smith break; 2108627564fSBarry Smith } else { 2118627564fSBarry Smith if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 2128627564fSBarry Smith str[ncnt++] = str[cnt]; 2138627564fSBarry Smith } 2148627564fSBarry Smith } 2158627564fSBarry Smith } else { 2168627564fSBarry Smith str[ncnt] = str[cnt]; 2178627564fSBarry Smith } 2188627564fSBarry Smith ncnt++; 2198627564fSBarry Smith } 2208627564fSBarry Smith while (cnt < leng) { 2219371c9d4SSatish Balay str[ncnt] = str[cnt]; 2229371c9d4SSatish Balay ncnt++; 2239371c9d4SSatish Balay cnt++; 2248627564fSBarry Smith } 2258627564fSBarry Smith str[ncnt] = 0; 2268627564fSBarry Smith } 2278627564fSBarry Smith } 228748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 229e51f71cfSBarry Smith /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 230748e1b9dSBarry Smith { 231748e1b9dSBarry Smith size_t cnt = 0, ncnt = 0, leng; 2329566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 233748e1b9dSBarry Smith if (leng > 5) { 234748e1b9dSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 235e51f71cfSBarry 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') { 2369371c9d4SSatish Balay str[ncnt] = str[cnt]; 2379371c9d4SSatish Balay ncnt++; 2389371c9d4SSatish Balay cnt++; 2399371c9d4SSatish Balay str[ncnt] = str[cnt]; 2409371c9d4SSatish Balay ncnt++; 2419371c9d4SSatish Balay cnt++; 2429371c9d4SSatish Balay cnt++; 243e51f71cfSBarry Smith str[ncnt] = str[cnt]; 244748e1b9dSBarry Smith } else { 245748e1b9dSBarry Smith str[ncnt] = str[cnt]; 246748e1b9dSBarry Smith } 247748e1b9dSBarry Smith ncnt++; 248748e1b9dSBarry Smith } 249748e1b9dSBarry Smith while (cnt < leng) { 2509371c9d4SSatish Balay str[ncnt] = str[cnt]; 2519371c9d4SSatish Balay ncnt++; 2529371c9d4SSatish Balay cnt++; 253748e1b9dSBarry Smith } 254748e1b9dSBarry Smith str[ncnt] = 0; 255748e1b9dSBarry Smith } 256748e1b9dSBarry Smith } 257748e1b9dSBarry Smith #endif 258c540d043SBarry Smith if (fullLength) *fullLength = 1 + (size_t)flen; 2593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 260e5c89e4eSSatish Balay } 261e5c89e4eSSatish Balay 262c9a19010SBarry Smith /*@C 263c69effb2SJacob Faibussowitsch PetscFFlush - Flush a file stream 264c69effb2SJacob Faibussowitsch 265c69effb2SJacob Faibussowitsch Input Parameter: 266c69effb2SJacob Faibussowitsch . fd - The file stream handle 267c69effb2SJacob Faibussowitsch 268c69effb2SJacob Faibussowitsch Level: intermediate 269c69effb2SJacob Faibussowitsch 270c69effb2SJacob Faibussowitsch Notes: 271c69effb2SJacob Faibussowitsch For output streams (and for update streams on which the last operation was output), writes 272c69effb2SJacob Faibussowitsch any unwritten data from the stream's buffer to the associated output device. 273c69effb2SJacob Faibussowitsch 274c69effb2SJacob Faibussowitsch For input streams (and for update streams on which the last operation was input), the 275c69effb2SJacob Faibussowitsch behavior is undefined. 276c69effb2SJacob Faibussowitsch 277c69effb2SJacob Faibussowitsch If `fd` is `NULL`, all open output streams are flushed, including ones not directly 278c69effb2SJacob Faibussowitsch accessible to the program. 279c69effb2SJacob Faibussowitsch 280c69effb2SJacob Faibussowitsch .seealso: `PetscPrintf()`, `PetscFPrintf()`, `PetscVFPrintf()`, `PetscVSNPrintf()` 281c69effb2SJacob Faibussowitsch @*/ 282c69effb2SJacob Faibussowitsch PetscErrorCode PetscFFlush(FILE *fd) 283c69effb2SJacob Faibussowitsch { 284c69effb2SJacob Faibussowitsch int ret; 285c69effb2SJacob Faibussowitsch 286c69effb2SJacob Faibussowitsch PetscFunctionBegin; 287c69effb2SJacob Faibussowitsch if (fd) PetscValidPointer(fd, 1); 288c69effb2SJacob Faibussowitsch ret = fflush(fd); 289c69effb2SJacob Faibussowitsch // could also use PetscCallExternal() here, but since we can get additional error explanation 290c69effb2SJacob Faibussowitsch // from strerror() we opted for a manual check 291c69effb2SJacob Faibussowitsch PetscCheck(ret == 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "Error in fflush(): error code %d (%s)", ret, strerror(errno)); 292c69effb2SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 293c69effb2SJacob Faibussowitsch } 294c69effb2SJacob Faibussowitsch 295c69effb2SJacob Faibussowitsch /*@C 296c9a19010SBarry Smith PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 297e5c89e4eSSatish Balay can be replaced with something that does not simply write to a file. 298e5c89e4eSSatish Balay 299c9a19010SBarry Smith To use, write your own function for example, 300058c9ee1SBarry Smith .vb 301058c9ee1SBarry Smith PetscErrorCode mypetscvfprintf(FILE *fd, const char format[], va_list Argp) 302058c9ee1SBarry Smith { 303058c9ee1SBarry Smith PetscErrorCode ierr; 304058c9ee1SBarry Smith 305058c9ee1SBarry Smith PetscFunctionBegin; 306058c9ee1SBarry Smith if (fd != stdout && fd != stderr) { handle regular files 307058c9ee1SBarry Smith CHKERR(PetscVFPrintfDefault(fd,format,Argp)); 308058c9ee1SBarry Smith } else { 309058c9ee1SBarry Smith char buff[BIG]; 310058c9ee1SBarry Smith size_t length; 311058c9ee1SBarry Smith PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp)); 312058c9ee1SBarry Smith now send buff to whatever stream or whatever you want 313058c9ee1SBarry Smith } 314058c9ee1SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 315058c9ee1SBarry Smith } 316058c9ee1SBarry Smith .ve 317058c9ee1SBarry Smith then before the call to `PetscInitialize()` do the assignment `PetscVFPrintf = mypetscvfprintf`; 318058c9ee1SBarry Smith 319058c9ee1SBarry Smith Level: developer 320c9a19010SBarry Smith 321811af0c4SBarry Smith Note: 322*21532e8aSBarry Smith For error messages this may be called by any MPI process, for regular standard out it is 323*21532e8aSBarry Smith called only by MPI rank 0 of a given communicator 324e5c89e4eSSatish Balay 325811af0c4SBarry Smith Developer Note: 326058c9ee1SBarry Smith This could be called by an error handler, if that happens then a recursion of the error handler may occur 327058c9ee1SBarry Smith and a resulting crash 328c9a19010SBarry Smith 329c69effb2SJacob Faibussowitsch .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscFFlush()` 330c9a19010SBarry Smith @*/ 331d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char *format, va_list Argp) 332d71ae5a4SJacob Faibussowitsch { 33314416c0eSBarry Smith char str[PETSCDEFAULTBUFFERSIZE]; 33414416c0eSBarry Smith char *buff = str; 33514416c0eSBarry Smith size_t fullLength; 3361531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 33714416c0eSBarry Smith va_list Argpcopy; 3381531940fSBarry Smith #endif 3391179db26SBarry Smith 340eed5747fSBarry Smith PetscFunctionBegin; 3411531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 34214416c0eSBarry Smith va_copy(Argpcopy, Argp); 3431531940fSBarry Smith #endif 3449566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp)); 34514416c0eSBarry Smith if (fullLength > sizeof(str)) { 3469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fullLength, &buff)); 3471531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 3489566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy)); 3491531940fSBarry Smith #else 3501531940fSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines"); 3511531940fSBarry Smith #endif 35214416c0eSBarry Smith } 353eae3dc7dSJacob Faibussowitsch #if defined(PETSC_HAVE_VA_COPY) 354eae3dc7dSJacob Faibussowitsch va_end(Argpcopy); 355eae3dc7dSJacob Faibussowitsch #endif 356c69effb2SJacob Faibussowitsch { 357c69effb2SJacob Faibussowitsch const int err = fprintf(fd, "%s", buff); 358c69effb2SJacob Faibussowitsch // cannot use PetscCallExternal() for fprintf since the return value is "number of 359c69effb2SJacob Faibussowitsch // characters transmitted to the output stream" on success 360c69effb2SJacob Faibussowitsch PetscCheck(err >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "fprintf() returned error code %d", err); 361c69effb2SJacob Faibussowitsch } 362c69effb2SJacob Faibussowitsch PetscCall(PetscFFlush(fd)); 36348a46eb9SPierre Jolivet if (buff != str) PetscCall(PetscFree(buff)); 3643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 365e5c89e4eSSatish Balay } 366e5c89e4eSSatish Balay 3675b5bc046SBarry Smith /*@C 3685b5bc046SBarry Smith PetscSNPrintf - Prints to a string of given length 3695b5bc046SBarry Smith 3705b5bc046SBarry Smith Not Collective 3715b5bc046SBarry Smith 3725b5bc046SBarry Smith Input Parameters: 373*21532e8aSBarry Smith + len - the length of `str` 374058c9ee1SBarry Smith . format - the usual `printf()` format string 37510699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 3765b5bc046SBarry Smith 377*21532e8aSBarry Smith Output Parameter: 378*21532e8aSBarry Smith . str - the resulting string 379*21532e8aSBarry Smith 3805b5bc046SBarry Smith Level: intermediate 3815b5bc046SBarry Smith 382db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 383c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 384c69effb2SJacob Faibussowitsch `PetscVFPrintf()`, `PetscFFlush()` 3855b5bc046SBarry Smith @*/ 386d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintf(char *str, size_t len, const char format[], ...) 387d71ae5a4SJacob Faibussowitsch { 388c9a19010SBarry Smith size_t fullLength; 3895b5bc046SBarry Smith va_list Argp; 3905b5bc046SBarry Smith 3915b5bc046SBarry Smith PetscFunctionBegin; 3925b5bc046SBarry Smith va_start(Argp, format); 3939566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp)); 394eae3dc7dSJacob Faibussowitsch va_end(Argp); 3953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3965b5bc046SBarry Smith } 3975b5bc046SBarry Smith 398257d2499SJed Brown /*@C 399058c9ee1SBarry Smith PetscSNPrintfCount - Prints to a string of given length, returns count of characters printed 400257d2499SJed Brown 401257d2499SJed Brown Not Collective 402257d2499SJed Brown 403257d2499SJed Brown Input Parameters: 404*21532e8aSBarry Smith + len - the length of `str` 405058c9ee1SBarry Smith . format - the usual `printf()` format string 40610699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 407257d2499SJed Brown 408*21532e8aSBarry Smith Output Parameters: 409*21532e8aSBarry Smith + str - the resulting string 410*21532e8aSBarry Smith - countused - number of characters printed 411cb398dd3SBarry Smith 412257d2499SJed Brown Level: intermediate 413257d2499SJed Brown 414db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 415db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()` 416257d2499SJed Brown @*/ 417d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintfCount(char *str, size_t len, const char format[], size_t *countused, ...) 418d71ae5a4SJacob Faibussowitsch { 419257d2499SJed Brown va_list Argp; 420257d2499SJed Brown 421257d2499SJed Brown PetscFunctionBegin; 422257d2499SJed Brown va_start(Argp, countused); 4239566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, countused, Argp)); 424eae3dc7dSJacob Faibussowitsch va_end(Argp); 4253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 426257d2499SJed Brown } 427257d2499SJed Brown 42802c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL; 429d30b0576SJed Brown int petsc_printfqueuelength = 0; 430e5c89e4eSSatish Balay 431eae3dc7dSJacob Faibussowitsch static inline PetscErrorCode PetscVFPrintf_Private(MPI_Comm comm, FILE *fd, const char format[], va_list Argp) 432eae3dc7dSJacob Faibussowitsch { 433eae3dc7dSJacob Faibussowitsch const PetscBool tee = (PetscBool)(petsc_history && (fd != petsc_history)); 434eae3dc7dSJacob Faibussowitsch PetscMPIInt rank; 435eae3dc7dSJacob Faibussowitsch va_list cpy; 436eae3dc7dSJacob Faibussowitsch 437eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 438eae3dc7dSJacob Faibussowitsch PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 439eae3dc7dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 440eae3dc7dSJacob Faibussowitsch if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS); 441eae3dc7dSJacob Faibussowitsch // must do this before we possibly consume Argp 442eae3dc7dSJacob Faibussowitsch if (tee) va_copy(cpy, Argp); 443eae3dc7dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fd, format, Argp)); 444eae3dc7dSJacob Faibussowitsch if (tee) { 445eae3dc7dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, cpy)); 446eae3dc7dSJacob Faibussowitsch va_end(cpy); 447eae3dc7dSJacob Faibussowitsch } 448eae3dc7dSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 449eae3dc7dSJacob Faibussowitsch } 450eae3dc7dSJacob Faibussowitsch 451eae3dc7dSJacob Faibussowitsch static inline PetscErrorCode PetscSynchronizedFPrintf_Private(MPI_Comm comm, FILE *fp, const char format[], va_list Argp) 452eae3dc7dSJacob Faibussowitsch { 453eae3dc7dSJacob Faibussowitsch PetscMPIInt rank; 454eae3dc7dSJacob Faibussowitsch va_list cpy; 455eae3dc7dSJacob Faibussowitsch 456eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 457eae3dc7dSJacob Faibussowitsch PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 458eae3dc7dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 459eae3dc7dSJacob Faibussowitsch /* First processor prints immediately to fp */ 460eae3dc7dSJacob Faibussowitsch if (rank == 0) { 461eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 462eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, fp, format, cpy)); 463eae3dc7dSJacob Faibussowitsch va_end(cpy); 464eae3dc7dSJacob Faibussowitsch } else { /* other processors add to local queue */ 465eae3dc7dSJacob Faibussowitsch PrintfQueue next; 466eae3dc7dSJacob Faibussowitsch size_t fullLength = PETSCDEFAULTBUFFERSIZE; 467eae3dc7dSJacob Faibussowitsch 468eae3dc7dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 469eae3dc7dSJacob Faibussowitsch if (petsc_printfqueue) { 470eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = next; 471eae3dc7dSJacob Faibussowitsch petsc_printfqueue = next; 472eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = NULL; 473eae3dc7dSJacob Faibussowitsch } else petsc_printfqueuebase = petsc_printfqueue = next; 474eae3dc7dSJacob Faibussowitsch petsc_printfqueuelength++; 475eae3dc7dSJacob Faibussowitsch next->size = 0; 476eae3dc7dSJacob Faibussowitsch next->string = NULL; 477eae3dc7dSJacob Faibussowitsch while (fullLength >= next->size) { 478eae3dc7dSJacob Faibussowitsch next->size = fullLength + 1; 479eae3dc7dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 480eae3dc7dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 481eae3dc7dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, next->size)); 482eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 483eae3dc7dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, cpy)); 484eae3dc7dSJacob Faibussowitsch va_end(cpy); 485eae3dc7dSJacob Faibussowitsch } 486eae3dc7dSJacob Faibussowitsch } 487eae3dc7dSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 488eae3dc7dSJacob Faibussowitsch } 489eae3dc7dSJacob Faibussowitsch 490e5c89e4eSSatish Balay /*@C 491*21532e8aSBarry Smith PetscSynchronizedPrintf - Prints synchronized output from multple MPI processes. 492e5c89e4eSSatish Balay Output of the first processor is followed by that of the second, etc. 493e5c89e4eSSatish Balay 494e5c89e4eSSatish Balay Not Collective 495e5c89e4eSSatish Balay 496e5c89e4eSSatish Balay Input Parameters: 497058c9ee1SBarry Smith + comm - the MPI communicator 4986026c97aSBarry Smith - format - the usual `printf()` format string 499e5c89e4eSSatish Balay 500e5c89e4eSSatish Balay Level: intermediate 501e5c89e4eSSatish Balay 502811af0c4SBarry Smith Note: 503811af0c4SBarry Smith REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information 504e5c89e4eSSatish Balay from all the processors to be printed. 505e5c89e4eSSatish Balay 506e5c89e4eSSatish Balay Fortran Note: 507058c9ee1SBarry Smith The call sequence is `PetscSynchronizedPrintf`(`MPI_Comm`, `character`(*), `PetscErrorCode` ierr). 508e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 509e5c89e4eSSatish Balay 510db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, 511c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 512c69effb2SJacob Faibussowitsch `PetscFFlush()` 513e5c89e4eSSatish Balay @*/ 514d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...) 515d71ae5a4SJacob Faibussowitsch { 516eae3dc7dSJacob Faibussowitsch va_list Argp; 517e5c89e4eSSatish Balay 518e5c89e4eSSatish Balay PetscFunctionBegin; 519e5c89e4eSSatish Balay va_start(Argp, format); 520eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 521e5c89e4eSSatish Balay va_end(Argp); 5223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 523e5c89e4eSSatish Balay } 524e5c89e4eSSatish Balay 525e5c89e4eSSatish Balay /*@C 526e5c89e4eSSatish Balay PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 527*21532e8aSBarry Smith several MPI processes. Output of the first process is followed by that of the 528e5c89e4eSSatish Balay second, etc. 529e5c89e4eSSatish Balay 530e5c89e4eSSatish Balay Not Collective 531e5c89e4eSSatish Balay 532e5c89e4eSSatish Balay Input Parameters: 533058c9ee1SBarry Smith + comm - the MPI communicator 534e5c89e4eSSatish Balay . fd - the file pointer 5356026c97aSBarry Smith - format - the usual `printf()` format string 536e5c89e4eSSatish Balay 537e5c89e4eSSatish Balay Level: intermediate 538e5c89e4eSSatish Balay 539811af0c4SBarry Smith Note: 540811af0c4SBarry Smith REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information 541e5c89e4eSSatish Balay from all the processors to be printed. 542e5c89e4eSSatish Balay 543db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`, 544c69effb2SJacob Faibussowitsch `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 545c69effb2SJacob Faibussowitsch `PetscFFlush()` 546e5c89e4eSSatish Balay @*/ 547d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...) 548d71ae5a4SJacob Faibussowitsch { 549eae3dc7dSJacob Faibussowitsch va_list Argp; 550e5c89e4eSSatish Balay 551e5c89e4eSSatish Balay PetscFunctionBegin; 552e5c89e4eSSatish Balay va_start(Argp, format); 553eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, fp, format, Argp)); 554e5c89e4eSSatish Balay va_end(Argp); 5553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 556e5c89e4eSSatish Balay } 557e5c89e4eSSatish Balay 5580ec8b6e3SBarry Smith /*@C 559e5c89e4eSSatish Balay PetscSynchronizedFlush - Flushes to the screen output from all processors 560811af0c4SBarry Smith involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls. 561e5c89e4eSSatish Balay 562d083f849SBarry Smith Collective 563e5c89e4eSSatish Balay 564e5c89e4eSSatish Balay Input Parameters: 565058c9ee1SBarry Smith + comm - the MPI communicator 566*21532e8aSBarry Smith - fd - the file pointer (valid on MPI rank 0 of the communicator) 567e5c89e4eSSatish Balay 568e5c89e4eSSatish Balay Level: intermediate 569e5c89e4eSSatish Balay 570811af0c4SBarry Smith Note: 571811af0c4SBarry Smith If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with 572811af0c4SBarry Smith different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators. 573e5c89e4eSSatish Balay 574811af0c4SBarry Smith Fortran Note: 575811af0c4SBarry Smith Pass `PETSC_STDOUT` if the flush is for standard out; otherwise pass a value obtained from `PetscFOpen()` 576e50bf69fSBarry Smith 577db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`, 578db781477SPatrick Sanan `PetscViewerASCIISynchronizedPrintf()` 5790087d953SMatthew G. Knepley @*/ 580d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd) 581d71ae5a4SJacob Faibussowitsch { 58229a5cbdcSMatthew G. Knepley PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0; 5832d609e63SMatthew Knepley char *message; 584e5c89e4eSSatish Balay MPI_Status status; 585e5c89e4eSSatish Balay 586e5c89e4eSSatish Balay PetscFunctionBegin; 5879566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(comm, &comm, &tag)); 5889566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5899566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 590e5c89e4eSSatish Balay 591e5c89e4eSSatish Balay /* First processor waits for messages from all other processors */ 592dd400576SPatrick Sanan if (rank == 0) { 5930ec8b6e3SBarry Smith if (!fd) fd = PETSC_STDOUT; 594e5c89e4eSSatish Balay for (i = 1; i < size; i++) { 5959f73f8ecSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 5969566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm)); 5979566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status)); 598e5c89e4eSSatish Balay for (j = 0; j < n; j++) { 59929a5cbdcSMatthew G. Knepley PetscMPIInt size = 0; 6002d609e63SMatthew Knepley 6019566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status)); 6029566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &message)); 6039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status)); 6049566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, "%s", message)); 6059566063dSJacob Faibussowitsch PetscCall(PetscFree(message)); 606e5c89e4eSSatish Balay } 607e5c89e4eSSatish Balay } 608e5c89e4eSSatish Balay } else { /* other processors send queue to processor 0 */ 609d30b0576SJed Brown PrintfQueue next = petsc_printfqueuebase, previous; 610e5c89e4eSSatish Balay 6119566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status)); 6129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm)); 613d30b0576SJed Brown for (i = 0; i < petsc_printfqueuelength; i++) { 6149566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm)); 6159566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm)); 616e5c89e4eSSatish Balay previous = next; 617e5c89e4eSSatish Balay next = next->next; 6189566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 6199566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 620e5c89e4eSSatish Balay } 62102c9f0b5SLisandro Dalcin petsc_printfqueue = NULL; 622d30b0576SJed Brown petsc_printfqueuelength = 0; 623e5c89e4eSSatish Balay } 6249566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&comm)); 6253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 626e5c89e4eSSatish Balay } 627e5c89e4eSSatish Balay 628e5c89e4eSSatish Balay /*@C 629e5c89e4eSSatish Balay PetscFPrintf - Prints to a file, only from the first 630*21532e8aSBarry Smith MPI process in the communicator. 631e5c89e4eSSatish Balay 632cf53795eSBarry Smith Not Collective; No Fortran Support 633e5c89e4eSSatish Balay 634e5c89e4eSSatish Balay Input Parameters: 635058c9ee1SBarry Smith + comm - the MPI communicator 636e5c89e4eSSatish Balay . fd - the file pointer 6376026c97aSBarry Smith - format - the usual `printf()` format string 638e5c89e4eSSatish Balay 639e5c89e4eSSatish Balay Level: intermediate 640e5c89e4eSSatish Balay 641058c9ee1SBarry Smith Developer Note: 642058c9ee1SBarry Smith This maybe, and is, called from PETSc error handlers and `PetscMallocValidate()` hence it does not use `PetscCallMPI()` which 643058c9ee1SBarry Smith could recursively restart the malloc validation. 644058c9ee1SBarry Smith 645db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 646c69effb2SJacob Faibussowitsch `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFFlush()` 647e5c89e4eSSatish Balay @*/ 648d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...) 649d71ae5a4SJacob Faibussowitsch { 650eae3dc7dSJacob Faibussowitsch va_list Argp; 651e5c89e4eSSatish Balay 652e5c89e4eSSatish Balay PetscFunctionBegin; 653e5c89e4eSSatish Balay va_start(Argp, format); 654eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, fd, format, Argp)); 655e5c89e4eSSatish Balay va_end(Argp); 6563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 657e5c89e4eSSatish Balay } 658e5c89e4eSSatish Balay 659e5c89e4eSSatish Balay /*@C 660e5c89e4eSSatish Balay PetscPrintf - Prints to standard out, only from the first 661*21532e8aSBarry Smith MPI process in the communicator. Calls from other processes are ignored. 662e5c89e4eSSatish Balay 663e5c89e4eSSatish Balay Not Collective 664e5c89e4eSSatish Balay 665e5c89e4eSSatish Balay Input Parameters: 666e5c89e4eSSatish Balay + comm - the communicator 667bfbbc7b7SBarry Smith - format - the usual `printf()` format string 668e5c89e4eSSatish Balay 669e5c89e4eSSatish Balay Level: intermediate 670e5c89e4eSSatish Balay 671811af0c4SBarry Smith Note: 672811af0c4SBarry Smith Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc. 673811af0c4SBarry Smith See the manual page for `PetscFormatConvert()` for details. 674b2706f25SRichard Tran Mills 675e5c89e4eSSatish Balay Fortran Note: 676811af0c4SBarry Smith The call sequence is `PetscPrintf`(MPI_Comm, character(*), `PetscErrorCode` ierr) from Fortran. 677e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 678e5c89e4eSSatish Balay 679c69effb2SJacob Faibussowitsch .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()`, `PetscFFlush()` 680e5c89e4eSSatish Balay @*/ 681d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...) 682d71ae5a4SJacob Faibussowitsch { 683eae3dc7dSJacob Faibussowitsch va_list Argp; 684e5c89e4eSSatish Balay 685e5c89e4eSSatish Balay PetscFunctionBegin; 686e5c89e4eSSatish Balay va_start(Argp, format); 687eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 688e5c89e4eSSatish Balay va_end(Argp); 6893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 690e5c89e4eSSatish Balay } 691e5c89e4eSSatish Balay 692d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...) 693d71ae5a4SJacob Faibussowitsch { 694eae3dc7dSJacob Faibussowitsch va_list Argp; 695e5c89e4eSSatish Balay 696e5c89e4eSSatish Balay PetscFunctionBegin; 697e5c89e4eSSatish Balay va_start(Argp, format); 698eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 699e5c89e4eSSatish Balay va_end(Argp); 7003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 701e5c89e4eSSatish Balay } 702e5c89e4eSSatish Balay 703e5c89e4eSSatish Balay /*@C 704*21532e8aSBarry Smith PetscSynchronizedFGets - Multiple MPI processes all get the same line from a file. 705e5c89e4eSSatish Balay 706d083f849SBarry Smith Collective 707e5c89e4eSSatish Balay 708e5c89e4eSSatish Balay Input Parameters: 709*21532e8aSBarry Smith + comm - the MPI communicator 710e5c89e4eSSatish Balay . fd - the file pointer 711*21532e8aSBarry Smith - len - the length of `string` 712e5c89e4eSSatish Balay 713e5c89e4eSSatish Balay Output Parameter: 714*21532e8aSBarry Smith . 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)); 727eae3dc7dSJacob Faibussowitsch if (rank != 0) PetscFunctionReturn(PETSC_SUCCESS); 728eae3dc7dSJacob 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 737*21532e8aSBarry Smith PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to `%` operations 7388c74ee41SBarry Smith 7392fe279fdSBarry Smith Input Parameter: 7408c74ee41SBarry Smith . format - the PETSc format string 7418c74ee41SBarry Smith 7428c74ee41SBarry Smith Level: developer 7438c74ee41SBarry Smith @*/ 744d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatStrip(char *format) 745d71ae5a4SJacob Faibussowitsch { 7468c74ee41SBarry Smith size_t loc1 = 0, loc2 = 0; 7478c74ee41SBarry Smith 7488c74ee41SBarry Smith PetscFunctionBegin; 7498c74ee41SBarry Smith while (format[loc2]) { 7508c74ee41SBarry Smith if (format[loc2] == '%') { 7518c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7528c74ee41SBarry Smith while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 7538c74ee41SBarry Smith } 7548c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7558c74ee41SBarry Smith } 7563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7578c74ee41SBarry Smith } 7588c74ee41SBarry Smith 759d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[]) 760d71ae5a4SJacob Faibussowitsch { 7611b5687a1SBarry Smith PetscInt i; 7621b5687a1SBarry Smith size_t left, count; 7631b5687a1SBarry Smith char *p; 7641b5687a1SBarry Smith 7651b5687a1SBarry Smith PetscFunctionBegin; 7661b5687a1SBarry Smith for (i = 0, p = buf, left = len; i < n; i++) { 7679566063dSJacob Faibussowitsch PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i])); 76808401ef6SPierre Jolivet PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer"); 7691b5687a1SBarry Smith left -= count; 7701b5687a1SBarry Smith p += count - 1; 7711b5687a1SBarry Smith *p++ = ' '; 7721b5687a1SBarry Smith } 7731b5687a1SBarry Smith p[i ? 0 : -1] = 0; 7743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7751b5687a1SBarry Smith } 776