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: }