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