xref: /petsc/src/sys/classes/viewer/impls/ascii/vcreatea.c (revision 5c6c1daec53e1d9ab0bec9db5309fd8fc7645b8d) !
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   /* make sure communicator is a PETSc communicator */
248   ierr = PetscCommDuplicate(comm,&comm,PETSC_NULL);CHKERRQ(ierr);
249   /* has file already been opened into a viewer */
250   ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
251   if (flg) {
252     while (vlink) {
253       ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr);
254       if (eq) {
255         ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr);
256         *lab = vlink->viewer;
257         ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
258         PetscFunctionReturn(0);
259       }
260       vlink = vlink->next;
261     }
262   }
263   ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr);
264   ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr);
265   if (name) {
266     ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr);
267   }
268   /* save viewer into communicator if needed later */
269   ierr       = PetscNew(PetscViewerLink,&nv);CHKERRQ(ierr);
270   nv->viewer = *lab;
271   if (!flg) {
272     ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr);
273   } else {
274     ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
275     if (vlink) {
276       while (vlink->next) vlink = vlink->next;
277       vlink->next = nv;
278     } else {
279       ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr);
280     }
281   }
282   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
283   PetscFunctionReturn(0);
284 }
285 
286 #undef __FUNCT__
287 #define __FUNCT__ "PetscViewerASCIIOpenWithFILE"
288 /*@C
289    PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it.
290 
291    Collective on MPI_Comm
292 
293    Input Parameters:
294 +  comm - the communicator
295 -  fd - the FILE pointer
296 
297    Output Parameter:
298 .  lab - the PetscViewer to use with the specified file
299 
300    Level: beginner
301 
302    Notes:
303    This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed.
304 
305    If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
306    then only the first processor in the group uses the file.  All other
307    processors send their data to the first processor to print.
308 
309   Concepts: PetscViewerASCII^creating
310   Concepts: printf
311   Concepts: printing
312   Concepts: accessing remote file
313   Concepts: remote file
314 
315 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
316           PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
317           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
318 @*/
319 PetscErrorCode  PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
320 {
321   PetscErrorCode    ierr;
322 
323   PetscFunctionBegin;
324   ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr);
325   ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr);
326   ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr);
327   PetscFunctionReturn(0);
328 }
329 
330 #undef __FUNCT__
331 #define __FUNCT__ "PetscViewerASCIISetFILE"
332 PetscErrorCode  PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
333 {
334   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
335 
336   PetscFunctionBegin;
337   vascii->fd        = fd;
338   vascii->closefile = PETSC_FALSE;
339   PetscFunctionReturn(0);
340 }
341 
342 
343 
344