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 `PETSCVIEWERASCII` `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: Note:
24: This should be used in all PETSc source code instead of `PETSC_VIEWER_STDOUT_()`
26: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
27: `PETSC_VIEWER_STDOUT_SELF`
28: @*/
29: PetscErrorCode PetscViewerASCIIGetStdout(MPI_Comm comm, PetscViewer *viewer)
30: {
31: PetscBool flg;
32: MPI_Comm ncomm;
34: PetscSpinlockLock(&PetscViewerASCIISpinLockStdout);
35: PetscCommDuplicate(comm, &ncomm, NULL);
36: if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Stdout_keyval, NULL);
37: MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void **)viewer, (PetscMPIInt *)&flg);
38: if (!flg) { /* PetscViewer not yet created */
39: PetscViewerASCIIOpen(ncomm, "stdout", viewer);
40: PetscObjectRegisterDestroy((PetscObject)*viewer);
41: MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void *)*viewer);
42: }
43: PetscCommDestroy(&ncomm);
44: PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout);
45: return 0;
46: }
48: /*@C
49: PETSC_VIEWER_STDOUT_ - Creates a ASCII `PetscViewer` shared by all processors
50: in a communicator.
52: Collective
54: Input Parameter:
55: . comm - the MPI communicator to share the `PetscViewer`
57: Level: beginner
59: Note:
60: Unlike almost all other PETSc routines, this does not return
61: an error code. Usually used in the form
62: $ XXXView(XXX object,PETSC_VIEWER_STDOUT_(comm));
64: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
65: `PETSC_VIEWER_STDOUT_SELF`
66: @*/
67: PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
68: {
70: PetscViewer viewer;
72: PetscViewerASCIIGetStdout(comm, &viewer);
73: if (ierr) {
74: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_STDOUT_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
75: return NULL;
76: }
77: return viewer;
78: }
80: /* ---------------------------------------------------------------------*/
82: /*
83: The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
84: is attached to a communicator, in this case the attribute is a PetscViewer.
85: */
86: PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
88: /*@
89: PetscViewerASCIIGetStderr - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all processors
90: in a communicator. Error returning version of `PETSC_VIEWER_STDERR_()`
92: Collective
94: Input Parameter:
95: . comm - the MPI communicator to share the `PetscViewer`
97: Level: beginner
99: Note:
100: This should be used in all PETSc source code instead of `PETSC_VIEWER_STDERR_()`
102: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDERR_WORLD`,
103: `PETSC_VIEWER_STDERR_SELF`
104: @*/
105: PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm, PetscViewer *viewer)
106: {
107: PetscBool flg;
108: MPI_Comm ncomm;
110: PetscSpinlockLock(&PetscViewerASCIISpinLockStderr);
111: PetscCommDuplicate(comm, &ncomm, NULL);
112: if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Stderr_keyval, NULL);
113: MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void **)viewer, (PetscMPIInt *)&flg);
114: if (!flg) { /* PetscViewer not yet created */
115: PetscViewerASCIIOpen(ncomm, "stderr", viewer);
116: PetscObjectRegisterDestroy((PetscObject)*viewer);
117: MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void *)*viewer);
118: }
119: PetscCommDestroy(&ncomm);
120: PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr);
121: return 0;
122: }
124: /*@C
125: PETSC_VIEWER_STDERR_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all processors
126: in a communicator.
128: Collective
130: Input Parameter:
131: . comm - the MPI communicator to share the `PetscViewer`
133: Level: beginner
135: Note:
136: Unlike almost all other PETSc routines, this does not return
137: an error code. Usually used in the form
138: $ XXXView(XXX object,PETSC_VIEWER_STDERR_(comm));
140: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDOUT_WORLD`,
141: `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDERR_WORLD`, `PETSC_VIEWER_STDERR_SELF`
142: @*/
143: PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
144: {
146: PetscViewer viewer;
148: PetscViewerASCIIGetStderr(comm, &viewer);
149: if (ierr) {
150: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_STDERR_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
151: return NULL;
152: }
153: return viewer;
154: }
156: PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
157: /*
158: 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
159: PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
161: This is called by MPI, not by users.
163: */
164: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm, PetscMPIInt keyval, void *attr_val, void *extra_state)
165: {
166: PetscInfo(NULL, "Removing viewer data attribute in an MPI_Comm %ld\n", (long)comm);
167: return MPI_SUCCESS;
168: }
170: /*@C
171: PetscViewerASCIIOpen - Opens an ASCII file for writing as a `PetscViewer`.
173: Collective
175: Input Parameters:
176: + comm - the communicator
177: - name - the file name
179: Output Parameter:
180: . lab - the PetscViewer to use with the specified file
182: Level: beginner
184: Notes:
185: To open a ASCII file as a viewer for reading one must use the sequence
186: .vb
187: PetscViewerCreate(comm,&lab);
188: PetscViewerSetType(lab,PETSCVIEWERASCII);
189: PetscViewerFileSetMode(lab,FILE_MODE_READ);
190: PetscViewerFileSetName(lab,name);
191: .ve
193: This `PetscViewer` can be destroyed with `PetscViewerDestroy()`.
195: The MPI communicator used here must match that used by the object one is viewing. For example if the
196: Mat was created with a `PETSC_COMM_WORLD`, then the Viewer must be created with `PETSC_COMM_WORLD`
198: As shown below, `PetscViewerASCIIOpen()` is useful in conjunction with
199: `MatView()` and `VecView()`
200: .vb
201: PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
202: MatView(matrix,viewer);
203: .ve
205: .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIRead()`, `PETSCVIEWERASCII`
206: `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
207: `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`,
208: @*/
209: PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm, const char name[], PetscViewer *lab)
210: {
211: PetscViewerLink *vlink, *nv;
212: PetscBool flg, eq;
213: size_t len;
215: PetscStrlen(name, &len);
216: if (!len) {
217: PetscViewerASCIIGetStdout(comm, lab);
218: PetscObjectReference((PetscObject)*lab);
219: return 0;
220: }
221: PetscSpinlockLock(&PetscViewerASCIISpinLockOpen);
222: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelViewer, &Petsc_Viewer_keyval, (void *)0);
223: /*
224: It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
225: we cannot do that, since PetscFileSetName() takes a communicator that already exists.
227: Plus if the original communicator that created the file has since been close this will not detect the old
228: communictor and hence will overwrite the old data. It may be better to simply remove all this code
229: */
230: /* make sure communicator is a PETSc communicator */
231: PetscCommDuplicate(comm, &comm, NULL);
232: /* has file already been opened into a viewer */
233: MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg);
234: if (flg) {
235: while (vlink) {
236: PetscStrcmp(name, ((PetscViewer_ASCII *)(vlink->viewer->data))->filename, &eq);
237: if (eq) {
238: PetscObjectReference((PetscObject)vlink->viewer);
239: *lab = vlink->viewer;
240: PetscCommDestroy(&comm);
241: PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
242: return 0;
243: }
244: vlink = vlink->next;
245: }
246: }
247: PetscViewerCreate(comm, lab);
248: PetscViewerSetType(*lab, PETSCVIEWERASCII);
249: if (name) PetscViewerFileSetName(*lab, name);
250: /* save viewer into communicator if needed later */
251: PetscNew(&nv);
252: nv->viewer = *lab;
253: if (!flg) {
254: MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv);
255: } else {
256: MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg);
257: if (vlink) {
258: while (vlink->next) vlink = vlink->next;
259: vlink->next = nv;
260: } else {
261: MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv);
262: }
263: }
264: PetscCommDestroy(&comm);
265: PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
266: return 0;
267: }
269: /*@C
270: PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it.
272: Collective
274: Input Parameters:
275: + comm - the communicator
276: - fd - the FILE pointer
278: Output Parameter:
279: . lab - the `PetscViewer` to use with the specified file
281: Level: beginner
283: Notes:
284: This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the fd will NOT be closed.
286: If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
287: then only the first processor in the group uses the file. All other
288: processors send their data to the first processor to print.
290: .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`,
291: `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
292: `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`
293: @*/
294: PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm, FILE *fd, PetscViewer *lab)
295: {
296: PetscViewerCreate(comm, lab);
297: PetscViewerSetType(*lab, PETSCVIEWERASCII);
298: PetscViewerASCIISetFILE(*lab, fd);
299: return 0;
300: }
302: /*@C
303: PetscViewerASCIISetFILE - Given an open file sets the ASCII viewer to use the file for output
305: Not collective
307: Input Parameters:
308: + viewer - the `PetscViewer` to use with the specified file
309: - fd - the FILE pointer
311: Level: beginner
313: Notes:
314: This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the fd will NOT be closed.
316: If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
317: then only the first processor in the group uses the file. All other
318: processors send their data to the first processor to print.
320: .seealso: `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`,
321: `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
322: `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIIOpenWithFILE()`, `PETSCVIEWERASCII`
323: @*/
324: PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer, FILE *fd)
325: {
326: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
328: vascii->fd = fd;
329: vascii->closefile = PETSC_FALSE;
330: return 0;
331: }