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 #undef __FUNCT__ 13 #define __FUNCT__ "PETSC_VIEWER_SAWS_" 14 /*@C 15 PETSC_VIEWER_SAWS_ - Creates an SAWs memory snooper PetscViewer shared by all processors 16 in a communicator. 17 18 Collective on MPI_Comm 19 20 Input Parameters: 21 . comm - the MPI communicator to share the PetscViewer 22 23 Level: developer 24 25 Notes: 26 Unlike almost all other PETSc routines, PETSC_VIEWER_SAWS_() does not return 27 an error code. The window PetscViewer is usually used in the form 28 $ XXXView(XXX object,PETSC_VIEWER_SAWS_(comm)); 29 30 .seealso: PETSC_VIEWER_SAWS_WORLD, PETSC_VIEWER_SAWS_SELF 31 @*/ 32 PetscViewer PETSC_VIEWER_SAWS_(MPI_Comm comm) 33 { 34 PetscErrorCode ierr; 35 PetscMPIInt flag; 36 PetscViewer viewer; 37 MPI_Comm ncomm; 38 39 PetscFunctionBegin; 40 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 41 if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) { 42 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_SAWs_keyval,0); 43 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 44 } 45 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_SAWs_keyval,(void**)&viewer,&flag); 46 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 47 if (!flag) { /* PetscViewer not yet created */ 48 ierr = PetscViewerSAWsOpen(comm,&viewer); 49 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 50 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 51 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 52 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_SAWs_keyval,(void*)viewer); 53 if (ierr) {PetscError(ncomm,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,1,PETSC_ERROR_INITIAL," "); viewer = NULL;} 54 } 55 ierr = PetscCommDestroy(&ncomm); 56 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SAWS_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 57 PetscFunctionReturn(viewer); 58 } 59 60 /* 61 If there is a PetscViewer associated with this communicator, it is destroyed. 62 */ 63 #undef __FUNCT__ 64 #define __FUNCT__ "PetscViewer_SAWS_Destroy" 65 PetscErrorCode PetscViewer_SAWS_Destroy(MPI_Comm comm) 66 { 67 PetscErrorCode ierr; 68 PetscMPIInt flag; 69 PetscViewer viewer; 70 71 PetscFunctionBegin; 72 if (Petsc_Viewer_SAWs_keyval == MPI_KEYVAL_INVALID) PetscFunctionReturn(0); 73 74 ierr = MPI_Attr_get(comm,Petsc_Viewer_SAWs_keyval,(void**)&viewer,&flag);CHKERRQ(ierr); 75 if (flag) { 76 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 77 ierr = MPI_Attr_delete(comm,Petsc_Viewer_SAWs_keyval);CHKERRQ(ierr); 78 } 79 PetscFunctionReturn(0); 80 } 81 82 #undef __FUNCT__ 83 #define __FUNCT__ "PetscViewerDestroy_SAWs" 84 static PetscErrorCode PetscViewerDestroy_SAWs(PetscViewer viewer) 85 { 86 PetscErrorCode ierr; 87 88 PetscFunctionBegin; 89 /* 90 Make sure that we mark that the stack is no longer published 91 */ 92 if (PetscObjectComm((PetscObject)viewer) == PETSC_COMM_WORLD) { 93 ierr = PetscStackSAWsViewOff();CHKERRQ(ierr); 94 } 95 PetscFunctionReturn(0); 96 } 97 98 #undef __FUNCT__ 99 #define __FUNCT__ "PetscViewerCreate_SAWs" 100 PETSC_EXTERN PetscErrorCode PetscViewerCreate_SAWs(PetscViewer v) 101 { 102 PetscFunctionBegin; 103 v->ops->destroy = PetscViewerDestroy_SAWs; 104 PetscFunctionReturn(0); 105 } 106 107 108 109