xref: /petsc/src/sys/classes/viewer/impls/ascii/vcreatea.c (revision 2205254efee3a00a594e5e2a3a70f74dcb40bc03)
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,PETSC_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,PETSC_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 EXTERN_C_BEGIN
168 #undef __FUNCT__
169 #define __FUNCT__ "Petsc_DelViewer"
170 /*
171    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
172    PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
173 
174   This is called by MPI, not by users.
175 
176 */
177 PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
178 {
179   PetscErrorCode ierr;
180 
181   PetscFunctionBegin;
182   ierr = PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
183   PetscFunctionReturn(MPI_SUCCESS);
184 }
185 EXTERN_C_END
186 
187 #undef __FUNCT__
188 #define __FUNCT__ "PetscViewerASCIIOpen"
189 /*@C
190    PetscViewerASCIIOpen - Opens an ASCII file as a PetscViewer.
191 
192    Collective on MPI_Comm
193 
194    Input Parameters:
195 +  comm - the communicator
196 -  name - the file name
197 
198    Output Parameter:
199 .  lab - the PetscViewer to use with the specified file
200 
201    Level: beginner
202 
203    Notes:
204    This PetscViewer can be destroyed with PetscViewerDestroy().
205 
206    If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
207    then only the first processor in the group opens the file.  All other
208    processors send their data to the first processor to print.
209 
210    Each processor can instead write its own independent output by
211    specifying the communicator PETSC_COMM_SELF.
212 
213    As shown below, PetscViewerASCIIOpen() is useful in conjunction with
214    MatView() and VecView()
215 .vb
216      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
217      MatView(matrix,viewer);
218 .ve
219 
220   Concepts: PetscViewerASCII^creating
221   Concepts: printf
222   Concepts: printing
223   Concepts: accessing remote file
224   Concepts: remote file
225 
226 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
227           PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
228           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF,
229 @*/
230 PetscErrorCode  PetscViewerASCIIOpen(MPI_Comm comm,const char name[],PetscViewer *lab)
231 {
232   PetscErrorCode  ierr;
233   PetscViewerLink *vlink,*nv;
234   PetscBool       flg,eq;
235   size_t          len;
236 
237   PetscFunctionBegin;
238   ierr = PetscStrlen(name,&len);CHKERRQ(ierr);
239   if (!len) {
240     ierr = PetscViewerASCIIGetStdout(comm,lab);CHKERRQ(ierr);
241     ierr = PetscObjectReference((PetscObject)*lab);CHKERRQ(ierr);
242     PetscFunctionReturn(0);
243   }
244   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
245     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr);
246   }
247   /*
248        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
249      we cannot do that, since PetscFileSetName() takes a communicator that already exists.
250 
251       Plus if the original communicator that created the file has since been close this will not detect the old
252       communictor and hence will overwrite the old data. It may be better to simply remove all this code
253   */
254   /* make sure communicator is a PETSc communicator */
255   ierr = PetscCommDuplicate(comm,&comm,PETSC_NULL);CHKERRQ(ierr);
256   /* has file already been opened into a viewer */
257   ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
258   if (flg) {
259     while (vlink) {
260       ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr);
261       if (eq) {
262         ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr);
263         *lab = vlink->viewer;
264         ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
265         PetscFunctionReturn(0);
266       }
267       vlink = vlink->next;
268     }
269   }
270   ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr);
271   ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr);
272   if (name) {
273     ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr);
274   }
275   /* save viewer into communicator if needed later */
276   ierr       = PetscNew(PetscViewerLink,&nv);CHKERRQ(ierr);
277   nv->viewer = *lab;
278   if (!flg) {
279     ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr);
280   } else {
281     ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
282     if (vlink) {
283       while (vlink->next) vlink = vlink->next;
284       vlink->next = nv;
285     } else {
286       ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr);
287     }
288   }
289   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
290   PetscFunctionReturn(0);
291 }
292 
293 #undef __FUNCT__
294 #define __FUNCT__ "PetscViewerASCIIOpenWithFILE"
295 /*@C
296    PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it.
297 
298    Collective on MPI_Comm
299 
300    Input Parameters:
301 +  comm - the communicator
302 -  fd - the FILE pointer
303 
304    Output Parameter:
305 .  lab - the PetscViewer to use with the specified file
306 
307    Level: beginner
308 
309    Notes:
310    This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed.
311 
312    If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
313    then only the first processor in the group uses the file.  All other
314    processors send their data to the first processor to print.
315 
316   Concepts: PetscViewerASCII^creating
317   Concepts: printf
318   Concepts: printing
319   Concepts: accessing remote file
320   Concepts: remote file
321 
322 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
323           PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
324           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
325 @*/
326 PetscErrorCode  PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
327 {
328   PetscErrorCode ierr;
329 
330   PetscFunctionBegin;
331   ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr);
332   ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr);
333   ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr);
334   PetscFunctionReturn(0);
335 }
336 
337 #undef __FUNCT__
338 #define __FUNCT__ "PetscViewerASCIISetFILE"
339 PetscErrorCode  PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
340 {
341   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
342 
343   PetscFunctionBegin;
344   vascii->fd        = fd;
345   vascii->closefile = PETSC_FALSE;
346   PetscFunctionReturn(0);
347 }
348 
349 
350 
351