Actual source code: vcreatea.c
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
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: {
32: PetscBool flg;
33: MPI_Comm ncomm;
35: PetscSpinlockLock(&PetscViewerASCIISpinLockStdout);
36: PetscCommDuplicate(comm,&ncomm,NULL);
37: if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) {
38: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Stdout_keyval,NULL);
39: }
40: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stdout_keyval,(void**)viewer,(PetscMPIInt*)&flg);
41: if (!flg) { /* PetscViewer not yet created */
42: PetscViewerASCIIOpen(ncomm,"stdout",viewer);
43: PetscObjectRegisterDestroy((PetscObject)*viewer);
44: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Stdout_keyval,(void*)*viewer);
45: }
46: PetscCommDestroy(&ncomm);
47: PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout);
48: return 0;
49: }
51: /*@C
52: PETSC_VIEWER_STDOUT_ - Creates a ASCII PetscViewer shared by all processors
53: in a communicator.
55: Collective
57: Input Parameter:
58: . comm - the MPI communicator to share the PetscViewer
60: Level: beginner
62: Notes:
63: Unlike almost all other PETSc routines, this does not return
64: an error code. Usually used in the form
65: $ XXXView(XXX object,PETSC_VIEWER_STDOUT_(comm));
67: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
68: PETSC_VIEWER_STDOUT_SELF
70: @*/
71: PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
72: {
74: PetscViewer viewer;
76: PetscViewerASCIIGetStdout(comm,&viewer);
77: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return NULL;}
78: return viewer;
79: }
81: /* ---------------------------------------------------------------------*/
83: /*
84: The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
85: is attached to a communicator, in this case the attribute is a PetscViewer.
86: */
87: PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
89: /*@
90: PetscViewerASCIIGetStderr - Creates a ASCII PetscViewer shared by all processors
91: in a communicator. Error returning version of PETSC_VIEWER_STDERR_()
93: Collective
95: Input Parameter:
96: . comm - the MPI communicator to share the PetscViewer
98: Level: beginner
100: Notes:
101: This should be used in all PETSc source code instead of PETSC_VIEWER_STDERR_()
103: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDERR_WORLD,
104: PETSC_VIEWER_STDERR_SELF
106: @*/
107: PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm,PetscViewer *viewer)
108: {
109: PetscBool flg;
110: MPI_Comm ncomm;
112: PetscSpinlockLock(&PetscViewerASCIISpinLockStderr);
113: PetscCommDuplicate(comm,&ncomm,NULL);
114: if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) {
115: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Stderr_keyval,NULL);
116: }
117: MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stderr_keyval,(void**)viewer,(PetscMPIInt*)&flg);
118: if (!flg) { /* PetscViewer not yet created */
119: PetscViewerASCIIOpen(ncomm,"stderr",viewer);
120: PetscObjectRegisterDestroy((PetscObject)*viewer);
121: MPI_Comm_set_attr(ncomm,Petsc_Viewer_Stderr_keyval,(void*)*viewer);
122: }
123: PetscCommDestroy(&ncomm);
124: PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr);
125: return 0;
126: }
128: /*@C
129: PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors
130: in a communicator.
132: Collective
134: Input Parameter:
135: . comm - the MPI communicator to share the PetscViewer
137: Level: beginner
139: Note:
140: Unlike almost all other PETSc routines, this does not return
141: an error code. Usually used in the form
142: $ XXXView(XXX object,PETSC_VIEWER_STDERR_(comm));
144: .seealso: PETSC_VIEWER_DRAW_, PetscViewerASCIIOpen(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDOUT_WORLD,
145: PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDERR_WORLD, PETSC_VIEWER_STDERR_SELF
146: @*/
147: PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
148: {
150: PetscViewer viewer;
152: PetscViewerASCIIGetStderr(comm,&viewer);
153: if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return NULL;}
154: return viewer;
155: }
157: PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
158: /*
159: 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
160: PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
162: This is called by MPI, not by users.
164: */
165: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
166: {
167: PetscInfo(NULL,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);
168: return MPI_SUCCESS;
169: }
171: /*@C
172: PetscViewerASCIIOpen - Opens an ASCII file for writing as a PetscViewer.
174: Collective
176: Input Parameters:
177: + comm - the communicator
178: - name - the file name
180: Output Parameter:
181: . lab - the PetscViewer to use with the specified file
183: Level: beginner
185: Notes:
186: To open a ASCII file as a viewer for reading one must use the sequence
187: $ PetscViewerCreate(comm,&lab);
188: $ PetscViewerSetType(lab,PETSCVIEWERASCII);
189: $ PetscViewerFileSetMode(lab,FILE_MODE_READ);
190: $ PetscViewerFileSetName(lab,name);
192: This PetscViewer can be destroyed with PetscViewerDestroy().
194: The MPI communicator used here must match that used by the object one is viewing. For example if the
195: Mat was created with a PETSC_COMM_WORLD, then the Viewer must be created with PETSC_COMM_WORLD
197: As shown below, PetscViewerASCIIOpen() is useful in conjunction with
198: MatView() and VecView()
199: .vb
200: PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
201: MatView(matrix,viewer);
202: .ve
204: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), PetscViewerASCIIRead()
205: PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
206: PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF,
207: @*/
208: PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm,const char name[],PetscViewer *lab)
209: {
210: PetscViewerLink *vlink,*nv;
211: PetscBool flg,eq;
212: size_t len;
214: PetscStrlen(name,&len);
215: if (!len) {
216: PetscViewerASCIIGetStdout(comm,lab);
217: PetscObjectReference((PetscObject)*lab);
218: return 0;
219: }
220: PetscSpinlockLock(&PetscViewerASCIISpinLockOpen);
221: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
222: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
223: }
224: /*
225: It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
226: we cannot do that, since PetscFileSetName() takes a communicator that already exists.
228: Plus if the original communicator that created the file has since been close this will not detect the old
229: communictor and hence will overwrite the old data. It may be better to simply remove all this code
230: */
231: /* make sure communicator is a PETSc communicator */
232: PetscCommDuplicate(comm,&comm,NULL);
233: /* has file already been opened into a viewer */
234: MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
235: if (flg) {
236: while (vlink) {
237: PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);
238: if (eq) {
239: PetscObjectReference((PetscObject)vlink->viewer);
240: *lab = vlink->viewer;
241: PetscCommDestroy(&comm);
242: PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
243: return 0;
244: }
245: vlink = vlink->next;
246: }
247: }
248: PetscViewerCreate(comm,lab);
249: PetscViewerSetType(*lab,PETSCVIEWERASCII);
250: if (name) {
251: PetscViewerFileSetName(*lab,name);
252: }
253: /* save viewer into communicator if needed later */
254: PetscNew(&nv);
255: nv->viewer = *lab;
256: if (!flg) {
257: MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);
258: } else {
259: MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
260: if (vlink) {
261: while (vlink->next) vlink = vlink->next;
262: vlink->next = nv;
263: } else {
264: MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);
265: }
266: }
267: PetscCommDestroy(&comm);
268: PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
269: return 0;
270: }
272: /*@C
273: PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it.
275: Collective
277: Input Parameters:
278: + comm - the communicator
279: - fd - the FILE pointer
281: Output Parameter:
282: . lab - the PetscViewer to use with the specified file
284: Level: beginner
286: Notes:
287: This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed.
289: If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
290: then only the first processor in the group uses the file. All other
291: processors send their data to the first processor to print.
293: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
294: PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
295: PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
296: @*/
297: PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
298: {
299: PetscViewerCreate(comm,lab);
300: PetscViewerSetType(*lab,PETSCVIEWERASCII);
301: PetscViewerASCIISetFILE(*lab,fd);
302: return 0;
303: }
305: PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
306: {
307: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
309: vascii->fd = fd;
310: vascii->closefile = PETSC_FALSE;
311: return 0;
312: }