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