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