xref: /petsc/src/sys/classes/viewer/impls/ascii/vcreatea.c (revision cd5eaeb712f0bc77bdce843018b541db19340d1f)
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__,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__,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    The MPI communicator used here must match that used by the object one is viewing. For example if the
205    Mat was created with a PETSC_COMM_WORLD, then the Viewer must be created with PETSC_COMM_WORLD
206 
207    As shown below, PetscViewerASCIIOpen() is useful in conjunction with
208    MatView() and VecView()
209 .vb
210      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
211      MatView(matrix,viewer);
212 .ve
213 
214   Concepts: PetscViewerASCII^creating
215   Concepts: printf
216   Concepts: printing
217   Concepts: accessing remote file
218   Concepts: remote file
219 
220 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
221           PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
222           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF,
223 @*/
224 PetscErrorCode  PetscViewerASCIIOpen(MPI_Comm comm,const char name[],PetscViewer *lab)
225 {
226   PetscErrorCode  ierr;
227   PetscViewerLink *vlink,*nv;
228   PetscBool       flg,eq;
229   size_t          len;
230 
231   PetscFunctionBegin;
232   ierr = PetscStrlen(name,&len);CHKERRQ(ierr);
233   if (!len) {
234     ierr = PetscViewerASCIIGetStdout(comm,lab);CHKERRQ(ierr);
235     ierr = PetscObjectReference((PetscObject)*lab);CHKERRQ(ierr);
236     PetscFunctionReturn(0);
237   }
238   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
239     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr);
240   }
241   /*
242        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
243      we cannot do that, since PetscFileSetName() takes a communicator that already exists.
244 
245       Plus if the original communicator that created the file has since been close this will not detect the old
246       communictor and hence will overwrite the old data. It may be better to simply remove all this code
247   */
248   /* make sure communicator is a PETSc communicator */
249   ierr = PetscCommDuplicate(comm,&comm,NULL);CHKERRQ(ierr);
250   /* has file already been opened into a viewer */
251   ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
252   if (flg) {
253     while (vlink) {
254       ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr);
255       if (eq) {
256         ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr);
257         *lab = vlink->viewer;
258         ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
259         PetscFunctionReturn(0);
260       }
261       vlink = vlink->next;
262     }
263   }
264   ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr);
265   ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr);
266   if (name) {
267     ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr);
268   }
269   /* save viewer into communicator if needed later */
270   ierr       = PetscNew(&nv);CHKERRQ(ierr);
271   nv->viewer = *lab;
272   if (!flg) {
273     ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr);
274   } else {
275     ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
276     if (vlink) {
277       while (vlink->next) vlink = vlink->next;
278       vlink->next = nv;
279     } else {
280       ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr);
281     }
282   }
283   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
284   PetscFunctionReturn(0);
285 }
286 
287 #undef __FUNCT__
288 #define __FUNCT__ "PetscViewerASCIIOpenWithFILE"
289 /*@C
290    PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it.
291 
292    Collective on MPI_Comm
293 
294    Input Parameters:
295 +  comm - the communicator
296 -  fd - the FILE pointer
297 
298    Output Parameter:
299 .  lab - the PetscViewer to use with the specified file
300 
301    Level: beginner
302 
303    Notes:
304    This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed.
305 
306    If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
307    then only the first processor in the group uses the file.  All other
308    processors send their data to the first processor to print.
309 
310   Concepts: PetscViewerASCII^creating
311   Concepts: printf
312   Concepts: printing
313   Concepts: accessing remote file
314   Concepts: remote file
315 
316 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
317           PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
318           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
319 @*/
320 PetscErrorCode  PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
321 {
322   PetscErrorCode ierr;
323 
324   PetscFunctionBegin;
325   ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr);
326   ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr);
327   ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr);
328   PetscFunctionReturn(0);
329 }
330 
331 #undef __FUNCT__
332 #define __FUNCT__ "PetscViewerASCIISetFILE"
333 PetscErrorCode  PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
334 {
335   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
336 
337   PetscFunctionBegin;
338   vascii->fd        = fd;
339   vascii->closefile = PETSC_FALSE;
340   PetscFunctionReturn(0);
341 }
342 
343 
344 
345