Actual source code: vcreatea.c
1: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>
3: /*
4: The variable Petsc_Viewer_Stdout_keyval is used to indicate an MPI attribute that
5: is attached to a communicator, in this case the attribute is a PetscViewer.
6: */
7: PetscMPIInt Petsc_Viewer_Stdout_keyval = MPI_KEYVAL_INVALID;
9: /*@C
10: PETSC_VIEWER_STDOUT_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
11: in a communicator.
13: Collective
15: Input Parameter:
16: . comm - the MPI communicator to share the `PetscViewer`
18: Level: beginner
20: Notes:
21: This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
23: Unlike almost all other PETSc routines, this does not return
24: an error code. Usually used in the form
25: .vb
26: XXXView(XXX object, PETSC_VIEWER_STDOUT_(comm));
27: .ve
29: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
30: `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIGetStdout()`, `PetscViewerASCIIGetStderr()`
31: @*/
32: PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
33: {
34: PetscViewer viewer;
36: PetscFunctionBegin;
37: PetscCallNull(PetscViewerASCIIGetStdout(comm, &viewer));
38: PetscFunctionReturn(viewer);
39: }
41: /*
42: The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
43: is attached to a communicator, in this case the attribute is a PetscViewer.
44: */
45: PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
47: /*@
48: PetscViewerASCIIGetStderr - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
49: in a communicator that prints to `stderr`. Error returning version of `PETSC_VIEWER_STDERR_()`
51: Collective
53: Input Parameter:
54: . comm - the MPI communicator to share the `PetscViewer`
56: Output Parameter:
57: . viewer - the viewer
59: Level: beginner
61: Note:
62: Use `PetscViewerDestroy()` to destroy it
64: Developer Note:
65: This should be used in all PETSc source code instead of `PETSC_VIEWER_STDERR_()` since it allows error checking
67: .seealso: [](sec_viewers), `PetscViewerASCIIGetStdout()`, `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDERR_WORLD`,
68: `PETSC_VIEWER_STDERR_SELF`
69: @*/
70: PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm, PetscViewer *viewer)
71: {
72: PetscBool flg;
73: MPI_Comm ncomm;
75: PetscFunctionBegin;
76: PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStderr));
77: PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
78: if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Stderr_keyval, NULL));
79: PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void **)viewer, (PetscMPIInt *)&flg));
80: if (!flg) { /* PetscViewer not yet created */
81: PetscCall(PetscViewerCreate(ncomm, viewer));
82: PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
83: PetscCall(PetscViewerFileSetName(*viewer, "stderr"));
84: PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
85: PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void *)*viewer));
86: }
87: PetscCall(PetscCommDestroy(&ncomm));
88: PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr));
89: PetscFunctionReturn(PETSC_SUCCESS);
90: }
92: /*@C
93: PETSC_VIEWER_STDERR_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
94: in a communicator.
96: Collective
98: Input Parameter:
99: . comm - the MPI communicator to share the `PetscViewer`
101: Level: beginner
103: Notes:
104: This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
106: Unlike almost all other PETSc routines, this does not return
107: an error code. Usually used in the form
108: $ XXXView(XXX object, PETSC_VIEWER_STDERR_(comm));
110: `PetscViewerASCIIGetStderr()` is preferred since it allows error checking
112: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDOUT_WORLD`,
113: `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDERR_WORLD`, `PETSC_VIEWER_STDERR_SELF`
114: @*/
115: PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
116: {
117: PetscViewer viewer;
119: PetscFunctionBegin;
120: PetscCallNull(PetscViewerASCIIGetStderr(comm, &viewer));
121: PetscFunctionReturn(viewer);
122: }
124: PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
125: /*
126: Called with MPI_Comm_free() is called on a communicator that has a viewer as an attribute. The viewer is not actually destroyed
127: because that is managed by PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
129: This is called by MPI, not by users.
131: */
132: PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm, PetscMPIInt keyval, void *attr_val, void *extra_state)
133: {
134: PetscFunctionBegin;
135: (void)keyval;
136: (void)attr_val;
137: (void)extra_state;
138: PetscCallReturnMPI(PetscInfo(NULL, "Removing viewer data attribute in an MPI_Comm %" PETSC_INTPTR_T_FMT "\n", (PETSC_INTPTR_T)comm));
139: PetscFunctionReturn(MPI_SUCCESS);
140: }
142: /*@
143: PetscViewerASCIIOpen - Opens an ASCII file for writing as a `PETSCVIEWERASCII` `PetscViewer`.
145: Collective
147: Input Parameters:
148: + comm - the communicator
149: - name - the file name
151: Output Parameter:
152: . viewer - the `PetscViewer` to use with the specified file
154: Level: beginner
156: Notes:
157: This routine only opens files for writing. To open a ASCII file as a `PetscViewer` for reading use the sequence
158: .vb
159: PetscViewerCreate(comm,&viewer);
160: PetscViewerSetType(viewer,PETSCVIEWERASCII);
161: PetscViewerFileSetMode(viewer,FILE_MODE_READ);
162: PetscViewerFileSetName(viewer,name);
163: .ve
165: This `PetscViewer` can be destroyed with `PetscViewerDestroy()`.
167: The MPI communicator used here must match that used by the object viewed. For example if the
168: Mat was created with a `PETSC_COMM_WORLD`, then `viewer` must be created with `PETSC_COMM_WORLD`
170: As shown below, `PetscViewerASCIIOpen()` is useful in conjunction with
171: `MatView()` and `VecView()`
172: .vb
173: PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
174: MatView(matrix,viewer);
175: .ve
177: Developer Note:
178: When called with `NULL`, `stdout`, or `stderr` this does not return the same communicator as `PetscViewerASCIIGetStdout()` or `PetscViewerASCIIGetStderr()`
179: but that is ok.
181: .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIRead()`, `PETSCVIEWERASCII`
182: `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
183: `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIGetStdout()`, `PetscViewerASCIIGetStderr()`
184: @*/
185: PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm, const char name[], PetscViewer *viewer)
186: {
187: PetscViewerLink *vlink, *nv;
188: PetscBool flg, eq;
189: size_t len;
191: PetscFunctionBegin;
192: PetscAssertPointer(viewer, 3);
193: PetscCall(PetscStrlen(name, &len));
194: if (!len) name = "stdout";
195: PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockOpen));
196: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelViewer, &Petsc_Viewer_keyval, NULL));
197: /*
198: It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
199: we cannot do that, since PetscFileSetName() takes a communicator that already exists.
201: Plus if the original communicator that created the file has since been close this will not detect the old
202: communictor and hence will overwrite the old data. It may be better to simply remove all this code
203: */
204: /* make sure communicator is a PETSc communicator */
205: PetscCall(PetscCommDuplicate(comm, &comm, NULL));
206: /* has file already been opened into a viewer */
207: PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
208: if (flg) {
209: while (vlink) {
210: PetscCall(PetscStrcmp(name, ((PetscViewer_ASCII *)vlink->viewer->data)->filename, &eq));
211: if (eq) {
212: PetscCall(PetscObjectReference((PetscObject)vlink->viewer));
213: *viewer = vlink->viewer;
214: PetscCall(PetscCommDestroy(&comm));
215: PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
216: PetscFunctionReturn(PETSC_SUCCESS);
217: }
218: vlink = vlink->next;
219: }
220: }
221: PetscCall(PetscViewerCreate(comm, viewer));
222: PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
223: PetscCall(PetscViewerFileSetName(*viewer, name));
224: /* save viewer into communicator if needed later */
225: PetscCall(PetscNew(&nv));
226: nv->viewer = *viewer;
227: if (!flg) {
228: PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
229: } else {
230: PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
231: if (vlink) {
232: while (vlink->next) vlink = vlink->next;
233: vlink->next = nv;
234: } else {
235: PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
236: }
237: }
238: PetscCall(PetscCommDestroy(&comm));
239: PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
240: PetscFunctionReturn(PETSC_SUCCESS);
241: }
243: /*@C
244: PetscViewerASCIIOpenWithFILE - Given an open file creates an `PETSCVIEWERASCII` viewer that prints to it.
246: Collective
248: Input Parameters:
249: + comm - the communicator
250: - fd - the `FILE` pointer
252: Output Parameter:
253: . viewer - the `PetscViewer` to use with the specified file
255: Level: beginner
257: Notes:
258: This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the fd will NOT be closed.
260: If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
261: then only the first processor in the group uses the file. All other
262: processors send their data to the first processor to print.
264: Fortran Notes:
265: Use `PetscViewerASCIIOpenWithFileUnit()`
267: .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIOpenWithFileUnit()`,
268: `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
269: `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`
270: @*/
271: PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm, FILE *fd, PetscViewer *viewer)
272: {
273: PetscFunctionBegin;
274: PetscCall(PetscViewerCreate(comm, viewer));
275: PetscCall(PetscViewerSetType(*viewer, PETSCVIEWERASCII));
276: PetscCall(PetscViewerASCIISetFILE(*viewer, fd));
277: PetscFunctionReturn(PETSC_SUCCESS);
278: }
280: /*@C
281: PetscViewerASCIISetFILE - Given an open file sets the `PETSCVIEWERASCII` viewer to use the file for output
283: Not Collective
285: Input Parameters:
286: + viewer - the `PetscViewer` to use with the specified file
287: - fd - the `FILE` pointer
289: Level: beginner
291: Notes:
292: This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the `fd` will NOT be closed.
294: If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
295: then only the first processor in the group uses the file. All other
296: processors send their data to the first processor to print.
298: Fortran Note:
299: Use `PetscViewerASCIISetFileUnit()`
301: .seealso: `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIISetFileUnit()`,
302: `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
303: `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIIOpenWithFILE()`, `PETSCVIEWERASCII`
304: @*/
305: PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer, FILE *fd)
306: {
307: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
309: PetscFunctionBegin;
310: vascii->fd = fd;
311: vascii->closefile = PETSC_FALSE;
312: PetscFunctionReturn(PETSC_SUCCESS);
313: }