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 @*/ 39*cc4c1da9SBarry Smith 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: 87a3b724e8SBarry 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 @*/ 101*cc4c1da9SBarry Smith 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 154*cc4c1da9SBarry Smith No Fortran Support 155*cc4c1da9SBarry Smith 156c9a19010SBarry Smith Input Parameters: 157c9a19010SBarry Smith + str - location to put result 15821532e8aSBarry Smith . len - the length of `str` 15910450e9eSJacob Faibussowitsch . format - the PETSc format string 16010450e9eSJacob Faibussowitsch - Argp - the variable argument list to format 16121532e8aSBarry Smith 16221532e8aSBarry Smith Output Parameter: 16321532e8aSBarry Smith . fullLength - the amount of space in `str` actually used. 164c9a19010SBarry Smith 165c9a19010SBarry Smith Level: developer 166c9a19010SBarry Smith 167aec76313SJacob Faibussowitsch Developer Notes: 168058c9ee1SBarry Smith This function may be called from an error handler, if an error occurs when it is called by the error handler than likely 169058c9ee1SBarry Smith a recursion will occur resulting in a crash of the program. 170058c9ee1SBarry Smith 17121532e8aSBarry 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()` 172058c9ee1SBarry Smith 17342747ad1SJacob Faibussowitsch .seealso: `PetscFormatConvert()`, `PetscFormatConvertGetSize()`, `PetscErrorPrintf()`, `PetscVPrintf()` 174c9a19010SBarry Smith @*/ 175*cc4c1da9SBarry Smith PetscErrorCode PetscVSNPrintf(char str[], size_t len, const char format[], size_t *fullLength, va_list Argp) 176d71ae5a4SJacob Faibussowitsch { 177d781fa04SBarry Smith char *newformat = NULL; 17814416c0eSBarry Smith char formatbuf[PETSCDEFAULTBUFFERSIZE]; 179d781fa04SBarry Smith size_t newLength; 18014416c0eSBarry Smith int flen; 181e5c89e4eSSatish Balay 182eed5747fSBarry Smith PetscFunctionBegin; 1839566063dSJacob Faibussowitsch PetscCall(PetscFormatConvertGetSize(format, &newLength)); 18494217ebdSBarry Smith if (newLength < sizeof(formatbuf)) { 185e2135aedSMatthew Knepley newformat = formatbuf; 18694217ebdSBarry Smith newLength = sizeof(formatbuf) - 1; 187e2135aedSMatthew Knepley } else { 1889566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(newLength, &newformat)); 189e2135aedSMatthew Knepley } 1909566063dSJacob Faibussowitsch PetscCall(PetscFormatConvert(format, newformat)); 1917b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF) 192152b30f0SSatish Balay flen = vsnprintf(str, len, newformat, Argp); 193e5c89e4eSSatish Balay #else 19489b07760SSatish Balay #error "vsnprintf not found" 195e5c89e4eSSatish Balay #endif 19648a46eb9SPierre Jolivet if (newLength > sizeof(formatbuf) - 1) PetscCall(PetscFree(newformat)); 1978627564fSBarry Smith { 1988627564fSBarry Smith PetscBool foundedot; 1998627564fSBarry Smith size_t cnt = 0, ncnt = 0, leng; 2009566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 20117ca8410SBarry Smith if (leng > 4) { 2028627564fSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 2038627564fSBarry Smith if (str[cnt] == '[' && str[cnt + 1] == '|') { 204c540d043SBarry Smith flen -= 4; 2059371c9d4SSatish Balay cnt++; 2069371c9d4SSatish Balay cnt++; 2078627564fSBarry Smith foundedot = PETSC_FALSE; 2088627564fSBarry Smith for (; cnt < leng - 1; cnt++) { 2098627564fSBarry Smith if (str[cnt] == '|' && str[cnt + 1] == ']') { 2108627564fSBarry Smith cnt++; 2118627564fSBarry Smith if (!foundedot) str[ncnt++] = '.'; 2128627564fSBarry Smith ncnt--; 2138627564fSBarry Smith break; 2148627564fSBarry Smith } else { 2158627564fSBarry Smith if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 2168627564fSBarry Smith str[ncnt++] = str[cnt]; 2178627564fSBarry Smith } 2188627564fSBarry Smith } 2198627564fSBarry Smith } else { 2208627564fSBarry Smith str[ncnt] = str[cnt]; 2218627564fSBarry Smith } 2228627564fSBarry Smith ncnt++; 2238627564fSBarry Smith } 2248627564fSBarry Smith while (cnt < leng) { 2259371c9d4SSatish Balay str[ncnt] = str[cnt]; 2269371c9d4SSatish Balay ncnt++; 2279371c9d4SSatish Balay cnt++; 2288627564fSBarry Smith } 2298627564fSBarry Smith str[ncnt] = 0; 2308627564fSBarry Smith } 2318627564fSBarry Smith } 232748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 233e51f71cfSBarry Smith /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 234748e1b9dSBarry Smith { 235748e1b9dSBarry Smith size_t cnt = 0, ncnt = 0, leng; 2369566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 237748e1b9dSBarry Smith if (leng > 5) { 238748e1b9dSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 239e51f71cfSBarry 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') { 2409371c9d4SSatish Balay str[ncnt] = str[cnt]; 2419371c9d4SSatish Balay ncnt++; 2429371c9d4SSatish Balay cnt++; 2439371c9d4SSatish Balay str[ncnt] = str[cnt]; 2449371c9d4SSatish Balay ncnt++; 2459371c9d4SSatish Balay cnt++; 2469371c9d4SSatish Balay cnt++; 247e51f71cfSBarry Smith str[ncnt] = str[cnt]; 248748e1b9dSBarry Smith } else { 249748e1b9dSBarry Smith str[ncnt] = str[cnt]; 250748e1b9dSBarry Smith } 251748e1b9dSBarry Smith ncnt++; 252748e1b9dSBarry Smith } 253748e1b9dSBarry Smith while (cnt < leng) { 2549371c9d4SSatish Balay str[ncnt] = str[cnt]; 2559371c9d4SSatish Balay ncnt++; 2569371c9d4SSatish Balay cnt++; 257748e1b9dSBarry Smith } 258748e1b9dSBarry Smith str[ncnt] = 0; 259748e1b9dSBarry Smith } 260748e1b9dSBarry Smith } 261748e1b9dSBarry Smith #endif 262c540d043SBarry Smith if (fullLength) *fullLength = 1 + (size_t)flen; 2633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 264e5c89e4eSSatish Balay } 265e5c89e4eSSatish Balay 266c9a19010SBarry Smith /*@C 267c69effb2SJacob Faibussowitsch PetscFFlush - Flush a file stream 268c69effb2SJacob Faibussowitsch 269c69effb2SJacob Faibussowitsch Input Parameter: 270c69effb2SJacob Faibussowitsch . fd - The file stream handle 271c69effb2SJacob Faibussowitsch 272c69effb2SJacob Faibussowitsch Level: intermediate 273c69effb2SJacob Faibussowitsch 274c69effb2SJacob Faibussowitsch Notes: 275c69effb2SJacob Faibussowitsch For output streams (and for update streams on which the last operation was output), writes 276c69effb2SJacob Faibussowitsch any unwritten data from the stream's buffer to the associated output device. 277c69effb2SJacob Faibussowitsch 278c69effb2SJacob Faibussowitsch For input streams (and for update streams on which the last operation was input), the 279c69effb2SJacob Faibussowitsch behavior is undefined. 280c69effb2SJacob Faibussowitsch 281c69effb2SJacob Faibussowitsch If `fd` is `NULL`, all open output streams are flushed, including ones not directly 282c69effb2SJacob Faibussowitsch accessible to the program. 283c69effb2SJacob Faibussowitsch 284*cc4c1da9SBarry Smith Fortran Note: 285*cc4c1da9SBarry Smith Use `PetscFlush()` 286*cc4c1da9SBarry Smith 287c69effb2SJacob Faibussowitsch .seealso: `PetscPrintf()`, `PetscFPrintf()`, `PetscVFPrintf()`, `PetscVSNPrintf()` 288c69effb2SJacob Faibussowitsch @*/ 289c69effb2SJacob Faibussowitsch PetscErrorCode PetscFFlush(FILE *fd) 290c69effb2SJacob Faibussowitsch { 291c69effb2SJacob Faibussowitsch PetscFunctionBegin; 2924f572ea9SToby Isaac if (fd) PetscAssertPointer(fd, 1); 293c69effb2SJacob Faibussowitsch // could also use PetscCallExternal() here, but since we can get additional error explanation 294c69effb2SJacob Faibussowitsch // from strerror() we opted for a manual check 295bf31d2d3SBarry Smith PetscCheck(0 == fflush(fd), PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "Error in fflush() due to \"%s\"", strerror(errno)); 296c69effb2SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 297c69effb2SJacob Faibussowitsch } 298c69effb2SJacob Faibussowitsch 299c69effb2SJacob Faibussowitsch /*@C 300aec76313SJacob Faibussowitsch PetscVFPrintfDefault - All PETSc standard out and error messages are sent through this function; so, in theory, this can 301e5c89e4eSSatish Balay can be replaced with something that does not simply write to a file. 302e5c89e4eSSatish Balay 303*cc4c1da9SBarry Smith No Fortran Support 304*cc4c1da9SBarry Smith 30510450e9eSJacob Faibussowitsch Input Parameters: 30610450e9eSJacob Faibussowitsch + fd - the file descriptor to write to 30710450e9eSJacob Faibussowitsch . format - the format string to write with 30810450e9eSJacob Faibussowitsch - Argp - the variable argument list of items to format and write 30910450e9eSJacob Faibussowitsch 31010450e9eSJacob Faibussowitsch Level: developer 31110450e9eSJacob Faibussowitsch 31210450e9eSJacob Faibussowitsch Note: 31310450e9eSJacob Faibussowitsch For error messages this may be called by any MPI process, for regular standard out it is 31410450e9eSJacob Faibussowitsch called only by MPI rank 0 of a given communicator 31510450e9eSJacob Faibussowitsch 31610450e9eSJacob Faibussowitsch Example Usage: 317c9a19010SBarry Smith To use, write your own function for example, 318058c9ee1SBarry Smith .vb 319058c9ee1SBarry Smith PetscErrorCode mypetscvfprintf(FILE *fd, const char format[], va_list Argp) 320058c9ee1SBarry Smith { 321058c9ee1SBarry Smith PetscErrorCode ierr; 322058c9ee1SBarry Smith 323058c9ee1SBarry Smith PetscFunctionBegin; 324058c9ee1SBarry Smith if (fd != stdout && fd != stderr) { handle regular files 325058c9ee1SBarry Smith CHKERR(PetscVFPrintfDefault(fd,format,Argp)); 326058c9ee1SBarry Smith } else { 327058c9ee1SBarry Smith char buff[BIG]; 328058c9ee1SBarry Smith size_t length; 329058c9ee1SBarry Smith PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp)); 330058c9ee1SBarry Smith now send buff to whatever stream or whatever you want 331058c9ee1SBarry Smith } 332058c9ee1SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 333058c9ee1SBarry Smith } 334058c9ee1SBarry Smith .ve 335058c9ee1SBarry Smith then before the call to `PetscInitialize()` do the assignment `PetscVFPrintf = mypetscvfprintf`; 336058c9ee1SBarry Smith 337aec76313SJacob Faibussowitsch Developer Notes: 338058c9ee1SBarry Smith This could be called by an error handler, if that happens then a recursion of the error handler may occur 339058c9ee1SBarry Smith and a resulting crash 340c9a19010SBarry Smith 341c69effb2SJacob Faibussowitsch .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscFFlush()` 342c9a19010SBarry Smith @*/ 343*cc4c1da9SBarry Smith PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char format[], va_list Argp) 344d71ae5a4SJacob Faibussowitsch { 34514416c0eSBarry Smith char str[PETSCDEFAULTBUFFERSIZE]; 34614416c0eSBarry Smith char *buff = str; 34714416c0eSBarry Smith size_t fullLength; 3481531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 34914416c0eSBarry Smith va_list Argpcopy; 3501531940fSBarry Smith #endif 3511179db26SBarry Smith 352eed5747fSBarry Smith PetscFunctionBegin; 3531531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 35414416c0eSBarry Smith va_copy(Argpcopy, Argp); 3551531940fSBarry Smith #endif 3569566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp)); 35714416c0eSBarry Smith if (fullLength > sizeof(str)) { 3589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fullLength, &buff)); 3591531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 3609566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy)); 3611531940fSBarry Smith #else 3621531940fSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines"); 3631531940fSBarry Smith #endif 36414416c0eSBarry Smith } 365eae3dc7dSJacob Faibussowitsch #if defined(PETSC_HAVE_VA_COPY) 366eae3dc7dSJacob Faibussowitsch va_end(Argpcopy); 367eae3dc7dSJacob Faibussowitsch #endif 368c69effb2SJacob Faibussowitsch { 3698c0ebe3fSBarry Smith int err; 3708c0ebe3fSBarry Smith 3718c0ebe3fSBarry Smith // POSIX C sets errno but otherwise it may not be set for *printf() system calls 3728c0ebe3fSBarry Smith // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html 3738c0ebe3fSBarry Smith errno = 0; 3748c0ebe3fSBarry Smith err = fprintf(fd, "%s", buff); 375c69effb2SJacob Faibussowitsch // cannot use PetscCallExternal() for fprintf since the return value is "number of 376c69effb2SJacob Faibussowitsch // characters transmitted to the output stream" on success 3778c0ebe3fSBarry 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)"); 378c69effb2SJacob Faibussowitsch } 379c69effb2SJacob Faibussowitsch PetscCall(PetscFFlush(fd)); 38048a46eb9SPierre Jolivet if (buff != str) PetscCall(PetscFree(buff)); 3813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 382e5c89e4eSSatish Balay } 383e5c89e4eSSatish Balay 3845b5bc046SBarry Smith /*@C 3855b5bc046SBarry Smith PetscSNPrintf - Prints to a string of given length 3865b5bc046SBarry Smith 387*cc4c1da9SBarry Smith Not Collective, No Fortran Support 3885b5bc046SBarry Smith 3895b5bc046SBarry Smith Input Parameters: 39021532e8aSBarry Smith + len - the length of `str` 39110450e9eSJacob Faibussowitsch - format - the usual `printf()` format string 3925b5bc046SBarry Smith 39321532e8aSBarry Smith Output Parameter: 39421532e8aSBarry Smith . str - the resulting string 39521532e8aSBarry Smith 3965b5bc046SBarry Smith Level: intermediate 3975b5bc046SBarry Smith 398db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 399c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 400c69effb2SJacob Faibussowitsch `PetscVFPrintf()`, `PetscFFlush()` 4015b5bc046SBarry Smith @*/ 402*cc4c1da9SBarry Smith PetscErrorCode PetscSNPrintf(char str[], size_t len, const char format[], ...) 403d71ae5a4SJacob Faibussowitsch { 404c9a19010SBarry Smith size_t fullLength; 4055b5bc046SBarry Smith va_list Argp; 4065b5bc046SBarry Smith 4075b5bc046SBarry Smith PetscFunctionBegin; 4085b5bc046SBarry Smith va_start(Argp, format); 4099566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp)); 410eae3dc7dSJacob Faibussowitsch va_end(Argp); 4113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4125b5bc046SBarry Smith } 4135b5bc046SBarry Smith 414257d2499SJed Brown /*@C 415058c9ee1SBarry Smith PetscSNPrintfCount - Prints to a string of given length, returns count of characters printed 416257d2499SJed Brown 417*cc4c1da9SBarry Smith Not Collective, No Fortran Support 418257d2499SJed Brown 419257d2499SJed Brown Input Parameters: 42021532e8aSBarry Smith + len - the length of `str` 421058c9ee1SBarry Smith . format - the usual `printf()` format string 42210450e9eSJacob Faibussowitsch - ... - args to format 423257d2499SJed Brown 42421532e8aSBarry Smith Output Parameters: 42521532e8aSBarry Smith + str - the resulting string 42621532e8aSBarry Smith - countused - number of characters printed 427cb398dd3SBarry Smith 428257d2499SJed Brown Level: intermediate 429257d2499SJed Brown 430db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 431db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()` 432257d2499SJed Brown @*/ 433*cc4c1da9SBarry Smith PetscErrorCode PetscSNPrintfCount(char str[], size_t len, const char format[], size_t *countused, ...) 434d71ae5a4SJacob Faibussowitsch { 435257d2499SJed Brown va_list Argp; 436257d2499SJed Brown 437257d2499SJed Brown PetscFunctionBegin; 438257d2499SJed Brown va_start(Argp, countused); 4399566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, countused, Argp)); 440eae3dc7dSJacob Faibussowitsch va_end(Argp); 4413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 442257d2499SJed Brown } 443257d2499SJed Brown 44402c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL; 445d30b0576SJed Brown int petsc_printfqueuelength = 0; 446e5c89e4eSSatish Balay 4478c509928SStefano Zampini static inline PetscErrorCode PetscVFPrintf_Private(FILE *fd, const char format[], va_list Argp) 448eae3dc7dSJacob Faibussowitsch { 449eae3dc7dSJacob Faibussowitsch const PetscBool tee = (PetscBool)(petsc_history && (fd != petsc_history)); 450eae3dc7dSJacob Faibussowitsch va_list cpy; 451eae3dc7dSJacob Faibussowitsch 452eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 453eae3dc7dSJacob Faibussowitsch // must do this before we possibly consume Argp 454eae3dc7dSJacob Faibussowitsch if (tee) va_copy(cpy, Argp); 455eae3dc7dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fd, format, Argp)); 456eae3dc7dSJacob Faibussowitsch if (tee) { 457eae3dc7dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, cpy)); 458eae3dc7dSJacob Faibussowitsch va_end(cpy); 459eae3dc7dSJacob Faibussowitsch } 460eae3dc7dSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 461eae3dc7dSJacob Faibussowitsch } 462eae3dc7dSJacob Faibussowitsch 4638c509928SStefano Zampini PETSC_INTERN PetscErrorCode PetscVFPrintf_Internal(FILE *fd, const char format[], ...) 4648c509928SStefano Zampini { 4658c509928SStefano Zampini va_list Argp; 4668c509928SStefano Zampini 4678c509928SStefano Zampini PetscFunctionBegin; 4688c509928SStefano Zampini va_start(Argp, format); 4698c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(fd, format, Argp)); 4708c509928SStefano Zampini va_end(Argp); 4718c509928SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 4728c509928SStefano Zampini } 4738c509928SStefano Zampini 474eae3dc7dSJacob Faibussowitsch static inline PetscErrorCode PetscSynchronizedFPrintf_Private(MPI_Comm comm, FILE *fp, const char format[], va_list Argp) 475eae3dc7dSJacob Faibussowitsch { 476eae3dc7dSJacob Faibussowitsch PetscMPIInt rank; 477eae3dc7dSJacob Faibussowitsch va_list cpy; 478eae3dc7dSJacob Faibussowitsch 479eae3dc7dSJacob Faibussowitsch PetscFunctionBegin; 480eae3dc7dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 481eae3dc7dSJacob Faibussowitsch /* First processor prints immediately to fp */ 482eae3dc7dSJacob Faibussowitsch if (rank == 0) { 483eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 4848c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(fp, format, cpy)); 485eae3dc7dSJacob Faibussowitsch va_end(cpy); 486eae3dc7dSJacob Faibussowitsch } else { /* other processors add to local queue */ 487eae3dc7dSJacob Faibussowitsch PrintfQueue next; 488eae3dc7dSJacob Faibussowitsch size_t fullLength = PETSCDEFAULTBUFFERSIZE; 489eae3dc7dSJacob Faibussowitsch 490eae3dc7dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 491eae3dc7dSJacob Faibussowitsch if (petsc_printfqueue) { 492eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = next; 493eae3dc7dSJacob Faibussowitsch petsc_printfqueue = next; 494eae3dc7dSJacob Faibussowitsch petsc_printfqueue->next = NULL; 495eae3dc7dSJacob Faibussowitsch } else petsc_printfqueuebase = petsc_printfqueue = next; 496eae3dc7dSJacob Faibussowitsch petsc_printfqueuelength++; 497eae3dc7dSJacob Faibussowitsch next->size = 0; 498eae3dc7dSJacob Faibussowitsch next->string = NULL; 499eae3dc7dSJacob Faibussowitsch while (fullLength >= next->size) { 500eae3dc7dSJacob Faibussowitsch next->size = fullLength + 1; 501eae3dc7dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 502eae3dc7dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 503eae3dc7dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, next->size)); 504eae3dc7dSJacob Faibussowitsch va_copy(cpy, Argp); 505eae3dc7dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, cpy)); 506eae3dc7dSJacob Faibussowitsch va_end(cpy); 507eae3dc7dSJacob Faibussowitsch } 508eae3dc7dSJacob Faibussowitsch } 509eae3dc7dSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 510eae3dc7dSJacob Faibussowitsch } 511eae3dc7dSJacob Faibussowitsch 512e5c89e4eSSatish Balay /*@C 5139c89aa79SPierre Jolivet PetscSynchronizedPrintf - Prints synchronized output from multiple MPI processes. 514e5c89e4eSSatish Balay Output of the first processor is followed by that of the second, etc. 515e5c89e4eSSatish Balay 516e5c89e4eSSatish Balay Not Collective 517e5c89e4eSSatish Balay 518e5c89e4eSSatish Balay Input Parameters: 519058c9ee1SBarry Smith + comm - the MPI communicator 5206026c97aSBarry Smith - format - the usual `printf()` format string 521e5c89e4eSSatish Balay 522e5c89e4eSSatish Balay Level: intermediate 523e5c89e4eSSatish Balay 524811af0c4SBarry Smith Note: 525811af0c4SBarry Smith REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information 526e5c89e4eSSatish Balay from all the processors to be printed. 527e5c89e4eSSatish Balay 528*cc4c1da9SBarry Smith Fortran Note: 529058c9ee1SBarry Smith The call sequence is `PetscSynchronizedPrintf`(`MPI_Comm`, `character`(*), `PetscErrorCode` ierr). 530e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 531e5c89e4eSSatish Balay 532db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, 533c69effb2SJacob Faibussowitsch `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, 534c69effb2SJacob Faibussowitsch `PetscFFlush()` 535e5c89e4eSSatish Balay @*/ 536d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...) 537d71ae5a4SJacob Faibussowitsch { 538eae3dc7dSJacob Faibussowitsch va_list Argp; 539e5c89e4eSSatish Balay 540e5c89e4eSSatish Balay PetscFunctionBegin; 541e5c89e4eSSatish Balay va_start(Argp, format); 542eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, PETSC_STDOUT, format, Argp)); 543e5c89e4eSSatish Balay va_end(Argp); 5443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 545e5c89e4eSSatish Balay } 546e5c89e4eSSatish Balay 547e5c89e4eSSatish Balay /*@C 548e5c89e4eSSatish Balay PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 54921532e8aSBarry Smith several MPI processes. Output of the first process is followed by that of the 550e5c89e4eSSatish Balay second, etc. 551e5c89e4eSSatish Balay 552e5c89e4eSSatish Balay Not Collective 553e5c89e4eSSatish Balay 554e5c89e4eSSatish Balay Input Parameters: 555058c9ee1SBarry Smith + comm - the MPI communicator 556*cc4c1da9SBarry Smith . fp - the file pointer, `PETSC_STDOUT` or value obtained from `PetscFOpen()` 5576026c97aSBarry Smith - format - the usual `printf()` format string 558e5c89e4eSSatish Balay 559e5c89e4eSSatish Balay Level: intermediate 560e5c89e4eSSatish Balay 561811af0c4SBarry Smith Note: 562811af0c4SBarry Smith REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information 563e5c89e4eSSatish Balay from all the processors to be printed. 564e5c89e4eSSatish Balay 565*cc4c1da9SBarry Smith Fortran Note: 566*cc4c1da9SBarry Smith The call sequence is `PetscSynchronizedPrintf`(`MPI_Comm`, fp, `character`(*), `PetscErrorCode` ierr). 567*cc4c1da9SBarry Smith That is, you can only pass a single character string from Fortran. 568*cc4c1da9SBarry Smith 569db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`, 570c69effb2SJacob Faibussowitsch `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 571c69effb2SJacob Faibussowitsch `PetscFFlush()` 572e5c89e4eSSatish Balay @*/ 573d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...) 574d71ae5a4SJacob Faibussowitsch { 575eae3dc7dSJacob Faibussowitsch va_list Argp; 576e5c89e4eSSatish Balay 577e5c89e4eSSatish Balay PetscFunctionBegin; 578e5c89e4eSSatish Balay va_start(Argp, format); 579eae3dc7dSJacob Faibussowitsch PetscCall(PetscSynchronizedFPrintf_Private(comm, fp, format, Argp)); 580e5c89e4eSSatish Balay va_end(Argp); 5813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 582e5c89e4eSSatish Balay } 583e5c89e4eSSatish Balay 5840ec8b6e3SBarry Smith /*@C 585e5c89e4eSSatish Balay PetscSynchronizedFlush - Flushes to the screen output from all processors 586811af0c4SBarry Smith involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls. 587e5c89e4eSSatish Balay 588d083f849SBarry Smith Collective 589e5c89e4eSSatish Balay 590e5c89e4eSSatish Balay Input Parameters: 591058c9ee1SBarry Smith + comm - the MPI communicator 592a3b724e8SBarry Smith - fd - the file pointer (valid on MPI rank 0 of the communicator), `PETSC_STDOUT` or value obtained from `PetscFOpen()` 593e5c89e4eSSatish Balay 594e5c89e4eSSatish Balay Level: intermediate 595e5c89e4eSSatish Balay 596811af0c4SBarry Smith Note: 597811af0c4SBarry Smith If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with 598811af0c4SBarry Smith different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators. 599e5c89e4eSSatish Balay 600db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`, 601db781477SPatrick Sanan `PetscViewerASCIISynchronizedPrintf()` 6020087d953SMatthew G. Knepley @*/ 603d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd) 604d71ae5a4SJacob Faibussowitsch { 60529a5cbdcSMatthew G. Knepley PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0; 6062d609e63SMatthew Knepley char *message; 607e5c89e4eSSatish Balay MPI_Status status; 608e5c89e4eSSatish Balay 609e5c89e4eSSatish Balay PetscFunctionBegin; 6109566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(comm, &comm, &tag)); 6119566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 613e5c89e4eSSatish Balay 614e5c89e4eSSatish Balay /* First processor waits for messages from all other processors */ 615dd400576SPatrick Sanan if (rank == 0) { 6160ec8b6e3SBarry Smith if (!fd) fd = PETSC_STDOUT; 617e5c89e4eSSatish Balay for (i = 1; i < size; i++) { 6189f73f8ecSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 6199566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm)); 6209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status)); 621e5c89e4eSSatish Balay for (j = 0; j < n; j++) { 62229a5cbdcSMatthew G. Knepley PetscMPIInt size = 0; 6232d609e63SMatthew Knepley 6249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status)); 6259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &message)); 6269566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status)); 6279566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, "%s", message)); 6289566063dSJacob Faibussowitsch PetscCall(PetscFree(message)); 629e5c89e4eSSatish Balay } 630e5c89e4eSSatish Balay } 631e5c89e4eSSatish Balay } else { /* other processors send queue to processor 0 */ 632d30b0576SJed Brown PrintfQueue next = petsc_printfqueuebase, previous; 633e5c89e4eSSatish Balay 6349566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status)); 6359566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm)); 636d30b0576SJed Brown for (i = 0; i < petsc_printfqueuelength; i++) { 6379566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm)); 6389566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm)); 639e5c89e4eSSatish Balay previous = next; 640e5c89e4eSSatish Balay next = next->next; 6419566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 6429566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 643e5c89e4eSSatish Balay } 64402c9f0b5SLisandro Dalcin petsc_printfqueue = NULL; 645d30b0576SJed Brown petsc_printfqueuelength = 0; 646e5c89e4eSSatish Balay } 6479566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&comm)); 6483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 649e5c89e4eSSatish Balay } 650e5c89e4eSSatish Balay 651e5c89e4eSSatish Balay /*@C 652e5c89e4eSSatish Balay PetscFPrintf - Prints to a file, only from the first 65321532e8aSBarry Smith MPI process in the communicator. 654e5c89e4eSSatish Balay 655*cc4c1da9SBarry Smith Not Collective 656e5c89e4eSSatish Balay 657e5c89e4eSSatish Balay Input Parameters: 658058c9ee1SBarry Smith + comm - the MPI communicator 659*cc4c1da9SBarry Smith . fd - the file pointer, `PETSC_STDOUT` or value obtained from `PetscFOpen()` 6606026c97aSBarry Smith - format - the usual `printf()` format string 661e5c89e4eSSatish Balay 662e5c89e4eSSatish Balay Level: intermediate 663e5c89e4eSSatish Balay 664*cc4c1da9SBarry Smith Fortran Note: 665*cc4c1da9SBarry Smith The call sequence is `PetscFPrintf`(`MPI_Comm`, fp, `character`(*), `PetscErrorCode` ierr). 666*cc4c1da9SBarry Smith That is, you can only pass a single character string from Fortran. 667*cc4c1da9SBarry Smith 668aec76313SJacob Faibussowitsch Developer Notes: 669058c9ee1SBarry Smith This maybe, and is, called from PETSc error handlers and `PetscMallocValidate()` hence it does not use `PetscCallMPI()` which 670058c9ee1SBarry Smith could recursively restart the malloc validation. 671058c9ee1SBarry Smith 672db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 673c69effb2SJacob Faibussowitsch `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFFlush()` 674e5c89e4eSSatish Balay @*/ 675d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...) 676d71ae5a4SJacob Faibussowitsch { 6778c509928SStefano Zampini PetscMPIInt rank; 678eae3dc7dSJacob Faibussowitsch va_list Argp; 679e5c89e4eSSatish Balay 680e5c89e4eSSatish Balay PetscFunctionBegin; 6818c509928SStefano Zampini PetscCallMPI(MPI_Comm_rank(comm, &rank)); 6828c509928SStefano Zampini if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS); 683e5c89e4eSSatish Balay va_start(Argp, format); 6848c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(fd, format, Argp)); 685e5c89e4eSSatish Balay va_end(Argp); 6863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 687e5c89e4eSSatish Balay } 688e5c89e4eSSatish Balay 689e5c89e4eSSatish Balay /*@C 690e5c89e4eSSatish Balay PetscPrintf - Prints to standard out, only from the first 69121532e8aSBarry Smith MPI process in the communicator. Calls from other processes are ignored. 692e5c89e4eSSatish Balay 693e5c89e4eSSatish Balay Not Collective 694e5c89e4eSSatish Balay 695e5c89e4eSSatish Balay Input Parameters: 696e5c89e4eSSatish Balay + comm - the communicator 697bfbbc7b7SBarry Smith - format - the usual `printf()` format string 698e5c89e4eSSatish Balay 699e5c89e4eSSatish Balay Level: intermediate 700e5c89e4eSSatish Balay 701811af0c4SBarry Smith Note: 702811af0c4SBarry Smith Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc. 703811af0c4SBarry Smith See the manual page for `PetscFormatConvert()` for details. 704b2706f25SRichard Tran Mills 705aec76313SJacob Faibussowitsch Fortran Notes: 706811af0c4SBarry Smith The call sequence is `PetscPrintf`(MPI_Comm, character(*), `PetscErrorCode` ierr) from Fortran. 707e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 708e5c89e4eSSatish Balay 709c69effb2SJacob Faibussowitsch .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()`, `PetscFFlush()` 710e5c89e4eSSatish Balay @*/ 711d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...) 712d71ae5a4SJacob Faibussowitsch { 7138c509928SStefano Zampini PetscMPIInt rank; 714eae3dc7dSJacob Faibussowitsch va_list Argp; 715e5c89e4eSSatish Balay 716e5c89e4eSSatish Balay PetscFunctionBegin; 7178c509928SStefano Zampini PetscCallMPI(MPI_Comm_rank(comm, &rank)); 7188c509928SStefano Zampini if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS); 719e5c89e4eSSatish Balay va_start(Argp, format); 7208c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(PETSC_STDOUT, format, Argp)); 721e5c89e4eSSatish Balay va_end(Argp); 7223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 723e5c89e4eSSatish Balay } 724e5c89e4eSSatish Balay 725d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...) 726d71ae5a4SJacob Faibussowitsch { 7278c509928SStefano Zampini PetscMPIInt rank; 728eae3dc7dSJacob Faibussowitsch va_list Argp; 729e5c89e4eSSatish Balay 730e5c89e4eSSatish Balay PetscFunctionBegin; 7318c509928SStefano Zampini PetscCallMPI(MPI_Comm_rank(comm, &rank)); 7328c509928SStefano Zampini if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS); 733e5c89e4eSSatish Balay va_start(Argp, format); 7348c509928SStefano Zampini PetscCall(PetscVFPrintf_Private(PETSC_STDOUT, format, Argp)); 735e5c89e4eSSatish Balay va_end(Argp); 7363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 737e5c89e4eSSatish Balay } 738e5c89e4eSSatish Balay 739e5c89e4eSSatish Balay /*@C 74021532e8aSBarry Smith PetscSynchronizedFGets - Multiple MPI processes all get the same line from a file. 741e5c89e4eSSatish Balay 742d083f849SBarry Smith Collective 743e5c89e4eSSatish Balay 744e5c89e4eSSatish Balay Input Parameters: 74521532e8aSBarry Smith + comm - the MPI communicator 746aec76313SJacob Faibussowitsch . fp - the file pointer 74721532e8aSBarry Smith - len - the length of `string` 748e5c89e4eSSatish Balay 749e5c89e4eSSatish Balay Output Parameter: 75021532e8aSBarry Smith . string - the line read from the file, at end of file `string`[0] == 0 751e5c89e4eSSatish Balay 752e5c89e4eSSatish Balay Level: intermediate 753e5c89e4eSSatish Balay 754db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, 755db781477SPatrick Sanan `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()` 756e5c89e4eSSatish Balay @*/ 757d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm, FILE *fp, size_t len, char string[]) 758d71ae5a4SJacob Faibussowitsch { 759e5c89e4eSSatish Balay PetscMPIInt rank; 760e5c89e4eSSatish Balay 761e5c89e4eSSatish Balay PetscFunctionBegin; 7629566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 76380971c97SJames Wright if (rank == 0) { 764eae3dc7dSJacob Faibussowitsch if (!fgets(string, len, fp)) { 765e31d4fa4SJed Brown string[0] = 0; 766bf31d2d3SBarry Smith PetscCheck(feof(fp), PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file due to \"%s\"", strerror(errno)); 767047b9c12SMatthew G Knepley } 768238ccf28SShri Abhyankar } 7699566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(string, len, MPI_BYTE, 0, comm)); 7703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 771e5c89e4eSSatish Balay } 772238ccf28SShri Abhyankar 773d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[]) 774d71ae5a4SJacob Faibussowitsch { 7751b5687a1SBarry Smith PetscInt i; 7761b5687a1SBarry Smith size_t left, count; 7771b5687a1SBarry Smith char *p; 7781b5687a1SBarry Smith 7791b5687a1SBarry Smith PetscFunctionBegin; 7801b5687a1SBarry Smith for (i = 0, p = buf, left = len; i < n; i++) { 7819566063dSJacob Faibussowitsch PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i])); 78208401ef6SPierre Jolivet PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer"); 7831b5687a1SBarry Smith left -= count; 7841b5687a1SBarry Smith p += count - 1; 7851b5687a1SBarry Smith *p++ = ' '; 7861b5687a1SBarry Smith } 7871b5687a1SBarry Smith p[i ? 0 : -1] = 0; 7883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7891b5687a1SBarry Smith } 790