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: /*@
10: PetscViewerASCIIGetStdout - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all processors
11: in a communicator. Error returning version of `PETSC_VIEWER_STDOUT_()`
13: Collective
15: Input Parameter:
16: . comm - the MPI communicator to share the `PetscViewer`
18: Output Parameter:
19: . viewer - the viewer
21: Level: beginner
23: Note:
24: This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
26: Developer Note:
27: This should be used in all PETSc source code instead of `PETSC_VIEWER_STDOUT_()` since it allows error checking
29: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
30: `PETSC_VIEWER_STDOUT_SELF`
31: @*/
32: PetscErrorCode PetscViewerASCIIGetStdout(MPI_Comm comm, PetscViewer *viewer)
33: {
34: PetscBool flg;
35: MPI_Comm ncomm;
37: PetscFunctionBegin;
38: PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStdout));
39: PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
40: if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_Stdout_keyval, NULL));
41: PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void **)viewer, (PetscMPIInt *)&flg));
42: if (!flg) { /* PetscViewer not yet created */
43: PetscCall(PetscViewerASCIIOpen(ncomm, "stdout", viewer));
44: ((PetscObject)*viewer)->persistent = PETSC_TRUE;
45: PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
46: PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stdout_keyval, (void *)*viewer));
47: }
48: PetscCall(PetscCommDestroy(&ncomm));
49: PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout));
50: PetscFunctionReturn(PETSC_SUCCESS);
51: }
53: /*@C
54: PETSC_VIEWER_STDOUT_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
55: in a communicator.
57: Collective
59: Input Parameter:
60: . comm - the MPI communicator to share the `PetscViewer`
62: Level: beginner
64: Notes:
65: This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
67: Unlike almost all other PETSc routines, this does not return
68: an error code. Usually used in the form
69: $ XXXView(XXX object, PETSC_VIEWER_STDOUT_(comm));
71: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDOUT_WORLD`,
72: `PETSC_VIEWER_STDOUT_SELF`
73: @*/
74: PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm)
75: {
76: PetscErrorCode ierr;
77: PetscViewer viewer;
79: PetscFunctionBegin;
80: ierr = PetscViewerASCIIGetStdout(comm, &viewer);
81: if (ierr) {
82: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_STDOUT_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
83: PetscFunctionReturn(NULL);
84: }
85: PetscFunctionReturn(viewer);
86: }
88: /*
89: The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
90: is attached to a communicator, in this case the attribute is a PetscViewer.
91: */
92: PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;
94: /*@
95: PetscViewerASCIIGetStderr - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
96: in a communicator. Error returning version of `PETSC_VIEWER_STDERR_()`
98: Collective
100: Input Parameter:
101: . comm - the MPI communicator to share the `PetscViewer`
103: Output Parameter:
104: . viewer - the viewer
106: Level: beginner
108: Note:
109: This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
111: Developer Note:
112: This should be used in all PETSc source code instead of `PETSC_VIEWER_STDERR_()` since it allows error checking
114: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_()`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDERR_`, `PETSC_VIEWER_STDERR_WORLD`,
115: `PETSC_VIEWER_STDERR_SELF`
116: @*/
117: PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm, PetscViewer *viewer)
118: {
119: PetscBool flg;
120: MPI_Comm ncomm;
122: PetscFunctionBegin;
123: PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockStderr));
124: PetscCall(PetscCommDuplicate(comm, &ncomm, NULL));
125: 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));
126: PetscCallMPI(MPI_Comm_get_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void **)viewer, (PetscMPIInt *)&flg));
127: if (!flg) { /* PetscViewer not yet created */
128: PetscCall(PetscViewerASCIIOpen(ncomm, "stderr", viewer));
129: ((PetscObject)*viewer)->persistent = PETSC_TRUE;
130: PetscCall(PetscObjectRegisterDestroy((PetscObject)*viewer));
131: PetscCallMPI(MPI_Comm_set_attr(ncomm, Petsc_Viewer_Stderr_keyval, (void *)*viewer));
132: }
133: PetscCall(PetscCommDestroy(&ncomm));
134: PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr));
135: PetscFunctionReturn(PETSC_SUCCESS);
136: }
138: /*@C
139: PETSC_VIEWER_STDERR_ - Creates a `PETSCVIEWERASCII` `PetscViewer` shared by all MPI processes
140: in a communicator.
142: Collective
144: Input Parameter:
145: . comm - the MPI communicator to share the `PetscViewer`
147: Level: beginner
149: Notes:
150: This object is destroyed in `PetscFinalize()`, `PetscViewerDestroy()` should never be called on it
152: Unlike almost all other PETSc routines, this does not return
153: an error code. Usually used in the form
154: $ XXXView(XXX object, PETSC_VIEWER_STDERR_(comm));
156: `PetscViewerASCIIGetStderr()` is preferred since it allows error checking
158: .seealso: [](sec_viewers), `PETSC_VIEWER_DRAW_`, `PetscViewerASCIIOpen()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDOUT_WORLD`,
159: `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDERR_WORLD`, `PETSC_VIEWER_STDERR_SELF`
160: @*/
161: PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm)
162: {
163: PetscErrorCode ierr;
164: PetscViewer viewer;
166: PetscFunctionBegin;
167: ierr = PetscViewerASCIIGetStderr(comm, &viewer);
168: if (ierr) {
169: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_STDERR_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
170: PetscFunctionReturn(NULL);
171: }
172: PetscFunctionReturn(viewer);
173: }
175: PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
176: /*
177: Called with MPI_Comm_free() is called on a communicator that has a viewer as an attribute. The viewer is not actually destroyed
178: because that is managed by PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.
180: This is called by MPI, not by users.
182: */
183: PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm, PetscMPIInt keyval, void *attr_val, void *extra_state)
184: {
185: PetscFunctionBegin;
186: (void)keyval;
187: (void)attr_val;
188: (void)extra_state;
189: PetscCallMPI(PetscInfo(NULL, "Removing viewer data attribute in an MPI_Comm %" PETSC_INTPTR_T_FMT "\n", (PETSC_INTPTR_T)comm));
190: PetscFunctionReturn(MPI_SUCCESS);
191: }
193: /*@C
194: PetscViewerASCIIOpen - Opens an ASCII file for writing as a `PETSCVIEWERASCII` `PetscViewer`.
196: Collective
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: To open a ASCII file as a viewer for reading one must use the sequence
209: .vb
210: PetscViewerCreate(comm,&lab);
211: PetscViewerSetType(lab,PETSCVIEWERASCII);
212: PetscViewerFileSetMode(lab,FILE_MODE_READ);
213: PetscViewerFileSetName(lab,name);
214: .ve
216: This `PetscViewer` can be destroyed with `PetscViewerDestroy()`.
218: The MPI communicator used here must match that used by the object one is viewing. For example if the
219: Mat was created with a `PETSC_COMM_WORLD`, then the Viewer must be created with `PETSC_COMM_WORLD`
221: As shown below, `PetscViewerASCIIOpen()` is useful in conjunction with
222: `MatView()` and `VecView()`
223: .vb
224: PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
225: MatView(matrix,viewer);
226: .ve
228: .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIRead()`, `PETSCVIEWERASCII`
229: `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
230: `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`,
231: @*/
232: PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm, const char name[], PetscViewer *lab)
233: {
234: PetscViewerLink *vlink, *nv;
235: PetscBool flg, eq;
236: size_t len;
238: PetscFunctionBegin;
239: PetscCall(PetscStrlen(name, &len));
240: if (!len) {
241: PetscCall(PetscViewerASCIIGetStdout(comm, lab));
242: PetscCall(PetscObjectReference((PetscObject)*lab));
243: PetscFunctionReturn(PETSC_SUCCESS);
244: }
245: PetscCall(PetscSpinlockLock(&PetscViewerASCIISpinLockOpen));
246: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, Petsc_DelViewer, &Petsc_Viewer_keyval, (void *)0));
247: /*
248: It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
249: we cannot do that, since PetscFileSetName() takes a communicator that already exists.
251: Plus if the original communicator that created the file has since been close this will not detect the old
252: communictor and hence will overwrite the old data. It may be better to simply remove all this code
253: */
254: /* make sure communicator is a PETSc communicator */
255: PetscCall(PetscCommDuplicate(comm, &comm, NULL));
256: /* has file already been opened into a viewer */
257: PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
258: if (flg) {
259: while (vlink) {
260: PetscCall(PetscStrcmp(name, ((PetscViewer_ASCII *)(vlink->viewer->data))->filename, &eq));
261: if (eq) {
262: PetscCall(PetscObjectReference((PetscObject)vlink->viewer));
263: *lab = vlink->viewer;
264: PetscCall(PetscCommDestroy(&comm));
265: PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
266: PetscFunctionReturn(PETSC_SUCCESS);
267: }
268: vlink = vlink->next;
269: }
270: }
271: PetscCall(PetscViewerCreate(comm, lab));
272: PetscCall(PetscViewerSetType(*lab, PETSCVIEWERASCII));
273: if (name) PetscCall(PetscViewerFileSetName(*lab, name));
274: /* save viewer into communicator if needed later */
275: PetscCall(PetscNew(&nv));
276: nv->viewer = *lab;
277: if (!flg) {
278: PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
279: } else {
280: PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_keyval, (void **)&vlink, (PetscMPIInt *)&flg));
281: if (vlink) {
282: while (vlink->next) vlink = vlink->next;
283: vlink->next = nv;
284: } else {
285: PetscCallMPI(MPI_Comm_set_attr(comm, Petsc_Viewer_keyval, nv));
286: }
287: }
288: PetscCall(PetscCommDestroy(&comm));
289: PetscCall(PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen));
290: PetscFunctionReturn(PETSC_SUCCESS);
291: }
293: /*@C
294: PetscViewerASCIIOpenWithFILE - Given an open file creates an `PETSCVIEWERASCII` viewer that prints to it.
296: Collective
298: Input Parameters:
299: + comm - the communicator
300: - fd - the `FILE` pointer
302: Output Parameter:
303: . lab - the `PetscViewer` to use with the specified file
305: Level: beginner
307: Notes:
308: This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the fd will NOT be closed.
310: If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
311: then only the first processor in the group uses the file. All other
312: processors send their data to the first processor to print.
314: Fortran Notes:
315: Use `PetscViewerASCIIOpenWithFileUnit()`
317: .seealso: [](sec_viewers), `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIIOpenWithFileUnit()`,
318: `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
319: `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIISetFILE()`, `PETSCVIEWERASCII`
320: @*/
321: PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm, FILE *fd, PetscViewer *lab)
322: {
323: PetscFunctionBegin;
324: PetscCall(PetscViewerCreate(comm, lab));
325: PetscCall(PetscViewerSetType(*lab, PETSCVIEWERASCII));
326: PetscCall(PetscViewerASCIISetFILE(*lab, fd));
327: PetscFunctionReturn(PETSC_SUCCESS);
328: }
330: /*@C
331: PetscViewerASCIISetFILE - Given an open file sets the `PETSCVIEWERASCII` viewer to use the file for output
333: Not Collective
335: Input Parameters:
336: + viewer - the `PetscViewer` to use with the specified file
337: - fd - the `FILE` pointer
339: Level: beginner
341: Notes:
342: This `PetscViewer` can be destroyed with `PetscViewerDestroy()`, but the `fd` will NOT be closed.
344: If a multiprocessor communicator is used (such as `PETSC_COMM_WORLD`),
345: then only the first processor in the group uses the file. All other
346: processors send their data to the first processor to print.
348: Fortran Notes:
349: Use `PetscViewerASCIISetFileUnit()`
351: .seealso: `MatView()`, `VecView()`, `PetscViewerDestroy()`, `PetscViewerBinaryOpen()`, `PetscViewerASCIISetFileUnit()`,
352: `PetscViewerASCIIGetPointer()`, `PetscViewerPushFormat()`, `PETSC_VIEWER_STDOUT_`, `PETSC_VIEWER_STDERR_`,
353: `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF`, `PetscViewerASCIIOpen()`, `PetscViewerASCIIOpenWithFILE()`, `PETSCVIEWERASCII`
354: @*/
355: PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer, FILE *fd)
356: {
357: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
359: PetscFunctionBegin;
360: vascii->fd = fd;
361: vascii->closefile = PETSC_FALSE;
362: PetscFunctionReturn(PETSC_SUCCESS);
363: }