xref: /petsc/src/sys/fileio/mprint.c (revision 7d0a6c19129e7069c8a40e210b34ed62989173db)
1 
2 /*
3       Utilites routines to add simple ASCII IO capability.
4 */
5 #include "../src/sys/fileio/mprint.h"
6 /*
7    If petsc_history is on, then all Petsc*Printf() results are saved
8    if the appropriate (usually .petschistory) file.
9 */
10 extern FILE *petsc_history;
11 /*
12      Allows one to overwrite where standard out is sent. For example
13      PETSC_STDOUT = fopen("/dev/ttyXX","w") will cause all standard out
14      writes to go to terminal XX; assuming you have write permission there
15 */
16 FILE *PETSC_STDOUT = 0;
17 /*
18      Allows one to overwrite where standard error is sent. For example
19      PETSC_STDERR = fopen("/dev/ttyXX","w") will cause all standard error
20      writes to go to terminal XX; assuming you have write permission there
21 */
22 FILE *PETSC_STDERR = 0;
23 /*
24      Used to output to Zope
25 */
26 FILE *PETSC_ZOPEFD = 0;
27 
28 #undef __FUNCT__
29 #define __FUNCT__ "PetscFormatConvert"
30 /*@C
31      PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string
32 
33    Input Parameters:
34 +   format - the PETSc format string
35 .   newformat - the location to put the standard C format string values
36 -   size - the length of newformat
37 
38     Note: this exists so we can have the same code when PetscInt is either int or long long and PetscScalar is either double or float
39 
40  Level: developer
41 
42 @*/
43 PetscErrorCode  PetscFormatConvert(const char *format,char *newformat,size_t size)
44 {
45   PetscInt i = 0,j = 0;
46 
47   while (format[i] && i < (PetscInt)size-1) {
48     if (format[i] == '%' && format[i+1] == 'D') {
49       newformat[j++] = '%';
50 #if !defined(PETSC_USE_64BIT_INDICES)
51       newformat[j++] = 'd';
52 #else
53       newformat[j++] = 'l';
54       newformat[j++] = 'l';
55       newformat[j++] = 'd';
56 #endif
57       i += 2;
58     } else if (format[i] == '%' && format[i+1] >= '1' && format[i+1] <= '9' && format[i+2] == 'D') {
59       newformat[j++] = '%';
60       newformat[j++] = format[i+1];
61 #if !defined(PETSC_USE_64BIT_INDICES)
62       newformat[j++] = 'd';
63 #else
64       newformat[j++] = 'l';
65       newformat[j++] = 'l';
66       newformat[j++] = 'd';
67 #endif
68       i += 3;
69     } else if (format[i] == '%' && format[i+1] == 'G') {
70       newformat[j++] = '%';
71 #if defined(PETSC_USE_SCALAR_INT)
72       newformat[j++] = 'd';
73 #elif !defined(PETSC_USE_SCALAR_LONG_DOUBLE)
74       newformat[j++] = 'g';
75 #else
76       newformat[j++] = 'L';
77       newformat[j++] = 'g';
78 #endif
79       i += 2;
80     }else {
81       newformat[j++] = format[i++];
82     }
83   }
84   newformat[j] = 0;
85   return 0;
86 }
87 
88 #undef __FUNCT__
89 #define __FUNCT__ "PetscVSNPrintf"
90 /*@C
91      PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the
92        function arguments into a string using the format statement.
93 
94    Input Parameters:
95 +   str - location to put result
96 .   len - the amount of space in str
97 +   format - the PETSc format string
98 -   fullLength - the amount of space in str actually used.
99 
100     Note:  No error handling because may be called by error handler
101 
102  Level: developer
103 
104 @*/
105 PetscErrorCode  PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp)
106 {
107   /* no malloc since may be called by error handler */
108   char          *newformat;
109   char           formatbuf[8*1024];
110   size_t         oldLength,length;
111   PetscErrorCode ierr;
112 
113   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
114   if (oldLength < 8*1024) {
115     newformat = formatbuf;
116   } else {
117     ierr = PetscMalloc((oldLength+1) * sizeof(char), &newformat);CHKERRQ(ierr);
118   }
119   PetscFormatConvert(format,newformat,oldLength+1);
120   ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr);
121 #if 0
122   if (length > len) {
123     newformat[len] = '\0';
124   }
125 #endif
126 #if defined(PETSC_HAVE_VSNPRINTF_CHAR)
127   *fullLength = vsnprintf(str,len,newformat,(char *)Argp);
128 #elif defined(PETSC_HAVE_VSNPRINTF)
129   *fullLength = vsnprintf(str,len,newformat,Argp);
130 #elif defined(PETSC_HAVE__VSNPRINTF)
131   *fullLength = _vsnprintf(str,len,newformat,Argp);
132 #else
133 #error "vsnprintf not found"
134 #endif
135   if (oldLength >= 8*1024) {
136     ierr = PetscFree(newformat);CHKERRQ(ierr);
137   }
138   return 0;
139 }
140 
141 #undef __FUNCT__
142 #define __FUNCT__ "PetscZopeLog"
143 PetscErrorCode  PetscZopeLog(const char *format,va_list Argp)
144 {
145   /* no malloc since may be called by error handler */
146   char        newformat[8*1024];
147   char        log[8*1024];
148   char        logstart[] = " <<<log>>>";
149   size_t      len,formatlen;
150 
151   PetscFormatConvert(format,newformat,8*1024);
152   PetscStrlen(logstart, &len);
153   PetscMemcpy(log, logstart, len);
154   PetscStrlen(newformat, &formatlen);
155   PetscMemcpy(&(log[len]), newformat, formatlen);
156   if (PETSC_ZOPEFD){
157 #if defined(PETSC_HAVE_VFPRINTF_CHAR)
158     vfprintf(PETSC_ZOPEFD,log,(char *)Argp);
159 #else
160     vfprintf(PETSC_ZOPEFD,log,Argp);
161 #endif
162     fflush(PETSC_ZOPEFD);
163   }
164   return 0;
165 }
166 
167 #undef __FUNCT__
168 #define __FUNCT__ "PetscVFPrintfDefault"
169 /*@C
170      PetscVFPrintf -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
171         can be replaced with something that does not simply write to a file.
172 
173       To use, write your own function for example,
174 $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp)
175 ${
176 $  PetscErrorCode ierr;
177 $
178 $  PetscFunctionBegin;
179 $   if (fd != stdout && fd != stderr) {  handle regular files
180 $      ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERR(ierr);
181 $  } else {
182 $     char   buff[BIG];
183 $     size_t length;
184 $     ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr);
185 $     now send buff to whatever stream or whatever you want
186 $ }
187 $ PetscFunctionReturn(0);
188 $}
189 then before the call to PetscInitialize() do the assignment
190 $    PetscVFPrintf = mypetscvfprintf;
191 
192       Notes: For error messages this may be called by any process, for regular standard out it is
193           called only by process 0 of a given communicator
194 
195       No error handling because may be called by error handler
196 
197   Level:  developer
198 
199 .seealso: PetscVSNPrintf(), PetscErrorPrintf()
200 
201 @*/
202 PetscErrorCode  PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp)
203 {
204   /* no malloc since may be called by error handler (assume no long messages in errors) */
205   char        *newformat;
206   char         formatbuf[8*1024];
207   size_t       oldLength;
208 
209   PetscStrlen(format, &oldLength);
210   if (oldLength < 8*1024) {
211     newformat = formatbuf;
212   } else {
213     (void)PetscMalloc((oldLength+1) * sizeof(char), &newformat);
214   }
215   PetscFormatConvert(format,newformat,oldLength+1);
216 
217 #if defined(PETSC_HAVE_VFPRINTF_CHAR)
218   vfprintf(fd,newformat,(char *)Argp);
219 #else
220   vfprintf(fd,newformat,Argp);
221 #endif
222   fflush(fd);
223   if (oldLength >= 8*1024) {
224     (void)PetscFree(newformat);
225   }
226   return 0;
227 }
228 
229 #undef __FUNCT__
230 #define __FUNCT__ "PetscSNPrintf"
231 /*@C
232     PetscSNPrintf - Prints to a string of given length
233 
234     Not Collective
235 
236     Input Parameters:
237 +   str - the string to print to
238 .   len - the length of str
239 .   format - the usual printf() format string
240 -   any arguments
241 
242    Level: intermediate
243 
244 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
245           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
246 @*/
247 PetscErrorCode  PetscSNPrintf(char *str,size_t len,const char format[],...)
248 {
249   PetscErrorCode ierr;
250   size_t         fullLength;
251   va_list        Argp;
252 
253   PetscFunctionBegin;
254   va_start(Argp,format);
255   ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr);
256   PetscFunctionReturn(0);
257 }
258 
259 /* ----------------------------------------------------------------------- */
260 
261 PrintfQueue queue       = 0,queuebase = 0;
262 int         queuelength = 0;
263 FILE        *queuefile  = PETSC_NULL;
264 
265 #undef __FUNCT__
266 #define __FUNCT__ "PetscSynchronizedPrintf"
267 /*@C
268     PetscSynchronizedPrintf - Prints synchronized output from several processors.
269     Output of the first processor is followed by that of the second, etc.
270 
271     Not Collective
272 
273     Input Parameters:
274 +   comm - the communicator
275 -   format - the usual printf() format string
276 
277    Level: intermediate
278 
279     Notes:
280     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
281     from all the processors to be printed.
282 
283     Fortran Note:
284     The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
285     That is, you can only pass a single character string from Fortran.
286 
287 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(),
288           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
289 @*/
290 PetscErrorCode  PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...)
291 {
292   PetscErrorCode ierr;
293   PetscMPIInt    rank;
294 
295   PetscFunctionBegin;
296   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
297 
298   /* First processor prints immediately to stdout */
299   if (!rank) {
300     va_list Argp;
301     va_start(Argp,format);
302     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
303     if (petsc_history) {
304       va_start(Argp,format);
305       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
306     }
307     va_end(Argp);
308   } else { /* other processors add to local queue */
309     va_list     Argp;
310     PrintfQueue next;
311     size_t      fullLength = 8191;
312 
313     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
314     if (queue) {queue->next = next; queue = next; queue->next = 0;}
315     else       {queuebase   = queue = next;}
316     queuelength++;
317     next->size = -1;
318     while((PetscInt)fullLength >= next->size) {
319       next->size = fullLength+1;
320       ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr);
321       va_start(Argp,format);
322       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
323       ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr);
324       va_end(Argp);
325     }
326   }
327 
328   PetscFunctionReturn(0);
329 }
330 
331 #undef __FUNCT__
332 #define __FUNCT__ "PetscSynchronizedFPrintf"
333 /*@C
334     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
335     several processors.  Output of the first processor is followed by that of the
336     second, etc.
337 
338     Not Collective
339 
340     Input Parameters:
341 +   comm - the communicator
342 .   fd - the file pointer
343 -   format - the usual printf() format string
344 
345     Level: intermediate
346 
347     Notes:
348     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
349     from all the processors to be printed.
350 
351 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
352           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
353 
354 @*/
355 PetscErrorCode  PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...)
356 {
357   PetscErrorCode ierr;
358   PetscMPIInt    rank;
359 
360   PetscFunctionBegin;
361   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
362 
363   /* First processor prints immediately to fp */
364   if (!rank) {
365     va_list Argp;
366     va_start(Argp,format);
367     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
368     queuefile = fp;
369     if (petsc_history && (fp !=petsc_history)) {
370       va_start(Argp,format);
371       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
372     }
373     va_end(Argp);
374   } else { /* other processors add to local queue */
375     va_list     Argp;
376     PrintfQueue next;
377     size_t      fullLength = 8191;
378     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
379     if (queue) {queue->next = next; queue = next; queue->next = 0;}
380     else       {queuebase   = queue = next;}
381     queuelength++;
382     next->size = -1;
383     while((PetscInt)fullLength >= next->size) {
384       next->size = fullLength+1;
385       ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr);
386       va_start(Argp,format);
387       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
388       ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr);
389       va_end(Argp);
390     }
391   }
392   PetscFunctionReturn(0);
393 }
394 
395 #undef __FUNCT__
396 #define __FUNCT__ "PetscSynchronizedFlush"
397 /*@
398     PetscSynchronizedFlush - Flushes to the screen output from all processors
399     involved in previous PetscSynchronizedPrintf() calls.
400 
401     Collective on MPI_Comm
402 
403     Input Parameters:
404 .   comm - the communicator
405 
406     Level: intermediate
407 
408     Notes:
409     Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with
410     different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush().
411 
412 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(),
413           PetscViewerASCIISynchronizedPrintf()
414 @*/
415 PetscErrorCode  PetscSynchronizedFlush(MPI_Comm comm)
416 {
417   PetscErrorCode ierr;
418   PetscMPIInt    rank,size,tag,i,j,n,dummy = 0;
419   char          *message;
420   MPI_Status     status;
421   FILE           *fd;
422 
423   PetscFunctionBegin;
424   ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
425   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
426   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
427 
428   /* First processor waits for messages from all other processors */
429   if (!rank) {
430     if (queuefile) {
431       fd = queuefile;
432     } else {
433       fd = PETSC_STDOUT;
434     }
435     for (i=1; i<size; i++) {
436       /* to prevent a flood of messages to process zero, request each message separately */
437       ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
438       ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
439       for (j=0; j<n; j++) {
440         PetscMPIInt size;
441 
442         ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
443         ierr = PetscMalloc(size * sizeof(char), &message);CHKERRQ(ierr);
444         ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
445         ierr = PetscFPrintf(comm,fd,"%s",message);
446         ierr = PetscFree(message);CHKERRQ(ierr);
447       }
448     }
449     queuefile = PETSC_NULL;
450   } else { /* other processors send queue to processor 0 */
451     PrintfQueue next = queuebase,previous;
452 
453     ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
454     ierr = MPI_Send(&queuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
455     for (i=0; i<queuelength; i++) {
456       ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
457       ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
458       previous = next;
459       next     = next->next;
460       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
461       ierr     = PetscFree(previous);CHKERRQ(ierr);
462     }
463     queue       = 0;
464     queuelength = 0;
465   }
466   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
467   PetscFunctionReturn(0);
468 }
469 
470 /* ---------------------------------------------------------------------------------------*/
471 
472 #undef __FUNCT__
473 #define __FUNCT__ "PetscFPrintf"
474 /*@C
475     PetscFPrintf - Prints to a file, only from the first
476     processor in the communicator.
477 
478     Not Collective
479 
480     Input Parameters:
481 +   comm - the communicator
482 .   fd - the file pointer
483 -   format - the usual printf() format string
484 
485     Level: intermediate
486 
487     Fortran Note:
488     This routine is not supported in Fortran.
489 
490    Concepts: printing^in parallel
491    Concepts: printf^in parallel
492 
493 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
494           PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush()
495 @*/
496 PetscErrorCode  PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...)
497 {
498   PetscErrorCode ierr;
499   PetscMPIInt    rank;
500 
501   PetscFunctionBegin;
502   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
503   if (!rank) {
504     va_list Argp;
505     va_start(Argp,format);
506     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
507     if (petsc_history && (fd !=petsc_history)) {
508       va_start(Argp,format);
509       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
510       }
511     va_end(Argp);
512   }
513   PetscFunctionReturn(0);
514 }
515 
516 #undef __FUNCT__
517 #define __FUNCT__ "PetscPrintf"
518 /*@C
519     PetscPrintf - Prints to standard out, only from the first
520     processor in the communicator.
521 
522     Not Collective
523 
524     Input Parameters:
525 +   comm - the communicator
526 -   format - the usual printf() format string
527 
528    Level: intermediate
529 
530     Fortran Note:
531     The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
532     That is, you can only pass a single character string from Fortran.
533 
534    Notes: The %A format specifier is special.  It assumes an argument of type PetscReal
535           and is replaced with %G unless the absolute value is < 1.e-12 when it is replaced
536           with "< 1.e-12" (1.e-6 for single precision).
537 
538    Concepts: printing^in parallel
539    Concepts: printf^in parallel
540 
541 .seealso: PetscFPrintf(), PetscSynchronizedPrintf()
542 @*/
543 PetscErrorCode  PetscPrintf(MPI_Comm comm,const char format[],...)
544 {
545   PetscErrorCode ierr;
546   PetscMPIInt    rank;
547   size_t         len;
548   char           *nformat,*sub1,*sub2;
549   PetscReal      value;
550 
551   PetscFunctionBegin;
552   if (!comm) comm = PETSC_COMM_WORLD;
553   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
554   if (!rank) {
555     va_list Argp;
556     va_start(Argp,format);
557 
558     ierr = PetscStrstr(format,"%A",&sub1);CHKERRQ(ierr);
559     if (sub1) {
560       ierr = PetscStrstr(format,"%",&sub2);CHKERRQ(ierr);
561       if (sub1 != sub2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"%%A format must be first in format string");
562       ierr    = PetscStrlen(format,&len);CHKERRQ(ierr);
563       ierr    = PetscMalloc((len+16)*sizeof(char),&nformat);CHKERRQ(ierr);
564       ierr    = PetscStrcpy(nformat,format);CHKERRQ(ierr);
565       ierr    = PetscStrstr(nformat,"%",&sub2);CHKERRQ(ierr);
566       sub2[0] = 0;
567       value   = va_arg(Argp,double);
568 #if defined(PETSC_USE_SCALAR_SINGLE)
569       if (PetscAbsReal(value) < 1.e-6) {
570         ierr    = PetscStrcat(nformat,"< 1.e-6");CHKERRQ(ierr);
571 #else
572       if (PetscAbsReal(value) < 1.e-12) {
573         ierr    = PetscStrcat(nformat,"< 1.e-12");CHKERRQ(ierr);
574 #endif
575       } else {
576         ierr    = PetscStrcat(nformat,"%G");CHKERRQ(ierr);
577         va_end(Argp);
578         va_start(Argp,format);
579       }
580       ierr    = PetscStrcat(nformat,sub1+2);CHKERRQ(ierr);
581     } else {
582       nformat = (char*)format;
583     }
584     ierr = (*PetscVFPrintf)(PETSC_STDOUT,nformat,Argp);CHKERRQ(ierr);
585     if (petsc_history) {
586       va_start(Argp,format);
587       ierr = (*PetscVFPrintf)(petsc_history,nformat,Argp);CHKERRQ(ierr);
588     }
589     va_end(Argp);
590     if (sub1) {ierr = PetscFree(nformat);CHKERRQ(ierr);}
591   }
592   PetscFunctionReturn(0);
593 }
594 
595 /* ---------------------------------------------------------------------------------------*/
596 #undef __FUNCT__
597 #define __FUNCT__ "PetscHelpPrintfDefault"
598 /*@C
599      PetscHelpPrintf -  All PETSc help messages are passing through this function. You can change how help messages are printed by
600         replacinng it  with something that does not simply write to a stdout.
601 
602       To use, write your own function for example,
603 $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....)
604 ${
605 $ PetscFunctionReturn(0);
606 $}
607 then before the call to PetscInitialize() do the assignment
608 $    PetscHelpPrintf = mypetschelpprintf;
609 
610   Note: the default routine used is called PetscHelpPrintfDefault().
611 
612   Level:  developer
613 
614 .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf()
615 @*/
616 PetscErrorCode  PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)
617 {
618   PetscErrorCode ierr;
619   PetscMPIInt    rank;
620 
621   PetscFunctionBegin;
622   if (!comm) comm = PETSC_COMM_WORLD;
623   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
624   if (!rank) {
625     va_list Argp;
626     va_start(Argp,format);
627     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
628     if (petsc_history) {
629       va_start(Argp,format);
630       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
631     }
632     va_end(Argp);
633   }
634   PetscFunctionReturn(0);
635 }
636 
637 /* ---------------------------------------------------------------------------------------*/
638 
639 
640 #undef __FUNCT__
641 #define __FUNCT__ "PetscSynchronizedFGets"
642 /*@C
643     PetscSynchronizedFGets - Several processors all get the same line from a file.
644 
645     Collective on MPI_Comm
646 
647     Input Parameters:
648 +   comm - the communicator
649 .   fd - the file pointer
650 -   len - the length of the output buffer
651 
652     Output Parameter:
653 .   string - the line read from the file
654 
655     Level: intermediate
656 
657 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
658           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
659 
660 @*/
661 PetscErrorCode  PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[])
662 {
663   PetscErrorCode ierr;
664   PetscMPIInt    rank;
665 
666   PetscFunctionBegin;
667   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
668 
669   if (!rank) {
670     (void) fgets(string,len,fp); /* Not very useful error behavior, but what is desired behavior for attempt to read at EOF? */
671   }
672   ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr);
673   PetscFunctionReturn(0);
674 }
675 
676 #if defined(PETSC_HAVE_MATLAB_ENGINE)
677 #include "mex.h"
678 #undef __FUNCT__
679 #define __FUNCT__ "PetscVFPrintf_Matlab"
680 PetscErrorCode  PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp)
681 {
682   PetscErrorCode ierr;
683 
684   PetscFunctionBegin;
685   if (fd != stdout && fd != stderr) { /* handle regular files */
686     ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERRQ(ierr);
687   } else {
688     size_t len=8*1024,length;
689     char   buf[len];
690 
691     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
692     mexPrintf("%s",buf);
693  }
694  PetscFunctionReturn(0);
695 }
696 #endif
697