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