xref: /petsc/src/sys/classes/viewer/impls/ascii/vcreatea.c (revision 3e1910f1ab6113d8365e15c6b8c907ccce7ce4ea)
1 
2 #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>  /*I     "petscsys.h"   I*/
3 
4 /* ---------------------------------------------------------------------*/
5 /*
6     The variable Petsc_Viewer_Stdout_keyval is used to indicate an MPI attribute that
7   is attached to a communicator, in this case the attribute is a PetscViewer.
8 */
9 static PetscMPIInt Petsc_Viewer_Stdout_keyval = MPI_KEYVAL_INVALID;
10 
11 #undef __FUNCT__
12 #define __FUNCT__ "PetscViewerASCIIGetStdout"
13 /*@C
14    PetscViewerASCIIGetStdout - Creates a ASCII PetscViewer shared by all processors
15                     in a communicator. Error returning version of PETSC_VIEWER_STDOUT_()
16 
17    Collective on MPI_Comm
18 
19    Input Parameter:
20 .  comm - the MPI communicator to share the PetscViewer
21 
22    Level: beginner
23 
24    Notes:
25      This should be used in all PETSc source code instead of PETSC_VIEWER_STDOUT_()
26 
27 .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
28           PETSC_VIEWER_STDOUT_SELF
29 
30 @*/
31 PetscErrorCode  PetscViewerASCIIGetStdout(MPI_Comm comm,PetscViewer *viewer)
32 {
33   PetscErrorCode ierr;
34   PetscBool      flg;
35   MPI_Comm       ncomm;
36 
37   PetscFunctionBegin;
38   ierr = PetscCommDuplicate(comm,&ncomm,NULL);CHKERRQ(ierr);
39   if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) {
40     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Stdout_keyval,0);CHKERRQ(ierr);
41   }
42   ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Stdout_keyval,(void**)viewer,(PetscMPIInt*)&flg);CHKERRQ(ierr);
43   if (!flg) { /* PetscViewer not yet created */
44     ierr = PetscViewerASCIIOpen(ncomm,"stdout",viewer);CHKERRQ(ierr);
45     ierr = PetscObjectRegisterDestroy((PetscObject)*viewer);CHKERRQ(ierr);
46     ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Stdout_keyval,(void*)*viewer);CHKERRQ(ierr);
47   }
48   ierr = PetscCommDestroy(&ncomm);CHKERRQ(ierr);
49   PetscFunctionReturn(0);
50 }
51 
52 #undef __FUNCT__
53 #define __FUNCT__ "PETSC_VIEWER_STDOUT_"
54 /*@C
55    PETSC_VIEWER_STDOUT_ - Creates a ASCII PetscViewer shared by all processors
56                     in a communicator.
57 
58    Collective on MPI_Comm
59 
60    Input Parameter:
61 .  comm - the MPI communicator to share the PetscViewer
62 
63    Level: beginner
64 
65    Notes:
66    Unlike almost all other PETSc routines, this does not return
67    an error code. Usually used in the form
68 $      XXXView(XXX object,PETSC_VIEWER_STDOUT_(comm));
69 
70 .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
71           PETSC_VIEWER_STDOUT_SELF
72 
73 @*/
74 PetscViewer  PETSC_VIEWER_STDOUT_(MPI_Comm comm)
75 {
76   PetscErrorCode ierr;
77   PetscViewer    viewer;
78 
79   PetscFunctionBegin;
80   ierr = PetscViewerASCIIGetStdout(comm,&viewer);
81   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(0);}
82   PetscFunctionReturn(viewer);
83 }
84 
85 /* ---------------------------------------------------------------------*/
86 /*
87     The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
88   is attached to a communicator, in this case the attribute is a PetscViewer.
89 */
90 static PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
91 
92 #undef __FUNCT__
93 #define __FUNCT__ "PetscViewerASCIIGetStderr"
94 /*@C
95    PetscViewerASCIIGetStderr - Creates a ASCII PetscViewer shared by all processors
96                     in a communicator. Error returning version of PETSC_VIEWER_STDERR_()
97 
98    Collective on MPI_Comm
99 
100    Input Parameter:
101 .  comm - the MPI communicator to share the PetscViewer
102 
103    Level: beginner
104 
105    Notes:
106      This should be used in all PETSc source code instead of PETSC_VIEWER_STDERR_()
107 
108 .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDERR_WORLD,
109           PETSC_VIEWER_STDERR_SELF
110 
111 @*/
112 PetscErrorCode  PetscViewerASCIIGetStderr(MPI_Comm comm,PetscViewer *viewer)
113 {
114   PetscErrorCode ierr;
115   PetscBool      flg;
116   MPI_Comm       ncomm;
117 
118   PetscFunctionBegin;
119   ierr = PetscCommDuplicate(comm,&ncomm,NULL);CHKERRQ(ierr);
120   if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) {
121     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Stderr_keyval,0);CHKERRQ(ierr);
122   }
123   ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Stderr_keyval,(void**)viewer,(PetscMPIInt*)&flg);CHKERRQ(ierr);
124   if (!flg) { /* PetscViewer not yet created */
125     ierr = PetscViewerASCIIOpen(ncomm,"stderr",viewer);CHKERRQ(ierr);
126     ierr = PetscObjectRegisterDestroy((PetscObject)*viewer);CHKERRQ(ierr);
127     ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Stderr_keyval,(void*)*viewer);CHKERRQ(ierr);
128   }
129   ierr = PetscCommDestroy(&ncomm);CHKERRQ(ierr);
130   PetscFunctionReturn(0);
131 }
132 
133 #undef __FUNCT__
134 #define __FUNCT__ "PETSC_VIEWER_STDERR_"
135 /*@C
136    PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors
137                     in a communicator.
138 
139    Collective on MPI_Comm
140 
141    Input Parameter:
142 .  comm - the MPI communicator to share the PetscViewer
143 
144    Level: beginner
145 
146    Note:
147    Unlike almost all other PETSc routines, this does not return
148    an error code. Usually used in the form
149 $      XXXView(XXX object,PETSC_VIEWER_STDERR_(comm));
150 
151 .seealso: PETSC_VIEWER_DRAW_, PetscViewerASCIIOpen(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDOUT_WORLD,
152           PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDERR_WORLD, PETSC_VIEWER_STDERR_SELF
153 @*/
154 PetscViewer  PETSC_VIEWER_STDERR_(MPI_Comm comm)
155 {
156   PetscErrorCode ierr;
157   PetscViewer    viewer;
158 
159   PetscFunctionBegin;
160   ierr = PetscViewerASCIIGetStderr(comm,&viewer);
161   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(0);}
162   PetscFunctionReturn(viewer);
163 }
164 
165 
166 PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
167 #undef __FUNCT__
168 #define __FUNCT__ "Petsc_DelViewer"
169 /*
170    Called with MPI_Comm_free() is called on a communicator that has a viewer as an attribute. The viewer is not actually destroyed because that is managed by
171    PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
172 
173   This is called by MPI, not by users.
174 
175 */
176 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
177 {
178   PetscErrorCode ierr;
179 
180   PetscFunctionBegin;
181   ierr = PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
182   PetscFunctionReturn(MPI_SUCCESS);
183 }
184 
185 #undef __FUNCT__
186 #define __FUNCT__ "PetscViewerASCIIOpen"
187 /*@C
188    PetscViewerASCIIOpen - Opens an ASCII file as a PetscViewer.
189 
190    Collective on MPI_Comm
191 
192    Input Parameters:
193 +  comm - the communicator
194 -  name - the file name
195 
196    Output Parameter:
197 .  lab - the PetscViewer to use with the specified file
198 
199    Level: beginner
200 
201    Notes:
202    This PetscViewer can be destroyed with PetscViewerDestroy().
203 
204    If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
205    then only the first processor in the group opens the file.  All other
206    processors send their data to the first processor to print.
207 
208    Each processor can instead write its own independent output by
209    specifying the communicator PETSC_COMM_SELF.
210 
211    As shown below, PetscViewerASCIIOpen() is useful in conjunction with
212    MatView() and VecView()
213 .vb
214      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
215      MatView(matrix,viewer);
216 .ve
217 
218   Concepts: PetscViewerASCII^creating
219   Concepts: printf
220   Concepts: printing
221   Concepts: accessing remote file
222   Concepts: remote file
223 
224 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
225           PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
226           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF,
227 @*/
228 PetscErrorCode  PetscViewerASCIIOpen(MPI_Comm comm,const char name[],PetscViewer *lab)
229 {
230   PetscErrorCode  ierr;
231   PetscViewerLink *vlink,*nv;
232   PetscBool       flg,eq;
233   size_t          len;
234 
235   PetscFunctionBegin;
236   ierr = PetscStrlen(name,&len);CHKERRQ(ierr);
237   if (!len) {
238     ierr = PetscViewerASCIIGetStdout(comm,lab);CHKERRQ(ierr);
239     ierr = PetscObjectReference((PetscObject)*lab);CHKERRQ(ierr);
240     PetscFunctionReturn(0);
241   }
242   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
243     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr);
244   }
245   /*
246        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
247      we cannot do that, since PetscFileSetName() takes a communicator that already exists.
248 
249       Plus if the original communicator that created the file has since been close this will not detect the old
250       communictor and hence will overwrite the old data. It may be better to simply remove all this code
251   */
252   /* make sure communicator is a PETSc communicator */
253   ierr = PetscCommDuplicate(comm,&comm,NULL);CHKERRQ(ierr);
254   /* has file already been opened into a viewer */
255   ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
256   if (flg) {
257     while (vlink) {
258       ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr);
259       if (eq) {
260         ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr);
261         *lab = vlink->viewer;
262         ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
263         PetscFunctionReturn(0);
264       }
265       vlink = vlink->next;
266     }
267   }
268   ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr);
269   ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr);
270   if (name) {
271     ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr);
272   }
273   /* save viewer into communicator if needed later */
274   ierr       = PetscNew(PetscViewerLink,&nv);CHKERRQ(ierr);
275   nv->viewer = *lab;
276   if (!flg) {
277     ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr);
278   } else {
279     ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
280     if (vlink) {
281       while (vlink->next) vlink = vlink->next;
282       vlink->next = nv;
283     } else {
284       ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr);
285     }
286   }
287   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
288   PetscFunctionReturn(0);
289 }
290 
291 #undef __FUNCT__
292 #define __FUNCT__ "PetscViewerASCIIOpenWithFILE"
293 /*@C
294    PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it.
295 
296    Collective on MPI_Comm
297 
298    Input Parameters:
299 +  comm - the communicator
300 -  fd - the FILE pointer
301 
302    Output Parameter:
303 .  lab - the PetscViewer to use with the specified file
304 
305    Level: beginner
306 
307    Notes:
308    This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed.
309 
310    If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
311    then only the first processor in the group uses the file.  All other
312    processors send their data to the first processor to print.
313 
314   Concepts: PetscViewerASCII^creating
315   Concepts: printf
316   Concepts: printing
317   Concepts: accessing remote file
318   Concepts: remote file
319 
320 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
321           PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
322           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
323 @*/
324 PetscErrorCode  PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
325 {
326   PetscErrorCode ierr;
327 
328   PetscFunctionBegin;
329   ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr);
330   ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr);
331   ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr);
332   PetscFunctionReturn(0);
333 }
334 
335 #undef __FUNCT__
336 #define __FUNCT__ "PetscViewerASCIISetFILE"
337 PetscErrorCode  PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
338 {
339   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
340 
341   PetscFunctionBegin;
342   vascii->fd        = fd;
343   vascii->closefile = PETSC_FALSE;
344   PetscFunctionReturn(0);
345 }
346 
347 
348 
349