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 2521532e8aSBarry 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 79*10450e9eSJacob Faibussowitsch PetscFormatConvert - converts %g to [|%g|] so that `PetscVSNPrintf()` can ensure all %g formatted numbers have a decimal point when printed. 80d781fa04SBarry Smith 81058c9ee1SBarry Smith No Fortran Support 82811af0c4SBarry Smith 83*10450e9eSJacob Faibussowitsch Input Parameter: 84*10450e9eSJacob Faibussowitsch . format - the PETSc format string 85d781fa04SBarry Smith 8621532e8aSBarry Smith Output Parameter: 87*10450e9eSJacob Faibussowitsch . newformat - the formatted string 8821532e8aSBarry Smith 89d781fa04SBarry Smith Level: developer 90d781fa04SBarry Smith 91058c9ee1SBarry Smith Note: 92*10450e9eSJacob Faibussowitsch The decimal point is then used by the `petscdiff` script so that differences in floating 93*10450e9eSJacob Faibussowitsch point number output is ignored in the test harness. 94*10450e9eSJacob Faibussowitsch 95*10450e9eSJacob Faibussowitsch Deprecated usage also converts the `%D` to `%d` for 32-bit PETSc indices and to `%lld` for 96*10450e9eSJacob Faibussowitsch 64-bit PETSc indices. This feature is no longer used in PETSc code instead use %" 97*10450e9eSJacob Faibussowitsch PetscInt_FMT " in the format string. 98058c9ee1SBarry Smith 99db781477SPatrick Sanan .seealso: `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscVFPrintf()` 100d781fa04SBarry Smith @*/ 101d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvert(const char *format, char *newformat) 102d71ae5a4SJacob Faibussowitsch { 103e5c89e4eSSatish Balay PetscInt i = 0, j = 0; 104e5c89e4eSSatish Balay 105eed5747fSBarry Smith PetscFunctionBegin; 106d781fa04SBarry Smith while (format[i]) { 1072a1ad9caSBarry Smith if (format[i] == '%' && format[i + 1] == '%') { 1082a1ad9caSBarry Smith newformat[j++] = format[i++]; 1092a1ad9caSBarry Smith newformat[j++] = format[i++]; 1102a1ad9caSBarry Smith } else if (format[i] == '%') { 1118627564fSBarry Smith if (format[i + 1] == 'g') { 1128627564fSBarry Smith newformat[j++] = '['; 1138627564fSBarry Smith newformat[j++] = '|'; 1148627564fSBarry Smith } 1157bc47156SJose Roman /* Find the letter */ 1167bc47156SJose Roman for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 1177bc47156SJose Roman switch (format[i]) { 1187bc47156SJose Roman case 'D': 1196de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 120e5c89e4eSSatish Balay newformat[j++] = 'd'; 121e5c89e4eSSatish Balay #else 122e5c89e4eSSatish Balay newformat[j++] = 'l'; 123e5c89e4eSSatish Balay newformat[j++] = 'l'; 124e5c89e4eSSatish Balay newformat[j++] = 'd'; 125e5c89e4eSSatish Balay #endif 1267bc47156SJose Roman break; 1278627564fSBarry Smith case 'g': 1288627564fSBarry Smith newformat[j++] = format[i]; 1298627564fSBarry Smith if (format[i - 1] == '%') { 1308627564fSBarry Smith newformat[j++] = '|'; 1318627564fSBarry Smith newformat[j++] = ']'; 1328627564fSBarry Smith } 1338627564fSBarry Smith break; 134d71ae5a4SJacob Faibussowitsch case 'G': 135d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%G format is no longer supported, use %%g and cast the argument to double"); 136d71ae5a4SJacob Faibussowitsch case 'F': 137d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%F format is no longer supported, use %%f and cast the argument to double"); 138d71ae5a4SJacob Faibussowitsch default: 139d71ae5a4SJacob Faibussowitsch newformat[j++] = format[i]; 140d71ae5a4SJacob Faibussowitsch break; 1417bc47156SJose Roman } 1427bc47156SJose Roman i++; 143a297a907SKarl Rupp } else newformat[j++] = format[i++]; 144e5c89e4eSSatish Balay } 145e5c89e4eSSatish Balay newformat[j] = 0; 1463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 147e5c89e4eSSatish Balay } 148e5c89e4eSSatish Balay 14914416c0eSBarry Smith #define PETSCDEFAULTBUFFERSIZE 8 * 1024 150d781fa04SBarry Smith 151c9a19010SBarry Smith /*@C 1526026c97aSBarry Smith PetscVSNPrintf - The PETSc version of `vsnprintf()`. Ensures that all `%g` formatted arguments' output contains the decimal point (which 153058c9ee1SBarry Smith is used by the test harness) 154c9a19010SBarry Smith 155c9a19010SBarry Smith Input Parameters: 156c9a19010SBarry Smith + str - location to put result 15721532e8aSBarry Smith . len - the length of `str` 158*10450e9eSJacob Faibussowitsch . format - the PETSc format string 159*10450e9eSJacob Faibussowitsch - Argp - the variable argument list to format 16021532e8aSBarry Smith 16121532e8aSBarry Smith Output Parameter: 16221532e8aSBarry Smith . fullLength - the amount of space in `str` actually used. 163c9a19010SBarry Smith 164c9a19010SBarry Smith Level: developer 165c9a19010SBarry Smith 166aec76313SJacob Faibussowitsch Developer Notes: 167058c9ee1SBarry Smith This function may be called from an error handler, if an error occurs when it is called by the error handler than likely 168058c9ee1SBarry Smith a recursion will occur resulting in a crash of the program. 169058c9ee1SBarry Smith 17021532e8aSBarry 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()` 171058c9ee1SBarry Smith 172058c9ee1SBarry Smith .seealso: `PetscFormatConvert()`, `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscVPrintf()` 173c9a19010SBarry Smith @*/ 174d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVSNPrintf(char *str, size_t len, const char *format, size_t *fullLength, va_list Argp) 175d71ae5a4SJacob Faibussowitsch { 176d781fa04SBarry Smith char *newformat = NULL; 17714416c0eSBarry Smith char formatbuf[PETSCDEFAULTBUFFERSIZE]; 178d781fa04SBarry Smith size_t newLength; 17914416c0eSBarry Smith int flen; 180e5c89e4eSSatish Balay 181eed5747fSBarry Smith PetscFunctionBegin; 1829566063dSJacob Faibussowitsch PetscCall(PetscFormatConvertGetSize(format, &newLength)); 18394217ebdSBarry Smith if (newLength < sizeof(formatbuf)) { 184e2135aedSMatthew Knepley newformat = formatbuf; 18594217ebdSBarry Smith newLength = sizeof(formatbuf) - 1; 186e2135aedSMatthew Knepley } else { 1879566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(newLength, &newformat)); 188e2135aedSMatthew Knepley } 1899566063dSJacob Faibussowitsch PetscCall(PetscFormatConvert(format, newformat)); 1907b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF) 191152b30f0SSatish Balay flen = vsnprintf(str, len, newformat, Argp); 192e5c89e4eSSatish Balay #else 19389b07760SSatish Balay #error "vsnprintf not found" 194e5c89e4eSSatish Balay #endif 19548a46eb9SPierre Jolivet if (newLength > sizeof(formatbuf) - 1) PetscCall(PetscFree(newformat)); 1968627564fSBarry Smith { 1978627564fSBarry Smith PetscBool foundedot; 1988627564fSBarry Smith size_t cnt = 0, ncnt = 0, leng; 1999566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 20017ca8410SBarry Smith if (leng > 4) { 2018627564fSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 2028627564fSBarry Smith if (str[cnt] == '[' && str[cnt + 1] == '|') { 203c540d043SBarry Smith flen -= 4; 2049371c9d4SSatish Balay cnt++; 2059371c9d4SSatish Balay cnt++; 2068627564fSBarry Smith foundedot = PETSC_FALSE; 2078627564fSBarry Smith for (; cnt < leng - 1; cnt++) { 2088627564fSBarry Smith if (str[cnt] == '|' && str[cnt + 1] == ']') { 2098627564fSBarry Smith cnt++; 2108627564fSBarry Smith if (!foundedot) str[ncnt++] = '.'; 2118627564fSBarry Smith ncnt--; 2128627564fSBarry Smith break; 2138627564fSBarry Smith } else { 2148627564fSBarry Smith if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 2158627564fSBarry Smith str[ncnt++] = str[cnt]; 2168627564fSBarry Smith } 2178627564fSBarry Smith } 2188627564fSBarry Smith } else { 2198627564fSBarry Smith str[ncnt] = str[cnt]; 2208627564fSBarry Smith } 2218627564fSBarry Smith ncnt++; 2228627564fSBarry Smith } 2238627564fSBarry Smith while (cnt < leng) { 2249371c9d4SSatish Balay str[ncnt] = str[cnt]; 2259371c9d4SSatish Balay ncnt++; 2269371c9d4SSatish Balay cnt++; 2278627564fSBarry Smith } 2288627564fSBarry Smith str[ncnt] = 0; 2298627564fSBarry Smith } 2308627564fSBarry Smith } 231748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 232e51f71cfSBarry Smith /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 233748e1b9dSBarry Smith { 234748e1b9dSBarry Smith size_t cnt = 0, ncnt = 0, leng; 2359566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 236748e1b9dSBarry Smith if (leng > 5) { 237748e1b9dSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 238e51f71cfSBarry 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') { 2399371c9d4SSatish Balay str[ncnt] = str[cnt]; 2409371c9d4SSatish Balay ncnt++; 2419371c9d4SSatish Balay cnt++; 2429371c9d4SSatish Balay str[ncnt] = str[cnt]; 2439371c9d4SSatish Balay ncnt++; 2449371c9d4SSatish Balay cnt++; 2459371c9d4SSatish Balay cnt++; 246e51f71cfSBarry Smith str[ncnt] = str[cnt]; 247748e1b9dSBarry Smith } else { 248748e1b9dSBarry Smith str[ncnt] = str[cnt]; 249748e1b9dSBarry Smith } 250748e1b9dSBarry Smith ncnt++; 251748e1b9dSBarry Smith } 252748e1b9dSBarry Smith while (cnt < leng) { 2539371c9d4SSatish Balay str[ncnt] = str[cnt]; 2549371c9d4SSatish Balay ncnt++; 2559371c9d4SSatish Balay cnt++; 256748e1b9dSBarry Smith } 257748e1b9dSBarry Smith str[ncnt] = 0; 258748e1b9dSBarry Smith } 259748e1b9dSBarry Smith } 260748e1b9dSBarry Smith #endif 261c540d043SBarry Smith if (fullLength) *fullLength = 1 + (size_t)flen; 2623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 263e5c89e4eSSatish Balay } 264e5c89e4eSSatish Balay 265c9a19010SBarry Smith /*@C 266c69effb2SJacob Faibussowitsch PetscFFlush - Flush a file stream 267c69effb2SJacob Faibussowitsch 268c69effb2SJacob Faibussowitsch Input Parameter: 269c69effb2SJacob Faibussowitsch . fd - The file stream handle 270c69effb2SJacob Faibussowitsch 271c69effb2SJacob Faibussowitsch Level: intermediate 272c69effb2SJacob Faibussowitsch 273c69effb2SJacob Faibussowitsch Notes: 274c69effb2SJacob Faibussowitsch For output streams (and for update streams on which the last operation was output), writes 275c69effb2SJacob Faibussowitsch any unwritten data from the stream's buffer to the associated output device. 276c69effb2SJacob Faibussowitsch 277c69effb2SJacob Faibussowitsch For input streams (and for update streams on which the last operation was input), the 278c69effb2SJacob Faibussowitsch behavior is undefined. 279c69effb2SJacob Faibussowitsch 280c69effb2SJacob Faibussowitsch If `fd` is `NULL`, all open output streams are flushed, including ones not directly 281c69effb2SJacob Faibussowitsch accessible to the program. 282c69effb2SJacob Faibussowitsch 283c69effb2SJacob Faibussowitsch .seealso: `PetscPrintf()`, `PetscFPrintf()`, `PetscVFPrintf()`, `PetscVSNPrintf()` 284c69effb2SJacob Faibussowitsch @*/ 285c69effb2SJacob Faibussowitsch PetscErrorCode PetscFFlush(FILE *fd) 286c69effb2SJacob Faibussowitsch { 287c69effb2SJacob Faibussowitsch PetscFunctionBegin; 288c69effb2SJacob Faibussowitsch if (fd) PetscValidPointer(fd, 1); 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 291bf31d2d3SBarry Smith PetscCheck(0 == fflush(fd), PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "Error in fflush() due to \"%s\"", strerror(errno)); 292c69effb2SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 293c69effb2SJacob Faibussowitsch } 294c69effb2SJacob Faibussowitsch 295c69effb2SJacob Faibussowitsch /*@C 296aec76313SJacob Faibussowitsch PetscVFPrintfDefault - 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 299*10450e9eSJacob Faibussowitsch Input Parameters: 300*10450e9eSJacob Faibussowitsch + fd - the file descriptor to write to 301*10450e9eSJacob Faibussowitsch . format - the format string to write with 302*10450e9eSJacob Faibussowitsch - Argp - the variable argument list of items to format and write 303*10450e9eSJacob Faibussowitsch 304*10450e9eSJacob Faibussowitsch Level: developer 305*10450e9eSJacob Faibussowitsch 306*10450e9eSJacob Faibussowitsch Note: 307*10450e9eSJacob Faibussowitsch For error messages this may be called by any MPI process, for regular standard out it is 308*10450e9eSJacob Faibussowitsch called only by MPI rank 0 of a given communicator 309*10450e9eSJacob Faibussowitsch 310*10450e9eSJacob Faibussowitsch Example Usage: 311c9a19010SBarry Smith To use, write your own function for example, 312058c9ee1SBarry Smith .vb 313058c9ee1SBarry Smith PetscErrorCode mypetscvfprintf(FILE *fd, const char format[], va_list Argp) 314058c9ee1SBarry Smith { 315058c9ee1SBarry Smith PetscErrorCode ierr; 316058c9ee1SBarry Smith 317058c9ee1SBarry Smith PetscFunctionBegin; 318058c9ee1SBarry Smith if (fd != stdout && fd != stderr) { handle regular files 319058c9ee1SBarry Smith CHKERR(PetscVFPrintfDefault(fd,format,Argp)); 320058c9ee1SBarry Smith } else { 321058c9ee1SBarry Smith char buff[BIG]; 322058c9ee1SBarry Smith size_t length; 323058c9ee1SBarry Smith PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp)); 324058c9ee1SBarry Smith now send buff to whatever stream or whatever you want 325058c9ee1SBarry Smith } 326058c9ee1SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 327058c9ee1SBarry Smith } 328058c9ee1SBarry Smith .ve 329058c9ee1SBarry Smith then before the call to `PetscInitialize()` do the assignment `PetscVFPrintf = mypetscvfprintf`; 330058c9ee1SBarry Smith 331aec76313SJacob Faibussowitsch Developer Notes: 332058c9ee1SBarry Smith This could be called by an error handler, if that happens then a recursion of the error handler may occur 333058c9ee1SBarry Smith and a resulting crash 334c9a19010SBarry Smith 335c69effb2SJacob Faibussowitsch .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscFFlush()` 336c9a19010SBarry Smith @*/ 337d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char *format, va_list Argp) 338d71ae5a4SJacob Faibussowitsch { 33914416c0eSBarry Smith char str[PETSCDEFAULTBUFFERSIZE]; 34014416c0eSBarry Smith char *buff = str; 34114416c0eSBarry Smith size_t fullLength; 3421531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 34314416c0eSBarry Smith va_list Argpcopy; 3441531940fSBarry Smith #endif 3451179db26SBarry Smith 346eed5747fSBarry Smith PetscFunctionBegin; 3471531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 34814416c0eSBarry Smith va_copy(Argpcopy, Argp); 3491531940fSBarry Smith #endif 3509566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp)); 35114416c0eSBarry Smith if (fullLength > sizeof(str)) { 3529566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fullLength, &buff)); 3531531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 3549566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy)); 3551531940fSBarry Smith #else 3561531940fSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines"); 3571531940fSBarry Smith #endif 35814416c0eSBarry Smith } 359eae3dc7dSJacob Faibussowitsch #if defined(PETSC_HAVE_VA_COPY) 360eae3dc7dSJacob Faibussowitsch va_end(Argpcopy); 361eae3dc7dSJacob Faibussowitsch #endif 362c69effb2SJacob Faibussowitsch { 363c69effb2SJacob Faibussowitsch const int err = fprintf(fd, "%s", buff); 364c69effb2SJacob Faibussowitsch // cannot use PetscCallExternal() for fprintf since the return value is "number of 365c69effb2SJacob Faibussowitsch // characters transmitted to the output stream" on success 366c69effb2SJacob Faibussowitsch PetscCheck(err >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "fprintf() returned error code %d", err); 367c69effb2SJacob Faibussowitsch } 368c69effb2SJacob Faibussowitsch PetscCall(PetscFFlush(fd)); 36948a46eb9SPierre Jolivet if (buff != str) PetscCall(PetscFree(buff)); 3703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 371e5c89e4eSSatish Balay } 372e5c89e4eSSatish Balay 3735b5bc046SBarry Smith /*@C 3745b5bc046SBarry Smith PetscSNPrintf - Prints to a string of given length 3755b5bc046SBarry Smith 3765b5bc046SBarry Smith Not Collective 3775b5bc046SBarry Smith 3785b5bc046SBarry Smith Input Parameters: 37921532e8aSBarry Smith + len - the length of `str` 380*10450e9eSJacob Faibussowitsch - format - the usual `printf()` format string 3815b5bc046SBarry Smith 38221532e8aSBarry Smith Output Parameter: 38321532e8aSBarry Smith . str - the resulting string 38421532e8aSBarry Smith 3855b5bc046SBarry Smith Level: intermediate 3865b5bc046SBarry Smith 387db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 388c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 389c69effb2SJacob Faibussowitsch `PetscVFPrintf()`, `PetscFFlush()` 3905b5bc046SBarry Smith @*/ 391d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintf(char *str, size_t len, const char format[], ...) 392d71ae5a4SJacob Faibussowitsch { 393c9a19010SBarry Smith size_t fullLength; 3945b5bc046SBarry Smith va_list Argp; 3955b5bc046SBarry Smith 3965b5bc046SBarry Smith PetscFunctionBegin; 3975b5bc046SBarry Smith va_start(Argp, format); 3989566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp)); 399eae3dc7dSJacob Faibussowitsch va_end(Argp); 4003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4015b5bc046SBarry Smith } 4025b5bc046SBarry Smith 403257d2499SJed Brown /*@C 404058c9ee1SBarry Smith PetscSNPrintfCount - Prints to a string of given length, returns count of characters printed 405257d2499SJed Brown 406257d2499SJed Brown Not Collective 407257d2499SJed Brown 408257d2499SJed Brown Input Parameters: 40921532e8aSBarry Smith + len - the length of `str` 410058c9ee1SBarry Smith . format - the usual `printf()` format string 411*10450e9eSJacob Faibussowitsch - ... - args to format 412257d2499SJed Brown 41321532e8aSBarry Smith Output Parameters: 41421532e8aSBarry Smith + str - the resulting string 41521532e8aSBarry Smith - countused - number of characters printed 416cb398dd3SBarry Smith 417257d2499SJed Brown Level: intermediate 418257d2499SJed Brown 419db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 420db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()` 421257d2499SJed Brown @*/ 422d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintfCount(char *str, size_t len, const char format[], size_t *countused, ...) 423d71ae5a4SJacob Faibussowitsch { 424257d2499SJed Brown va_list Argp; 425257d2499SJed Brown 426257d2499SJed Brown PetscFunctionBegin; 427257d2499SJed Brown va_start(Argp, countused); 4289566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, countused, Argp)); 429eae3dc7dSJacob Faibussowitsch va_end(Argp); 4303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 431257d2499SJed Brown } 432257d2499SJed Brown 43302c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL; 434d30b0576SJed Brown int petsc_printfqueuelength = 0; 435e5c89e4eSSatish Balay 436eae3dc7dSJacob Faibussowitsch static inline PetscErrorCode PetscVFPrintf_Private(MPI_Comm comm, FILE *fd, const char format[], va_list Argp) 437eae3dc7dSJacob Faibussowitsch { 438eae3dc7dSJacob Faibussowitsch const PetscBool tee = (PetscBool)(petsc_history && (fd != petsc_history)); 439eae3dc7dSJacob Faibussowitsch PetscMPIInt rank; 440eae3dc7dSJacob Faibussowitsch va_list cpy; 441eae3dc7dSJacob Faibussowitsch 442eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 443eae3dc7dSJacob Faibussowitsch PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 444eae3dc7dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 445eae3dc7dSJacob Faibussowitsch if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS); 446eae3dc7dSJacob Faibussowitsch // must do this before we possibly consume Argp 447eae3dc7dSJacob Faibussowitsch if (tee) va_copy(cpy, Argp); 448eae3dc7dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fd, format, Argp)); 449eae3dc7dSJacob Faibussowitsch if (tee) { 450eae3dc7dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, cpy)); 451eae3dc7dSJacob Faibussowitsch va_end(cpy); 452eae3dc7dSJacob Faibussowitsch } 453eae3dc7dSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 454eae3dc7dSJacob Faibussowitsch } 455eae3dc7dSJacob Faibussowitsch 456eae3dc7dSJacob Faibussowitsch static inline PetscErrorCode PetscSynchronizedFPrintf_Private(MPI_Comm comm, FILE *fp, const char format[], va_list Argp) 457eae3dc7dSJacob Faibussowitsch { 458eae3dc7dSJacob Faibussowitsch PetscMPIInt rank; 459eae3dc7dSJacob Faibussowitsch va_list cpy; 460eae3dc7dSJacob Faibussowitsch 461eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 462eae3dc7dSJacob Faibussowitsch PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 463eae3dc7dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 464eae3dc7dSJacob Faibussowitsch /* First processor prints immediately to fp */ 465eae3dc7dSJacob Faibussowitsch if (rank == 0) { 466eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 467eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, fp, format, cpy)); 468eae3dc7dSJacob Faibussowitsch va_end(cpy); 469eae3dc7dSJacob Faibussowitsch } else { /* other processors add to local queue */ 470eae3dc7dSJacob Faibussowitsch PrintfQueue next; 471eae3dc7dSJacob Faibussowitsch size_t fullLength = PETSCDEFAULTBUFFERSIZE; 472eae3dc7dSJacob Faibussowitsch 473eae3dc7dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 474eae3dc7dSJacob Faibussowitsch if (petsc_printfqueue) { 475eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = next; 476eae3dc7dSJacob Faibussowitsch petsc_printfqueue = next; 477eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = NULL; 478eae3dc7dSJacob Faibussowitsch } else petsc_printfqueuebase = petsc_printfqueue = next; 479eae3dc7dSJacob Faibussowitsch petsc_printfqueuelength++; 480eae3dc7dSJacob Faibussowitsch next->size = 0; 481eae3dc7dSJacob Faibussowitsch next->string = NULL; 482eae3dc7dSJacob Faibussowitsch while (fullLength >= next->size) { 483eae3dc7dSJacob Faibussowitsch next->size = fullLength + 1; 484eae3dc7dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 485eae3dc7dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 486eae3dc7dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, next->size)); 487eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 488eae3dc7dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, cpy)); 489eae3dc7dSJacob Faibussowitsch va_end(cpy); 490eae3dc7dSJacob Faibussowitsch } 491eae3dc7dSJacob Faibussowitsch } 492eae3dc7dSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 493eae3dc7dSJacob Faibussowitsch } 494eae3dc7dSJacob Faibussowitsch 495e5c89e4eSSatish Balay /*@C 4969c89aa79SPierre Jolivet PetscSynchronizedPrintf - Prints synchronized output from multiple MPI processes. 497e5c89e4eSSatish Balay Output of the first processor is followed by that of the second, etc. 498e5c89e4eSSatish Balay 499e5c89e4eSSatish Balay Not Collective 500e5c89e4eSSatish Balay 501e5c89e4eSSatish Balay Input Parameters: 502058c9ee1SBarry Smith + comm - the MPI communicator 5036026c97aSBarry Smith - format - the usual `printf()` format string 504e5c89e4eSSatish Balay 505e5c89e4eSSatish Balay Level: intermediate 506e5c89e4eSSatish Balay 507811af0c4SBarry Smith Note: 508811af0c4SBarry Smith REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information 509e5c89e4eSSatish Balay from all the processors to be printed. 510e5c89e4eSSatish Balay 511aec76313SJacob Faibussowitsch Fortran Notes: 512058c9ee1SBarry Smith The call sequence is `PetscSynchronizedPrintf`(`MPI_Comm`, `character`(*), `PetscErrorCode` ierr). 513e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 514e5c89e4eSSatish Balay 515db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, 516c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 517c69effb2SJacob Faibussowitsch `PetscFFlush()` 518e5c89e4eSSatish Balay @*/ 519d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...) 520d71ae5a4SJacob Faibussowitsch { 521eae3dc7dSJacob Faibussowitsch va_list Argp; 522e5c89e4eSSatish Balay 523e5c89e4eSSatish Balay PetscFunctionBegin; 524e5c89e4eSSatish Balay va_start(Argp, format); 525eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 526e5c89e4eSSatish Balay va_end(Argp); 5273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 528e5c89e4eSSatish Balay } 529e5c89e4eSSatish Balay 530e5c89e4eSSatish Balay /*@C 531e5c89e4eSSatish Balay PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 53221532e8aSBarry Smith several MPI processes. Output of the first process is followed by that of the 533e5c89e4eSSatish Balay second, etc. 534e5c89e4eSSatish Balay 535e5c89e4eSSatish Balay Not Collective 536e5c89e4eSSatish Balay 537e5c89e4eSSatish Balay Input Parameters: 538058c9ee1SBarry Smith + comm - the MPI communicator 539aec76313SJacob Faibussowitsch . fp - the file pointer 5406026c97aSBarry Smith - format - the usual `printf()` format string 541e5c89e4eSSatish Balay 542e5c89e4eSSatish Balay Level: intermediate 543e5c89e4eSSatish Balay 544811af0c4SBarry Smith Note: 545811af0c4SBarry Smith REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information 546e5c89e4eSSatish Balay from all the processors to be printed. 547e5c89e4eSSatish Balay 548db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`, 549c69effb2SJacob Faibussowitsch `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 550c69effb2SJacob Faibussowitsch `PetscFFlush()` 551e5c89e4eSSatish Balay @*/ 552d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...) 553d71ae5a4SJacob Faibussowitsch { 554eae3dc7dSJacob Faibussowitsch va_list Argp; 555e5c89e4eSSatish Balay 556e5c89e4eSSatish Balay PetscFunctionBegin; 557e5c89e4eSSatish Balay va_start(Argp, format); 558eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, fp, format, Argp)); 559e5c89e4eSSatish Balay va_end(Argp); 5603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 561e5c89e4eSSatish Balay } 562e5c89e4eSSatish Balay 5630ec8b6e3SBarry Smith /*@C 564e5c89e4eSSatish Balay PetscSynchronizedFlush - Flushes to the screen output from all processors 565811af0c4SBarry Smith involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls. 566e5c89e4eSSatish Balay 567d083f849SBarry Smith Collective 568e5c89e4eSSatish Balay 569e5c89e4eSSatish Balay Input Parameters: 570058c9ee1SBarry Smith + comm - the MPI communicator 57121532e8aSBarry Smith - fd - the file pointer (valid on MPI rank 0 of the communicator) 572e5c89e4eSSatish Balay 573e5c89e4eSSatish Balay Level: intermediate 574e5c89e4eSSatish Balay 575811af0c4SBarry Smith Note: 576811af0c4SBarry Smith If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with 577811af0c4SBarry Smith different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators. 578e5c89e4eSSatish Balay 579aec76313SJacob Faibussowitsch Fortran Notes: 580811af0c4SBarry Smith Pass `PETSC_STDOUT` if the flush is for standard out; otherwise pass a value obtained from `PetscFOpen()` 581e50bf69fSBarry Smith 582db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`, 583db781477SPatrick Sanan `PetscViewerASCIISynchronizedPrintf()` 5840087d953SMatthew G. Knepley @*/ 585d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd) 586d71ae5a4SJacob Faibussowitsch { 58729a5cbdcSMatthew G. Knepley PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0; 5882d609e63SMatthew Knepley char *message; 589e5c89e4eSSatish Balay MPI_Status status; 590e5c89e4eSSatish Balay 591e5c89e4eSSatish Balay PetscFunctionBegin; 5929566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(comm, &comm, &tag)); 5939566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5949566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 595e5c89e4eSSatish Balay 596e5c89e4eSSatish Balay /* First processor waits for messages from all other processors */ 597dd400576SPatrick Sanan if (rank == 0) { 5980ec8b6e3SBarry Smith if (!fd) fd = PETSC_STDOUT; 599e5c89e4eSSatish Balay for (i = 1; i < size; i++) { 6009f73f8ecSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 6019566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm)); 6029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status)); 603e5c89e4eSSatish Balay for (j = 0; j < n; j++) { 60429a5cbdcSMatthew G. Knepley PetscMPIInt size = 0; 6052d609e63SMatthew Knepley 6069566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status)); 6079566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &message)); 6089566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status)); 6099566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, "%s", message)); 6109566063dSJacob Faibussowitsch PetscCall(PetscFree(message)); 611e5c89e4eSSatish Balay } 612e5c89e4eSSatish Balay } 613e5c89e4eSSatish Balay } else { /* other processors send queue to processor 0 */ 614d30b0576SJed Brown PrintfQueue next = petsc_printfqueuebase, previous; 615e5c89e4eSSatish Balay 6169566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status)); 6179566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm)); 618d30b0576SJed Brown for (i = 0; i < petsc_printfqueuelength; i++) { 6199566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm)); 6209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm)); 621e5c89e4eSSatish Balay previous = next; 622e5c89e4eSSatish Balay next = next->next; 6239566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 6249566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 625e5c89e4eSSatish Balay } 62602c9f0b5SLisandro Dalcin petsc_printfqueue = NULL; 627d30b0576SJed Brown petsc_printfqueuelength = 0; 628e5c89e4eSSatish Balay } 6299566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&comm)); 6303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 631e5c89e4eSSatish Balay } 632e5c89e4eSSatish Balay 633e5c89e4eSSatish Balay /*@C 634e5c89e4eSSatish Balay PetscFPrintf - Prints to a file, only from the first 63521532e8aSBarry Smith MPI process in the communicator. 636e5c89e4eSSatish Balay 637cf53795eSBarry Smith Not Collective; No Fortran Support 638e5c89e4eSSatish Balay 639e5c89e4eSSatish Balay Input Parameters: 640058c9ee1SBarry Smith + comm - the MPI communicator 641e5c89e4eSSatish Balay . fd - the file pointer 6426026c97aSBarry Smith - format - the usual `printf()` format string 643e5c89e4eSSatish Balay 644e5c89e4eSSatish Balay Level: intermediate 645e5c89e4eSSatish Balay 646aec76313SJacob Faibussowitsch Developer Notes: 647058c9ee1SBarry Smith This maybe, and is, called from PETSc error handlers and `PetscMallocValidate()` hence it does not use `PetscCallMPI()` which 648058c9ee1SBarry Smith could recursively restart the malloc validation. 649058c9ee1SBarry Smith 650db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 651c69effb2SJacob Faibussowitsch `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFFlush()` 652e5c89e4eSSatish Balay @*/ 653d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...) 654d71ae5a4SJacob Faibussowitsch { 655eae3dc7dSJacob Faibussowitsch va_list Argp; 656e5c89e4eSSatish Balay 657e5c89e4eSSatish Balay PetscFunctionBegin; 658e5c89e4eSSatish Balay va_start(Argp, format); 659eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, fd, format, Argp)); 660e5c89e4eSSatish Balay va_end(Argp); 6613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 662e5c89e4eSSatish Balay } 663e5c89e4eSSatish Balay 664e5c89e4eSSatish Balay /*@C 665e5c89e4eSSatish Balay PetscPrintf - Prints to standard out, only from the first 66621532e8aSBarry Smith MPI process in the communicator. Calls from other processes are ignored. 667e5c89e4eSSatish Balay 668e5c89e4eSSatish Balay Not Collective 669e5c89e4eSSatish Balay 670e5c89e4eSSatish Balay Input Parameters: 671e5c89e4eSSatish Balay + comm - the communicator 672bfbbc7b7SBarry Smith - format - the usual `printf()` format string 673e5c89e4eSSatish Balay 674e5c89e4eSSatish Balay Level: intermediate 675e5c89e4eSSatish Balay 676811af0c4SBarry Smith Note: 677811af0c4SBarry Smith Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc. 678811af0c4SBarry Smith See the manual page for `PetscFormatConvert()` for details. 679b2706f25SRichard Tran Mills 680aec76313SJacob Faibussowitsch Fortran Notes: 681811af0c4SBarry Smith The call sequence is `PetscPrintf`(MPI_Comm, character(*), `PetscErrorCode` ierr) from Fortran. 682e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 683e5c89e4eSSatish Balay 684c69effb2SJacob Faibussowitsch .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()`, `PetscFFlush()` 685e5c89e4eSSatish Balay @*/ 686d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...) 687d71ae5a4SJacob Faibussowitsch { 688eae3dc7dSJacob Faibussowitsch va_list Argp; 689e5c89e4eSSatish Balay 690e5c89e4eSSatish Balay PetscFunctionBegin; 691e5c89e4eSSatish Balay va_start(Argp, format); 692eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 693e5c89e4eSSatish Balay va_end(Argp); 6943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 695e5c89e4eSSatish Balay } 696e5c89e4eSSatish Balay 697d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...) 698d71ae5a4SJacob Faibussowitsch { 699eae3dc7dSJacob Faibussowitsch va_list Argp; 700e5c89e4eSSatish Balay 701e5c89e4eSSatish Balay PetscFunctionBegin; 702e5c89e4eSSatish Balay va_start(Argp, format); 703eae3dc7dSJacob Faibussowitsch PetscCall(PetscVFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 704e5c89e4eSSatish Balay va_end(Argp); 7053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 706e5c89e4eSSatish Balay } 707e5c89e4eSSatish Balay 708e5c89e4eSSatish Balay /*@C 70921532e8aSBarry Smith PetscSynchronizedFGets - Multiple MPI processes all get the same line from a file. 710e5c89e4eSSatish Balay 711d083f849SBarry Smith Collective 712e5c89e4eSSatish Balay 713e5c89e4eSSatish Balay Input Parameters: 71421532e8aSBarry Smith + comm - the MPI communicator 715aec76313SJacob Faibussowitsch . fp - the file pointer 71621532e8aSBarry Smith - len - the length of `string` 717e5c89e4eSSatish Balay 718e5c89e4eSSatish Balay Output Parameter: 71921532e8aSBarry Smith . string - the line read from the file, at end of file `string`[0] == 0 720e5c89e4eSSatish Balay 721e5c89e4eSSatish Balay Level: intermediate 722e5c89e4eSSatish Balay 723db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, 724db781477SPatrick Sanan `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()` 725e5c89e4eSSatish Balay @*/ 726d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm, FILE *fp, size_t len, char string[]) 727d71ae5a4SJacob Faibussowitsch { 728e5c89e4eSSatish Balay PetscMPIInt rank; 729e5c89e4eSSatish Balay 730e5c89e4eSSatish Balay PetscFunctionBegin; 7319566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 73280971c97SJames Wright if (rank == 0) { 733eae3dc7dSJacob Faibussowitsch if (!fgets(string, len, fp)) { 734e31d4fa4SJed Brown string[0] = 0; 735bf31d2d3SBarry Smith PetscCheck(feof(fp), PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file due to \"%s\"", strerror(errno)); 736047b9c12SMatthew G Knepley } 737238ccf28SShri Abhyankar } 7389566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(string, len, MPI_BYTE, 0, comm)); 7393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 740e5c89e4eSSatish Balay } 741238ccf28SShri Abhyankar 742d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[]) 743d71ae5a4SJacob Faibussowitsch { 7441b5687a1SBarry Smith PetscInt i; 7451b5687a1SBarry Smith size_t left, count; 7461b5687a1SBarry Smith char *p; 7471b5687a1SBarry Smith 7481b5687a1SBarry Smith PetscFunctionBegin; 7491b5687a1SBarry Smith for (i = 0, p = buf, left = len; i < n; i++) { 7509566063dSJacob Faibussowitsch PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i])); 75108401ef6SPierre Jolivet PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer"); 7521b5687a1SBarry Smith left -= count; 7531b5687a1SBarry Smith p += count - 1; 7541b5687a1SBarry Smith *p++ = ' '; 7551b5687a1SBarry Smith } 7561b5687a1SBarry Smith p[i ? 0 : -1] = 0; 7573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7581b5687a1SBarry Smith } 759