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 an SAWs `PetscViewer` shared by all processors in a communicator.
15: Collective
17: Input Parameters:
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: {
32: PetscMPIInt flag;
33: PetscViewer viewer;
34: MPI_Comm ncomm;
36: PetscCommDuplicate(comm, &ncomm, NULL);
37: if (ierr) {
38: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
39: return 0;
40: }
41: if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) {
42: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_SAWs_keyval, 0);
43: if (ierr) {
44: PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_INITIAL, " ");
45: return NULL;
46: }
47: }
48: MPI_Comm_get_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void **)&viewer, &flag);
49: if (ierr) {
50: PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_INITIAL, " ");
51: return NULL;
52: }
53: if (!flag) { /* PetscViewer not yet created */
54: PetscViewerSAWsOpen(comm, &viewer);
55: if (ierr) {
56: PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_REPEAT, " ");
57: return NULL;
58: }
59: PetscObjectRegisterDestroy((PetscObject)viewer);
60: if (ierr) {
61: PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_REPEAT, " ");
62: return NULL;
63: }
64: MPI_Comm_set_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void *)viewer);
65: if (ierr) {
66: PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_INITIAL, " ");
67: return NULL;
68: }
69: }
70: PetscCommDestroy(&ncomm);
71: if (ierr) {
72: PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
73: return NULL;
74: }
75: return viewer;
76: }
78: /*
79: If there is a PetscViewer associated with this communicator, it is destroyed.
80: */
81: PetscErrorCode PetscViewer_SAWS_Destroy(MPI_Comm comm)
82: {
83: PetscMPIInt flag;
84: PetscViewer viewer;
86: if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) return 0;
88: MPI_Comm_get_attr(comm, Petsc_Viewer_SAWs_keyval, (void **)&viewer, &flag);
89: if (flag) {
90: PetscViewerDestroy(&viewer);
91: MPI_Comm_delete_attr(comm, Petsc_Viewer_SAWs_keyval);
92: }
93: return 0;
94: }
96: static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer)
97: {
98: /*
99: Make sure that we mark that the stack is no longer published
100: */
101: if (PetscObjectComm((PetscObject)viewer) == PETSC_COMM_WORLD) PetscStackSAWsViewOff();
102: return 0;
103: }
105: PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v)
106: {
107: v->ops->destroy = PetscViewerDestroy_SAWs;
108: return 0;
109: }