Actual source code: vcreatea.c
petsc-3.7.7 2017-09-25
2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscsys.h" I*/
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: static PetscMPIInt Petsc_Viewer_Stdout_keyval = MPI_KEYVAL_INVALID;
14: /*@C
15: PetscViewerASCIIGetStdout - Creates a ASCII PetscViewer shared by all processors
16: in a communicator. Error returning version of PETSC_VIEWER_STDOUT_()
18: Collective on MPI_Comm
20: Input Parameter:
21: . comm - the MPI communicator to share the PetscViewer
23: Level: beginner
25: Notes:
26: This should be used in all PETSc source code instead of PETSC_VIEWER_STDOUT_()
28: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
29: PETSC_VIEWER_STDOUT_SELF
31: @*/
32: PetscErrorCode PetscViewerASCIIGetStdout(MPI_Comm comm,PetscViewer *viewer)
33: {
35: PetscBool flg;
36: MPI_Comm ncomm;
39: PetscSpinlockLock(&PetscViewerASCIISpinLockStdout);
40: PetscCommDuplicate(comm,&ncomm,NULL);
41: if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) {
42: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Stdout_keyval,0);
43: }
44: MPI_Attr_get(ncomm,Petsc_Viewer_Stdout_keyval,(void**)viewer,(PetscMPIInt*)&flg);
45: if (!flg) { /* PetscViewer not yet created */
46: PetscViewerASCIIOpen(ncomm,"stdout",viewer);
47: PetscObjectRegisterDestroy((PetscObject)*viewer);
48: MPI_Attr_put(ncomm,Petsc_Viewer_Stdout_keyval,(void*)*viewer);
49: }
50: PetscCommDestroy(&ncomm);
51: PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout);
52: return(0);
53: }
57: /*@C
58: PETSC_VIEWER_STDOUT_ - Creates a ASCII PetscViewer shared by all processors
59: in a communicator.
61: Collective on MPI_Comm
63: Input Parameter:
64: . comm - the MPI communicator to share the PetscViewer
66: Level: beginner
68: Notes:
69: Unlike almost all other PETSc routines, this does not return
70: an error code. Usually used in the form
71: $ XXXView(XXX object,PETSC_VIEWER_STDOUT_(comm));
73: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
74: PETSC_VIEWER_STDOUT_SELF
76: @*/
77: PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
78: {
80: PetscViewer viewer;
83: PetscViewerASCIIGetStdout(comm,&viewer);
84: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return(0);}
85: PetscFunctionReturn(viewer);
86: }
88: /* ---------------------------------------------------------------------*/
90: /*
91: The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
92: is attached to a communicator, in this case the attribute is a PetscViewer.
93: */
94: static PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
98: /*@C
99: PetscViewerASCIIGetStderr - Creates a ASCII PetscViewer shared by all processors
100: in a communicator. Error returning version of PETSC_VIEWER_STDERR_()
102: Collective on MPI_Comm
104: Input Parameter:
105: . comm - the MPI communicator to share the PetscViewer
107: Level: beginner
109: Notes:
110: This should be used in all PETSc source code instead of PETSC_VIEWER_STDERR_()
112: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDERR_WORLD,
113: PETSC_VIEWER_STDERR_SELF
115: @*/
116: PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm,PetscViewer *viewer)
117: {
119: PetscBool flg;
120: MPI_Comm ncomm;
123: PetscSpinlockLock(&PetscViewerASCIISpinLockStderr);
124: PetscCommDuplicate(comm,&ncomm,NULL);
125: if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) {
126: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Stderr_keyval,0);
127: }
128: MPI_Attr_get(ncomm,Petsc_Viewer_Stderr_keyval,(void**)viewer,(PetscMPIInt*)&flg);
129: if (!flg) { /* PetscViewer not yet created */
130: PetscViewerASCIIOpen(ncomm,"stderr",viewer);
131: PetscObjectRegisterDestroy((PetscObject)*viewer);
132: MPI_Attr_put(ncomm,Petsc_Viewer_Stderr_keyval,(void*)*viewer);
133: }
134: PetscCommDestroy(&ncomm);
135: PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr);
136: return(0);
137: }
141: /*@C
142: PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors
143: in a communicator.
145: Collective on MPI_Comm
147: Input Parameter:
148: . comm - the MPI communicator to share the PetscViewer
150: Level: beginner
152: Note:
153: Unlike almost all other PETSc routines, this does not return
154: an error code. Usually used in the form
155: $ XXXView(XXX object,PETSC_VIEWER_STDERR_(comm));
157: .seealso: PETSC_VIEWER_DRAW_, PetscViewerASCIIOpen(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDOUT_WORLD,
158: PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDERR_WORLD, PETSC_VIEWER_STDERR_SELF
159: @*/
160: PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
161: {
163: PetscViewer viewer;
166: PetscViewerASCIIGetStderr(comm,&viewer);
167: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return(0);}
168: PetscFunctionReturn(viewer);
169: }
172: PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
175: /*
176: 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
177: PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
179: This is called by MPI, not by users.
181: */
182: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
183: {
187: PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
188: PetscFunctionReturn(MPI_SUCCESS);
189: }
193: /*@C
194: PetscViewerASCIIOpen - Opens an ASCII file as a PetscViewer.
196: Collective on MPI_Comm
198: Input Parameters:
199: + comm - the communicator
200: - name - the file name
202: Output Parameter:
203: . lab - the PetscViewer to use with the specified file
205: Level: beginner
207: Notes:
208: This PetscViewer can be destroyed with PetscViewerDestroy().
210: The MPI communicator used here must match that used by the object one is viewing. For example if the
211: Mat was created with a PETSC_COMM_WORLD, then the Viewer must be created with PETSC_COMM_WORLD
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
220: Concepts: PetscViewerASCII^creating
221: Concepts: printf
222: Concepts: printing
223: Concepts: accessing remote file
224: Concepts: remote file
226: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
227: PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), 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;
238: PetscStrlen(name,&len);
239: if (!len) {
240: PetscViewerASCIIGetStdout(comm,lab);
241: PetscObjectReference((PetscObject)*lab);
242: return(0);
243: }
244: PetscSpinlockLock(&PetscViewerASCIISpinLockOpen);
245: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
246: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
247: }
248: /*
249: It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
250: we cannot do that, since PetscFileSetName() takes a communicator that already exists.
252: Plus if the original communicator that created the file has since been close this will not detect the old
253: communictor and hence will overwrite the old data. It may be better to simply remove all this code
254: */
255: /* make sure communicator is a PETSc communicator */
256: PetscCommDuplicate(comm,&comm,NULL);
257: /* has file already been opened into a viewer */
258: MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
259: if (flg) {
260: while (vlink) {
261: PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);
262: if (eq) {
263: PetscObjectReference((PetscObject)vlink->viewer);
264: *lab = vlink->viewer;
265: PetscCommDestroy(&comm);
266: PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
267: return(0);
268: }
269: vlink = vlink->next;
270: }
271: }
272: PetscViewerCreate(comm,lab);
273: PetscViewerSetType(*lab,PETSCVIEWERASCII);
274: if (name) {
275: PetscViewerFileSetName(*lab,name);
276: }
277: /* save viewer into communicator if needed later */
278: PetscNew(&nv);
279: nv->viewer = *lab;
280: if (!flg) {
281: MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);
282: } else {
283: MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
284: if (vlink) {
285: while (vlink->next) vlink = vlink->next;
286: vlink->next = nv;
287: } else {
288: MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);
289: }
290: }
291: PetscCommDestroy(&comm);
292: PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
293: return(0);
294: }
298: /*@C
299: PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it.
301: Collective on MPI_Comm
303: Input Parameters:
304: + comm - the communicator
305: - fd - the FILE pointer
307: Output Parameter:
308: . lab - the PetscViewer to use with the specified file
310: Level: beginner
312: Notes:
313: This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed.
315: If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
316: then only the first processor in the group uses the file. All other
317: processors send their data to the first processor to print.
319: Concepts: PetscViewerASCII^creating
320: Concepts: printf
321: Concepts: printing
322: Concepts: accessing remote file
323: Concepts: remote file
325: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
326: PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
327: PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
328: @*/
329: PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
330: {
334: PetscViewerCreate(comm,lab);
335: PetscViewerSetType(*lab,PETSCVIEWERASCII);
336: PetscViewerASCIISetFILE(*lab,fd);
337: return(0);
338: }
342: PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
343: {
344: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
347: vascii->fd = fd;
348: vascii->closefile = PETSC_FALSE;
349: return(0);
350: }