xref: /petsc/src/sys/classes/viewer/impls/ams/ams.c (revision 2d30e087755efd99e28fdfe792ffbeb2ee1ea928)
1 
2 #include <petsc/private/viewerimpl.h>
3 #include <petscviewersaws.h>
4 #include <petscsys.h>
5 
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;
11 
12 /*@C
13      PETSC_VIEWER_SAWS_ - Creates an SAWs `PetscViewer` shared by all processors in a communicator.
14 
15      Collective
16 
17      Input Parameters:
18 .    comm - the MPI communicator to share the `PetscViewer`
19 
20      Level: developer
21 
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));
26 
27 .seealso: `PetscViewer`, `PETSC_VIEWER_SAWS_WORLD`, `PETSC_VIEWER_SAWS_SELF`
28 @*/
29 PetscViewer PETSC_VIEWER_SAWS_(MPI_Comm comm) {
30   PetscErrorCode ierr;
31   PetscMPIInt    flag;
32   PetscViewer    viewer;
33   MPI_Comm       ncomm;
34 
35   PetscFunctionBegin;
36   ierr = PetscCommDuplicate(comm, &ncomm, NULL);
37   if (ierr) {
38     PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_INITIAL, " ");
39     PetscFunctionReturn(0);
40   }
41   if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) {
42     ierr = 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       PetscFunctionReturn(NULL);
46     }
47   }
48   ierr = 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     PetscFunctionReturn(NULL);
52   }
53   if (!flag) { /* PetscViewer not yet created */
54     ierr = PetscViewerSAWsOpen(comm, &viewer);
55     if (ierr) {
56       PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_REPEAT, " ");
57       PetscFunctionReturn(NULL);
58     }
59     ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
60     if (ierr) {
61       PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, 1, PETSC_ERROR_REPEAT, " ");
62       PetscFunctionReturn(NULL);
63     }
64     ierr = 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       PetscFunctionReturn(NULL);
68     }
69   }
70   ierr = PetscCommDestroy(&ncomm);
71   if (ierr) {
72     PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_PLIB, PETSC_ERROR_REPEAT, " ");
73     PetscFunctionReturn(NULL);
74   }
75   PetscFunctionReturn(viewer);
76 }
77 
78 /*
79        If there is a PetscViewer associated with this communicator, it is destroyed.
80 */
81 PetscErrorCode PetscViewer_SAWS_Destroy(MPI_Comm comm) {
82   PetscMPIInt flag;
83   PetscViewer viewer;
84 
85   PetscFunctionBegin;
86   if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) PetscFunctionReturn(0);
87 
88   PetscCallMPI(MPI_Comm_get_attr(comm, Petsc_Viewer_SAWs_keyval, (void **)&viewer, &flag));
89   if (flag) {
90     PetscCall(PetscViewerDestroy(&viewer));
91     PetscCallMPI(MPI_Comm_delete_attr(comm, Petsc_Viewer_SAWs_keyval));
92   }
93   PetscFunctionReturn(0);
94 }
95 
96 static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer) {
97   PetscFunctionBegin;
98   /*
99      Make sure that we mark that the stack is no longer published
100   */
101   if (PetscObjectComm((PetscObject)viewer) == PETSC_COMM_WORLD) PetscCall(PetscStackSAWsViewOff());
102   PetscFunctionReturn(0);
103 }
104 
105 PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v) {
106   PetscFunctionBegin;
107   v->ops->destroy = PetscViewerDestroy_SAWs;
108   PetscFunctionReturn(0);
109 }
110