Actual source code: ams.c
2: #include <petsc/private/viewerimpl.h>
3: #include <petscviewersaws.h>
4: #include <petscsys.h>
6: /*
7: The variable Petsc_Viewer_SAWs_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: static PetscMPIInt Petsc_Viewer_SAWs_keyval = MPI_KEYVAL_INVALID;
12: /*@C
13: PETSC_VIEWER_SAWS_ - Creates a SAWs `PetscViewer` shared by all MPI processes in a communicator.
15: Collective
17: Input Parameter:
18: . comm - the MPI communicator to share the `PetscViewer`
20: Level: developer
22: Note:
23: Unlike almost all other PETSc routines, `PETSC_VIEWER_SAWS_()` does not return
24: an error code. The resulting `PetscViewer` is usually used in the form
25: $ XXXView(XXX object, PETSC_VIEWER_SAWS_(comm));
27: .seealso: [](sec_viewers), `PetscViewer`, `PETSC_VIEWER_SAWS_WORLD`, `PETSC_VIEWER_SAWS_SELF`
28: @*/
29: PetscViewer PETSC_VIEWER_SAWS_(MPI_Comm comm)
30: {
31: PetscErrorCode ierr;
32: PetscMPIInt flag;
33: PetscViewer viewer;
34: MPI_Comm ncomm;
36: PetscFunctionBegin;
37: ierr = PetscCommDuplicate(comm, &ncomm, NULL);
38: if (ierr) {
39: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, ierr, PETSC_ERROR_INITIAL, " ");
40: PetscFunctionReturn(NULL);
41: }
42: if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) {
43: ierr = (PetscErrorCode)MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_SAWs_keyval, 0);
44: if (ierr) {
45: ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_MPI, PETSC_ERROR_INITIAL, " ");
46: PetscFunctionReturn(NULL);
47: }
48: }
49: ierr = (PetscErrorCode)MPI_Comm_get_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void **)&viewer, &flag);
50: if (ierr) {
51: ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_MPI, PETSC_ERROR_INITIAL, " ");
52: PetscFunctionReturn(NULL);
53: }
54: if (!flag) { /* PetscViewer not yet created */
55: ierr = PetscViewerSAWsOpen(comm, &viewer);
56: if (ierr) {
57: ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, ierr, PETSC_ERROR_REPEAT, " ");
58: PetscFunctionReturn(NULL);
59: }
60: ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
61: if (ierr) {
62: ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, ierr, PETSC_ERROR_REPEAT, " ");
63: PetscFunctionReturn(NULL);
64: }
65: ierr = (PetscErrorCode)MPI_Comm_set_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void *)viewer);
66: if (ierr) {
67: ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_MPI, PETSC_ERROR_INITIAL, " ");
68: PetscFunctionReturn(NULL);
69: }
70: }
71: ierr = PetscCommDestroy(&ncomm);
72: if (ierr) {
73: ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, ierr, PETSC_ERROR_REPEAT, " ");
74: PetscFunctionReturn(NULL);
75: }
76: PetscFunctionReturn(viewer);
77: }
79: /*
80: If there is a PetscViewer associated with this communicator, it is destroyed.
81: */
82: PetscErrorCode PetscViewer_SAWS_Destroy(MPI_Comm comm)
83: {
84: PetscMPIInt flag;
85: PetscViewer viewer;
87: PetscFunctionBegin;
88: if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) PetscFunctionReturn(PETSC_SUCCESS);
90: PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_SAWs_keyval, (void **)&viewer, &flag));
91: if (flag) {
92: PetscCall(PetscViewerDestroy(&viewer));
93: PetscCallMPI(MPI_Comm_delete_attr(comm, Petsc_Viewer_SAWs_keyval));
94: }
95: PetscFunctionReturn(PETSC_SUCCESS);
96: }
98: static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer)
99: {
100: PetscFunctionBegin;
101: /*
102: Make sure that we mark that the stack is no longer published
103: */
104: if (PetscObjectComm((PetscObject)viewer) == PETSC_COMM_WORLD) PetscCall(PetscStackSAWsViewOff());
105: PetscFunctionReturn(PETSC_SUCCESS);
106: }
108: PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v)
109: {
110: PetscFunctionBegin;
111: v->ops->destroy = PetscViewerDestroy_SAWs;
112: PetscFunctionReturn(PETSC_SUCCESS);
113: }