1e5c89e4eSSatish Balay /* 2e5c89e4eSSatish Balay Utilites routines to add simple ASCII IO capability. 3e5c89e4eSSatish Balay */ 4c6db04a5SJed Brown #include <../src/sys/fileio/mprint.h> 579c0e996SJed Brown #include <errno.h> 6e5c89e4eSSatish Balay /* 7e5c89e4eSSatish Balay If petsc_history is on, then all Petsc*Printf() results are saved 8e5c89e4eSSatish Balay if the appropriate (usually .petschistory) file. 9e5c89e4eSSatish Balay */ 1095c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history; 11e5c89e4eSSatish Balay /* 12e5c89e4eSSatish Balay Allows one to overwrite where standard out is sent. For example 135106ddf5SBarry Smith PETSC_STDOUT = fopen("/dev/ttyXX","w") will cause all standard out 14e5c89e4eSSatish Balay writes to go to terminal XX; assuming you have write permission there 15e5c89e4eSSatish Balay */ 1602c9f0b5SLisandro Dalcin FILE *PETSC_STDOUT = NULL; 17ae9b4142SLisandro Dalcin /* 18ae9b4142SLisandro Dalcin Allows one to overwrite where standard error is sent. For example 19ae9b4142SLisandro Dalcin PETSC_STDERR = fopen("/dev/ttyXX","w") will cause all standard error 20ae9b4142SLisandro Dalcin writes to go to terminal XX; assuming you have write permission there 21ae9b4142SLisandro Dalcin */ 2202c9f0b5SLisandro Dalcin FILE *PETSC_STDERR = NULL; 23b13499bfSbcordonn 24c9a19010SBarry Smith /*@C 25811af0c4SBarry Smith PetscFormatConvertGetSize - Gets the length of a string needed to hold format converted with `PetscFormatConvert()` 26811af0c4SBarry Smith 27811af0c4SBarry Smith Deprecated 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*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvertGetSize(const char *format, size_t *size) 40*d71ae5a4SJacob 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) 61*d71ae5a4SJacob Faibussowitsch case 'D': 62*d71ae5a4SJacob Faibussowitsch sz += 2; 63*d71ae5a4SJacob Faibussowitsch break; 64d781fa04SBarry Smith #endif 65*d71ae5a4SJacob Faibussowitsch case 'g': 66*d71ae5a4SJacob Faibussowitsch sz += 4; 67*d71ae5a4SJacob Faibussowitsch default: 68*d71ae5a4SJacob Faibussowitsch break; 69d781fa04SBarry Smith } 70d781fa04SBarry Smith } 713ca90d2dSJacob Faibussowitsch ++i; 723ca90d2dSJacob Faibussowitsch ++sz; 73d781fa04SBarry Smith } 743ca90d2dSJacob Faibussowitsch *size = sz + 1; /* space for NULL character */ 75d781fa04SBarry Smith PetscFunctionReturn(0); 76d781fa04SBarry Smith } 77d781fa04SBarry Smith 78d781fa04SBarry Smith /*@C 79d781fa04SBarry Smith PetscFormatConvert - Takes a PETSc format string and converts the %D to %d for 32 bit PETSc indices and %lld for 64 bit PETSc indices. Also 80d781fa04SBarry Smith converts %g to [|%g|] so that PetscVSNPrintf() can easily insure all %g formatted numbers have a decimal point when printed. 81d781fa04SBarry Smith 82811af0c4SBarry Smith Deprecated 83811af0c4SBarry Smith 84d781fa04SBarry Smith Input Parameters: 85d781fa04SBarry Smith + format - the PETSc format string 86d781fa04SBarry Smith . newformat - the location to put the new format 87811af0c4SBarry Smith - size - the length of newformat, you can use `PetscFormatConvertGetSize()` to compute the needed size 88d781fa04SBarry Smith 89811af0c4SBarry Smith Note: this exists so we can have the same code when `PetscInt` is either int or long long int 90d781fa04SBarry Smith 91d781fa04SBarry Smith Level: developer 92d781fa04SBarry Smith 93db781477SPatrick Sanan .seealso: `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscVFPrintf()` 94d781fa04SBarry Smith @*/ 95*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvert(const char *format, char *newformat) 96*d71ae5a4SJacob Faibussowitsch { 97e5c89e4eSSatish Balay PetscInt i = 0, j = 0; 98e5c89e4eSSatish Balay 99eed5747fSBarry Smith PetscFunctionBegin; 100d781fa04SBarry Smith while (format[i]) { 1012a1ad9caSBarry Smith if (format[i] == '%' && format[i + 1] == '%') { 1022a1ad9caSBarry Smith newformat[j++] = format[i++]; 1032a1ad9caSBarry Smith newformat[j++] = format[i++]; 1042a1ad9caSBarry Smith } else if (format[i] == '%') { 1058627564fSBarry Smith if (format[i + 1] == 'g') { 1068627564fSBarry Smith newformat[j++] = '['; 1078627564fSBarry Smith newformat[j++] = '|'; 1088627564fSBarry Smith } 1097bc47156SJose Roman /* Find the letter */ 1107bc47156SJose Roman for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 1117bc47156SJose Roman switch (format[i]) { 1127bc47156SJose Roman case 'D': 1136de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 114e5c89e4eSSatish Balay newformat[j++] = 'd'; 115e5c89e4eSSatish Balay #else 116e5c89e4eSSatish Balay newformat[j++] = 'l'; 117e5c89e4eSSatish Balay newformat[j++] = 'l'; 118e5c89e4eSSatish Balay newformat[j++] = 'd'; 119e5c89e4eSSatish Balay #endif 1207bc47156SJose Roman break; 1218627564fSBarry Smith case 'g': 1228627564fSBarry Smith newformat[j++] = format[i]; 1238627564fSBarry Smith if (format[i - 1] == '%') { 1248627564fSBarry Smith newformat[j++] = '|'; 1258627564fSBarry Smith newformat[j++] = ']'; 1268627564fSBarry Smith } 1278627564fSBarry Smith break; 128*d71ae5a4SJacob Faibussowitsch case 'G': 129*d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%G format is no longer supported, use %%g and cast the argument to double"); 130*d71ae5a4SJacob Faibussowitsch case 'F': 131*d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%F format is no longer supported, use %%f and cast the argument to double"); 132*d71ae5a4SJacob Faibussowitsch default: 133*d71ae5a4SJacob Faibussowitsch newformat[j++] = format[i]; 134*d71ae5a4SJacob Faibussowitsch break; 1357bc47156SJose Roman } 1367bc47156SJose Roman i++; 137a297a907SKarl Rupp } else newformat[j++] = format[i++]; 138e5c89e4eSSatish Balay } 139e5c89e4eSSatish Balay newformat[j] = 0; 140eed5747fSBarry Smith PetscFunctionReturn(0); 141e5c89e4eSSatish Balay } 142e5c89e4eSSatish Balay 14314416c0eSBarry Smith #define PETSCDEFAULTBUFFERSIZE 8 * 1024 144d781fa04SBarry Smith 145c9a19010SBarry Smith /*@C 146c9a19010SBarry Smith PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 147c9a19010SBarry Smith function arguments into a string using the format statement. 148c9a19010SBarry Smith 149c9a19010SBarry Smith Input Parameters: 150c9a19010SBarry Smith + str - location to put result 151c9a19010SBarry Smith . len - the amount of space in str 152c9a19010SBarry Smith + format - the PETSc format string 153c9a19010SBarry Smith - fullLength - the amount of space in str actually used. 154c9a19010SBarry Smith 155811af0c4SBarry Smith Developer Note: 15695452b02SPatrick Sanan this function may be called from an error handler, if an error occurs when it is called by the error handler than likely 157eed5747fSBarry Smith a recursion will occur and possible crash. 158c9a19010SBarry Smith 159c9a19010SBarry Smith Level: developer 160c9a19010SBarry Smith 161db781477SPatrick Sanan .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscVPrintf()` 162c9a19010SBarry Smith @*/ 163*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVSNPrintf(char *str, size_t len, const char *format, size_t *fullLength, va_list Argp) 164*d71ae5a4SJacob Faibussowitsch { 165d781fa04SBarry Smith char *newformat = NULL; 16614416c0eSBarry Smith char formatbuf[PETSCDEFAULTBUFFERSIZE]; 167d781fa04SBarry Smith size_t newLength; 16814416c0eSBarry Smith int flen; 169e5c89e4eSSatish Balay 170eed5747fSBarry Smith PetscFunctionBegin; 1719566063dSJacob Faibussowitsch PetscCall(PetscFormatConvertGetSize(format, &newLength)); 17294217ebdSBarry Smith if (newLength < sizeof(formatbuf)) { 173e2135aedSMatthew Knepley newformat = formatbuf; 17494217ebdSBarry Smith newLength = sizeof(formatbuf) - 1; 175e2135aedSMatthew Knepley } else { 1769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(newLength, &newformat)); 177e2135aedSMatthew Knepley } 1789566063dSJacob Faibussowitsch PetscCall(PetscFormatConvert(format, newformat)); 1797b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF) 180152b30f0SSatish Balay flen = vsnprintf(str, len, newformat, Argp); 181e5c89e4eSSatish Balay #else 18289b07760SSatish Balay #error "vsnprintf not found" 183e5c89e4eSSatish Balay #endif 18448a46eb9SPierre Jolivet if (newLength > sizeof(formatbuf) - 1) PetscCall(PetscFree(newformat)); 1858627564fSBarry Smith { 1868627564fSBarry Smith PetscBool foundedot; 1878627564fSBarry Smith size_t cnt = 0, ncnt = 0, leng; 1889566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 18917ca8410SBarry Smith if (leng > 4) { 1908627564fSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 1918627564fSBarry Smith if (str[cnt] == '[' && str[cnt + 1] == '|') { 192c540d043SBarry Smith flen -= 4; 1939371c9d4SSatish Balay cnt++; 1949371c9d4SSatish Balay cnt++; 1958627564fSBarry Smith foundedot = PETSC_FALSE; 1968627564fSBarry Smith for (; cnt < leng - 1; cnt++) { 1978627564fSBarry Smith if (str[cnt] == '|' && str[cnt + 1] == ']') { 1988627564fSBarry Smith cnt++; 1998627564fSBarry Smith if (!foundedot) str[ncnt++] = '.'; 2008627564fSBarry Smith ncnt--; 2018627564fSBarry Smith break; 2028627564fSBarry Smith } else { 2038627564fSBarry Smith if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 2048627564fSBarry Smith str[ncnt++] = str[cnt]; 2058627564fSBarry Smith } 2068627564fSBarry Smith } 2078627564fSBarry Smith } else { 2088627564fSBarry Smith str[ncnt] = str[cnt]; 2098627564fSBarry Smith } 2108627564fSBarry Smith ncnt++; 2118627564fSBarry Smith } 2128627564fSBarry Smith while (cnt < leng) { 2139371c9d4SSatish Balay str[ncnt] = str[cnt]; 2149371c9d4SSatish Balay ncnt++; 2159371c9d4SSatish Balay cnt++; 2168627564fSBarry Smith } 2178627564fSBarry Smith str[ncnt] = 0; 2188627564fSBarry Smith } 2198627564fSBarry Smith } 220748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 221e51f71cfSBarry Smith /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 222748e1b9dSBarry Smith { 223748e1b9dSBarry Smith size_t cnt = 0, ncnt = 0, leng; 2249566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str, &leng)); 225748e1b9dSBarry Smith if (leng > 5) { 226748e1b9dSBarry Smith for (cnt = 0; cnt < leng - 4; cnt++) { 227e51f71cfSBarry 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') { 2289371c9d4SSatish Balay str[ncnt] = str[cnt]; 2299371c9d4SSatish Balay ncnt++; 2309371c9d4SSatish Balay cnt++; 2319371c9d4SSatish Balay str[ncnt] = str[cnt]; 2329371c9d4SSatish Balay ncnt++; 2339371c9d4SSatish Balay cnt++; 2349371c9d4SSatish Balay cnt++; 235e51f71cfSBarry Smith str[ncnt] = str[cnt]; 236748e1b9dSBarry Smith } else { 237748e1b9dSBarry Smith str[ncnt] = str[cnt]; 238748e1b9dSBarry Smith } 239748e1b9dSBarry Smith ncnt++; 240748e1b9dSBarry Smith } 241748e1b9dSBarry Smith while (cnt < leng) { 2429371c9d4SSatish Balay str[ncnt] = str[cnt]; 2439371c9d4SSatish Balay ncnt++; 2449371c9d4SSatish Balay cnt++; 245748e1b9dSBarry Smith } 246748e1b9dSBarry Smith str[ncnt] = 0; 247748e1b9dSBarry Smith } 248748e1b9dSBarry Smith } 249748e1b9dSBarry Smith #endif 250c540d043SBarry Smith if (fullLength) *fullLength = 1 + (size_t)flen; 251eed5747fSBarry Smith PetscFunctionReturn(0); 252e5c89e4eSSatish Balay } 253e5c89e4eSSatish Balay 254c9a19010SBarry Smith /*@C 255c9a19010SBarry Smith PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 256e5c89e4eSSatish Balay can be replaced with something that does not simply write to a file. 257e5c89e4eSSatish Balay 258c9a19010SBarry Smith To use, write your own function for example, 259c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 260c9a19010SBarry Smith ${ 261c9a19010SBarry Smith $ PetscErrorCode ierr; 262c9a19010SBarry Smith $ 263c9a19010SBarry Smith $ PetscFunctionBegin; 264c9a19010SBarry Smith $ if (fd != stdout && fd != stderr) { handle regular files 2655f80ce2aSJacob Faibussowitsch $ CHKERR(PetscVFPrintfDefault(fd,format,Argp)); 266c9a19010SBarry Smith $ } else { 267c9a19010SBarry Smith $ char buff[BIG]; 268c9a19010SBarry Smith $ size_t length; 2699566063dSJacob Faibussowitsch $ PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp)); 270c9a19010SBarry Smith $ now send buff to whatever stream or whatever you want 271c9a19010SBarry Smith $ } 272c9a19010SBarry Smith $ PetscFunctionReturn(0); 273c9a19010SBarry Smith $} 274c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment 275c9a19010SBarry Smith $ PetscVFPrintf = mypetscvfprintf; 276c9a19010SBarry Smith 277811af0c4SBarry Smith Note: 27895452b02SPatrick Sanan For error messages this may be called by any process, for regular standard out it is 279e5c89e4eSSatish Balay called only by process 0 of a given communicator 280e5c89e4eSSatish Balay 281811af0c4SBarry Smith Developer Note: 28295452b02SPatrick Sanan this could be called by an error handler, if that happens then a recursion of the error handler may occur 283eed5747fSBarry Smith and a crash 284c9a19010SBarry Smith 285c9a19010SBarry Smith Level: developer 286c9a19010SBarry Smith 287db781477SPatrick Sanan .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()` 288c9a19010SBarry Smith @*/ 289*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char *format, va_list Argp) 290*d71ae5a4SJacob Faibussowitsch { 29114416c0eSBarry Smith char str[PETSCDEFAULTBUFFERSIZE]; 29214416c0eSBarry Smith char *buff = str; 29314416c0eSBarry Smith size_t fullLength; 2941531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 29514416c0eSBarry Smith va_list Argpcopy; 2961531940fSBarry Smith #endif 2971179db26SBarry Smith 298eed5747fSBarry Smith PetscFunctionBegin; 2991531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 30014416c0eSBarry Smith va_copy(Argpcopy, Argp); 3011531940fSBarry Smith #endif 3029566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp)); 30314416c0eSBarry Smith if (fullLength > sizeof(str)) { 3049566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fullLength, &buff)); 3051531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 3069566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy)); 3071531940fSBarry Smith #else 3081531940fSBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines"); 3091531940fSBarry Smith #endif 31014416c0eSBarry Smith } 3112f613bf5SBarry Smith fprintf(fd, "%s", buff); 3125a058713SBarry Smith fflush(fd); 31348a46eb9SPierre Jolivet if (buff != str) PetscCall(PetscFree(buff)); 314eed5747fSBarry Smith PetscFunctionReturn(0); 315e5c89e4eSSatish Balay } 316e5c89e4eSSatish Balay 3175b5bc046SBarry Smith /*@C 3185b5bc046SBarry Smith PetscSNPrintf - Prints to a string of given length 3195b5bc046SBarry Smith 3205b5bc046SBarry Smith Not Collective 3215b5bc046SBarry Smith 3225b5bc046SBarry Smith Input Parameters: 3235b5bc046SBarry Smith + str - the string to print to 3245b5bc046SBarry Smith . len - the length of str 3255b5bc046SBarry Smith . format - the usual printf() format string 32610699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 3275b5bc046SBarry Smith 3285b5bc046SBarry Smith Level: intermediate 3295b5bc046SBarry Smith 330db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 331db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscVFPrintf()` 3325b5bc046SBarry Smith @*/ 333*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintf(char *str, size_t len, const char format[], ...) 334*d71ae5a4SJacob Faibussowitsch { 335c9a19010SBarry Smith size_t fullLength; 3365b5bc046SBarry Smith va_list Argp; 3375b5bc046SBarry Smith 3385b5bc046SBarry Smith PetscFunctionBegin; 3395b5bc046SBarry Smith va_start(Argp, format); 3409566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp)); 3415b5bc046SBarry Smith PetscFunctionReturn(0); 3425b5bc046SBarry Smith } 3435b5bc046SBarry Smith 344257d2499SJed Brown /*@C 345257d2499SJed Brown PetscSNPrintfCount - Prints to a string of given length, returns count 346257d2499SJed Brown 347257d2499SJed Brown Not Collective 348257d2499SJed Brown 349257d2499SJed Brown Input Parameters: 350257d2499SJed Brown + str - the string to print to 351257d2499SJed Brown . len - the length of str 352257d2499SJed Brown . format - the usual printf() format string 35310699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 354257d2499SJed Brown 355cb398dd3SBarry Smith Output Parameter: 356cb398dd3SBarry Smith . countused - number of characters used 357cb398dd3SBarry Smith 358257d2499SJed Brown Level: intermediate 359257d2499SJed Brown 360db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`, 361db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()` 362257d2499SJed Brown @*/ 363*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintfCount(char *str, size_t len, const char format[], size_t *countused, ...) 364*d71ae5a4SJacob Faibussowitsch { 365257d2499SJed Brown va_list Argp; 366257d2499SJed Brown 367257d2499SJed Brown PetscFunctionBegin; 368257d2499SJed Brown va_start(Argp, countused); 3699566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str, len, format, countused, Argp)); 370257d2499SJed Brown PetscFunctionReturn(0); 371257d2499SJed Brown } 372257d2499SJed Brown 373e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */ 374e5c89e4eSSatish Balay 37502c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL; 376d30b0576SJed Brown int petsc_printfqueuelength = 0; 377e5c89e4eSSatish Balay 378e5c89e4eSSatish Balay /*@C 379e5c89e4eSSatish Balay PetscSynchronizedPrintf - Prints synchronized output from several processors. 380e5c89e4eSSatish Balay Output of the first processor is followed by that of the second, etc. 381e5c89e4eSSatish Balay 382e5c89e4eSSatish Balay Not Collective 383e5c89e4eSSatish Balay 384e5c89e4eSSatish Balay Input Parameters: 385e5c89e4eSSatish Balay + comm - the communicator 386e5c89e4eSSatish Balay - format - the usual printf() format string 387e5c89e4eSSatish Balay 388e5c89e4eSSatish Balay Level: intermediate 389e5c89e4eSSatish Balay 390811af0c4SBarry Smith Note: 391811af0c4SBarry Smith REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information 392e5c89e4eSSatish Balay from all the processors to be printed. 393e5c89e4eSSatish Balay 394e5c89e4eSSatish Balay Fortran Note: 395811af0c4SBarry Smith The call sequence is `PetscSynchronizedPrintf`(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 396e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 397e5c89e4eSSatish Balay 398db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, 399db781477SPatrick Sanan `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()` 400e5c89e4eSSatish Balay @*/ 401*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...) 402*d71ae5a4SJacob Faibussowitsch { 403e5c89e4eSSatish Balay PetscMPIInt rank; 404e5c89e4eSSatish Balay 405e5c89e4eSSatish Balay PetscFunctionBegin; 40608401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 4079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 408e5c89e4eSSatish Balay 409e5c89e4eSSatish Balay /* First processor prints immediately to stdout */ 410dd400576SPatrick Sanan if (rank == 0) { 411e5c89e4eSSatish Balay va_list Argp; 412e5c89e4eSSatish Balay va_start(Argp, format); 4139566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp)); 414e5c89e4eSSatish Balay if (petsc_history) { 415cdc7d174SSatish Balay va_start(Argp, format); 4169566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 417e5c89e4eSSatish Balay } 418e5c89e4eSSatish Balay va_end(Argp); 419e5c89e4eSSatish Balay } else { /* other processors add to local queue */ 420e5c89e4eSSatish Balay va_list Argp; 421e5c89e4eSSatish Balay PrintfQueue next; 42214416c0eSBarry Smith size_t fullLength = PETSCDEFAULTBUFFERSIZE; 423e5c89e4eSSatish Balay 4249566063dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 425a297a907SKarl Rupp if (petsc_printfqueue) { 426a297a907SKarl Rupp petsc_printfqueue->next = next; 427a297a907SKarl Rupp petsc_printfqueue = next; 42802c9f0b5SLisandro Dalcin petsc_printfqueue->next = NULL; 429a297a907SKarl Rupp } else petsc_printfqueuebase = petsc_printfqueue = next; 430d30b0576SJed Brown petsc_printfqueuelength++; 43194217ebdSBarry Smith next->size = 0; 43214416c0eSBarry Smith next->string = NULL; 43394217ebdSBarry Smith while (fullLength >= next->size) { 4342d609e63SMatthew Knepley next->size = fullLength + 1; 4359566063dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 4369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 437e5c89e4eSSatish Balay va_start(Argp, format); 4389566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, next->size)); 4399566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, Argp)); 440e5c89e4eSSatish Balay va_end(Argp); 441e5c89e4eSSatish Balay } 4422d609e63SMatthew Knepley } 443e5c89e4eSSatish Balay PetscFunctionReturn(0); 444e5c89e4eSSatish Balay } 445e5c89e4eSSatish Balay 446e5c89e4eSSatish Balay /*@C 447e5c89e4eSSatish Balay PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 448e5c89e4eSSatish Balay several processors. Output of the first processor is followed by that of the 449e5c89e4eSSatish Balay second, etc. 450e5c89e4eSSatish Balay 451e5c89e4eSSatish Balay Not Collective 452e5c89e4eSSatish Balay 453e5c89e4eSSatish Balay Input Parameters: 454e5c89e4eSSatish Balay + comm - the communicator 455e5c89e4eSSatish Balay . fd - the file pointer 456e5c89e4eSSatish Balay - format - the usual printf() format string 457e5c89e4eSSatish Balay 458e5c89e4eSSatish Balay Level: intermediate 459e5c89e4eSSatish Balay 460811af0c4SBarry Smith Note: 461811af0c4SBarry Smith REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information 462e5c89e4eSSatish Balay from all the processors to be printed. 463e5c89e4eSSatish Balay 464db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`, 465db781477SPatrick Sanan `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()` 466e5c89e4eSSatish Balay @*/ 467*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...) 468*d71ae5a4SJacob Faibussowitsch { 469e5c89e4eSSatish Balay PetscMPIInt rank; 470e5c89e4eSSatish Balay 471e5c89e4eSSatish Balay PetscFunctionBegin; 47208401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 4739566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 474e5c89e4eSSatish Balay 475e5c89e4eSSatish Balay /* First processor prints immediately to fp */ 476dd400576SPatrick Sanan if (rank == 0) { 477e5c89e4eSSatish Balay va_list Argp; 478e5c89e4eSSatish Balay va_start(Argp, format); 4799566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fp, format, Argp)); 480cdc7d174SSatish Balay if (petsc_history && (fp != petsc_history)) { 481cdc7d174SSatish Balay va_start(Argp, format); 4829566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 483e5c89e4eSSatish Balay } 484e5c89e4eSSatish Balay va_end(Argp); 485e5c89e4eSSatish Balay } else { /* other processors add to local queue */ 486e5c89e4eSSatish Balay va_list Argp; 487e5c89e4eSSatish Balay PrintfQueue next; 48814416c0eSBarry Smith size_t fullLength = PETSCDEFAULTBUFFERSIZE; 48914416c0eSBarry Smith 4909566063dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 491a297a907SKarl Rupp if (petsc_printfqueue) { 492a297a907SKarl Rupp petsc_printfqueue->next = next; 493a297a907SKarl Rupp petsc_printfqueue = next; 49402c9f0b5SLisandro Dalcin petsc_printfqueue->next = NULL; 495a297a907SKarl Rupp } else petsc_printfqueuebase = petsc_printfqueue = next; 496d30b0576SJed Brown petsc_printfqueuelength++; 49794217ebdSBarry Smith next->size = 0; 49814416c0eSBarry Smith next->string = NULL; 49994217ebdSBarry Smith while (fullLength >= next->size) { 5002d609e63SMatthew Knepley next->size = fullLength + 1; 5019566063dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 5029566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 503e5c89e4eSSatish Balay va_start(Argp, format); 5049566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string, next->size)); 5059566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, Argp)); 506e5c89e4eSSatish Balay va_end(Argp); 507e5c89e4eSSatish Balay } 5082d609e63SMatthew Knepley } 509e5c89e4eSSatish Balay PetscFunctionReturn(0); 510e5c89e4eSSatish Balay } 511e5c89e4eSSatish Balay 5120ec8b6e3SBarry Smith /*@C 513e5c89e4eSSatish Balay PetscSynchronizedFlush - Flushes to the screen output from all processors 514811af0c4SBarry Smith involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls. 515e5c89e4eSSatish Balay 516d083f849SBarry Smith Collective 517e5c89e4eSSatish Balay 518e5c89e4eSSatish Balay Input Parameters: 5190ec8b6e3SBarry Smith + comm - the communicator 5200ec8b6e3SBarry Smith - fd - the file pointer (valid on process 0 of the communicator) 521e5c89e4eSSatish Balay 522e5c89e4eSSatish Balay Level: intermediate 523e5c89e4eSSatish Balay 524811af0c4SBarry Smith Note: 525811af0c4SBarry Smith If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with 526811af0c4SBarry Smith different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators. 527e5c89e4eSSatish Balay 528811af0c4SBarry Smith Fortran Note: 529811af0c4SBarry Smith Pass `PETSC_STDOUT` if the flush is for standard out; otherwise pass a value obtained from `PetscFOpen()` 530e50bf69fSBarry Smith 531db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`, 532db781477SPatrick Sanan `PetscViewerASCIISynchronizedPrintf()` 5330087d953SMatthew G. Knepley @*/ 534*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd) 535*d71ae5a4SJacob Faibussowitsch { 53629a5cbdcSMatthew G. Knepley PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0; 5372d609e63SMatthew Knepley char *message; 538e5c89e4eSSatish Balay MPI_Status status; 539e5c89e4eSSatish Balay 540e5c89e4eSSatish Balay PetscFunctionBegin; 5419566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(comm, &comm, &tag)); 5429566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 5439566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 544e5c89e4eSSatish Balay 545e5c89e4eSSatish Balay /* First processor waits for messages from all other processors */ 546dd400576SPatrick Sanan if (rank == 0) { 5470ec8b6e3SBarry Smith if (!fd) fd = PETSC_STDOUT; 548e5c89e4eSSatish Balay for (i = 1; i < size; i++) { 5499f73f8ecSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 5509566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm)); 5519566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status)); 552e5c89e4eSSatish Balay for (j = 0; j < n; j++) { 55329a5cbdcSMatthew G. Knepley PetscMPIInt size = 0; 5542d609e63SMatthew Knepley 5559566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status)); 5569566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &message)); 5579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status)); 5589566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, "%s", message)); 5599566063dSJacob Faibussowitsch PetscCall(PetscFree(message)); 560e5c89e4eSSatish Balay } 561e5c89e4eSSatish Balay } 562e5c89e4eSSatish Balay } else { /* other processors send queue to processor 0 */ 563d30b0576SJed Brown PrintfQueue next = petsc_printfqueuebase, previous; 564e5c89e4eSSatish Balay 5659566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status)); 5669566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm)); 567d30b0576SJed Brown for (i = 0; i < petsc_printfqueuelength; i++) { 5689566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm)); 5699566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm)); 570e5c89e4eSSatish Balay previous = next; 571e5c89e4eSSatish Balay next = next->next; 5729566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 5739566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 574e5c89e4eSSatish Balay } 57502c9f0b5SLisandro Dalcin petsc_printfqueue = NULL; 576d30b0576SJed Brown petsc_printfqueuelength = 0; 577e5c89e4eSSatish Balay } 5789566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&comm)); 579e5c89e4eSSatish Balay PetscFunctionReturn(0); 580e5c89e4eSSatish Balay } 581e5c89e4eSSatish Balay 582e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 583e5c89e4eSSatish Balay 584e5c89e4eSSatish Balay /*@C 585e5c89e4eSSatish Balay PetscFPrintf - Prints to a file, only from the first 586e5c89e4eSSatish Balay processor in the communicator. 587e5c89e4eSSatish Balay 588e5c89e4eSSatish Balay Not Collective 589e5c89e4eSSatish Balay 590e5c89e4eSSatish Balay Input Parameters: 591e5c89e4eSSatish Balay + comm - the communicator 592e5c89e4eSSatish Balay . fd - the file pointer 593e5c89e4eSSatish Balay - format - the usual printf() format string 594e5c89e4eSSatish Balay 595e5c89e4eSSatish Balay Level: intermediate 596e5c89e4eSSatish Balay 597e5c89e4eSSatish Balay Fortran Note: 598e5c89e4eSSatish Balay This routine is not supported in Fortran. 599e5c89e4eSSatish Balay 600db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, 601db781477SPatrick Sanan `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()` 602e5c89e4eSSatish Balay @*/ 603*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...) 604*d71ae5a4SJacob Faibussowitsch { 605e5c89e4eSSatish Balay PetscMPIInt rank; 606e5c89e4eSSatish Balay 607e5c89e4eSSatish Balay PetscFunctionBegin; 60808401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 6099566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 610dd400576SPatrick Sanan if (rank == 0) { 611e5c89e4eSSatish Balay va_list Argp; 612e5c89e4eSSatish Balay va_start(Argp, format); 6139566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fd, format, Argp)); 614cdc7d174SSatish Balay if (petsc_history && (fd != petsc_history)) { 615cdc7d174SSatish Balay va_start(Argp, format); 6169566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 617e5c89e4eSSatish Balay } 618e5c89e4eSSatish Balay va_end(Argp); 619e5c89e4eSSatish Balay } 620e5c89e4eSSatish Balay PetscFunctionReturn(0); 621e5c89e4eSSatish Balay } 622e5c89e4eSSatish Balay 623e5c89e4eSSatish Balay /*@C 624e5c89e4eSSatish Balay PetscPrintf - Prints to standard out, only from the first 625eed5747fSBarry Smith processor in the communicator. Calls from other processes are ignored. 626e5c89e4eSSatish Balay 627e5c89e4eSSatish Balay Not Collective 628e5c89e4eSSatish Balay 629e5c89e4eSSatish Balay Input Parameters: 630e5c89e4eSSatish Balay + comm - the communicator 631e5c89e4eSSatish Balay - format - the usual printf() format string 632e5c89e4eSSatish Balay 633e5c89e4eSSatish Balay Level: intermediate 634e5c89e4eSSatish Balay 635811af0c4SBarry Smith Note: 636811af0c4SBarry Smith Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc. 637811af0c4SBarry Smith See the manual page for `PetscFormatConvert()` for details. 638b2706f25SRichard Tran Mills 639e5c89e4eSSatish Balay Fortran Note: 640811af0c4SBarry Smith The call sequence is `PetscPrintf`(MPI_Comm, character(*), `PetscErrorCode` ierr) from Fortran. 641e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 642e5c89e4eSSatish Balay 643db781477SPatrick Sanan .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()` 644e5c89e4eSSatish Balay @*/ 645*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...) 646*d71ae5a4SJacob Faibussowitsch { 647e5c89e4eSSatish Balay PetscMPIInt rank; 648e5c89e4eSSatish Balay 649e5c89e4eSSatish Balay PetscFunctionBegin; 65008401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 6519566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 652dd400576SPatrick Sanan if (rank == 0) { 653e5c89e4eSSatish Balay va_list Argp; 654e5c89e4eSSatish Balay va_start(Argp, format); 6559566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp)); 656e5c89e4eSSatish Balay if (petsc_history) { 657cdc7d174SSatish Balay va_start(Argp, format); 6589566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 659e5c89e4eSSatish Balay } 660e5c89e4eSSatish Balay va_end(Argp); 661e5c89e4eSSatish Balay } 662e5c89e4eSSatish Balay PetscFunctionReturn(0); 663e5c89e4eSSatish Balay } 664e5c89e4eSSatish Balay 665*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...) 666*d71ae5a4SJacob Faibussowitsch { 667e5c89e4eSSatish Balay PetscMPIInt rank; 668e5c89e4eSSatish Balay 669e5c89e4eSSatish Balay PetscFunctionBegin; 67008401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 6719566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 672dd400576SPatrick Sanan if (rank == 0) { 673e5c89e4eSSatish Balay va_list Argp; 674e5c89e4eSSatish Balay va_start(Argp, format); 6759566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp)); 676e5c89e4eSSatish Balay if (petsc_history) { 677cdc7d174SSatish Balay va_start(Argp, format); 6789566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history, format, Argp)); 679e5c89e4eSSatish Balay } 680e5c89e4eSSatish Balay va_end(Argp); 681e5c89e4eSSatish Balay } 682e5c89e4eSSatish Balay PetscFunctionReturn(0); 683e5c89e4eSSatish Balay } 684e5c89e4eSSatish Balay 685e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 686e5c89e4eSSatish Balay 687e5c89e4eSSatish Balay /*@C 688e5c89e4eSSatish Balay PetscSynchronizedFGets - Several processors all get the same line from a file. 689e5c89e4eSSatish Balay 690d083f849SBarry Smith Collective 691e5c89e4eSSatish Balay 692e5c89e4eSSatish Balay Input Parameters: 693e5c89e4eSSatish Balay + comm - the communicator 694e5c89e4eSSatish Balay . fd - the file pointer 695e5c89e4eSSatish Balay - len - the length of the output buffer 696e5c89e4eSSatish Balay 697e5c89e4eSSatish Balay Output Parameter: 698e31d4fa4SJed Brown . string - the line read from the file, at end of file string[0] == 0 699e5c89e4eSSatish Balay 700e5c89e4eSSatish Balay Level: intermediate 701e5c89e4eSSatish Balay 702db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, 703db781477SPatrick Sanan `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()` 704e5c89e4eSSatish Balay @*/ 705*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm, FILE *fp, size_t len, char string[]) 706*d71ae5a4SJacob Faibussowitsch { 707e5c89e4eSSatish Balay PetscMPIInt rank; 708e5c89e4eSSatish Balay 709e5c89e4eSSatish Balay PetscFunctionBegin; 7109566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 711e5c89e4eSSatish Balay 712dd400576SPatrick Sanan if (rank == 0) { 713047b9c12SMatthew G Knepley char *ptr = fgets(string, len, fp); 714047b9c12SMatthew G Knepley 715047b9c12SMatthew G Knepley if (!ptr) { 716e31d4fa4SJed Brown string[0] = 0; 71708401ef6SPierre Jolivet PetscCheck(feof(fp), PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 718047b9c12SMatthew G Knepley } 719e5c89e4eSSatish Balay } 7209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(string, len, MPI_BYTE, 0, comm)); 721e5c89e4eSSatish Balay PetscFunctionReturn(0); 722e5c89e4eSSatish Balay } 723238ccf28SShri Abhyankar 7242475b7caSBarry Smith #if defined(PETSC_HAVE_CLOSURE) 725f1d7fe2eSBarry Smith int (^SwiftClosure)(const char *) = 0; 726f1d7fe2eSBarry Smith 727*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfToString(FILE *fd, const char format[], va_list Argp) 728*d71ae5a4SJacob Faibussowitsch { 729f1d7fe2eSBarry Smith PetscFunctionBegin; 730f1d7fe2eSBarry Smith if (fd != stdout && fd != stderr) { /* handle regular files */ 7319566063dSJacob Faibussowitsch PetscCall(PetscVFPrintfDefault(fd, format, Argp)); 732f1d7fe2eSBarry Smith } else { 73314416c0eSBarry Smith size_t length; 73414416c0eSBarry Smith char buff[PETSCDEFAULTBUFFERSIZE]; 735f1d7fe2eSBarry Smith 7369566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff, sizeof(buff), format, &length, Argp)); 7379566063dSJacob Faibussowitsch PetscCall(SwiftClosure(buff)); 738f1d7fe2eSBarry Smith } 739f1d7fe2eSBarry Smith PetscFunctionReturn(0); 740f1d7fe2eSBarry Smith } 741f1d7fe2eSBarry Smith 742f1d7fe2eSBarry Smith /* 743f1d7fe2eSBarry Smith Provide a Swift function that processes all the PETSc calls to PetscVFPrintf() 744f1d7fe2eSBarry Smith */ 745*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char *)) 746*d71ae5a4SJacob Faibussowitsch { 747f1d7fe2eSBarry Smith PetscVFPrintf = PetscVFPrintfToString; 748f1d7fe2eSBarry Smith SwiftClosure = closure; 749f1d7fe2eSBarry Smith return 0; 750f1d7fe2eSBarry Smith } 751f1d7fe2eSBarry Smith #endif 752f1d7fe2eSBarry Smith 7538c74ee41SBarry Smith /*@C 7548c74ee41SBarry Smith PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 7558c74ee41SBarry Smith 7568c74ee41SBarry Smith Input Parameters: 7578c74ee41SBarry Smith . format - the PETSc format string 7588c74ee41SBarry Smith 7598c74ee41SBarry Smith Level: developer 7608c74ee41SBarry Smith 7618c74ee41SBarry Smith @*/ 762*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatStrip(char *format) 763*d71ae5a4SJacob Faibussowitsch { 7648c74ee41SBarry Smith size_t loc1 = 0, loc2 = 0; 7658c74ee41SBarry Smith 7668c74ee41SBarry Smith PetscFunctionBegin; 7678c74ee41SBarry Smith while (format[loc2]) { 7688c74ee41SBarry Smith if (format[loc2] == '%') { 7698c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7708c74ee41SBarry Smith while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 7718c74ee41SBarry Smith } 7728c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7738c74ee41SBarry Smith } 7748c74ee41SBarry Smith PetscFunctionReturn(0); 7758c74ee41SBarry Smith } 7768c74ee41SBarry Smith 777*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[]) 778*d71ae5a4SJacob Faibussowitsch { 7791b5687a1SBarry Smith PetscInt i; 7801b5687a1SBarry Smith size_t left, count; 7811b5687a1SBarry Smith char *p; 7821b5687a1SBarry Smith 7831b5687a1SBarry Smith PetscFunctionBegin; 7841b5687a1SBarry Smith for (i = 0, p = buf, left = len; i < n; i++) { 7859566063dSJacob Faibussowitsch PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i])); 78608401ef6SPierre Jolivet PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer"); 7871b5687a1SBarry Smith left -= count; 7881b5687a1SBarry Smith p += count - 1; 7891b5687a1SBarry Smith *p++ = ' '; 7901b5687a1SBarry Smith } 7911b5687a1SBarry Smith p[i ? 0 : -1] = 0; 7921b5687a1SBarry Smith PetscFunctionReturn(0); 7931b5687a1SBarry Smith } 794