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 25d781fa04SBarry Smith PetscFormatConvertGetSize - Gets the length of a string needed to hold format converted with PetscFormatConvert() 26c9a19010SBarry Smith 27d781fa04SBarry Smith Input Parameter: 28d781fa04SBarry Smith . format - the PETSc format string 29c9a19010SBarry Smith 30d781fa04SBarry Smith Output Parameter: 31d781fa04SBarry Smith . size - the needed length of the new format 32c9a19010SBarry Smith 33c9a19010SBarry Smith Level: developer 34c9a19010SBarry Smith 35d781fa04SBarry Smith .seealso: PetscFormatConvert(), PetscVSNPrintf(), PetscVFPrintf() 36d781fa04SBarry Smith 37c9a19010SBarry Smith @*/ 38d781fa04SBarry Smith PetscErrorCode PetscFormatConvertGetSize(const char *format,size_t *size) 39d781fa04SBarry Smith { 403ca90d2dSJacob Faibussowitsch size_t sz = 0; 41d781fa04SBarry Smith PetscInt i = 0; 42d781fa04SBarry Smith 43d781fa04SBarry Smith PetscFunctionBegin; 443ca90d2dSJacob Faibussowitsch PetscValidCharPointer(format,1); 453ca90d2dSJacob Faibussowitsch PetscValidPointer(size,2); 46d781fa04SBarry Smith while (format[i]) { 473ca90d2dSJacob Faibussowitsch if (format[i] == '%') { 483ca90d2dSJacob Faibussowitsch if (format[i+1] == '%') { 493ca90d2dSJacob Faibussowitsch i += 2; 503ca90d2dSJacob Faibussowitsch sz += 2; 513ca90d2dSJacob Faibussowitsch continue; 523ca90d2dSJacob Faibussowitsch } 53d781fa04SBarry Smith /* Find the letter */ 543ca90d2dSJacob Faibussowitsch while (format[i] && (format[i] <= '9')) {++i;++sz;} 55d781fa04SBarry Smith switch (format[i]) { 563ca90d2dSJacob Faibussowitsch #if PetscDefined(USE_64BIT_INDICES) 57d781fa04SBarry Smith case 'D': 583ca90d2dSJacob Faibussowitsch sz += 2; 593ca90d2dSJacob Faibussowitsch break; 60d781fa04SBarry Smith #endif 61d781fa04SBarry Smith case 'g': 623ca90d2dSJacob Faibussowitsch sz += 4; 63d781fa04SBarry Smith default: 64d781fa04SBarry Smith break; 65d781fa04SBarry Smith } 66d781fa04SBarry Smith } 673ca90d2dSJacob Faibussowitsch ++i; 683ca90d2dSJacob Faibussowitsch ++sz; 69d781fa04SBarry Smith } 703ca90d2dSJacob Faibussowitsch *size = sz+1; /* space for NULL character */ 71d781fa04SBarry Smith PetscFunctionReturn(0); 72d781fa04SBarry Smith } 73d781fa04SBarry Smith 74d781fa04SBarry Smith /*@C 75d781fa04SBarry 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 76d781fa04SBarry Smith converts %g to [|%g|] so that PetscVSNPrintf() can easily insure all %g formatted numbers have a decimal point when printed. 77d781fa04SBarry Smith 78d781fa04SBarry Smith Input Parameters: 79d781fa04SBarry Smith + format - the PETSc format string 80d781fa04SBarry Smith . newformat - the location to put the new format 81d781fa04SBarry Smith - size - the length of newformat, you can use PetscFormatConvertGetSize() to compute the needed size 82d781fa04SBarry Smith 83d781fa04SBarry Smith Note: this exists so we can have the same code when PetscInt is either int or long long int 84d781fa04SBarry Smith 85d781fa04SBarry Smith Level: developer 86d781fa04SBarry Smith 87d781fa04SBarry Smith .seealso: PetscFormatConvertGetSize(), PetscVSNPrintf(), PetscVFPrintf() 88d781fa04SBarry Smith 89d781fa04SBarry Smith @*/ 90d781fa04SBarry Smith PetscErrorCode PetscFormatConvert(const char *format,char *newformat) 91e5c89e4eSSatish Balay { 92e5c89e4eSSatish Balay PetscInt i = 0, j = 0; 93e5c89e4eSSatish Balay 94eed5747fSBarry Smith PetscFunctionBegin; 95d781fa04SBarry Smith while (format[i]) { 962a1ad9caSBarry Smith if (format[i] == '%' && format[i+1] == '%') { 972a1ad9caSBarry Smith newformat[j++] = format[i++]; 982a1ad9caSBarry Smith newformat[j++] = format[i++]; 992a1ad9caSBarry Smith } else if (format[i] == '%') { 1008627564fSBarry Smith if (format[i+1] == 'g') { 1018627564fSBarry Smith newformat[j++] = '['; 1028627564fSBarry Smith newformat[j++] = '|'; 1038627564fSBarry Smith } 1047bc47156SJose Roman /* Find the letter */ 1057bc47156SJose Roman for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 1067bc47156SJose Roman switch (format[i]) { 1077bc47156SJose Roman case 'D': 1086de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 109e5c89e4eSSatish Balay newformat[j++] = 'd'; 110e5c89e4eSSatish Balay #else 111e5c89e4eSSatish Balay newformat[j++] = 'l'; 112e5c89e4eSSatish Balay newformat[j++] = 'l'; 113e5c89e4eSSatish Balay newformat[j++] = 'd'; 114e5c89e4eSSatish Balay #endif 1157bc47156SJose Roman break; 1168627564fSBarry Smith case 'g': 1178627564fSBarry Smith newformat[j++] = format[i]; 1188627564fSBarry Smith if (format[i-1] == '%') { 1198627564fSBarry Smith newformat[j++] = '|'; 1208627564fSBarry Smith newformat[j++] = ']'; 1218627564fSBarry Smith } 1228627564fSBarry Smith break; 1237bc47156SJose Roman case 'G': 124145505e7SDominic Meiser SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%G format is no longer supported, use %%g and cast the argument to double"); 125121a09c4SJose Roman case 'F': 126145505e7SDominic Meiser SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%F format is no longer supported, use %%f and cast the argument to double"); 1277bc47156SJose Roman default: 1287bc47156SJose Roman newformat[j++] = format[i]; 1297bc47156SJose Roman break; 1307bc47156SJose Roman } 1317bc47156SJose Roman i++; 132a297a907SKarl Rupp } else newformat[j++] = format[i++]; 133e5c89e4eSSatish Balay } 134e5c89e4eSSatish Balay newformat[j] = 0; 135eed5747fSBarry Smith PetscFunctionReturn(0); 136e5c89e4eSSatish Balay } 137e5c89e4eSSatish Balay 13814416c0eSBarry Smith #define PETSCDEFAULTBUFFERSIZE 8*1024 139d781fa04SBarry Smith 140c9a19010SBarry Smith /*@C 141c9a19010SBarry Smith PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 142c9a19010SBarry Smith function arguments into a string using the format statement. 143c9a19010SBarry Smith 144c9a19010SBarry Smith Input Parameters: 145c9a19010SBarry Smith + str - location to put result 146c9a19010SBarry Smith . len - the amount of space in str 147c9a19010SBarry Smith + format - the PETSc format string 148c9a19010SBarry Smith - fullLength - the amount of space in str actually used. 149c9a19010SBarry Smith 15095452b02SPatrick Sanan Developer Notes: 15195452b02SPatrick Sanan this function may be called from an error handler, if an error occurs when it is called by the error handler than likely 152eed5747fSBarry Smith a recursion will occur and possible crash. 153c9a19010SBarry Smith 154c9a19010SBarry Smith Level: developer 155c9a19010SBarry Smith 156d781fa04SBarry Smith .seealso: PetscVSNPrintf(), PetscErrorPrintf(), PetscVPrintf() 157d781fa04SBarry Smith 158c9a19010SBarry Smith @*/ 1597087cfbeSBarry Smith PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) 160e5c89e4eSSatish Balay { 161d781fa04SBarry Smith char *newformat = NULL; 16214416c0eSBarry Smith char formatbuf[PETSCDEFAULTBUFFERSIZE]; 163d781fa04SBarry Smith size_t newLength; 16414416c0eSBarry Smith int flen; 165e5c89e4eSSatish Balay 166eed5747fSBarry Smith PetscFunctionBegin; 1679566063dSJacob Faibussowitsch PetscCall(PetscFormatConvertGetSize(format,&newLength)); 16894217ebdSBarry Smith if (newLength < sizeof(formatbuf)) { 169e2135aedSMatthew Knepley newformat = formatbuf; 17094217ebdSBarry Smith newLength = sizeof(formatbuf)-1; 171e2135aedSMatthew Knepley } else { 1729566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(newLength, &newformat)); 173e2135aedSMatthew Knepley } 1749566063dSJacob Faibussowitsch PetscCall(PetscFormatConvert(format,newformat)); 1757b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF) 176152b30f0SSatish Balay flen = vsnprintf(str,len,newformat,Argp); 177e5c89e4eSSatish Balay #else 17889b07760SSatish Balay #error "vsnprintf not found" 179e5c89e4eSSatish Balay #endif 18094217ebdSBarry Smith if (newLength > sizeof(formatbuf)-1) { 1819566063dSJacob Faibussowitsch PetscCall(PetscFree(newformat)); 182e2135aedSMatthew Knepley } 1838627564fSBarry Smith { 1848627564fSBarry Smith PetscBool foundedot; 1858627564fSBarry Smith size_t cnt = 0,ncnt = 0,leng; 1869566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str,&leng)); 18717ca8410SBarry Smith if (leng > 4) { 1888627564fSBarry Smith for (cnt=0; cnt<leng-4; cnt++) { 1898627564fSBarry Smith if (str[cnt] == '[' && str[cnt+1] == '|') { 190c540d043SBarry Smith flen -= 4; 1918627564fSBarry Smith cnt++; cnt++; 1928627564fSBarry Smith foundedot = PETSC_FALSE; 1938627564fSBarry Smith for (; cnt<leng-1; cnt++) { 1948627564fSBarry Smith if (str[cnt] == '|' && str[cnt+1] == ']') { 1958627564fSBarry Smith cnt++; 1968627564fSBarry Smith if (!foundedot) str[ncnt++] = '.'; 1978627564fSBarry Smith ncnt--; 1988627564fSBarry Smith break; 1998627564fSBarry Smith } else { 2008627564fSBarry Smith if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; 2018627564fSBarry Smith str[ncnt++] = str[cnt]; 2028627564fSBarry Smith } 2038627564fSBarry Smith } 2048627564fSBarry Smith } else { 2058627564fSBarry Smith str[ncnt] = str[cnt]; 2068627564fSBarry Smith } 2078627564fSBarry Smith ncnt++; 2088627564fSBarry Smith } 2098627564fSBarry Smith while (cnt < leng) { 2108627564fSBarry Smith str[ncnt] = str[cnt]; ncnt++; cnt++; 2118627564fSBarry Smith } 2128627564fSBarry Smith str[ncnt] = 0; 2138627564fSBarry Smith } 2148627564fSBarry Smith } 215748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) 216e51f71cfSBarry Smith /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ 217748e1b9dSBarry Smith { 218748e1b9dSBarry Smith size_t cnt = 0,ncnt = 0,leng; 2199566063dSJacob Faibussowitsch PetscCall(PetscStrlen(str,&leng)); 220748e1b9dSBarry Smith if (leng > 5) { 221748e1b9dSBarry Smith for (cnt=0; cnt<leng-4; cnt++) { 222e51f71cfSBarry 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') { 223748e1b9dSBarry Smith str[ncnt] = str[cnt]; ncnt++; cnt++; 224e51f71cfSBarry Smith str[ncnt] = str[cnt]; ncnt++; cnt++; cnt++; 225e51f71cfSBarry Smith str[ncnt] = str[cnt]; 226748e1b9dSBarry Smith } else { 227748e1b9dSBarry Smith str[ncnt] = str[cnt]; 228748e1b9dSBarry Smith } 229748e1b9dSBarry Smith ncnt++; 230748e1b9dSBarry Smith } 231748e1b9dSBarry Smith while (cnt < leng) { 232748e1b9dSBarry Smith str[ncnt] = str[cnt]; ncnt++; cnt++; 233748e1b9dSBarry Smith } 234748e1b9dSBarry Smith str[ncnt] = 0; 235748e1b9dSBarry Smith } 236748e1b9dSBarry Smith } 237748e1b9dSBarry Smith #endif 238c540d043SBarry Smith if (fullLength) *fullLength = 1 + (size_t) flen; 239eed5747fSBarry Smith PetscFunctionReturn(0); 240e5c89e4eSSatish Balay } 241e5c89e4eSSatish Balay 242c9a19010SBarry Smith /*@C 243c9a19010SBarry Smith PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 244e5c89e4eSSatish Balay can be replaced with something that does not simply write to a file. 245e5c89e4eSSatish Balay 246c9a19010SBarry Smith To use, write your own function for example, 247c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 248c9a19010SBarry Smith ${ 249c9a19010SBarry Smith $ PetscErrorCode ierr; 250c9a19010SBarry Smith $ 251c9a19010SBarry Smith $ PetscFunctionBegin; 252c9a19010SBarry Smith $ if (fd != stdout && fd != stderr) { handle regular files 2535f80ce2aSJacob Faibussowitsch $ CHKERR(PetscVFPrintfDefault(fd,format,Argp)); 254c9a19010SBarry Smith $ } else { 255c9a19010SBarry Smith $ char buff[BIG]; 256c9a19010SBarry Smith $ size_t length; 2579566063dSJacob Faibussowitsch $ PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp)); 258c9a19010SBarry Smith $ now send buff to whatever stream or whatever you want 259c9a19010SBarry Smith $ } 260c9a19010SBarry Smith $ PetscFunctionReturn(0); 261c9a19010SBarry Smith $} 262c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment 263c9a19010SBarry Smith $ PetscVFPrintf = mypetscvfprintf; 264c9a19010SBarry Smith 26595452b02SPatrick Sanan Notes: 26695452b02SPatrick Sanan For error messages this may be called by any process, for regular standard out it is 267e5c89e4eSSatish Balay called only by process 0 of a given communicator 268e5c89e4eSSatish Balay 26995452b02SPatrick Sanan Developer Notes: 27095452b02SPatrick Sanan this could be called by an error handler, if that happens then a recursion of the error handler may occur 271eed5747fSBarry Smith and a crash 272c9a19010SBarry Smith 273c9a19010SBarry Smith Level: developer 274c9a19010SBarry Smith 275c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscErrorPrintf() 276c9a19010SBarry Smith 277c9a19010SBarry Smith @*/ 2787087cfbeSBarry Smith PetscErrorCode PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp) 279e5c89e4eSSatish Balay { 28014416c0eSBarry Smith char str[PETSCDEFAULTBUFFERSIZE]; 28114416c0eSBarry Smith char *buff = str; 28214416c0eSBarry Smith size_t fullLength; 2831531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 28414416c0eSBarry Smith va_list Argpcopy; 2851531940fSBarry Smith #endif 2861179db26SBarry Smith 287eed5747fSBarry Smith PetscFunctionBegin; 2881531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 28914416c0eSBarry Smith va_copy(Argpcopy,Argp); 2901531940fSBarry Smith #endif 2919566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str,sizeof(str),format,&fullLength,Argp)); 29214416c0eSBarry Smith if (fullLength > sizeof(str)) { 2939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(fullLength,&buff)); 2941531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY) 2959566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff,fullLength,format,NULL,Argpcopy)); 2961531940fSBarry Smith #else 2971531940fSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"C89 does not support va_copy() hence cannot print long strings with PETSc printing routines"); 2981531940fSBarry Smith #endif 29914416c0eSBarry Smith } 3002f613bf5SBarry Smith fprintf(fd,"%s",buff); 3015a058713SBarry Smith fflush(fd); 30214416c0eSBarry Smith if (buff != str) { 3039566063dSJacob Faibussowitsch PetscCall(PetscFree(buff)); 30414416c0eSBarry Smith } 305eed5747fSBarry Smith PetscFunctionReturn(0); 306e5c89e4eSSatish Balay } 307e5c89e4eSSatish Balay 3085b5bc046SBarry Smith /*@C 3095b5bc046SBarry Smith PetscSNPrintf - Prints to a string of given length 3105b5bc046SBarry Smith 3115b5bc046SBarry Smith Not Collective 3125b5bc046SBarry Smith 3135b5bc046SBarry Smith Input Parameters: 3145b5bc046SBarry Smith + str - the string to print to 3155b5bc046SBarry Smith . len - the length of str 3165b5bc046SBarry Smith . format - the usual printf() format string 31710699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 3185b5bc046SBarry Smith 3195b5bc046SBarry Smith Level: intermediate 3205b5bc046SBarry Smith 3215b5bc046SBarry Smith .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 322d781fa04SBarry Smith PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscVFPrintf() 3235b5bc046SBarry Smith @*/ 3247087cfbeSBarry Smith PetscErrorCode PetscSNPrintf(char *str,size_t len,const char format[],...) 3255b5bc046SBarry Smith { 326c9a19010SBarry Smith size_t fullLength; 3275b5bc046SBarry Smith va_list Argp; 3285b5bc046SBarry Smith 3295b5bc046SBarry Smith PetscFunctionBegin; 3305b5bc046SBarry Smith va_start(Argp,format); 3319566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str,len,format,&fullLength,Argp)); 3325b5bc046SBarry Smith PetscFunctionReturn(0); 3335b5bc046SBarry Smith } 3345b5bc046SBarry Smith 335257d2499SJed Brown /*@C 336257d2499SJed Brown PetscSNPrintfCount - Prints to a string of given length, returns count 337257d2499SJed Brown 338257d2499SJed Brown Not Collective 339257d2499SJed Brown 340257d2499SJed Brown Input Parameters: 341257d2499SJed Brown + str - the string to print to 342257d2499SJed Brown . len - the length of str 343257d2499SJed Brown . format - the usual printf() format string 34410699b91SBarry Smith - ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument 345257d2499SJed Brown 346cb398dd3SBarry Smith Output Parameter: 347cb398dd3SBarry Smith . countused - number of characters used 348cb398dd3SBarry Smith 349257d2499SJed Brown Level: intermediate 350257d2499SJed Brown 351257d2499SJed Brown .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 352d781fa04SBarry Smith PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf(), PetscVFPrintf() 353257d2499SJed Brown @*/ 354257d2499SJed Brown PetscErrorCode PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...) 355257d2499SJed Brown { 356257d2499SJed Brown va_list Argp; 357257d2499SJed Brown 358257d2499SJed Brown PetscFunctionBegin; 359257d2499SJed Brown va_start(Argp,countused); 3609566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(str,len,format,countused,Argp)); 361257d2499SJed Brown PetscFunctionReturn(0); 362257d2499SJed Brown } 363257d2499SJed Brown 364e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */ 365e5c89e4eSSatish Balay 36602c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL,petsc_printfqueuebase = NULL; 367d30b0576SJed Brown int petsc_printfqueuelength = 0; 368e5c89e4eSSatish Balay 369e5c89e4eSSatish Balay /*@C 370e5c89e4eSSatish Balay PetscSynchronizedPrintf - Prints synchronized output from several processors. 371e5c89e4eSSatish Balay Output of the first processor is followed by that of the second, etc. 372e5c89e4eSSatish Balay 373e5c89e4eSSatish Balay Not Collective 374e5c89e4eSSatish Balay 375e5c89e4eSSatish Balay Input Parameters: 376e5c89e4eSSatish Balay + comm - the communicator 377e5c89e4eSSatish Balay - format - the usual printf() format string 378e5c89e4eSSatish Balay 379e5c89e4eSSatish Balay Level: intermediate 380e5c89e4eSSatish Balay 381e5c89e4eSSatish Balay Notes: 3827889ec69SBarry Smith REQUIRES a call to PetscSynchronizedFlush() by all the processes after the completion of the calls to PetscSynchronizedPrintf() for the information 383e5c89e4eSSatish Balay from all the processors to be printed. 384e5c89e4eSSatish Balay 385e5c89e4eSSatish Balay Fortran Note: 386d60d70ccSBarry Smith The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 387e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 388e5c89e4eSSatish Balay 389e5c89e4eSSatish Balay .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 390e5c89e4eSSatish Balay PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 391e5c89e4eSSatish Balay @*/ 3927087cfbeSBarry Smith PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 393e5c89e4eSSatish Balay { 394e5c89e4eSSatish Balay PetscMPIInt rank; 395e5c89e4eSSatish Balay 396e5c89e4eSSatish Balay PetscFunctionBegin; 397*08401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 3989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 399e5c89e4eSSatish Balay 400e5c89e4eSSatish Balay /* First processor prints immediately to stdout */ 401dd400576SPatrick Sanan if (rank == 0) { 402e5c89e4eSSatish Balay va_list Argp; 403e5c89e4eSSatish Balay va_start(Argp,format); 4049566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(PETSC_STDOUT,format,Argp)); 405e5c89e4eSSatish Balay if (petsc_history) { 406cdc7d174SSatish Balay va_start(Argp,format); 4079566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history,format,Argp)); 408e5c89e4eSSatish Balay } 409e5c89e4eSSatish Balay va_end(Argp); 410e5c89e4eSSatish Balay } else { /* other processors add to local queue */ 411e5c89e4eSSatish Balay va_list Argp; 412e5c89e4eSSatish Balay PrintfQueue next; 41314416c0eSBarry Smith size_t fullLength = PETSCDEFAULTBUFFERSIZE; 414e5c89e4eSSatish Balay 4159566063dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 416a297a907SKarl Rupp if (petsc_printfqueue) { 417a297a907SKarl Rupp petsc_printfqueue->next = next; 418a297a907SKarl Rupp petsc_printfqueue = next; 41902c9f0b5SLisandro Dalcin petsc_printfqueue->next = NULL; 420a297a907SKarl Rupp } else petsc_printfqueuebase = petsc_printfqueue = next; 421d30b0576SJed Brown petsc_printfqueuelength++; 42294217ebdSBarry Smith next->size = 0; 42314416c0eSBarry Smith next->string = NULL; 42494217ebdSBarry Smith while (fullLength >= next->size) { 4252d609e63SMatthew Knepley next->size = fullLength+1; 4269566063dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 4279566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 428e5c89e4eSSatish Balay va_start(Argp,format); 4299566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string,next->size)); 4309566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp)); 431e5c89e4eSSatish Balay va_end(Argp); 432e5c89e4eSSatish Balay } 4332d609e63SMatthew Knepley } 434e5c89e4eSSatish Balay PetscFunctionReturn(0); 435e5c89e4eSSatish Balay } 436e5c89e4eSSatish Balay 437e5c89e4eSSatish Balay /*@C 438e5c89e4eSSatish Balay PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 439e5c89e4eSSatish Balay several processors. Output of the first processor is followed by that of the 440e5c89e4eSSatish Balay second, etc. 441e5c89e4eSSatish Balay 442e5c89e4eSSatish Balay Not Collective 443e5c89e4eSSatish Balay 444e5c89e4eSSatish Balay Input Parameters: 445e5c89e4eSSatish Balay + comm - the communicator 446e5c89e4eSSatish Balay . fd - the file pointer 447e5c89e4eSSatish Balay - format - the usual printf() format string 448e5c89e4eSSatish Balay 449e5c89e4eSSatish Balay Level: intermediate 450e5c89e4eSSatish Balay 451e5c89e4eSSatish Balay Notes: 452e5c89e4eSSatish Balay REQUIRES a intervening call to PetscSynchronizedFlush() for the information 453e5c89e4eSSatish Balay from all the processors to be printed. 454e5c89e4eSSatish Balay 455e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 456e5c89e4eSSatish Balay PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 457e5c89e4eSSatish Balay 458e5c89e4eSSatish Balay @*/ 4597087cfbeSBarry Smith PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm,FILE *fp,const char format[],...) 460e5c89e4eSSatish Balay { 461e5c89e4eSSatish Balay PetscMPIInt rank; 462e5c89e4eSSatish Balay 463e5c89e4eSSatish Balay PetscFunctionBegin; 464*08401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 4659566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 466e5c89e4eSSatish Balay 467e5c89e4eSSatish Balay /* First processor prints immediately to fp */ 468dd400576SPatrick Sanan if (rank == 0) { 469e5c89e4eSSatish Balay va_list Argp; 470e5c89e4eSSatish Balay va_start(Argp,format); 4719566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fp,format,Argp)); 472cdc7d174SSatish Balay if (petsc_history && (fp !=petsc_history)) { 473cdc7d174SSatish Balay va_start(Argp,format); 4749566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history,format,Argp)); 475e5c89e4eSSatish Balay } 476e5c89e4eSSatish Balay va_end(Argp); 477e5c89e4eSSatish Balay } else { /* other processors add to local queue */ 478e5c89e4eSSatish Balay va_list Argp; 479e5c89e4eSSatish Balay PrintfQueue next; 48014416c0eSBarry Smith size_t fullLength = PETSCDEFAULTBUFFERSIZE; 48114416c0eSBarry Smith 4829566063dSJacob Faibussowitsch PetscCall(PetscNew(&next)); 483a297a907SKarl Rupp if (petsc_printfqueue) { 484a297a907SKarl Rupp petsc_printfqueue->next = next; 485a297a907SKarl Rupp petsc_printfqueue = next; 48602c9f0b5SLisandro Dalcin petsc_printfqueue->next = NULL; 487a297a907SKarl Rupp } else petsc_printfqueuebase = petsc_printfqueue = next; 488d30b0576SJed Brown petsc_printfqueuelength++; 48994217ebdSBarry Smith next->size = 0; 49014416c0eSBarry Smith next->string = NULL; 49194217ebdSBarry Smith while (fullLength >= next->size) { 4922d609e63SMatthew Knepley next->size = fullLength+1; 4939566063dSJacob Faibussowitsch PetscCall(PetscFree(next->string)); 4949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(next->size, &next->string)); 495e5c89e4eSSatish Balay va_start(Argp,format); 4969566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(next->string,next->size)); 4979566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp)); 498e5c89e4eSSatish Balay va_end(Argp); 499e5c89e4eSSatish Balay } 5002d609e63SMatthew Knepley } 501e5c89e4eSSatish Balay PetscFunctionReturn(0); 502e5c89e4eSSatish Balay } 503e5c89e4eSSatish Balay 5040ec8b6e3SBarry Smith /*@C 505e5c89e4eSSatish Balay PetscSynchronizedFlush - Flushes to the screen output from all processors 5067889ec69SBarry Smith involved in previous PetscSynchronizedPrintf()/PetscSynchronizedFPrintf() calls. 507e5c89e4eSSatish Balay 508d083f849SBarry Smith Collective 509e5c89e4eSSatish Balay 510e5c89e4eSSatish Balay Input Parameters: 5110ec8b6e3SBarry Smith + comm - the communicator 5120ec8b6e3SBarry Smith - fd - the file pointer (valid on process 0 of the communicator) 513e5c89e4eSSatish Balay 514e5c89e4eSSatish Balay Level: intermediate 515e5c89e4eSSatish Balay 516e5c89e4eSSatish Balay Notes: 5177889ec69SBarry Smith If PetscSynchronizedPrintf() and/or PetscSynchronizedFPrintf() are called with 5187889ec69SBarry Smith different MPI communicators there must be an intervening call to PetscSynchronizedFlush() between the calls with different MPI communicators. 519e5c89e4eSSatish Balay 520e50bf69fSBarry Smith From Fortran pass PETSC_STDOUT if the flush is for standard out; otherwise pass a value obtained from PetscFOpen() 521e50bf69fSBarry Smith 522e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 523e5c89e4eSSatish Balay PetscViewerASCIISynchronizedPrintf() 5240087d953SMatthew G. Knepley @*/ 5250ec8b6e3SBarry Smith PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm,FILE *fd) 526e5c89e4eSSatish Balay { 52729a5cbdcSMatthew G. Knepley PetscMPIInt rank,size,tag,i,j,n = 0,dummy = 0; 5282d609e63SMatthew Knepley char *message; 529e5c89e4eSSatish Balay MPI_Status status; 530e5c89e4eSSatish Balay 531e5c89e4eSSatish Balay PetscFunctionBegin; 5329566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(comm,&comm,&tag)); 5339566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 5349566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm,&size)); 535e5c89e4eSSatish Balay 536e5c89e4eSSatish Balay /* First processor waits for messages from all other processors */ 537dd400576SPatrick Sanan if (rank == 0) { 5380ec8b6e3SBarry Smith if (!fd) fd = PETSC_STDOUT; 539e5c89e4eSSatish Balay for (i=1; i<size; i++) { 5409f73f8ecSBarry Smith /* to prevent a flood of messages to process zero, request each message separately */ 5419566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&dummy,1,MPI_INT,i,tag,comm)); 5429566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status)); 543e5c89e4eSSatish Balay for (j=0; j<n; j++) { 54429a5cbdcSMatthew G. Knepley PetscMPIInt size = 0; 5452d609e63SMatthew Knepley 5469566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status)); 5479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &message)); 5489566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status)); 5499566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm,fd,"%s",message)); 5509566063dSJacob Faibussowitsch PetscCall(PetscFree(message)); 551e5c89e4eSSatish Balay } 552e5c89e4eSSatish Balay } 553e5c89e4eSSatish Balay } else { /* other processors send queue to processor 0 */ 554d30b0576SJed Brown PrintfQueue next = petsc_printfqueuebase,previous; 555e5c89e4eSSatish Balay 5569566063dSJacob Faibussowitsch PetscCallMPI(MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status)); 5579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm)); 558d30b0576SJed Brown for (i=0; i<petsc_printfqueuelength; i++) { 5599566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(&next->size,1,MPI_INT,0,tag,comm)); 5609566063dSJacob Faibussowitsch PetscCallMPI(MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm)); 561e5c89e4eSSatish Balay previous = next; 562e5c89e4eSSatish Balay next = next->next; 5639566063dSJacob Faibussowitsch PetscCall(PetscFree(previous->string)); 5649566063dSJacob Faibussowitsch PetscCall(PetscFree(previous)); 565e5c89e4eSSatish Balay } 56602c9f0b5SLisandro Dalcin petsc_printfqueue = NULL; 567d30b0576SJed Brown petsc_printfqueuelength = 0; 568e5c89e4eSSatish Balay } 5699566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&comm)); 570e5c89e4eSSatish Balay PetscFunctionReturn(0); 571e5c89e4eSSatish Balay } 572e5c89e4eSSatish Balay 573e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 574e5c89e4eSSatish Balay 575e5c89e4eSSatish Balay /*@C 576e5c89e4eSSatish Balay PetscFPrintf - Prints to a file, only from the first 577e5c89e4eSSatish Balay processor in the communicator. 578e5c89e4eSSatish Balay 579e5c89e4eSSatish Balay Not Collective 580e5c89e4eSSatish Balay 581e5c89e4eSSatish Balay Input Parameters: 582e5c89e4eSSatish Balay + comm - the communicator 583e5c89e4eSSatish Balay . fd - the file pointer 584e5c89e4eSSatish Balay - format - the usual printf() format string 585e5c89e4eSSatish Balay 586e5c89e4eSSatish Balay Level: intermediate 587e5c89e4eSSatish Balay 588e5c89e4eSSatish Balay Fortran Note: 589e5c89e4eSSatish Balay This routine is not supported in Fortran. 590e5c89e4eSSatish Balay 591e5c89e4eSSatish Balay .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 592e5c89e4eSSatish Balay PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 593e5c89e4eSSatish Balay @*/ 5947087cfbeSBarry Smith PetscErrorCode PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 595e5c89e4eSSatish Balay { 596e5c89e4eSSatish Balay PetscMPIInt rank; 597e5c89e4eSSatish Balay 598e5c89e4eSSatish Balay PetscFunctionBegin; 599*08401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 6009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 601dd400576SPatrick Sanan if (rank == 0) { 602e5c89e4eSSatish Balay va_list Argp; 603e5c89e4eSSatish Balay va_start(Argp,format); 6049566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(fd,format,Argp)); 605cdc7d174SSatish Balay if (petsc_history && (fd !=petsc_history)) { 606cdc7d174SSatish Balay va_start(Argp,format); 6079566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history,format,Argp)); 608e5c89e4eSSatish Balay } 609e5c89e4eSSatish Balay va_end(Argp); 610e5c89e4eSSatish Balay } 611e5c89e4eSSatish Balay PetscFunctionReturn(0); 612e5c89e4eSSatish Balay } 613e5c89e4eSSatish Balay 614e5c89e4eSSatish Balay /*@C 615e5c89e4eSSatish Balay PetscPrintf - Prints to standard out, only from the first 616eed5747fSBarry Smith processor in the communicator. Calls from other processes are ignored. 617e5c89e4eSSatish Balay 618e5c89e4eSSatish Balay Not Collective 619e5c89e4eSSatish Balay 620e5c89e4eSSatish Balay Input Parameters: 621e5c89e4eSSatish Balay + comm - the communicator 622e5c89e4eSSatish Balay - format - the usual printf() format string 623e5c89e4eSSatish Balay 624e5c89e4eSSatish Balay Level: intermediate 625e5c89e4eSSatish Balay 626b2706f25SRichard Tran Mills Notes: 627b2706f25SRichard Tran Mills PetscPrintf() supports some format specifiers that are unique to PETSc. 628b2706f25SRichard Tran Mills See the manual page for PetscFormatConvert() for details. 629b2706f25SRichard Tran Mills 630e5c89e4eSSatish Balay Fortran Note: 631d60d70ccSBarry Smith The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 632e5c89e4eSSatish Balay That is, you can only pass a single character string from Fortran. 633e5c89e4eSSatish Balay 634b2706f25SRichard Tran Mills .seealso: PetscFPrintf(), PetscSynchronizedPrintf(), PetscFormatConvert() 635e5c89e4eSSatish Balay @*/ 6367087cfbeSBarry Smith PetscErrorCode PetscPrintf(MPI_Comm comm,const char format[],...) 637e5c89e4eSSatish Balay { 638e5c89e4eSSatish Balay PetscMPIInt rank; 639e5c89e4eSSatish Balay 640e5c89e4eSSatish Balay PetscFunctionBegin; 641*08401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 6429566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 643dd400576SPatrick Sanan if (rank == 0) { 644e5c89e4eSSatish Balay va_list Argp; 645e5c89e4eSSatish Balay va_start(Argp,format); 6469566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(PETSC_STDOUT,format,Argp)); 647e5c89e4eSSatish Balay if (petsc_history) { 648cdc7d174SSatish Balay va_start(Argp,format); 6499566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history,format,Argp)); 650e5c89e4eSSatish Balay } 651e5c89e4eSSatish Balay va_end(Argp); 652e5c89e4eSSatish Balay } 653e5c89e4eSSatish Balay PetscFunctionReturn(0); 654e5c89e4eSSatish Balay } 655e5c89e4eSSatish Balay 6567087cfbeSBarry Smith PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 657e5c89e4eSSatish Balay { 658e5c89e4eSSatish Balay PetscMPIInt rank; 659e5c89e4eSSatish Balay 660e5c89e4eSSatish Balay PetscFunctionBegin; 661*08401ef6SPierre Jolivet PetscCheck(comm != MPI_COMM_NULL,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 6629566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 663dd400576SPatrick Sanan if (rank == 0) { 664e5c89e4eSSatish Balay va_list Argp; 665e5c89e4eSSatish Balay va_start(Argp,format); 6669566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(PETSC_STDOUT,format,Argp)); 667e5c89e4eSSatish Balay if (petsc_history) { 668cdc7d174SSatish Balay va_start(Argp,format); 6699566063dSJacob Faibussowitsch PetscCall((*PetscVFPrintf)(petsc_history,format,Argp)); 670e5c89e4eSSatish Balay } 671e5c89e4eSSatish Balay va_end(Argp); 672e5c89e4eSSatish Balay } 673e5c89e4eSSatish Balay PetscFunctionReturn(0); 674e5c89e4eSSatish Balay } 675e5c89e4eSSatish Balay 676e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/ 677e5c89e4eSSatish Balay 678e5c89e4eSSatish Balay /*@C 679e5c89e4eSSatish Balay PetscSynchronizedFGets - Several processors all get the same line from a file. 680e5c89e4eSSatish Balay 681d083f849SBarry Smith Collective 682e5c89e4eSSatish Balay 683e5c89e4eSSatish Balay Input Parameters: 684e5c89e4eSSatish Balay + comm - the communicator 685e5c89e4eSSatish Balay . fd - the file pointer 686e5c89e4eSSatish Balay - len - the length of the output buffer 687e5c89e4eSSatish Balay 688e5c89e4eSSatish Balay Output Parameter: 689e31d4fa4SJed Brown . string - the line read from the file, at end of file string[0] == 0 690e5c89e4eSSatish Balay 691e5c89e4eSSatish Balay Level: intermediate 692e5c89e4eSSatish Balay 693e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 694e5c89e4eSSatish Balay PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 695e5c89e4eSSatish Balay 696e5c89e4eSSatish Balay @*/ 6977087cfbeSBarry Smith PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[]) 698e5c89e4eSSatish Balay { 699e5c89e4eSSatish Balay PetscMPIInt rank; 700e5c89e4eSSatish Balay 701e5c89e4eSSatish Balay PetscFunctionBegin; 7029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 703e5c89e4eSSatish Balay 704dd400576SPatrick Sanan if (rank == 0) { 705047b9c12SMatthew G Knepley char *ptr = fgets(string, len, fp); 706047b9c12SMatthew G Knepley 707047b9c12SMatthew G Knepley if (!ptr) { 708e31d4fa4SJed Brown string[0] = 0; 709*08401ef6SPierre Jolivet PetscCheck(feof(fp),PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 710047b9c12SMatthew G Knepley } 711e5c89e4eSSatish Balay } 7129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(string,len,MPI_BYTE,0,comm)); 713e5c89e4eSSatish Balay PetscFunctionReturn(0); 714e5c89e4eSSatish Balay } 715238ccf28SShri Abhyankar 7162475b7caSBarry Smith #if defined(PETSC_HAVE_CLOSURE) 717f1d7fe2eSBarry Smith int (^SwiftClosure)(const char*) = 0; 718f1d7fe2eSBarry Smith 719f1d7fe2eSBarry Smith PetscErrorCode PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp) 720f1d7fe2eSBarry Smith { 721f1d7fe2eSBarry Smith PetscFunctionBegin; 722f1d7fe2eSBarry Smith if (fd != stdout && fd != stderr) { /* handle regular files */ 7239566063dSJacob Faibussowitsch PetscCall(PetscVFPrintfDefault(fd,format,Argp)); 724f1d7fe2eSBarry Smith } else { 72514416c0eSBarry Smith size_t length; 72614416c0eSBarry Smith char buff[PETSCDEFAULTBUFFERSIZE]; 727f1d7fe2eSBarry Smith 7289566063dSJacob Faibussowitsch PetscCall(PetscVSNPrintf(buff,sizeof(buff),format,&length,Argp)); 7299566063dSJacob Faibussowitsch PetscCall(SwiftClosure(buff)); 730f1d7fe2eSBarry Smith } 731f1d7fe2eSBarry Smith PetscFunctionReturn(0); 732f1d7fe2eSBarry Smith } 733f1d7fe2eSBarry Smith 734f1d7fe2eSBarry Smith /* 735f1d7fe2eSBarry Smith Provide a Swift function that processes all the PETSc calls to PetscVFPrintf() 736f1d7fe2eSBarry Smith */ 737f1d7fe2eSBarry Smith PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*)) 738f1d7fe2eSBarry Smith { 739f1d7fe2eSBarry Smith PetscVFPrintf = PetscVFPrintfToString; 740f1d7fe2eSBarry Smith SwiftClosure = closure; 741f1d7fe2eSBarry Smith return 0; 742f1d7fe2eSBarry Smith } 743f1d7fe2eSBarry Smith #endif 744f1d7fe2eSBarry Smith 7458c74ee41SBarry Smith /*@C 7468c74ee41SBarry Smith PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 7478c74ee41SBarry Smith 7488c74ee41SBarry Smith Input Parameters: 7498c74ee41SBarry Smith . format - the PETSc format string 7508c74ee41SBarry Smith 7518c74ee41SBarry Smith Level: developer 7528c74ee41SBarry Smith 7538c74ee41SBarry Smith @*/ 7548c74ee41SBarry Smith PetscErrorCode PetscFormatStrip(char *format) 7558c74ee41SBarry Smith { 7568c74ee41SBarry Smith size_t loc1 = 0, loc2 = 0; 7578c74ee41SBarry Smith 7588c74ee41SBarry Smith PetscFunctionBegin; 7598c74ee41SBarry Smith while (format[loc2]) { 7608c74ee41SBarry Smith if (format[loc2] == '%') { 7618c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7628c74ee41SBarry Smith while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 7638c74ee41SBarry Smith } 7648c74ee41SBarry Smith format[loc1++] = format[loc2++]; 7658c74ee41SBarry Smith } 7668c74ee41SBarry Smith PetscFunctionReturn(0); 7678c74ee41SBarry Smith } 7688c74ee41SBarry Smith 7691b5687a1SBarry Smith PetscErrorCode PetscFormatRealArray(char buf[],size_t len,const char *fmt,PetscInt n,const PetscReal x[]) 7701b5687a1SBarry Smith { 7711b5687a1SBarry Smith PetscInt i; 7721b5687a1SBarry Smith size_t left,count; 7731b5687a1SBarry Smith char *p; 7741b5687a1SBarry Smith 7751b5687a1SBarry Smith PetscFunctionBegin; 7761b5687a1SBarry Smith for (i=0,p=buf,left=len; i<n; i++) { 7779566063dSJacob Faibussowitsch PetscCall(PetscSNPrintfCount(p,left,fmt,&count,(double)x[i])); 778*08401ef6SPierre Jolivet PetscCheck(count < left,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Insufficient space in buffer"); 7791b5687a1SBarry Smith left -= count; 7801b5687a1SBarry Smith p += count-1; 7811b5687a1SBarry Smith *p++ = ' '; 7821b5687a1SBarry Smith } 7831b5687a1SBarry Smith p[i ? 0 : -1] = 0; 7841b5687a1SBarry Smith PetscFunctionReturn(0); 7851b5687a1SBarry Smith } 786