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; 454f572ea9SToby Isaac PetscAssertPointer(format, 1); 464f572ea9SToby Isaac PetscAssertPointer(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 7910450e9eSJacob 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 8310450e9eSJacob Faibussowitsch Input Parameter: 8410450e9eSJacob Faibussowitsch . format - the PETSc format string 85d781fa04SBarry Smith 8621532e8aSBarry Smith Output Parameter: 87*a3b724e8SBarry Smith . newformat - the formatted string, must be long enough to hold result 8821532e8aSBarry Smith 89d781fa04SBarry Smith Level: developer 90d781fa04SBarry Smith 91058c9ee1SBarry Smith Note: 9210450e9eSJacob Faibussowitsch The decimal point is then used by the `petscdiff` script so that differences in floating 9310450e9eSJacob Faibussowitsch point number output is ignored in the test harness. 9410450e9eSJacob Faibussowitsch 9510450e9eSJacob Faibussowitsch Deprecated usage also converts the `%D` to `%d` for 32-bit PETSc indices and to `%lld` for 9610450e9eSJacob Faibussowitsch 64-bit PETSc indices. This feature is no longer used in PETSc code instead use %" 9710450e9eSJacob 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 1528c509928SStefano Zampini PetscVSNPrintf - The PETSc version of `vsnprintf()`. Ensures that all `%g` formatted arguments' output contains the decimal point (which is used by the test harness) 153c9a19010SBarry Smith 154c9a19010SBarry Smith Input Parameters: 155c9a19010SBarry Smith + str - location to put result 15621532e8aSBarry Smith . len - the length of `str` 15710450e9eSJacob Faibussowitsch . format - the PETSc format string 15810450e9eSJacob Faibussowitsch - Argp - the variable argument list to format 15921532e8aSBarry Smith 16021532e8aSBarry Smith Output Parameter: 16121532e8aSBarry Smith . fullLength - the amount of space in `str` actually used. 162c9a19010SBarry Smith 163c9a19010SBarry Smith Level: developer 164c9a19010SBarry Smith 165aec76313SJacob Faibussowitsch Developer Notes: 166058c9ee1SBarry Smith This function may be called from an error handler, if an error occurs when it is called by the error handler than likely 167058c9ee1SBarry Smith a recursion will occur resulting in a crash of the program. 168058c9ee1SBarry Smith 16921532e8aSBarry 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()` 170058c9ee1SBarry Smith 17142747ad1SJacob Faibussowitsch .seealso: `PetscFormatConvert()`, `PetscFormatConvertGetSize()`, `PetscErrorPrintf()`, `PetscVPrintf()` 172c9a19010SBarry Smith @*/ 173d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVSNPrintf(char *str, size_t len, const char *format, size_t *fullLength, va_list Argp) 174d71ae5a4SJacob Faibussowitsch { 175d781fa04SBarry Smith char *newformat = NULL; 17614416c0eSBarry Smith char formatbuf[PETSCDEFAULTBUFFERSIZE]; 177d781fa04SBarry Smith size_t newLength; 17814416c0eSBarry Smith int flen; 179e5c89e4eSSatish Balay 180eed5747fSBarry Smith PetscFunctionBegin; 1819566063dSJacob Faibussowitsch PetscCall(PetscFormatConvertGetSize(format, &newLength)); 18294217ebdSBarry Smith if (newLength < sizeof(formatbuf)) { 183e2135aedSMatthew Knepley newformat = formatbuf; 18494217ebdSBarry Smith newLength = sizeof(formatbuf) - 1; 185e2135aedSMatthew Knepley } else { 1869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(newLength, &newformat)); 187e2135aedSMatthew Knepley } 1889566063dSJacob Faibussowitsch PetscCall(PetscFormatConvert(format, newformat)); 1897b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF) 190152b30f0SSatish Balay flen = vsnprintf(str, len, newformat, Argp); 191e5c89e4eSSatish Balay #else 19289b07760SSatish Balay #error "vsnprintf not found" 193e5c89e4eSSatish Balay #endif 19448a46eb9SPierre Jolivet if (newLength > sizeof(formatbuf) - 1) PetscCall(PetscFree(newformat)); 1958627564fSBarry Smith { 1968627564fSBarry Smith PetscBool foundedot; 1978627564fSBarry Smith size_t cnt = 0, ncnt = 0, leng; 1989566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 19917ca8410SBarry Smith if (leng > 4) { 2008627564fSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 2018627564fSBarry Smith if (str[cnt] == '[' && str[cnt + 1] == '|') { 202c540d043SBarry Smith flen -= 4; 2039371c9d4SSatish Balay cnt++; 2049371c9d4SSatish Balay cnt++; 2058627564fSBarry Smith foundedot = PETSC_FALSE; 2068627564fSBarry Smith for (; cnt < leng - 1; cnt++) { 2078627564fSBarry Smith if (str[cnt] == '|' && str[cnt + 1] == ']') { 2088627564fSBarry Smith cnt++; 2098627564fSBarry Smith if (!foundedot) str[ncnt++] = '.'; 2108627564fSBarry Smith ncnt--; 2118627564fSBarry Smith break; 2128627564fSBarry Smith } else { 2138627564fSBarry Smith if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 2148627564fSBarry Smith str[ncnt++] = str[cnt]; 2158627564fSBarry Smith } 2168627564fSBarry Smith } 2178627564fSBarry Smith } else { 2188627564fSBarry Smith str[ncnt] = str[cnt]; 2198627564fSBarry Smith } 2208627564fSBarry Smith ncnt++; 2218627564fSBarry Smith } 2228627564fSBarry Smith while (cnt < leng) { 2239371c9d4SSatish Balay str[ncnt] = str[cnt]; 2249371c9d4SSatish Balay ncnt++; 2259371c9d4SSatish Balay cnt++; 2268627564fSBarry Smith } 2278627564fSBarry Smith str[ncnt] = 0; 2288627564fSBarry Smith } 2298627564fSBarry Smith } 230748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 231e51f71cfSBarry Smith /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 232748e1b9dSBarry Smith { 233748e1b9dSBarry Smith size_t cnt = 0, ncnt = 0, leng; 2349566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 235748e1b9dSBarry Smith if (leng > 5) { 236748e1b9dSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 237e51f71cfSBarry 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') { 2389371c9d4SSatish Balay str[ncnt] = str[cnt]; 2399371c9d4SSatish Balay ncnt++; 2409371c9d4SSatish Balay cnt++; 2419371c9d4SSatish Balay str[ncnt] = str[cnt]; 2429371c9d4SSatish Balay ncnt++; 2439371c9d4SSatish Balay cnt++; 2449371c9d4SSatish Balay cnt++; 245e51f71cfSBarry Smith str[ncnt] = str[cnt]; 246748e1b9dSBarry Smith } else { 247748e1b9dSBarry Smith str[ncnt] = str[cnt]; 248748e1b9dSBarry Smith } 249748e1b9dSBarry Smith ncnt++; 250748e1b9dSBarry Smith } 251748e1b9dSBarry Smith while (cnt < leng) { 2529371c9d4SSatish Balay str[ncnt] = str[cnt]; 2539371c9d4SSatish Balay ncnt++; 2549371c9d4SSatish Balay cnt++; 255748e1b9dSBarry Smith } 256748e1b9dSBarry Smith str[ncnt] = 0; 257748e1b9dSBarry Smith } 258748e1b9dSBarry Smith } 259748e1b9dSBarry Smith #endif 260c540d043SBarry Smith if (fullLength) *fullLength = 1 + (size_t)flen; 2613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 262e5c89e4eSSatish Balay } 263e5c89e4eSSatish Balay 264c9a19010SBarry Smith /*@C 265c69effb2SJacob Faibussowitsch PetscFFlush - Flush a file stream 266c69effb2SJacob Faibussowitsch 267c69effb2SJacob Faibussowitsch Input Parameter: 268c69effb2SJacob Faibussowitsch . fd - The file stream handle 269c69effb2SJacob Faibussowitsch 270c69effb2SJacob Faibussowitsch Level: intermediate 271c69effb2SJacob Faibussowitsch 272c69effb2SJacob Faibussowitsch Notes: 273c69effb2SJacob Faibussowitsch For output streams (and for update streams on which the last operation was output), writes 274c69effb2SJacob Faibussowitsch any unwritten data from the stream's buffer to the associated output device. 275c69effb2SJacob Faibussowitsch 276c69effb2SJacob Faibussowitsch For input streams (and for update streams on which the last operation was input), the 277c69effb2SJacob Faibussowitsch behavior is undefined. 278c69effb2SJacob Faibussowitsch 279c69effb2SJacob Faibussowitsch If `fd` is `NULL`, all open output streams are flushed, including ones not directly 280c69effb2SJacob Faibussowitsch accessible to the program. 281c69effb2SJacob Faibussowitsch 282c69effb2SJacob Faibussowitsch .seealso: `PetscPrintf()`, `PetscFPrintf()`, `PetscVFPrintf()`, `PetscVSNPrintf()` 283c69effb2SJacob Faibussowitsch @*/ 284c69effb2SJacob Faibussowitsch PetscErrorCode PetscFFlush(FILE *fd) 285c69effb2SJacob Faibussowitsch { 286c69effb2SJacob Faibussowitsch PetscFunctionBegin; 2874f572ea9SToby Isaac if (fd) PetscAssertPointer(fd, 1); 288c69effb2SJacob Faibussowitsch // could also use PetscCallExternal() here, but since we can get additional error explanation 289c69effb2SJacob Faibussowitsch // from strerror() we opted for a manual check 290bf31d2d3SBarry Smith PetscCheck(0 == fflush(fd), PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "Error in fflush() due to \"%s\"", strerror(errno)); 291c69effb2SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 292c69effb2SJacob Faibussowitsch } 293c69effb2SJacob Faibussowitsch 294c69effb2SJacob Faibussowitsch /*@C 295aec76313SJacob Faibussowitsch PetscVFPrintfDefault - All PETSc standard out and error messages are sent through this function; so, in theory, this can 296e5c89e4eSSatish Balay can be replaced with something that does not simply write to a file. 297e5c89e4eSSatish Balay 29810450e9eSJacob Faibussowitsch Input Parameters: 29910450e9eSJacob Faibussowitsch + fd - the file descriptor to write to 30010450e9eSJacob Faibussowitsch . format - the format string to write with 30110450e9eSJacob Faibussowitsch - Argp - the variable argument list of items to format and write 30210450e9eSJacob Faibussowitsch 30310450e9eSJacob Faibussowitsch Level: developer 30410450e9eSJacob Faibussowitsch 30510450e9eSJacob Faibussowitsch Note: 30610450e9eSJacob Faibussowitsch For error messages this may be called by any MPI process, for regular standard out it is 30710450e9eSJacob Faibussowitsch called only by MPI rank 0 of a given communicator 30810450e9eSJacob Faibussowitsch 30910450e9eSJacob Faibussowitsch Example Usage: 310c9a19010SBarry Smith To use, write your own function for example, 311058c9ee1SBarry Smith .vb 312058c9ee1SBarry Smith PetscErrorCode mypetscvfprintf(FILE *fd, const char format[], va_list Argp) 313058c9ee1SBarry Smith { 314058c9ee1SBarry Smith PetscErrorCode ierr; 315058c9ee1SBarry Smith 316058c9ee1SBarry Smith PetscFunctionBegin; 317058c9ee1SBarry Smith if (fd != stdout && fd != stderr) { handle regular files 318058c9ee1SBarry Smith CHKERR(PetscVFPrintfDefault(fd,format,Argp)); 319058c9ee1SBarry Smith } else { 320058c9ee1SBarry Smith char buff[BIG]; 321058c9ee1SBarry Smith size_t length; 322058c9ee1SBarry Smith PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp)); 323058c9ee1SBarry Smith now send buff to whatever stream or whatever you want 324058c9ee1SBarry Smith } 325058c9ee1SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 326058c9ee1SBarry Smith } 327058c9ee1SBarry Smith .ve 328058c9ee1SBarry Smith then before the call to `PetscInitialize()` do the assignment `PetscVFPrintf = mypetscvfprintf`; 329058c9ee1SBarry Smith 330aec76313SJacob Faibussowitsch Developer Notes: 331058c9ee1SBarry Smith This could be called by an error handler, if that happens then a recursion of the error handler may occur 332058c9ee1SBarry Smith and a resulting crash 333c9a19010SBarry Smith 334c69effb2SJacob Faibussowitsch .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscFFlush()` 335c9a19010SBarry Smith @*/ 336d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char *format, va_list Argp) 337d71ae5a4SJacob Faibussowitsch { 33814416c0eSBarry Smith char str[PETSCDEFAULTBUFFERSIZE]; 33914416c0eSBarry Smith char *buff = str; 34014416c0eSBarry Smith size_t fullLength; 3411531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 34214416c0eSBarry Smith va_list Argpcopy; 3431531940fSBarry Smith #endif 3441179db26SBarry Smith 345eed5747fSBarry Smith PetscFunctionBegin; 3461531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 34714416c0eSBarry Smith va_copy(Argpcopy, Argp); 3481531940fSBarry Smith #endif 3499566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp)); 35014416c0eSBarry Smith if (fullLength > sizeof(str)) { 3519566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fullLength, &buff)); 3521531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 3539566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy)); 3541531940fSBarry Smith #else 3551531940fSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines"); 3561531940fSBarry Smith #endif 35714416c0eSBarry Smith } 358eae3dc7dSJacob Faibussowitsch #if defined(PETSC_HAVE_VA_COPY) 359eae3dc7dSJacob Faibussowitsch va_end(Argpcopy); 360eae3dc7dSJacob Faibussowitsch #endif 361c69effb2SJacob Faibussowitsch { 3628c0ebe3fSBarry Smith int err; 3638c0ebe3fSBarry Smith 3648c0ebe3fSBarry Smith // POSIX C sets errno but otherwise it may not be set for *printf() system calls 3658c0ebe3fSBarry Smith // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html 3668c0ebe3fSBarry Smith errno = 0; 3678c0ebe3fSBarry Smith err = fprintf(fd, "%s", buff); 368c69effb2SJacob Faibussowitsch // cannot use PetscCallExternal() for fprintf since the return value is "number of 369c69effb2SJacob Faibussowitsch // characters transmitted to the output stream" on success 3708c0ebe3fSBarry Smith PetscCheck(err >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "fprintf() returned error code %d: %s", err, errno > 0 ? strerror(errno) : "unknown (errno not set)"); 371c69effb2SJacob Faibussowitsch } 372c69effb2SJacob Faibussowitsch PetscCall(PetscFFlush(fd)); 37348a46eb9SPierre Jolivet if (buff != str) PetscCall(PetscFree(buff)); 3743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 375e5c89e4eSSatish Balay } 376e5c89e4eSSatish Balay 3775b5bc046SBarry Smith /*@C 3785b5bc046SBarry Smith PetscSNPrintf - Prints to a string of given length 3795b5bc046SBarry Smith 3805b5bc046SBarry Smith Not Collective 3815b5bc046SBarry Smith 3825b5bc046SBarry Smith Input Parameters: 38321532e8aSBarry Smith + len - the length of `str` 38410450e9eSJacob Faibussowitsch - format - the usual `printf()` format string 3855b5bc046SBarry Smith 38621532e8aSBarry Smith Output Parameter: 38721532e8aSBarry Smith . str - the resulting string 38821532e8aSBarry Smith 3895b5bc046SBarry Smith Level: intermediate 3905b5bc046SBarry Smith 391db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 392c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 393c69effb2SJacob Faibussowitsch `PetscVFPrintf()`, `PetscFFlush()` 3945b5bc046SBarry Smith @*/ 395d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintf(char *str, size_t len, const char format[], ...) 396d71ae5a4SJacob Faibussowitsch { 397c9a19010SBarry Smith size_t fullLength; 3985b5bc046SBarry Smith va_list Argp; 3995b5bc046SBarry Smith 4005b5bc046SBarry Smith PetscFunctionBegin; 4015b5bc046SBarry Smith va_start(Argp, format); 4029566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp)); 403eae3dc7dSJacob Faibussowitsch va_end(Argp); 4043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4055b5bc046SBarry Smith } 4065b5bc046SBarry Smith 407257d2499SJed Brown /*@C 408058c9ee1SBarry Smith PetscSNPrintfCount - Prints to a string of given length, returns count of characters printed 409257d2499SJed Brown 410257d2499SJed Brown Not Collective 411257d2499SJed Brown 412257d2499SJed Brown Input Parameters: 41321532e8aSBarry Smith + len - the length of `str` 414058c9ee1SBarry Smith . format - the usual `printf()` format string 41510450e9eSJacob Faibussowitsch - ... - args to format 416257d2499SJed Brown 41721532e8aSBarry Smith Output Parameters: 41821532e8aSBarry Smith + str - the resulting string 41921532e8aSBarry Smith - countused - number of characters printed 420cb398dd3SBarry Smith 421257d2499SJed Brown Level: intermediate 422257d2499SJed Brown 423db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 424db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()` 425257d2499SJed Brown @*/ 426d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintfCount(char *str, size_t len, const char format[], size_t *countused, ...) 427d71ae5a4SJacob Faibussowitsch { 428257d2499SJed Brown va_list Argp; 429257d2499SJed Brown 430257d2499SJed Brown PetscFunctionBegin; 431257d2499SJed Brown va_start(Argp, countused); 4329566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, countused, Argp)); 433eae3dc7dSJacob Faibussowitsch va_end(Argp); 4343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 435257d2499SJed Brown } 436257d2499SJed Brown 43702c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL; 438d30b0576SJed Brown int petsc_printfqueuelength = 0; 439e5c89e4eSSatish Balay 4408c509928SStefano Zampini static inline PetscErrorCode PetscVFPrintf_Private(FILE *fd, const char format[], va_list Argp) 441eae3dc7dSJacob Faibussowitsch { 442eae3dc7dSJacob Faibussowitsch const PetscBool tee = (PetscBool)(petsc_history && (fd != petsc_history)); 443eae3dc7dSJacob Faibussowitsch va_list cpy; 444eae3dc7dSJacob Faibussowitsch 445eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 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 4568c509928SStefano Zampini PETSC_INTERN PetscErrorCode PetscVFPrintf_Internal(FILE *fd, const char format[], ...) 4578c509928SStefano Zampini { 4588c509928SStefano Zampini va_list Argp; 4598c509928SStefano Zampini 4608c509928SStefano Zampini PetscFunctionBegin; 4618c509928SStefano Zampini va_start(Argp, format); 4628c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(fd, format, Argp)); 4638c509928SStefano Zampini va_end(Argp); 4648c509928SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 4658c509928SStefano Zampini } 4668c509928SStefano Zampini 467eae3dc7dSJacob Faibussowitsch static inline PetscErrorCode PetscSynchronizedFPrintf_Private(MPI_Comm comm, FILE *fp, const char format[], va_list Argp) 468eae3dc7dSJacob Faibussowitsch { 469eae3dc7dSJacob Faibussowitsch PetscMPIInt rank; 470eae3dc7dSJacob Faibussowitsch va_list cpy; 471eae3dc7dSJacob Faibussowitsch 472eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 473eae3dc7dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 474eae3dc7dSJacob Faibussowitsch /* First processor prints immediately to fp */ 475eae3dc7dSJacob Faibussowitsch if (rank == 0) { 476eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 4778c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(fp, format, cpy)); 478eae3dc7dSJacob Faibussowitsch va_end(cpy); 479eae3dc7dSJacob Faibussowitsch } else { /* other processors add to local queue */ 480eae3dc7dSJacob Faibussowitsch PrintfQueue next; 481eae3dc7dSJacob Faibussowitsch size_t fullLength = PETSCDEFAULTBUFFERSIZE; 482eae3dc7dSJacob Faibussowitsch 483eae3dc7dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 484eae3dc7dSJacob Faibussowitsch if (petsc_printfqueue) { 485eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = next; 486eae3dc7dSJacob Faibussowitsch petsc_printfqueue = next; 487eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = NULL; 488eae3dc7dSJacob Faibussowitsch } else petsc_printfqueuebase = petsc_printfqueue = next; 489eae3dc7dSJacob Faibussowitsch petsc_printfqueuelength++; 490eae3dc7dSJacob Faibussowitsch next->size = 0; 491eae3dc7dSJacob Faibussowitsch next->string = NULL; 492eae3dc7dSJacob Faibussowitsch while (fullLength >= next->size) { 493eae3dc7dSJacob Faibussowitsch next->size = fullLength + 1; 494eae3dc7dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 495eae3dc7dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 496eae3dc7dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, next->size)); 497eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 498eae3dc7dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, cpy)); 499eae3dc7dSJacob Faibussowitsch va_end(cpy); 500eae3dc7dSJacob Faibussowitsch } 501eae3dc7dSJacob Faibussowitsch } 502eae3dc7dSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 503eae3dc7dSJacob Faibussowitsch } 504eae3dc7dSJacob Faibussowitsch 505e5c89e4eSSatish Balay /*@C 5069c89aa79SPierre Jolivet PetscSynchronizedPrintf - Prints synchronized output from multiple MPI processes. 507e5c89e4eSSatish Balay Output of the first processor is followed by that of the second, etc. 508e5c89e4eSSatish Balay 509e5c89e4eSSatish Balay Not Collective 510e5c89e4eSSatish Balay 511e5c89e4eSSatish Balay Input Parameters: 512058c9ee1SBarry Smith + comm - the MPI communicator 5136026c97aSBarry Smith - format - the usual `printf()` format string 514e5c89e4eSSatish Balay 515e5c89e4eSSatish Balay Level: intermediate 516e5c89e4eSSatish Balay 517811af0c4SBarry Smith Note: 518811af0c4SBarry Smith REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information 519e5c89e4eSSatish Balay from all the processors to be printed. 520e5c89e4eSSatish Balay 521aec76313SJacob Faibussowitsch Fortran Notes: 522058c9ee1SBarry Smith The call sequence is `PetscSynchronizedPrintf`(`MPI_Comm`, `character`(*), `PetscErrorCode` ierr). 523e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 524e5c89e4eSSatish Balay 525db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, 526c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 527c69effb2SJacob Faibussowitsch `PetscFFlush()` 528e5c89e4eSSatish Balay @*/ 529d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...) 530d71ae5a4SJacob Faibussowitsch { 531eae3dc7dSJacob Faibussowitsch va_list Argp; 532e5c89e4eSSatish Balay 533e5c89e4eSSatish Balay PetscFunctionBegin; 534e5c89e4eSSatish Balay va_start(Argp, format); 535eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 536e5c89e4eSSatish Balay va_end(Argp); 5373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 538e5c89e4eSSatish Balay } 539e5c89e4eSSatish Balay 540e5c89e4eSSatish Balay /*@C 541e5c89e4eSSatish Balay PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 54221532e8aSBarry Smith several MPI processes. Output of the first process is followed by that of the 543e5c89e4eSSatish Balay second, etc. 544e5c89e4eSSatish Balay 545e5c89e4eSSatish Balay Not Collective 546e5c89e4eSSatish Balay 547e5c89e4eSSatish Balay Input Parameters: 548058c9ee1SBarry Smith + comm - the MPI communicator 549aec76313SJacob Faibussowitsch . fp - the file pointer 5506026c97aSBarry Smith - format - the usual `printf()` format string 551e5c89e4eSSatish Balay 552e5c89e4eSSatish Balay Level: intermediate 553e5c89e4eSSatish Balay 554811af0c4SBarry Smith Note: 555811af0c4SBarry Smith REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information 556e5c89e4eSSatish Balay from all the processors to be printed. 557e5c89e4eSSatish Balay 558db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`, 559c69effb2SJacob Faibussowitsch `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 560c69effb2SJacob Faibussowitsch `PetscFFlush()` 561e5c89e4eSSatish Balay @*/ 562d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...) 563d71ae5a4SJacob Faibussowitsch { 564eae3dc7dSJacob Faibussowitsch va_list Argp; 565e5c89e4eSSatish Balay 566e5c89e4eSSatish Balay PetscFunctionBegin; 567e5c89e4eSSatish Balay va_start(Argp, format); 568eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, fp, format, Argp)); 569e5c89e4eSSatish Balay va_end(Argp); 5703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 571e5c89e4eSSatish Balay } 572e5c89e4eSSatish Balay 5730ec8b6e3SBarry Smith /*@C 574e5c89e4eSSatish Balay PetscSynchronizedFlush - Flushes to the screen output from all processors 575811af0c4SBarry Smith involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls. 576e5c89e4eSSatish Balay 577d083f849SBarry Smith Collective 578e5c89e4eSSatish Balay 579e5c89e4eSSatish Balay Input Parameters: 580058c9ee1SBarry Smith + comm - the MPI communicator 581*a3b724e8SBarry Smith - fd - the file pointer (valid on MPI rank 0 of the communicator), `PETSC_STDOUT` or value obtained from `PetscFOpen()` 582e5c89e4eSSatish Balay 583e5c89e4eSSatish Balay Level: intermediate 584e5c89e4eSSatish Balay 585811af0c4SBarry Smith Note: 586811af0c4SBarry Smith If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with 587811af0c4SBarry Smith different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators. 588e5c89e4eSSatish Balay 589aec76313SJacob Faibussowitsch Fortran Notes: 590811af0c4SBarry Smith Pass `PETSC_STDOUT` if the flush is for standard out; otherwise pass a value obtained from `PetscFOpen()` 591e50bf69fSBarry Smith 592db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`, 593db781477SPatrick Sanan `PetscViewerASCIISynchronizedPrintf()` 5940087d953SMatthew G. Knepley @*/ 595d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd) 596d71ae5a4SJacob Faibussowitsch { 59729a5cbdcSMatthew G. Knepley PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0; 5982d609e63SMatthew Knepley char *message; 599e5c89e4eSSatish Balay MPI_Status status; 600e5c89e4eSSatish Balay 601e5c89e4eSSatish Balay PetscFunctionBegin; 6029566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(comm, &comm, &tag)); 6039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 605e5c89e4eSSatish Balay 606e5c89e4eSSatish Balay /* First processor waits for messages from all other processors */ 607dd400576SPatrick Sanan if (rank == 0) { 6080ec8b6e3SBarry Smith if (!fd) fd = PETSC_STDOUT; 609e5c89e4eSSatish Balay for (i = 1; i < size; i++) { 6109f73f8ecSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 6119566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm)); 6129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status)); 613e5c89e4eSSatish Balay for (j = 0; j < n; j++) { 61429a5cbdcSMatthew G. Knepley PetscMPIInt size = 0; 6152d609e63SMatthew Knepley 6169566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status)); 6179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &message)); 6189566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status)); 6199566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, "%s", message)); 6209566063dSJacob Faibussowitsch PetscCall(PetscFree(message)); 621e5c89e4eSSatish Balay } 622e5c89e4eSSatish Balay } 623e5c89e4eSSatish Balay } else { /* other processors send queue to processor 0 */ 624d30b0576SJed Brown PrintfQueue next = petsc_printfqueuebase, previous; 625e5c89e4eSSatish Balay 6269566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status)); 6279566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm)); 628d30b0576SJed Brown for (i = 0; i < petsc_printfqueuelength; i++) { 6299566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm)); 6309566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm)); 631e5c89e4eSSatish Balay previous = next; 632e5c89e4eSSatish Balay next = next->next; 6339566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 6349566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 635e5c89e4eSSatish Balay } 63602c9f0b5SLisandro Dalcin petsc_printfqueue = NULL; 637d30b0576SJed Brown petsc_printfqueuelength = 0; 638e5c89e4eSSatish Balay } 6399566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&comm)); 6403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 641e5c89e4eSSatish Balay } 642e5c89e4eSSatish Balay 643e5c89e4eSSatish Balay /*@C 644e5c89e4eSSatish Balay PetscFPrintf - Prints to a file, only from the first 64521532e8aSBarry Smith MPI process in the communicator. 646e5c89e4eSSatish Balay 647cf53795eSBarry Smith Not Collective; No Fortran Support 648e5c89e4eSSatish Balay 649e5c89e4eSSatish Balay Input Parameters: 650058c9ee1SBarry Smith + comm - the MPI communicator 651e5c89e4eSSatish Balay . fd - the file pointer 6526026c97aSBarry Smith - format - the usual `printf()` format string 653e5c89e4eSSatish Balay 654e5c89e4eSSatish Balay Level: intermediate 655e5c89e4eSSatish Balay 656aec76313SJacob Faibussowitsch Developer Notes: 657058c9ee1SBarry Smith This maybe, and is, called from PETSc error handlers and `PetscMallocValidate()` hence it does not use `PetscCallMPI()` which 658058c9ee1SBarry Smith could recursively restart the malloc validation. 659058c9ee1SBarry Smith 660db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 661c69effb2SJacob Faibussowitsch `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFFlush()` 662e5c89e4eSSatish Balay @*/ 663d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...) 664d71ae5a4SJacob Faibussowitsch { 6658c509928SStefano Zampini PetscMPIInt rank; 666eae3dc7dSJacob Faibussowitsch va_list Argp; 667e5c89e4eSSatish Balay 668e5c89e4eSSatish Balay PetscFunctionBegin; 6698c509928SStefano Zampini PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6708c509928SStefano Zampini if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS); 671e5c89e4eSSatish Balay va_start(Argp, format); 6728c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(fd, format, Argp)); 673e5c89e4eSSatish Balay va_end(Argp); 6743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 675e5c89e4eSSatish Balay } 676e5c89e4eSSatish Balay 677e5c89e4eSSatish Balay /*@C 678e5c89e4eSSatish Balay PetscPrintf - Prints to standard out, only from the first 67921532e8aSBarry Smith MPI process in the communicator. Calls from other processes are ignored. 680e5c89e4eSSatish Balay 681e5c89e4eSSatish Balay Not Collective 682e5c89e4eSSatish Balay 683e5c89e4eSSatish Balay Input Parameters: 684e5c89e4eSSatish Balay + comm - the communicator 685bfbbc7b7SBarry Smith - format - the usual `printf()` format string 686e5c89e4eSSatish Balay 687e5c89e4eSSatish Balay Level: intermediate 688e5c89e4eSSatish Balay 689811af0c4SBarry Smith Note: 690811af0c4SBarry Smith Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc. 691811af0c4SBarry Smith See the manual page for `PetscFormatConvert()` for details. 692b2706f25SRichard Tran Mills 693aec76313SJacob Faibussowitsch Fortran Notes: 694811af0c4SBarry Smith The call sequence is `PetscPrintf`(MPI_Comm, character(*), `PetscErrorCode` ierr) from Fortran. 695e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 696e5c89e4eSSatish Balay 697c69effb2SJacob Faibussowitsch .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()`, `PetscFFlush()` 698e5c89e4eSSatish Balay @*/ 699d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...) 700d71ae5a4SJacob Faibussowitsch { 7018c509928SStefano Zampini PetscMPIInt rank; 702eae3dc7dSJacob Faibussowitsch va_list Argp; 703e5c89e4eSSatish Balay 704e5c89e4eSSatish Balay PetscFunctionBegin; 7058c509928SStefano Zampini PetscCallMPI(MPI_Comm_rank(comm, &rank)); 7068c509928SStefano Zampini if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS); 707e5c89e4eSSatish Balay va_start(Argp, format); 7088c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(PETSC_STDOUT, format, Argp)); 709e5c89e4eSSatish Balay va_end(Argp); 7103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 711e5c89e4eSSatish Balay } 712e5c89e4eSSatish Balay 713d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...) 714d71ae5a4SJacob Faibussowitsch { 7158c509928SStefano Zampini PetscMPIInt rank; 716eae3dc7dSJacob Faibussowitsch va_list Argp; 717e5c89e4eSSatish Balay 718e5c89e4eSSatish Balay PetscFunctionBegin; 7198c509928SStefano Zampini PetscCallMPI(MPI_Comm_rank(comm, &rank)); 7208c509928SStefano Zampini if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS); 721e5c89e4eSSatish Balay va_start(Argp, format); 7228c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(PETSC_STDOUT, format, Argp)); 723e5c89e4eSSatish Balay va_end(Argp); 7243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 725e5c89e4eSSatish Balay } 726e5c89e4eSSatish Balay 727e5c89e4eSSatish Balay /*@C 72821532e8aSBarry Smith PetscSynchronizedFGets - Multiple MPI processes all get the same line from a file. 729e5c89e4eSSatish Balay 730d083f849SBarry Smith Collective 731e5c89e4eSSatish Balay 732e5c89e4eSSatish Balay Input Parameters: 73321532e8aSBarry Smith + comm - the MPI communicator 734aec76313SJacob Faibussowitsch . fp - the file pointer 73521532e8aSBarry Smith - len - the length of `string` 736e5c89e4eSSatish Balay 737e5c89e4eSSatish Balay Output Parameter: 73821532e8aSBarry Smith . string - the line read from the file, at end of file `string`[0] == 0 739e5c89e4eSSatish Balay 740e5c89e4eSSatish Balay Level: intermediate 741e5c89e4eSSatish Balay 742db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, 743db781477SPatrick Sanan `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()` 744e5c89e4eSSatish Balay @*/ 745d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm, FILE *fp, size_t len, char string[]) 746d71ae5a4SJacob Faibussowitsch { 747e5c89e4eSSatish Balay PetscMPIInt rank; 748e5c89e4eSSatish Balay 749e5c89e4eSSatish Balay PetscFunctionBegin; 7509566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 75180971c97SJames Wright if (rank == 0) { 752eae3dc7dSJacob Faibussowitsch if (!fgets(string, len, fp)) { 753e31d4fa4SJed Brown string[0] = 0; 754bf31d2d3SBarry Smith PetscCheck(feof(fp), PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file due to \"%s\"", strerror(errno)); 755047b9c12SMatthew G Knepley } 756238ccf28SShri Abhyankar } 7579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(string, len, MPI_BYTE, 0, comm)); 7583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 759e5c89e4eSSatish Balay } 760238ccf28SShri Abhyankar 761d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[]) 762d71ae5a4SJacob Faibussowitsch { 7631b5687a1SBarry Smith PetscInt i; 7641b5687a1SBarry Smith size_t left, count; 7651b5687a1SBarry Smith char *p; 7661b5687a1SBarry Smith 7671b5687a1SBarry Smith PetscFunctionBegin; 7681b5687a1SBarry Smith for (i = 0, p = buf, left = len; i < n; i++) { 7699566063dSJacob Faibussowitsch PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i])); 77008401ef6SPierre Jolivet PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer"); 7711b5687a1SBarry Smith left -= count; 7721b5687a1SBarry Smith p += count - 1; 7731b5687a1SBarry Smith *p++ = ' '; 7741b5687a1SBarry Smith } 7751b5687a1SBarry Smith p[i ? 0 : -1] = 0; 7763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7771b5687a1SBarry Smith } 778