xref: /petsc/src/sys/fileio/mprint.c (revision db81a22fc6a71a2fb932d0d72fd0961297e5f61a)
1 #define PETSC_DLL
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 PetscErrorCode PETSC_DLLEXPORT PetscFormatConvert(const char *format,char *newformat,PetscInt size)
31 {
32   PetscInt i = 0,j = 0;
33 
34   while (format[i] && i < size-1) {
35     if (format[i] == '%' && format[i+1] == 'D') {
36       newformat[j++] = '%';
37 #if !defined(PETSC_USE_64BIT_INDICES)
38       newformat[j++] = 'd';
39 #else
40       newformat[j++] = 'l';
41       newformat[j++] = 'l';
42       newformat[j++] = 'd';
43 #endif
44       i += 2;
45     } else if (format[i] == '%' && format[i+1] >= '1' && format[i+1] <= '9' && format[i+2] == 'D') {
46       newformat[j++] = '%';
47       newformat[j++] = format[i+1];
48 #if !defined(PETSC_USE_64BIT_INDICES)
49       newformat[j++] = 'd';
50 #else
51       newformat[j++] = 'l';
52       newformat[j++] = 'l';
53       newformat[j++] = 'd';
54 #endif
55       i += 3;
56     } else if (format[i] == '%' && format[i+1] == 'G') {
57       newformat[j++] = '%';
58 #if defined(PETSC_USE_SCALAR_INT)
59       newformat[j++] = 'd';
60 #elif !defined(PETSC_USE_SCALAR_LONG_DOUBLE)
61       newformat[j++] = 'g';
62 #else
63       newformat[j++] = 'L';
64       newformat[j++] = 'g';
65 #endif
66       i += 2;
67     }else {
68       newformat[j++] = format[i++];
69     }
70   }
71   newformat[j] = 0;
72   return 0;
73 }
74 
75 #undef __FUNCT__
76 #define __FUNCT__ "PetscVSNPrintf"
77 /*
78    No error handling because may be called by error handler
79 */
80 PetscErrorCode PETSC_DLLEXPORT PetscVSNPrintf(char *str,size_t len,const char *format,int *fullLength,va_list Argp)
81 {
82   /* no malloc since may be called by error handler */
83   char          *newformat;
84   char           formatbuf[8*1024];
85   size_t         oldLength,length;
86   PetscErrorCode ierr;
87 
88   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
89   if (oldLength < 8*1024) {
90     newformat = formatbuf;
91   } else {
92     ierr = PetscMalloc((oldLength+1) * sizeof(char), &newformat);CHKERRQ(ierr);
93   }
94   PetscFormatConvert(format,newformat,oldLength+1);
95   ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr);
96 #if 0
97   if (length > len) {
98     newformat[len] = '\0';
99   }
100 #endif
101 #if defined(PETSC_HAVE_VSNPRINTF_CHAR)
102   *fullLength = vsnprintf(str,len,newformat,(char *)Argp);
103 #elif defined(PETSC_HAVE_VSNPRINTF)
104   *fullLength = vsnprintf(str,len,newformat,Argp);
105 #elif defined(PETSC_HAVE__VSNPRINTF)
106   *fullLength = _vsnprintf(str,len,newformat,Argp);
107 #else
108 #error "vsnprintf not found"
109 #endif
110   if (oldLength >= 8*1024) {
111     ierr = PetscFree(newformat);CHKERRQ(ierr);
112   }
113   return 0;
114 }
115 
116 #undef __FUNCT__
117 #define __FUNCT__ "PetscZopeLog"
118 
119 PetscErrorCode PETSC_DLLEXPORT PetscZopeLog(const char *format,va_list Argp){
120   /* no malloc since may be called by error handler */
121   char     newformat[8*1024];
122   char     log[8*1024];
123 
124   extern FILE * PETSC_ZOPEFD;
125   char logstart[] = " <<<log>>>";
126   size_t len;
127   size_t formatlen;
128   PetscFormatConvert(format,newformat,8*1024);
129   PetscStrlen(logstart, &len);
130   PetscMemcpy(log, logstart, len);
131   PetscStrlen(newformat, &formatlen);
132   PetscMemcpy(&(log[len]), newformat, formatlen);
133   if(PETSC_ZOPEFD != NULL){
134 #if defined(PETSC_HAVE_VFPRINTF_CHAR)
135   vfprintf(PETSC_ZOPEFD,log,(char *)Argp);
136 #else
137   vfprintf(PETSC_ZOPEFD,log,Argp);
138 #endif
139   fflush(PETSC_ZOPEFD);
140 }
141   return 0;
142 }
143 
144 #undef __FUNCT__
145 #define __FUNCT__ "PetscVFPrintf"
146 /*
147    All PETSc standard out and error messages are sent through this function; so, in theory, this can
148    can be replaced with something that does not simply write to a file.
149 
150    Note: For error messages this may be called by a process, for regular standard out it is
151    called only by process 0 of a given communicator
152 
153    No error handling because may be called by error handler
154 */
155 PetscErrorCode PETSC_DLLEXPORT PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp)
156 {
157   /* no malloc since may be called by error handler (assume no long messages in errors) */
158   char        *newformat;
159   char         formatbuf[8*1024];
160   size_t       oldLength;
161   extern FILE *PETSC_ZOPEFD;
162 
163   PetscStrlen(format, &oldLength);
164   if (oldLength < 8*1024) {
165     newformat = formatbuf;
166   } else {
167     (void)PetscMalloc((oldLength+1) * sizeof(char), &newformat);
168   }
169   PetscFormatConvert(format,newformat,oldLength+1);
170   if(PETSC_ZOPEFD != NULL && PETSC_ZOPEFD != PETSC_STDOUT){
171     va_list s;
172 #if defined(PETSC_HAVE_VA_COPY)
173     va_copy(s, Argp);
174 #elif defined(PETSC_HAVE___VA_COPY)
175     __va_copy(s, Argp);
176 #else
177     SETERRQ(PETSC_ERR_SUP_SYS,"Zope not supported due to missing va_copy()");
178 #endif
179 
180 #if defined(PETSC_HAVE_VA_COPY) || defined(PETSC_HAVE___VA_COPY)
181 #if defined(PETSC_HAVE_VFPRINTF_CHAR)
182     vfprintf(PETSC_ZOPEFD,newformat,(char *)s);
183 #else
184     vfprintf(PETSC_ZOPEFD,newformat,s);
185 #endif
186     fflush(PETSC_ZOPEFD);
187 #endif
188   }
189 
190 #if defined(PETSC_HAVE_VFPRINTF_CHAR)
191   vfprintf(fd,newformat,(char *)Argp);
192 #else
193   vfprintf(fd,newformat,Argp);
194 #endif
195   fflush(fd);
196   if (oldLength >= 8*1024) {
197     if (PetscFree(newformat)) {};
198   }
199   return 0;
200 }
201 
202 #undef __FUNCT__
203 #define __FUNCT__ "PetscSNPrintf"
204 /*@C
205     PetscSNPrintf - Prints to a string of given length
206 
207     Not Collective
208 
209     Input Parameters:
210 +   str - the string to print to
211 .   len - the length of str
212 .   format - the usual printf() format string
213 -   any arguments
214 
215    Level: intermediate
216 
217 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
218           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
219 @*/
220 PetscErrorCode PETSC_DLLEXPORT PetscSNPrintf(char *str,size_t len,const char format[],...)
221 {
222   PetscErrorCode ierr;
223   int            fullLength;
224   va_list        Argp;
225 
226   PetscFunctionBegin;
227   va_start(Argp,format);
228   ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr);
229   PetscFunctionReturn(0);
230 }
231 
232 /* ----------------------------------------------------------------------- */
233 
234 PrintfQueue queue       = 0,queuebase = 0;
235 int         queuelength = 0;
236 FILE        *queuefile  = PETSC_NULL;
237 
238 #undef __FUNCT__
239 #define __FUNCT__ "PetscSynchronizedPrintf"
240 /*@C
241     PetscSynchronizedPrintf - Prints synchronized output from several processors.
242     Output of the first processor is followed by that of the second, etc.
243 
244     Not Collective
245 
246     Input Parameters:
247 +   comm - the communicator
248 -   format - the usual printf() format string
249 
250    Level: intermediate
251 
252     Notes:
253     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
254     from all the processors to be printed.
255 
256     Fortran Note:
257     The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
258     That is, you can only pass a single character string from Fortran.
259 
260 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(),
261           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
262 @*/
263 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...)
264 {
265   PetscErrorCode ierr;
266   PetscMPIInt    rank;
267 
268   PetscFunctionBegin;
269   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
270 
271   /* First processor prints immediately to stdout */
272   if (!rank) {
273     va_list Argp;
274     va_start(Argp,format);
275     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
276     if (petsc_history) {
277       va_start(Argp,format);
278       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
279     }
280     va_end(Argp);
281   } else { /* other processors add to local queue */
282     va_list     Argp;
283     PrintfQueue next;
284     int         fullLength = 8191;
285 
286     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
287     if (queue) {queue->next = next; queue = next; queue->next = 0;}
288     else       {queuebase   = queue = next;}
289     queuelength++;
290     next->size = -1;
291     while(fullLength >= next->size) {
292       next->size = fullLength+1;
293       ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr);
294       va_start(Argp,format);
295       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
296       ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr);
297       va_end(Argp);
298     }
299   }
300 
301   PetscFunctionReturn(0);
302 }
303 
304 #undef __FUNCT__
305 #define __FUNCT__ "PetscSynchronizedFPrintf"
306 /*@C
307     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
308     several processors.  Output of the first processor is followed by that of the
309     second, etc.
310 
311     Not Collective
312 
313     Input Parameters:
314 +   comm - the communicator
315 .   fd - the file pointer
316 -   format - the usual printf() format string
317 
318     Level: intermediate
319 
320     Notes:
321     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
322     from all the processors to be printed.
323 
324 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
325           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
326 
327 @*/
328 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...)
329 {
330   PetscErrorCode ierr;
331   PetscMPIInt    rank;
332 
333   PetscFunctionBegin;
334   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
335 
336   /* First processor prints immediately to fp */
337   if (!rank) {
338     va_list Argp;
339     va_start(Argp,format);
340     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
341     queuefile = fp;
342     if (petsc_history && (fp !=petsc_history)) {
343       va_start(Argp,format);
344       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
345     }
346     va_end(Argp);
347   } else { /* other processors add to local queue */
348     va_list     Argp;
349     PrintfQueue next;
350     int         fullLength = 8191;
351     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
352     if (queue) {queue->next = next; queue = next; queue->next = 0;}
353     else       {queuebase   = queue = next;}
354     queuelength++;
355     next->size = -1;
356     while(fullLength >= next->size) {
357       next->size = fullLength+1;
358       ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr);
359       va_start(Argp,format);
360       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
361       ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr);
362       va_end(Argp);
363     }
364   }
365   PetscFunctionReturn(0);
366 }
367 
368 #undef __FUNCT__
369 #define __FUNCT__ "PetscSynchronizedFlush"
370 /*@
371     PetscSynchronizedFlush - Flushes to the screen output from all processors
372     involved in previous PetscSynchronizedPrintf() calls.
373 
374     Collective on MPI_Comm
375 
376     Input Parameters:
377 .   comm - the communicator
378 
379     Level: intermediate
380 
381     Notes:
382     Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with
383     different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush().
384 
385 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(),
386           PetscViewerASCIISynchronizedPrintf()
387 @*/
388 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFlush(MPI_Comm comm)
389 {
390   PetscErrorCode ierr;
391   PetscMPIInt    rank,size,tag,i,j,n;
392   char          *message;
393   MPI_Status     status;
394   FILE           *fd;
395 
396   PetscFunctionBegin;
397   ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
398   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
399   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
400 
401   /* First processor waits for messages from all other processors */
402   if (!rank) {
403     if (queuefile) {
404       fd = queuefile;
405     } else {
406       fd = PETSC_STDOUT;
407     }
408     for (i=1; i<size; i++) {
409       ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
410       for (j=0; j<n; j++) {
411         int size;
412 
413         ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
414         ierr = PetscMalloc(size * sizeof(char), &message);CHKERRQ(ierr);
415         ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
416         ierr = PetscFPrintf(comm,fd,"%s",message);
417         ierr = PetscFree(message);CHKERRQ(ierr);
418       }
419     }
420     queuefile = PETSC_NULL;
421   } else { /* other processors send queue to processor 0 */
422     PrintfQueue next = queuebase,previous;
423 
424     ierr = MPI_Send(&queuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
425     for (i=0; i<queuelength; i++) {
426       ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
427       ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
428       previous = next;
429       next     = next->next;
430       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
431       ierr     = PetscFree(previous);CHKERRQ(ierr);
432     }
433     queue       = 0;
434     queuelength = 0;
435   }
436   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
437   PetscFunctionReturn(0);
438 }
439 
440 /* ---------------------------------------------------------------------------------------*/
441 
442 #undef __FUNCT__
443 #define __FUNCT__ "PetscFPrintf"
444 /*@C
445     PetscFPrintf - Prints to a file, only from the first
446     processor in the communicator.
447 
448     Not Collective
449 
450     Input Parameters:
451 +   comm - the communicator
452 .   fd - the file pointer
453 -   format - the usual printf() format string
454 
455     Level: intermediate
456 
457     Fortran Note:
458     This routine is not supported in Fortran.
459 
460    Concepts: printing^in parallel
461    Concepts: printf^in parallel
462 
463 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
464           PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush()
465 @*/
466 PetscErrorCode PETSC_DLLEXPORT PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...)
467 {
468   PetscErrorCode ierr;
469   PetscMPIInt    rank;
470 
471   PetscFunctionBegin;
472   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
473   if (!rank) {
474     va_list Argp;
475     va_start(Argp,format);
476     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
477     if (petsc_history && (fd !=petsc_history)) {
478       va_start(Argp,format);
479       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
480       }
481     va_end(Argp);
482   }
483   PetscFunctionReturn(0);
484 }
485 
486 #undef __FUNCT__
487 #define __FUNCT__ "PetscPrintf"
488 /*@C
489     PetscPrintf - Prints to standard out, only from the first
490     processor in the communicator.
491 
492     Not Collective
493 
494     Input Parameters:
495 +   comm - the communicator
496 -   format - the usual printf() format string
497 
498    Level: intermediate
499 
500     Fortran Note:
501     The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
502     That is, you can only pass a single character string from Fortran.
503 
504    Notes: %A is replace with %g unless the value is < 1.e-12 when it is
505           replaced with < 1.e-12
506 
507    Concepts: printing^in parallel
508    Concepts: printf^in parallel
509 
510 .seealso: PetscFPrintf(), PetscSynchronizedPrintf()
511 @*/
512 PetscErrorCode PETSC_DLLEXPORT PetscPrintf(MPI_Comm comm,const char format[],...)
513 {
514   PetscErrorCode ierr;
515   PetscMPIInt    rank;
516   size_t         len;
517   char           *nformat,*sub1,*sub2;
518   PetscReal      value;
519 
520   PetscFunctionBegin;
521   if (!comm) comm = PETSC_COMM_WORLD;
522   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
523   if (!rank) {
524     va_list Argp;
525     va_start(Argp,format);
526 
527     ierr = PetscStrstr(format,"%A",&sub1);CHKERRQ(ierr);
528     if (sub1) {
529       ierr = PetscStrstr(format,"%",&sub2);CHKERRQ(ierr);
530       if (sub1 != sub2) SETERRQ(PETSC_ERR_ARG_WRONG,"%%A format must be first in format string");
531       ierr    = PetscStrlen(format,&len);CHKERRQ(ierr);
532       ierr    = PetscMalloc((len+16)*sizeof(char),&nformat);CHKERRQ(ierr);
533       ierr    = PetscStrcpy(nformat,format);CHKERRQ(ierr);
534       ierr    = PetscStrstr(nformat,"%",&sub2);CHKERRQ(ierr);
535       sub2[0] = 0;
536       value   = (double)va_arg(Argp,double);
537       if (PetscAbsReal(value) < 1.e-12) {
538         ierr    = PetscStrcat(nformat,"< 1.e-12");CHKERRQ(ierr);
539       } else {
540         ierr    = PetscStrcat(nformat,"%g");CHKERRQ(ierr);
541         va_end(Argp);
542         va_start(Argp,format);
543       }
544       ierr    = PetscStrcat(nformat,sub1+2);CHKERRQ(ierr);
545     } else {
546       nformat = (char*)format;
547     }
548     ierr = (*PetscVFPrintf)(PETSC_STDOUT,nformat,Argp);CHKERRQ(ierr);
549     if (petsc_history) {
550       va_start(Argp,format);
551       ierr = (*PetscVFPrintf)(petsc_history,nformat,Argp);CHKERRQ(ierr);
552     }
553     va_end(Argp);
554     if (sub1) {ierr = PetscFree(nformat);CHKERRQ(ierr);}
555   }
556   PetscFunctionReturn(0);
557 }
558 
559 /* ---------------------------------------------------------------------------------------*/
560 #undef __FUNCT__
561 #define __FUNCT__ "PetscHelpPrintfDefault"
562 PetscErrorCode PETSC_DLLEXPORT PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)
563 {
564   PetscErrorCode ierr;
565   PetscMPIInt    rank;
566 
567   PetscFunctionBegin;
568   if (!comm) comm = PETSC_COMM_WORLD;
569   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
570   if (!rank) {
571     va_list Argp;
572     va_start(Argp,format);
573     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
574     if (petsc_history) {
575       va_start(Argp,format);
576       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
577     }
578     va_end(Argp);
579   }
580   PetscFunctionReturn(0);
581 }
582 
583 /* ---------------------------------------------------------------------------------------*/
584 
585 
586 #undef __FUNCT__
587 #define __FUNCT__ "PetscSynchronizedFGets"
588 /*@C
589     PetscSynchronizedFGets - Several processors all get the same line from a file.
590 
591     Collective on MPI_Comm
592 
593     Input Parameters:
594 +   comm - the communicator
595 .   fd - the file pointer
596 -   len - the length of the output buffer
597 
598     Output Parameter:
599 .   string - the line read from the file
600 
601     Level: intermediate
602 
603 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
604           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
605 
606 @*/
607 PetscErrorCode PETSC_DLLEXPORT PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[])
608 {
609   PetscErrorCode ierr;
610   PetscMPIInt    rank;
611 
612   PetscFunctionBegin;
613   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
614 
615   if (!rank) {
616     fgets(string,len,fp);
617   }
618   ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr);
619   PetscFunctionReturn(0);
620 }
621