xref: /petsc/src/sys/fileio/mprint.c (revision 0b8bdde92eb4bc9ed9cee42fe7fcadba66103007)
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 @*/
PetscFormatConvertGetSize(const char format[],size_t * size)39cc4c1da9SBarry 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 @*/
PetscFormatConvert(const char format[],char newformat[])101cc4c1da9SBarry 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 
154cc4c1da9SBarry Smith   No Fortran Support
155cc4c1da9SBarry 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 @*/
PetscVSNPrintf(char str[],size_t len,const char format[],size_t * fullLength,va_list Argp)175cc4c1da9SBarry 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   }
232c540d043SBarry Smith   if (fullLength) *fullLength = 1 + (size_t)flen;
2333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
234e5c89e4eSSatish Balay }
235e5c89e4eSSatish Balay 
236c9a19010SBarry Smith /*@C
237c69effb2SJacob Faibussowitsch   PetscFFlush - Flush a file stream
238c69effb2SJacob Faibussowitsch 
239c69effb2SJacob Faibussowitsch   Input Parameter:
240c69effb2SJacob Faibussowitsch . fd - The file stream handle
241c69effb2SJacob Faibussowitsch 
242c69effb2SJacob Faibussowitsch   Level: intermediate
243c69effb2SJacob Faibussowitsch 
244c69effb2SJacob Faibussowitsch   Notes:
245c69effb2SJacob Faibussowitsch   For output streams (and for update streams on which the last operation was output), writes
246c69effb2SJacob Faibussowitsch   any unwritten data from the stream's buffer to the associated output device.
247c69effb2SJacob Faibussowitsch 
248c69effb2SJacob Faibussowitsch   For input streams (and for update streams on which the last operation was input), the
249c69effb2SJacob Faibussowitsch   behavior is undefined.
250c69effb2SJacob Faibussowitsch 
251c69effb2SJacob Faibussowitsch   If `fd` is `NULL`, all open output streams are flushed, including ones not directly
252c69effb2SJacob Faibussowitsch   accessible to the program.
253c69effb2SJacob Faibussowitsch 
254cc4c1da9SBarry Smith   Fortran Note:
255cc4c1da9SBarry Smith   Use `PetscFlush()`
256cc4c1da9SBarry Smith 
257c69effb2SJacob Faibussowitsch .seealso: `PetscPrintf()`, `PetscFPrintf()`, `PetscVFPrintf()`, `PetscVSNPrintf()`
258c69effb2SJacob Faibussowitsch @*/
PetscFFlush(FILE * fd)259c69effb2SJacob Faibussowitsch PetscErrorCode PetscFFlush(FILE *fd)
260c69effb2SJacob Faibussowitsch {
26133ff13ceSLisandro Dalcin   int err;
26233ff13ceSLisandro Dalcin 
263c69effb2SJacob Faibussowitsch   PetscFunctionBegin;
2644f572ea9SToby Isaac   if (fd) PetscAssertPointer(fd, 1);
26533ff13ceSLisandro Dalcin   err = fflush(fd);
26633ff13ceSLisandro Dalcin #if !defined(PETSC_MISSING_SIGPIPE) && defined(EPIPE) && defined(ECONNRESET)
26733ff13ceSLisandro Dalcin   if (fd && err && (errno == EPIPE || errno == ECONNRESET)) err = 0; /* ignore error, rely on SIGPIPE */
26833ff13ceSLisandro Dalcin #endif
269c69effb2SJacob Faibussowitsch   // could also use PetscCallExternal() here, but since we can get additional error explanation
270c69effb2SJacob Faibussowitsch   // from strerror() we opted for a manual check
27133ff13ceSLisandro Dalcin   PetscCheck(0 == err, PETSC_COMM_SELF, PETSC_ERR_FILE_WRITE, "Error in fflush() due to \"%s\"", strerror(errno));
272c69effb2SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
273c69effb2SJacob Faibussowitsch }
274c69effb2SJacob Faibussowitsch 
275c69effb2SJacob Faibussowitsch /*@C
276aec76313SJacob Faibussowitsch   PetscVFPrintfDefault -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
277e5c89e4eSSatish Balay   can be replaced with something that does not simply write to a file.
278e5c89e4eSSatish Balay 
279cc4c1da9SBarry Smith   No Fortran Support
280cc4c1da9SBarry Smith 
28110450e9eSJacob Faibussowitsch   Input Parameters:
28210450e9eSJacob Faibussowitsch + fd     - the file descriptor to write to
28310450e9eSJacob Faibussowitsch . format - the format string to write with
28410450e9eSJacob Faibussowitsch - Argp   - the variable argument list of items to format and write
28510450e9eSJacob Faibussowitsch 
28610450e9eSJacob Faibussowitsch   Level: developer
28710450e9eSJacob Faibussowitsch 
28810450e9eSJacob Faibussowitsch   Note:
28910450e9eSJacob Faibussowitsch   For error messages this may be called by any MPI process, for regular standard out it is
29010450e9eSJacob Faibussowitsch   called only by MPI rank 0 of a given communicator
29110450e9eSJacob Faibussowitsch 
29210450e9eSJacob Faibussowitsch   Example Usage:
293c9a19010SBarry Smith   To use, write your own function for example,
294058c9ee1SBarry Smith .vb
295058c9ee1SBarry Smith    PetscErrorCode mypetscvfprintf(FILE *fd, const char format[], va_list Argp)
296058c9ee1SBarry Smith    {
297058c9ee1SBarry Smith 
298058c9ee1SBarry Smith      PetscFunctionBegin;
299058c9ee1SBarry Smith       if (fd != stdout && fd != stderr) {  handle regular files
300058c9ee1SBarry Smith          CHKERR(PetscVFPrintfDefault(fd,format,Argp));
301058c9ee1SBarry Smith      } else {
302058c9ee1SBarry Smith         char   buff[BIG];
303058c9ee1SBarry Smith         size_t length;
304058c9ee1SBarry Smith         PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp));
305058c9ee1SBarry Smith         now send buff to whatever stream or whatever you want
306058c9ee1SBarry Smith     }
307058c9ee1SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
308058c9ee1SBarry Smith    }
309058c9ee1SBarry Smith .ve
310058c9ee1SBarry Smith   then before the call to `PetscInitialize()` do the assignment `PetscVFPrintf = mypetscvfprintf`;
311058c9ee1SBarry Smith 
312aec76313SJacob Faibussowitsch   Developer Notes:
313058c9ee1SBarry Smith   This could be called by an error handler, if that happens then a recursion of the error handler may occur
314058c9ee1SBarry Smith   and a resulting crash
315c9a19010SBarry Smith 
316c69effb2SJacob Faibussowitsch .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscFFlush()`
317c9a19010SBarry Smith @*/
PetscVFPrintfDefault(FILE * fd,const char format[],va_list Argp)318cc4c1da9SBarry Smith PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char format[], va_list Argp)
319d71ae5a4SJacob Faibussowitsch {
32014416c0eSBarry Smith   char   str[PETSCDEFAULTBUFFERSIZE];
32114416c0eSBarry Smith   char  *buff = str;
32214416c0eSBarry Smith   size_t fullLength;
3231531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY)
32414416c0eSBarry Smith   va_list Argpcopy;
3251531940fSBarry Smith #endif
3261179db26SBarry Smith 
327eed5747fSBarry Smith   PetscFunctionBegin;
3281531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY)
32914416c0eSBarry Smith   va_copy(Argpcopy, Argp);
3301531940fSBarry Smith #endif
3319566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp));
33214416c0eSBarry Smith   if (fullLength > sizeof(str)) {
3339566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(fullLength, &buff));
3341531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY)
3359566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy));
3361531940fSBarry Smith #else
3371531940fSBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines");
3381531940fSBarry Smith #endif
33914416c0eSBarry Smith   }
340eae3dc7dSJacob Faibussowitsch #if defined(PETSC_HAVE_VA_COPY)
341eae3dc7dSJacob Faibussowitsch   va_end(Argpcopy);
342eae3dc7dSJacob Faibussowitsch #endif
343c69effb2SJacob Faibussowitsch   {
3448c0ebe3fSBarry Smith     int err;
3458c0ebe3fSBarry Smith 
3468c0ebe3fSBarry Smith     // POSIX C sets errno but otherwise it may not be set for *printf() system calls
3478c0ebe3fSBarry Smith     // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html
3488c0ebe3fSBarry Smith     errno = 0;
3498c0ebe3fSBarry Smith     err   = fprintf(fd, "%s", buff);
350c69effb2SJacob Faibussowitsch     // cannot use PetscCallExternal() for fprintf since the return value is "number of
351c69effb2SJacob Faibussowitsch     // characters transmitted to the output stream" on success
3528c0ebe3fSBarry 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)");
353c69effb2SJacob Faibussowitsch   }
354c69effb2SJacob Faibussowitsch   PetscCall(PetscFFlush(fd));
35548a46eb9SPierre Jolivet   if (buff != str) PetscCall(PetscFree(buff));
3563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
357e5c89e4eSSatish Balay }
358e5c89e4eSSatish Balay 
3595b5bc046SBarry Smith /*@C
3605b5bc046SBarry Smith   PetscSNPrintf - Prints to a string of given length
3615b5bc046SBarry Smith 
362cc4c1da9SBarry Smith   Not Collective, No Fortran Support
3635b5bc046SBarry Smith 
3645b5bc046SBarry Smith   Input Parameters:
36521532e8aSBarry Smith + len    - the length of `str`
36610450e9eSJacob Faibussowitsch - format - the usual `printf()` format string
3675b5bc046SBarry Smith 
36821532e8aSBarry Smith   Output Parameter:
36921532e8aSBarry Smith . str - the resulting string
37021532e8aSBarry Smith 
3715b5bc046SBarry Smith   Level: intermediate
3725b5bc046SBarry Smith 
373db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`,
374c69effb2SJacob Faibussowitsch           `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`,
375c69effb2SJacob Faibussowitsch           `PetscVFPrintf()`, `PetscFFlush()`
3765b5bc046SBarry Smith @*/
PetscSNPrintf(char str[],size_t len,const char format[],...)377cc4c1da9SBarry Smith PetscErrorCode PetscSNPrintf(char str[], size_t len, const char format[], ...)
378d71ae5a4SJacob Faibussowitsch {
379c9a19010SBarry Smith   size_t  fullLength;
3805b5bc046SBarry Smith   va_list Argp;
3815b5bc046SBarry Smith 
3825b5bc046SBarry Smith   PetscFunctionBegin;
3835b5bc046SBarry Smith   va_start(Argp, format);
3849566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp));
385eae3dc7dSJacob Faibussowitsch   va_end(Argp);
3863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3875b5bc046SBarry Smith }
3885b5bc046SBarry Smith 
389257d2499SJed Brown /*@C
390058c9ee1SBarry Smith   PetscSNPrintfCount - Prints to a string of given length, returns count of characters printed
391257d2499SJed Brown 
392cc4c1da9SBarry Smith   Not Collective, No Fortran Support
393257d2499SJed Brown 
394257d2499SJed Brown   Input Parameters:
39521532e8aSBarry Smith + len    - the length of `str`
396058c9ee1SBarry Smith . format - the usual `printf()` format string
39710450e9eSJacob Faibussowitsch - ...    - args to format
398257d2499SJed Brown 
39921532e8aSBarry Smith   Output Parameters:
40021532e8aSBarry Smith + str       - the resulting string
40121532e8aSBarry Smith - countused - number of characters printed
402cb398dd3SBarry Smith 
403257d2499SJed Brown   Level: intermediate
404257d2499SJed Brown 
405db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`,
406db781477SPatrick Sanan           `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()`
407257d2499SJed Brown @*/
PetscSNPrintfCount(char str[],size_t len,const char format[],size_t * countused,...)408cc4c1da9SBarry Smith PetscErrorCode PetscSNPrintfCount(char str[], size_t len, const char format[], size_t *countused, ...)
409d71ae5a4SJacob Faibussowitsch {
410257d2499SJed Brown   va_list Argp;
411257d2499SJed Brown 
412257d2499SJed Brown   PetscFunctionBegin;
413257d2499SJed Brown   va_start(Argp, countused);
4149566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(str, len, format, countused, Argp));
415eae3dc7dSJacob Faibussowitsch   va_end(Argp);
4163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
417257d2499SJed Brown }
418257d2499SJed Brown 
41902c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL;
420d30b0576SJed Brown int         petsc_printfqueuelength = 0;
421e5c89e4eSSatish Balay 
PetscVFPrintf_Private(FILE * fd,const char format[],va_list Argp)4228c509928SStefano Zampini static inline PetscErrorCode PetscVFPrintf_Private(FILE *fd, const char format[], va_list Argp)
423eae3dc7dSJacob Faibussowitsch {
424eae3dc7dSJacob Faibussowitsch   const PetscBool tee = (PetscBool)(petsc_history && (fd != petsc_history));
425eae3dc7dSJacob Faibussowitsch   va_list         cpy;
426eae3dc7dSJacob Faibussowitsch 
427eae3dc7dSJacob Faibussowitsch   PetscFunctionBegin;
428eae3dc7dSJacob Faibussowitsch   // must do this before we possibly consume Argp
429eae3dc7dSJacob Faibussowitsch   if (tee) va_copy(cpy, Argp);
430eae3dc7dSJacob Faibussowitsch   PetscCall((*PetscVFPrintf)(fd, format, Argp));
431eae3dc7dSJacob Faibussowitsch   if (tee) {
432eae3dc7dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(petsc_history, format, cpy));
433eae3dc7dSJacob Faibussowitsch     va_end(cpy);
434eae3dc7dSJacob Faibussowitsch   }
435eae3dc7dSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
436eae3dc7dSJacob Faibussowitsch }
437eae3dc7dSJacob Faibussowitsch 
PetscVFPrintf_Internal(FILE * fd,const char format[],...)4388c509928SStefano Zampini PETSC_INTERN PetscErrorCode PetscVFPrintf_Internal(FILE *fd, const char format[], ...)
4398c509928SStefano Zampini {
4408c509928SStefano Zampini   va_list Argp;
4418c509928SStefano Zampini 
4428c509928SStefano Zampini   PetscFunctionBegin;
4438c509928SStefano Zampini   va_start(Argp, format);
4448c509928SStefano Zampini   PetscCall(PetscVFPrintf_Private(fd, format, Argp));
4458c509928SStefano Zampini   va_end(Argp);
4468c509928SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
4478c509928SStefano Zampini }
4488c509928SStefano Zampini 
PetscSynchronizedFPrintf_Private(MPI_Comm comm,FILE * fp,const char format[],va_list Argp)449eae3dc7dSJacob Faibussowitsch static inline PetscErrorCode PetscSynchronizedFPrintf_Private(MPI_Comm comm, FILE *fp, const char format[], va_list Argp)
450eae3dc7dSJacob Faibussowitsch {
451eae3dc7dSJacob Faibussowitsch   PetscMPIInt rank;
452eae3dc7dSJacob Faibussowitsch   va_list     cpy;
453eae3dc7dSJacob Faibussowitsch 
454eae3dc7dSJacob Faibussowitsch   PetscFunctionBegin;
455eae3dc7dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
456eae3dc7dSJacob Faibussowitsch   /* First processor prints immediately to fp */
457eae3dc7dSJacob Faibussowitsch   if (rank == 0) {
458eae3dc7dSJacob Faibussowitsch     va_copy(cpy, Argp);
4598c509928SStefano Zampini     PetscCall(PetscVFPrintf_Private(fp, format, cpy));
460eae3dc7dSJacob Faibussowitsch     va_end(cpy);
461eae3dc7dSJacob Faibussowitsch   } else { /* other processors add to local queue */
462eae3dc7dSJacob Faibussowitsch     PrintfQueue next;
463eae3dc7dSJacob Faibussowitsch     size_t      fullLength = PETSCDEFAULTBUFFERSIZE;
464eae3dc7dSJacob Faibussowitsch 
465eae3dc7dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
466eae3dc7dSJacob Faibussowitsch     if (petsc_printfqueue) {
467eae3dc7dSJacob Faibussowitsch       petsc_printfqueue->next = next;
468eae3dc7dSJacob Faibussowitsch       petsc_printfqueue       = next;
469eae3dc7dSJacob Faibussowitsch       petsc_printfqueue->next = NULL;
470eae3dc7dSJacob Faibussowitsch     } else petsc_printfqueuebase = petsc_printfqueue = next;
471eae3dc7dSJacob Faibussowitsch     petsc_printfqueuelength++;
472eae3dc7dSJacob Faibussowitsch     next->size   = 0;
473eae3dc7dSJacob Faibussowitsch     next->string = NULL;
474eae3dc7dSJacob Faibussowitsch     while (fullLength >= next->size) {
475eae3dc7dSJacob Faibussowitsch       next->size = fullLength + 1;
476eae3dc7dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
477eae3dc7dSJacob Faibussowitsch       PetscCall(PetscMalloc1(next->size, &next->string));
478eae3dc7dSJacob Faibussowitsch       PetscCall(PetscArrayzero(next->string, next->size));
479eae3dc7dSJacob Faibussowitsch       va_copy(cpy, Argp);
480eae3dc7dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, cpy));
481eae3dc7dSJacob Faibussowitsch       va_end(cpy);
482eae3dc7dSJacob Faibussowitsch     }
483eae3dc7dSJacob Faibussowitsch   }
484eae3dc7dSJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
485eae3dc7dSJacob Faibussowitsch }
486eae3dc7dSJacob Faibussowitsch 
487e5c89e4eSSatish Balay /*@C
4889c89aa79SPierre Jolivet   PetscSynchronizedPrintf - Prints synchronized output from multiple MPI processes.
489e5c89e4eSSatish Balay   Output of the first processor is followed by that of the second, etc.
490e5c89e4eSSatish Balay 
491e5c89e4eSSatish Balay   Not Collective
492e5c89e4eSSatish Balay 
493e5c89e4eSSatish Balay   Input Parameters:
494058c9ee1SBarry Smith + comm   - the MPI communicator
4956026c97aSBarry Smith - format - the usual `printf()` format string
496e5c89e4eSSatish Balay 
497e5c89e4eSSatish Balay   Level: intermediate
498e5c89e4eSSatish Balay 
499811af0c4SBarry Smith   Note:
500811af0c4SBarry Smith   REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information
501e5c89e4eSSatish Balay   from all the processors to be printed.
502e5c89e4eSSatish Balay 
503cc4c1da9SBarry Smith   Fortran Note:
504058c9ee1SBarry Smith   The call sequence is `PetscSynchronizedPrintf`(`MPI_Comm`, `character`(*), `PetscErrorCode` ierr).
505e5c89e4eSSatish Balay   That is, you can only pass a single character string from Fortran.
506e5c89e4eSSatish Balay 
507db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`,
508c69effb2SJacob Faibussowitsch           `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`,
509c69effb2SJacob Faibussowitsch           `PetscFFlush()`
510e5c89e4eSSatish Balay @*/
PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...)511d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...)
512d71ae5a4SJacob Faibussowitsch {
513eae3dc7dSJacob Faibussowitsch   va_list Argp;
514e5c89e4eSSatish Balay 
515e5c89e4eSSatish Balay   PetscFunctionBegin;
516e5c89e4eSSatish Balay   va_start(Argp, format);
517eae3dc7dSJacob Faibussowitsch   PetscCall(PetscSynchronizedFPrintf_Private(comm, PETSC_STDOUT, format, Argp));
518e5c89e4eSSatish Balay   va_end(Argp);
5193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
520e5c89e4eSSatish Balay }
521e5c89e4eSSatish Balay 
522e5c89e4eSSatish Balay /*@C
523e5c89e4eSSatish Balay   PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
52421532e8aSBarry Smith   several MPI processes.  Output of the first process is followed by that of the
525e5c89e4eSSatish Balay   second, etc.
526e5c89e4eSSatish Balay 
527e5c89e4eSSatish Balay   Not Collective
528e5c89e4eSSatish Balay 
529e5c89e4eSSatish Balay   Input Parameters:
530058c9ee1SBarry Smith + comm   - the MPI communicator
531cc4c1da9SBarry Smith . fp     - the file pointer, `PETSC_STDOUT` or value obtained from `PetscFOpen()`
5326026c97aSBarry Smith - format - the usual `printf()` format string
533e5c89e4eSSatish Balay 
534e5c89e4eSSatish Balay   Level: intermediate
535e5c89e4eSSatish Balay 
536811af0c4SBarry Smith   Note:
537811af0c4SBarry Smith   REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information
538e5c89e4eSSatish Balay   from all the processors to be printed.
539e5c89e4eSSatish Balay 
540cc4c1da9SBarry Smith   Fortran Note:
541cc4c1da9SBarry Smith   The call sequence is `PetscSynchronizedPrintf`(`MPI_Comm`, fp, `character`(*), `PetscErrorCode` ierr).
542cc4c1da9SBarry Smith   That is, you can only pass a single character string from Fortran.
543cc4c1da9SBarry Smith 
544db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`,
545c69effb2SJacob Faibussowitsch           `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
546c69effb2SJacob Faibussowitsch           `PetscFFlush()`
547e5c89e4eSSatish Balay @*/
PetscSynchronizedFPrintf(MPI_Comm comm,FILE * fp,const char format[],...)548d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...)
549d71ae5a4SJacob Faibussowitsch {
550eae3dc7dSJacob Faibussowitsch   va_list Argp;
551e5c89e4eSSatish Balay 
552e5c89e4eSSatish Balay   PetscFunctionBegin;
553e5c89e4eSSatish Balay   va_start(Argp, format);
554eae3dc7dSJacob Faibussowitsch   PetscCall(PetscSynchronizedFPrintf_Private(comm, fp, format, Argp));
555e5c89e4eSSatish Balay   va_end(Argp);
5563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
557e5c89e4eSSatish Balay }
558e5c89e4eSSatish Balay 
5590ec8b6e3SBarry Smith /*@C
560e5c89e4eSSatish Balay   PetscSynchronizedFlush - Flushes to the screen output from all processors
561811af0c4SBarry Smith   involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls.
562e5c89e4eSSatish Balay 
563d083f849SBarry Smith   Collective
564e5c89e4eSSatish Balay 
565e5c89e4eSSatish Balay   Input Parameters:
566058c9ee1SBarry Smith + comm - the MPI communicator
567a3b724e8SBarry Smith - fd   - the file pointer (valid on MPI rank 0 of the communicator), `PETSC_STDOUT` or value obtained from `PetscFOpen()`
568e5c89e4eSSatish Balay 
569e5c89e4eSSatish Balay   Level: intermediate
570e5c89e4eSSatish Balay 
571811af0c4SBarry Smith   Note:
572811af0c4SBarry Smith   If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with
573811af0c4SBarry Smith   different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators.
574e5c89e4eSSatish Balay 
575db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`,
576db781477SPatrick Sanan           `PetscViewerASCIISynchronizedPrintf()`
5770087d953SMatthew G. Knepley @*/
PetscSynchronizedFlush(MPI_Comm comm,FILE * fd)578d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd)
579d71ae5a4SJacob Faibussowitsch {
58029a5cbdcSMatthew G. Knepley   PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0;
5812d609e63SMatthew Knepley   char       *message;
582e5c89e4eSSatish Balay   MPI_Status  status;
583e5c89e4eSSatish Balay 
584e5c89e4eSSatish Balay   PetscFunctionBegin;
5859566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &comm, &tag));
5869566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
5879566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
588e5c89e4eSSatish Balay 
589e5c89e4eSSatish Balay   /* First processor waits for messages from all other processors */
590dd400576SPatrick Sanan   if (rank == 0) {
5910ec8b6e3SBarry Smith     if (!fd) fd = PETSC_STDOUT;
592e5c89e4eSSatish Balay     for (i = 1; i < size; i++) {
5939f73f8ecSBarry Smith       /* to prevent a flood of messages to process zero, request each message separately */
5949566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm));
5959566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status));
596e5c89e4eSSatish Balay       for (j = 0; j < n; j++) {
59729a5cbdcSMatthew G. Knepley         PetscMPIInt size = 0;
5982d609e63SMatthew Knepley 
5999566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status));
6009566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &message));
6019566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status));
6029566063dSJacob Faibussowitsch         PetscCall(PetscFPrintf(comm, fd, "%s", message));
6039566063dSJacob Faibussowitsch         PetscCall(PetscFree(message));
604e5c89e4eSSatish Balay       }
605e5c89e4eSSatish Balay     }
606e5c89e4eSSatish Balay   } else { /* other processors send queue to processor 0 */
607d30b0576SJed Brown     PrintfQueue next = petsc_printfqueuebase, previous;
608e5c89e4eSSatish Balay 
6099566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status));
6109566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm));
611d30b0576SJed Brown     for (i = 0; i < petsc_printfqueuelength; i++) {
6129566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm));
6136497c311SBarry Smith       PetscCallMPI(MPI_Send(next->string, (PetscMPIInt)next->size, MPI_CHAR, 0, tag, comm));
614e5c89e4eSSatish Balay       previous = next;
615e5c89e4eSSatish Balay       next     = next->next;
6169566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
6179566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
618e5c89e4eSSatish Balay     }
61902c9f0b5SLisandro Dalcin     petsc_printfqueue       = NULL;
620d30b0576SJed Brown     petsc_printfqueuelength = 0;
621e5c89e4eSSatish Balay   }
6229566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&comm));
6233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
624e5c89e4eSSatish Balay }
625e5c89e4eSSatish Balay 
626e5c89e4eSSatish Balay /*@C
627e5c89e4eSSatish Balay   PetscFPrintf - Prints to a file, only from the first
62821532e8aSBarry Smith   MPI process in the communicator.
629e5c89e4eSSatish Balay 
630cc4c1da9SBarry Smith   Not Collective
631e5c89e4eSSatish Balay 
632e5c89e4eSSatish Balay   Input Parameters:
633058c9ee1SBarry Smith + comm   - the MPI communicator
634cc4c1da9SBarry Smith . fd     - the file pointer, `PETSC_STDOUT` or value obtained from `PetscFOpen()`
6356026c97aSBarry Smith - format - the usual `printf()` format string
636e5c89e4eSSatish Balay 
637e5c89e4eSSatish Balay   Level: intermediate
638e5c89e4eSSatish Balay 
639cc4c1da9SBarry Smith   Fortran Note:
640cc4c1da9SBarry Smith   The call sequence is `PetscFPrintf`(`MPI_Comm`, fp, `character`(*), `PetscErrorCode` ierr).
641cc4c1da9SBarry Smith   That is, you can only pass a single character string from Fortran.
642cc4c1da9SBarry Smith 
643aec76313SJacob Faibussowitsch   Developer Notes:
644058c9ee1SBarry Smith   This maybe, and is, called from PETSc error handlers and `PetscMallocValidate()` hence it does not use `PetscCallMPI()` which
645058c9ee1SBarry Smith   could recursively restart the malloc validation.
646058c9ee1SBarry Smith 
647db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
648c69effb2SJacob Faibussowitsch           `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFFlush()`
649e5c89e4eSSatish Balay @*/
PetscFPrintf(MPI_Comm comm,FILE * fd,const char format[],...)650d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...)
651d71ae5a4SJacob Faibussowitsch {
6528c509928SStefano Zampini   PetscMPIInt rank;
653eae3dc7dSJacob Faibussowitsch   va_list     Argp;
654e5c89e4eSSatish Balay 
655e5c89e4eSSatish Balay   PetscFunctionBegin;
6568c509928SStefano Zampini   PetscCallMPI(MPI_Comm_rank(comm, &rank));
6578c509928SStefano Zampini   if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS);
658e5c89e4eSSatish Balay   va_start(Argp, format);
6598c509928SStefano Zampini   PetscCall(PetscVFPrintf_Private(fd, format, Argp));
660e5c89e4eSSatish Balay   va_end(Argp);
6613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
662e5c89e4eSSatish Balay }
663e5c89e4eSSatish Balay 
664e5c89e4eSSatish Balay /*@C
665e5c89e4eSSatish Balay   PetscPrintf - Prints to standard out, only from the first
66621532e8aSBarry Smith   MPI process in the communicator. Calls from other processes are ignored.
667e5c89e4eSSatish Balay 
668e5c89e4eSSatish Balay   Not Collective
669e5c89e4eSSatish Balay 
670e5c89e4eSSatish Balay   Input Parameters:
671e5c89e4eSSatish Balay + comm   - the communicator
672bfbbc7b7SBarry Smith - format - the usual `printf()` format string
673e5c89e4eSSatish Balay 
674e5c89e4eSSatish Balay   Level: intermediate
675e5c89e4eSSatish Balay 
676811af0c4SBarry Smith   Note:
677811af0c4SBarry Smith   Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc.
678811af0c4SBarry Smith   See the manual page for `PetscFormatConvert()` for details.
679b2706f25SRichard Tran Mills 
680aec76313SJacob Faibussowitsch   Fortran Notes:
681*3f7bdce8SBarry Smith   The call sequence is `PetscPrintf`(`MPI_Comm`, `character(*)`, `PetscErrorCode` ierr).
682e5c89e4eSSatish Balay   That is, you can only pass a single character string from Fortran.
683e5c89e4eSSatish Balay 
684c69effb2SJacob Faibussowitsch .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()`, `PetscFFlush()`
685e5c89e4eSSatish Balay @*/
PetscPrintf(MPI_Comm comm,const char format[],...)686d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...)
687d71ae5a4SJacob Faibussowitsch {
6888c509928SStefano Zampini   PetscMPIInt rank;
689eae3dc7dSJacob Faibussowitsch   va_list     Argp;
690e5c89e4eSSatish Balay 
691e5c89e4eSSatish Balay   PetscFunctionBegin;
6928c509928SStefano Zampini   PetscCallMPI(MPI_Comm_rank(comm, &rank));
6938c509928SStefano Zampini   if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS);
694e5c89e4eSSatish Balay   va_start(Argp, format);
6958c509928SStefano Zampini   PetscCall(PetscVFPrintf_Private(PETSC_STDOUT, format, Argp));
696e5c89e4eSSatish Balay   va_end(Argp);
6973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
698e5c89e4eSSatish Balay }
699e5c89e4eSSatish Balay 
PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)700d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...)
701d71ae5a4SJacob Faibussowitsch {
7028c509928SStefano Zampini   PetscMPIInt rank;
703eae3dc7dSJacob Faibussowitsch   va_list     Argp;
704e5c89e4eSSatish Balay 
705e5c89e4eSSatish Balay   PetscFunctionBegin;
7068c509928SStefano Zampini   PetscCallMPI(MPI_Comm_rank(comm, &rank));
7078c509928SStefano Zampini   if (PetscLikely(rank != 0)) PetscFunctionReturn(PETSC_SUCCESS);
708e5c89e4eSSatish Balay   va_start(Argp, format);
7098c509928SStefano Zampini   PetscCall(PetscVFPrintf_Private(PETSC_STDOUT, format, Argp));
710e5c89e4eSSatish Balay   va_end(Argp);
7113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
712e5c89e4eSSatish Balay }
713e5c89e4eSSatish Balay 
714e5c89e4eSSatish Balay /*@C
71521532e8aSBarry Smith   PetscSynchronizedFGets - Multiple MPI processes all get the same line from a file.
716e5c89e4eSSatish Balay 
717d083f849SBarry Smith   Collective
718e5c89e4eSSatish Balay 
719e5c89e4eSSatish Balay   Input Parameters:
72021532e8aSBarry Smith + comm - the MPI communicator
721aec76313SJacob Faibussowitsch . fp   - the file pointer
72221532e8aSBarry Smith - len  - the length of `string`
723e5c89e4eSSatish Balay 
724e5c89e4eSSatish Balay   Output Parameter:
72521532e8aSBarry Smith . string - the line read from the file, at end of file `string`[0] == 0
726e5c89e4eSSatish Balay 
727e5c89e4eSSatish Balay   Level: intermediate
728e5c89e4eSSatish Balay 
729db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`,
730db781477SPatrick Sanan           `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`
731e5c89e4eSSatish Balay @*/
PetscSynchronizedFGets(MPI_Comm comm,FILE * fp,size_t len,char string[])732d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm, FILE *fp, size_t len, char string[])
733d71ae5a4SJacob Faibussowitsch {
734e5c89e4eSSatish Balay   PetscMPIInt rank;
735e5c89e4eSSatish Balay 
736e5c89e4eSSatish Balay   PetscFunctionBegin;
7379566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
73880971c97SJames Wright   if (rank == 0) {
7396497c311SBarry Smith     if (!fgets(string, (int)len, fp)) {
740e31d4fa4SJed Brown       string[0] = 0;
741bf31d2d3SBarry Smith       PetscCheck(feof(fp), PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file due to \"%s\"", strerror(errno));
742047b9c12SMatthew G Knepley     }
743238ccf28SShri Abhyankar   }
7446497c311SBarry Smith   PetscCallMPI(MPI_Bcast(string, (PetscMPIInt)len, MPI_BYTE, 0, comm));
7453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
746e5c89e4eSSatish Balay }
747238ccf28SShri Abhyankar 
PetscFormatRealArray(char buf[],size_t len,const char * fmt,PetscInt n,const PetscReal x[])748d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[])
749d71ae5a4SJacob Faibussowitsch {
7501b5687a1SBarry Smith   PetscInt i;
7511b5687a1SBarry Smith   size_t   left, count;
7521b5687a1SBarry Smith   char    *p;
7531b5687a1SBarry Smith 
7541b5687a1SBarry Smith   PetscFunctionBegin;
7551b5687a1SBarry Smith   for (i = 0, p = buf, left = len; i < n; i++) {
7569566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i]));
75708401ef6SPierre Jolivet     PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer");
7581b5687a1SBarry Smith     left -= count;
7591b5687a1SBarry Smith     p += count - 1;
7601b5687a1SBarry Smith     *p++ = ' ';
7611b5687a1SBarry Smith   }
7621b5687a1SBarry Smith   p[i ? 0 : -1] = 0;
7633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7641b5687a1SBarry Smith }
765