Actual source code: ams.c

  1: #include <petsc/private/viewerimpl.h>
  2: #include <petscviewersaws.h>
  3: #include <petscsys.h>

  5: /*
  6:     The variable Petsc_Viewer_SAWs_keyval is used to indicate an MPI attribute that
  7:   is attached to a communicator, in this case the attribute is a PetscViewer.
  8: */
  9: static PetscMPIInt Petsc_Viewer_SAWs_keyval = MPI_KEYVAL_INVALID;

 11: /*@C
 12:      PETSC_VIEWER_SAWS_ - Creates a SAWs `PetscViewer` shared by all MPI processes in a communicator.

 14:      Collective

 16:      Input Parameter:
 17: .    comm - the MPI communicator to share the `PetscViewer`

 19:      Level: developer

 21:      Note:
 22:      Unlike almost all other PETSc routines, `PETSC_VIEWER_SAWS_()` does not return
 23:      an error code.  The resulting `PetscViewer` is usually used in the form
 24: $       XXXView(XXX object, PETSC_VIEWER_SAWS_(comm));

 26: .seealso: [](sec_viewers), `PetscViewer`, `PETSC_VIEWER_SAWS_WORLD`, `PETSC_VIEWER_SAWS_SELF`
 27: @*/
 28: PetscViewer PETSC_VIEWER_SAWS_(MPI_Comm comm)
 29: {
 30:   PetscErrorCode ierr;
 31:   PetscMPIInt    flag;
 32:   PetscViewer    viewer;
 33:   MPI_Comm       ncomm;

 35:   PetscFunctionBegin;
 36:   ierr = PetscCommDuplicate(comm, &ncomm, NULL);
 37:   if (ierr) {
 38:     ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, ierr, PETSC_ERROR_INITIAL, " ");
 39:     PetscFunctionReturn(NULL);
 40:   }
 41:   if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) {
 42:     ierr = (PetscErrorCode)MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN, &Petsc_Viewer_SAWs_keyval, 0);
 43:     if (ierr) {
 44:       ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_MPI, PETSC_ERROR_INITIAL, " ");
 45:       PetscFunctionReturn(NULL);
 46:     }
 47:   }
 48:   ierr = (PetscErrorCode)MPI_Comm_get_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void **)&viewer, &flag);
 49:   if (ierr) {
 50:     ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_MPI, PETSC_ERROR_INITIAL, " ");
 51:     PetscFunctionReturn(NULL);
 52:   }
 53:   if (!flag) { /* PetscViewer not yet created */
 54:     ierr = PetscViewerSAWsOpen(comm, &viewer);
 55:     if (ierr) {
 56:       ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, ierr, PETSC_ERROR_REPEAT, " ");
 57:       PetscFunctionReturn(NULL);
 58:     }
 59:     ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
 60:     if (ierr) {
 61:       ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, ierr, PETSC_ERROR_REPEAT, " ");
 62:       PetscFunctionReturn(NULL);
 63:     }
 64:     ierr = (PetscErrorCode)MPI_Comm_set_attr(ncomm, Petsc_Viewer_SAWs_keyval, (void *)viewer);
 65:     if (ierr) {
 66:       ierr = PetscError(ncomm, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, PETSC_ERR_MPI, PETSC_ERROR_INITIAL, " ");
 67:       PetscFunctionReturn(NULL);
 68:     }
 69:   }
 70:   ierr = PetscCommDestroy(&ncomm);
 71:   if (ierr) {
 72:     ierr = PetscError(PETSC_COMM_SELF, __LINE__, "PETSC_VIEWER_SAWS_", __FILE__, ierr, PETSC_ERROR_REPEAT, " ");
 73:     PetscFunctionReturn(NULL);
 74:   }
 75:   PetscFunctionReturn(viewer);
 76: }

 78: static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer)
 79: {
 80:   PetscFunctionBegin;
 81:   /*
 82:      Make sure that we mark that the stack is no longer published
 83:   */
 84:   if (PetscObjectComm((PetscObject)viewer) == PETSC_COMM_WORLD) PetscCall(PetscStackSAWsViewOff());
 85:   PetscFunctionReturn(PETSC_SUCCESS);
 86: }

 88: PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v)
 89: {
 90:   PetscFunctionBegin;
 91:   v->ops->destroy = PetscViewerDestroy_SAWs;
 92:   PetscFunctionReturn(PETSC_SUCCESS);
 93: }