1 #include <petscis.h> /*I "petscis.h" I*/ 2 #include <petsc/private/isimpl.h> 3 #include <petsc/private/viewerimpl.h> 4 #include <petsclayouthdf5.h> 5 6 #if defined(PETSC_HAVE_HDF5) 7 /* 8 This should handle properly the cases where PetscInt is 32 or 64 and hsize_t is 32 or 64. These means properly casting with 9 checks back and forth between the two types of variables. 10 */ 11 PetscErrorCode ISLoad_HDF5(IS is, PetscViewer viewer) 12 { 13 hid_t inttype; /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */ 14 PetscInt *ind; 15 const char *isname; 16 PetscErrorCode ierr; 17 18 PetscFunctionBegin; 19 if (!((PetscObject)is)->name) SETERRQ(PetscObjectComm((PetscObject)is), PETSC_ERR_SUP, "Since HDF5 format gives ASCII name for each object in file; must use ISLoad() after setting name of Vec with PetscObjectSetName()"); 20 #if defined(PETSC_USE_64BIT_INDICES) 21 inttype = H5T_NATIVE_LLONG; 22 #else 23 inttype = H5T_NATIVE_INT; 24 #endif 25 ierr = PetscObjectGetName((PetscObject)is, &isname);CHKERRQ(ierr); 26 ierr = PetscViewerHDF5Load(viewer, isname, is->map, inttype, (void**)&ind);CHKERRQ(ierr); 27 ierr = ISGeneralSetIndices(is, is->map->n, ind, PETSC_OWN_POINTER);CHKERRQ(ierr); 28 PetscFunctionReturn(0); 29 } 30 #endif 31 32 PetscErrorCode ISLoad_Binary(IS is, PetscViewer viewer) 33 { 34 PetscErrorCode ierr; 35 PetscBool isgeneral,skipHeader,useMPIIO; 36 int fd; 37 PetscInt tr[2],N,ln,*idx; 38 MPI_Request request; 39 MPI_Status status; 40 MPI_Comm comm; 41 PetscMPIInt rank,size,tag; 42 43 PetscFunctionBegin; 44 ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 45 ierr = PetscObjectTypeCompare((PetscObject)is,ISGENERAL,&isgeneral);CHKERRQ(ierr); 46 if (!isgeneral) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"IS must be of type ISGENERAL to load into it"); 47 ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 48 if (skipHeader) SETERRQ(comm,PETSC_ERR_USER, "Currently no support for binary files without headers"); 49 /* force binary viewer to load .info file if it has not yet done so */ 50 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 51 52 ierr = PetscViewerBinaryRead(viewer,tr,2,NULL,PETSC_INT);CHKERRQ(ierr); 53 if (tr[0] != IS_FILE_CLASSID) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Not an IS next in file"); 54 55 /* Has IS already had its layout defined */ 56 /* ierr = ISGetLayout(is,&map);CHKERRQ(ierr); */ 57 ierr = PetscLayoutGetSize(is->map,&N);CHKERRQ(ierr); 58 if (N > -1 && N != tr[1]) SETERRQ2(comm,PETSC_ERR_ARG_SIZ,"Size of IS in file %D does not match size of IS provided",tr[1],N); 59 if (N == -1) { 60 N = tr[1]; 61 ierr = PetscLayoutSetSize(is->map,N);CHKERRQ(ierr); 62 ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); 63 } 64 ierr = PetscLayoutGetLocalSize(is->map,&ln);CHKERRQ(ierr); 65 ierr = PetscMalloc1(ln,&idx);CHKERRQ(ierr); 66 67 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);CHKERRQ(ierr); 68 #if defined(PETSC_HAVE_MPIIO) 69 if (useMPIIO) { 70 MPI_File mfdes; 71 MPI_Offset off; 72 PetscMPIInt lsize; 73 PetscInt rstart; 74 75 ierr = PetscMPIIntCast(ln,&lsize);CHKERRQ(ierr); 76 ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr); 77 ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr); 78 ierr = PetscLayoutGetRange(is->map,&rstart,NULL);CHKERRQ(ierr); 79 off += rstart*(MPI_Offset)sizeof(PetscInt); 80 ierr = MPIU_File_read_at_all(mfdes,off,idx,lsize,MPIU_INT,MPI_STATUS_IGNORE);CHKERRQ(ierr); 81 ierr = PetscViewerBinaryAddMPIIOOffset(viewer,N*(MPI_Offset)sizeof(PetscInt));CHKERRQ(ierr); 82 ierr = ISGeneralSetIndices(is,ln,idx,PETSC_OWN_POINTER);CHKERRQ(ierr); 83 PetscFunctionReturn(0); 84 } 85 #endif 86 87 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 88 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 89 ierr = PetscObjectGetNewTag((PetscObject)viewer,&tag);CHKERRQ(ierr); 90 ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 91 92 if (!rank) { 93 ierr = PetscBinaryRead(fd,idx,ln,NULL,PETSC_INT);CHKERRQ(ierr); 94 95 if (size > 1) { 96 PetscInt *range,n,i,*idxwork; 97 98 /* read in other chuncks and send to other processors */ 99 /* determine maximum chunck owned by other */ 100 range = is->map->range; 101 n = 1; 102 for (i=1; i<size; i++) n = PetscMax(n,range[i+1] - range[i]); 103 104 ierr = PetscMalloc1(n,&idxwork);CHKERRQ(ierr); 105 for (i=1; i<size; i++) { 106 n = range[i+1] - range[i]; 107 ierr = PetscBinaryRead(fd,idxwork,n,NULL,PETSC_INT);CHKERRQ(ierr); 108 ierr = MPI_Isend(idxwork,n,MPIU_INT,i,tag,comm,&request);CHKERRQ(ierr); 109 ierr = MPI_Wait(&request,&status);CHKERRQ(ierr); 110 } 111 ierr = PetscFree(idxwork);CHKERRQ(ierr); 112 } 113 } else { 114 ierr = MPI_Recv(idx,ln,MPIU_INT,0,tag,comm,&status);CHKERRQ(ierr); 115 } 116 ierr = ISGeneralSetIndices(is,ln,idx,PETSC_OWN_POINTER);CHKERRQ(ierr); 117 PetscFunctionReturn(0); 118 } 119 120 PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer) 121 { 122 PetscBool isbinary; 123 #if defined(PETSC_HAVE_HDF5) 124 PetscBool ishdf5; 125 #endif 126 PetscErrorCode ierr; 127 128 PetscFunctionBegin; 129 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 130 #if defined(PETSC_HAVE_HDF5) 131 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 132 #endif 133 if (isbinary) { 134 ierr = ISLoad_Binary(is, viewer);CHKERRQ(ierr); 135 #if defined(PETSC_HAVE_HDF5) 136 } else if (ishdf5) { 137 ierr = ISLoad_HDF5(is, viewer);CHKERRQ(ierr); 138 #endif 139 } 140 PetscFunctionReturn(0); 141 } 142