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