Actual source code: vcreatea.c
petsc-3.11.4 2019-09-28
2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>
4: /* ---------------------------------------------------------------------*/
6: /*
7: The variable Petsc_Viewer_Stdout_keyval is used to indicate an MPI attribute that
8: is attached to a communicator, in this case the attribute is a PetscViewer.
9: */
10: PetscMPIInt Petsc_Viewer_Stdout_keyval = MPI_KEYVAL_INVALID;
12: /*@
13: PetscViewerASCIIGetStdout - Creates a ASCII PetscViewer shared by all processors
14: in a communicator. Error returning version of PETSC_VIEWER_STDOUT_()
16: Collective on MPI_Comm
18: Input Parameter:
19: . comm - the MPI communicator to share the PetscViewer
21: Level: beginner
23: Notes:
24: This should be used in all PETSc source code instead of PETSC_VIEWER_STDOUT_()
26: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
27: PETSC_VIEWER_STDOUT_SELF
29: @*/
30: PetscErrorCode PetscViewerASCIIGetStdout(MPI_Comm comm,PetscViewer *viewer)
31: {
33: PetscBool flg;
34: MPI_Comm ncomm;
37: PetscSpinlockLock(&PetscViewerASCIISpinLockStdout);
38: PetscCommDuplicate(comm,&ncomm,NULL);
39: if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) {
40: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Stdout_keyval,0);
41: }
42: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stdout_keyval,(void**)viewer,(PetscMPIInt*)&flg);
43: if (!flg) { /* PetscViewer not yet created */
44: PetscViewerASCIIOpen(ncomm,"stdout",viewer);
45: PetscObjectRegisterDestroy((PetscObject)*viewer);
46: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Stdout_keyval,(void*)*viewer);
47: }
48: PetscCommDestroy(&ncomm);
49: PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout);
50: return(0);
51: }
53: /*@C
54: PETSC_VIEWER_STDOUT_ - Creates a ASCII PetscViewer shared by all processors
55: in a communicator.
57: Collective on MPI_Comm
59: Input Parameter:
60: . comm - the MPI communicator to share the PetscViewer
62: Level: beginner
64: Notes:
65: Unlike almost all other PETSc routines, this does not return
66: an error code. Usually used in the form
67: $ XXXView(XXX object,PETSC_VIEWER_STDOUT_(comm));
69: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
70: PETSC_VIEWER_STDOUT_SELF
72: @*/
73: PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
74: {
76: PetscViewer viewer;
79: PetscViewerASCIIGetStdout(comm,&viewer);
80: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return(0);}
81: PetscFunctionReturn(viewer);
82: }
84: /* ---------------------------------------------------------------------*/
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: PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
92: /*@
93: PetscViewerASCIIGetStderr - Creates a ASCII PetscViewer shared by all processors
94: in a communicator. Error returning version of PETSC_VIEWER_STDERR_()
96: Collective on MPI_Comm
98: Input Parameter:
99: . comm - the MPI communicator to share the PetscViewer
101: Level: beginner
103: Notes:
104: This should be used in all PETSc source code instead of PETSC_VIEWER_STDERR_()
106: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDERR_WORLD,
107: PETSC_VIEWER_STDERR_SELF
109: @*/
110: PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm,PetscViewer *viewer)
111: {
113: PetscBool flg;
114: MPI_Comm ncomm;
117: PetscSpinlockLock(&PetscViewerASCIISpinLockStderr);
118: PetscCommDuplicate(comm,&ncomm,NULL);
119: if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) {
120: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Stderr_keyval,0);
121: }
122: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stderr_keyval,(void**)viewer,(PetscMPIInt*)&flg);
123: if (!flg) { /* PetscViewer not yet created */
124: PetscViewerASCIIOpen(ncomm,"stderr",viewer);
125: PetscObjectRegisterDestroy((PetscObject)*viewer);
126: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Stderr_keyval,(void*)*viewer);
127: }
128: PetscCommDestroy(&ncomm);
129: PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr);
130: return(0);
131: }
133: /*@C
134: PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors
135: in a communicator.
137: Collective on MPI_Comm
139: Input Parameter:
140: . comm - the MPI communicator to share the PetscViewer
142: Level: beginner
144: Note:
145: Unlike almost all other PETSc routines, this does not return
146: an error code. Usually used in the form
147: $ XXXView(XXX object,PETSC_VIEWER_STDERR_(comm));
149: .seealso: PETSC_VIEWER_DRAW_, PetscViewerASCIIOpen(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDOUT_WORLD,
150: PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDERR_WORLD, PETSC_VIEWER_STDERR_SELF
151: @*/
152: PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
153: {
155: PetscViewer viewer;
158: PetscViewerASCIIGetStderr(comm,&viewer);
159: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return(0);}
160: PetscFunctionReturn(viewer);
161: }
164: PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
165: /*
166: 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
167: PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
169: This is called by MPI, not by users.
171: */
172: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
173: {
177: PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);CHKERRMPI(ierr);
178: PetscFunctionReturn(MPI_SUCCESS);
179: }
181: /*@C
182: PetscViewerASCIIOpen - Opens an ASCII file for writing as a PetscViewer.
184: Collective on MPI_Comm
186: Input Parameters:
187: + comm - the communicator
188: - name - the file name
190: Output Parameter:
191: . lab - the PetscViewer to use with the specified file
193: Level: beginner
195: Notes:
196: To open a ASCII file as a viewer for reading one must use the sequence
197: $ PetscViewerCreate(comm,&lab);
198: $ PetscViewerSetType(lab,PETSCVIEWERASCII);
199: $ PetscViewerFileSetMode(lab,FILE_MODE_READ);
200: $ PetscViewerFileSetName(lab,name);
202: This PetscViewer can be destroyed with PetscViewerDestroy().
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
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
214: Concepts: PetscViewerASCII^creating
215: Concepts: printf
216: Concepts: printing
217: Concepts: accessing remote file
218: Concepts: remote file
220: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), PetscViewerASCIIRead()
221: PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), 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;
232: PetscStrlen(name,&len);
233: if (!len) {
234: PetscViewerASCIIGetStdout(comm,lab);
235: PetscObjectReference((PetscObject)*lab);
236: return(0);
237: }
238: PetscSpinlockLock(&PetscViewerASCIISpinLockOpen);
239: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
240: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
241: }
242: /*
243: It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
244: we cannot do that, since PetscFileSetName() takes a communicator that already exists.
246: Plus if the original communicator that created the file has since been close this will not detect the old
247: communictor and hence will overwrite the old data. It may be better to simply remove all this code
248: */
249: /* make sure communicator is a PETSc communicator */
250: PetscCommDuplicate(comm,&comm,NULL);
251: /* has file already been opened into a viewer */
252: MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
253: if (flg) {
254: while (vlink) {
255: PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);
256: if (eq) {
257: PetscObjectReference((PetscObject)vlink->viewer);
258: *lab = vlink->viewer;
259: PetscCommDestroy(&comm);
260: PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
261: return(0);
262: }
263: vlink = vlink->next;
264: }
265: }
266: PetscViewerCreate(comm,lab);
267: PetscViewerSetType(*lab,PETSCVIEWERASCII);
268: if (name) {
269: PetscViewerFileSetName(*lab,name);
270: }
271: /* save viewer into communicator if needed later */
272: PetscNew(&nv);
273: nv->viewer = *lab;
274: if (!flg) {
275: MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);
276: } else {
277: MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
278: if (vlink) {
279: while (vlink->next) vlink = vlink->next;
280: vlink->next = nv;
281: } else {
282: MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);
283: }
284: }
285: PetscCommDestroy(&comm);
286: PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
287: return(0);
288: }
290: /*@C
291: PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it.
293: Collective on MPI_Comm
295: Input Parameters:
296: + comm - the communicator
297: - fd - the FILE pointer
299: Output Parameter:
300: . lab - the PetscViewer to use with the specified file
302: Level: beginner
304: Notes:
305: This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed.
307: If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
308: then only the first processor in the group uses the file. All other
309: processors send their data to the first processor to print.
311: Concepts: PetscViewerASCII^creating
312: Concepts: printf
313: Concepts: printing
314: Concepts: accessing remote file
315: Concepts: remote file
317: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
318: PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
319: PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
320: @*/
321: PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
322: {
326: PetscViewerCreate(comm,lab);
327: PetscViewerSetType(*lab,PETSCVIEWERASCII);
328: PetscViewerASCIISetFILE(*lab,fd);
329: return(0);
330: }
332: PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
333: {
334: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
337: vascii->fd = fd;
338: vascii->closefile = PETSC_FALSE;
339: return(0);
340: }