1235f7792SMatthew G. Knepley #include <petscis.h> /*I "petscis.h" I*/ 2af0996ceSBarry Smith #include <petsc/private/isimpl.h> 3235f7792SMatthew G. Knepley #include <petscviewerhdf5.h> 4235f7792SMatthew G. Knepley 5235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 6235f7792SMatthew G. Knepley #undef __FUNCT__ 7235f7792SMatthew G. Knepley #define __FUNCT__ "ISLoad_HDF5" 8235f7792SMatthew G. Knepley /* 9235f7792SMatthew G. Knepley This should handle properly the cases where PetscInt is 32 or 64 and hsize_t is 32 or 64. These means properly casting with 10235f7792SMatthew G. Knepley checks back and forth between the two types of variables. 11235f7792SMatthew G. Knepley */ 12235f7792SMatthew G. Knepley PetscErrorCode ISLoad_HDF5(IS is, PetscViewer viewer) 13235f7792SMatthew G. Knepley { 14235f7792SMatthew G. Knepley hid_t inttype; /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */ 15235f7792SMatthew G. Knepley hid_t file_id, group, dset_id, filespace, memspace, plist_id; 16794a961bSBarry Smith int rdim, dim; 17235f7792SMatthew G. Knepley hsize_t dims[3], count[3], offset[3]; 1833334011SMatthew G. Knepley PetscInt n, N, bs, bsInd, lenInd, low, timestep; 19235f7792SMatthew G. Knepley const PetscInt *ind; 20235f7792SMatthew G. Knepley const char *isname; 21235f7792SMatthew G. Knepley PetscErrorCode ierr; 22235f7792SMatthew G. Knepley 23235f7792SMatthew G. Knepley PetscFunctionBegin; 24*ede126feSBarry Smith 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()"); 25235f7792SMatthew G. Knepley ierr = PetscViewerHDF5OpenGroup(viewer, &file_id, &group);CHKERRQ(ierr); 26235f7792SMatthew G. Knepley ierr = PetscViewerHDF5GetTimestep(viewer, ×tep);CHKERRQ(ierr); 27235f7792SMatthew G. Knepley ierr = ISGetBlockSize(is, &bs);CHKERRQ(ierr); 28235f7792SMatthew G. Knepley /* Create the dataset with default properties and close filespace */ 29235f7792SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) is, &isname);CHKERRQ(ierr); 30235f7792SMatthew G. Knepley #if (H5_VERS_MAJOR * 10000 + H5_VERS_MINOR * 100 + H5_VERS_RELEASE >= 10800) 31729ab6d9SBarry Smith PetscStackCallHDF5Return(dset_id,H5Dopen2,(group, isname, H5P_DEFAULT)); 32235f7792SMatthew G. Knepley #else 33729ab6d9SBarry Smith PetscStackCallHDF5Return(dset_id,H5Dopen,(group, isname)); 34235f7792SMatthew G. Knepley #endif 35235f7792SMatthew G. Knepley /* Retrieve the dataspace for the dataset */ 36729ab6d9SBarry Smith PetscStackCallHDF5Return(filespace,H5Dget_space,(dset_id)); 37235f7792SMatthew G. Knepley dim = 0; 38235f7792SMatthew G. Knepley if (timestep >= 0) ++dim; 39235f7792SMatthew G. Knepley ++dim; 4033334011SMatthew G. Knepley ++dim; 41729ab6d9SBarry Smith PetscStackCallHDF5Return(rdim,H5Sget_simple_extent_dims,(filespace, dims, NULL)); 42235f7792SMatthew G. Knepley bsInd = rdim-1; 43235f7792SMatthew G. Knepley lenInd = timestep >= 0 ? 1 : 0; 4433334011SMatthew G. Knepley if (rdim != dim) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Dimension of array in file %d not %d as expected",rdim,dim); 4533334011SMatthew G. Knepley else if (bs != (PetscInt) dims[bsInd]) { 4633334011SMatthew G. Knepley ierr = ISSetBlockSize(is, dims[bsInd]); 47235f7792SMatthew G. Knepley if (ierr) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED, "Block size %d specified for IS does not match blocksize in file %d",bs,dims[bsInd]); 48235f7792SMatthew G. Knepley bs = dims[bsInd]; 49235f7792SMatthew G. Knepley } 50235f7792SMatthew G. Knepley 51235f7792SMatthew G. Knepley /* Set Vec sizes,blocksize,and type if not already set */ 52235f7792SMatthew G. Knepley ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr); 53235f7792SMatthew G. Knepley ierr = ISGetSize(is, &N);CHKERRQ(ierr); 54235f7792SMatthew G. Knepley if (n < 0 && N < 0) {ierr = PetscLayoutSetSize(is->map, dims[lenInd]*bs);CHKERRQ(ierr);} 55235f7792SMatthew G. Knepley ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); 56235f7792SMatthew G. Knepley /* If sizes and type already set,check if the vector global size is correct */ 57235f7792SMatthew G. Knepley ierr = ISGetSize(is, &N);CHKERRQ(ierr); 58235f7792SMatthew G. Knepley if (N/bs != (PetscInt) dims[lenInd]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "IS in file different length (%d) then input vector (%d)", (PetscInt) dims[lenInd], N/bs); 59235f7792SMatthew G. Knepley 60235f7792SMatthew G. Knepley /* Each process defines a dataset and reads it from the hyperslab in the file */ 61235f7792SMatthew G. Knepley ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr); 62235f7792SMatthew G. Knepley dim = 0; 63235f7792SMatthew G. Knepley if (timestep >= 0) { 64235f7792SMatthew G. Knepley count[dim] = 1; 65235f7792SMatthew G. Knepley ++dim; 66235f7792SMatthew G. Knepley } 67235f7792SMatthew G. Knepley ierr = PetscHDF5IntCast(n/bs,count + dim);CHKERRQ(ierr); 68235f7792SMatthew G. Knepley ++dim; 69235f7792SMatthew G. Knepley if (bs >= 1) { 70235f7792SMatthew G. Knepley count[dim] = bs; 71235f7792SMatthew G. Knepley ++dim; 72235f7792SMatthew G. Knepley } 73729ab6d9SBarry Smith PetscStackCallHDF5Return(memspace,H5Screate_simple,(dim, count, NULL)); 74235f7792SMatthew G. Knepley 75235f7792SMatthew G. Knepley /* Select hyperslab in the file */ 76235f7792SMatthew G. Knepley ierr = PetscLayoutGetRange(is->map, &low, NULL);CHKERRQ(ierr); 77235f7792SMatthew G. Knepley dim = 0; 78235f7792SMatthew G. Knepley if (timestep >= 0) { 79235f7792SMatthew G. Knepley offset[dim] = timestep; 80235f7792SMatthew G. Knepley ++dim; 81235f7792SMatthew G. Knepley } 82235f7792SMatthew G. Knepley ierr = PetscHDF5IntCast(low/bs,offset + dim);CHKERRQ(ierr); 83235f7792SMatthew G. Knepley ++dim; 84235f7792SMatthew G. Knepley if (bs >= 1) { 85235f7792SMatthew G. Knepley offset[dim] = 0; 86235f7792SMatthew G. Knepley ++dim; 87235f7792SMatthew G. Knepley } 88729ab6d9SBarry Smith PetscStackCallHDF5(H5Sselect_hyperslab,(filespace, H5S_SELECT_SET, offset, NULL, count, NULL)); 89235f7792SMatthew G. Knepley 90235f7792SMatthew G. Knepley /* Create property list for collective dataset read */ 91729ab6d9SBarry Smith PetscStackCallHDF5Return(plist_id,H5Pcreate,(H5P_DATASET_XFER)); 92235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO) 93729ab6d9SBarry Smith PetscStackCallHDF5(H5Pset_dxpl_mpio,(plist_id, H5FD_MPIO_COLLECTIVE)); 94235f7792SMatthew G. Knepley #endif 95235f7792SMatthew G. Knepley /* To write dataset independently use H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_INDEPENDENT) */ 96235f7792SMatthew G. Knepley 97235f7792SMatthew G. Knepley #if defined(PETSC_USE_64BIT_INDICES) 98235f7792SMatthew G. Knepley inttype = H5T_NATIVE_LLONG; 99235f7792SMatthew G. Knepley #else 100235f7792SMatthew G. Knepley inttype = H5T_NATIVE_INT; 101235f7792SMatthew G. Knepley #endif 102235f7792SMatthew G. Knepley ierr = PetscMalloc1(n,&ind);CHKERRQ(ierr); 103729ab6d9SBarry Smith PetscStackCallHDF5(H5Dread,(dset_id, inttype, memspace, filespace, plist_id, (void *) ind)); 104235f7792SMatthew G. Knepley ierr = ISGeneralSetIndices(is, n, ind, PETSC_OWN_POINTER);CHKERRQ(ierr); 105235f7792SMatthew G. Knepley 106235f7792SMatthew G. Knepley /* Close/release resources */ 107729ab6d9SBarry Smith if (group != file_id) PetscStackCallHDF5(H5Gclose,(group)); 108729ab6d9SBarry Smith PetscStackCallHDF5(H5Pclose,(plist_id)); 109729ab6d9SBarry Smith PetscStackCallHDF5(H5Sclose,(filespace)); 110729ab6d9SBarry Smith PetscStackCallHDF5(H5Sclose,(memspace)); 111729ab6d9SBarry Smith PetscStackCallHDF5(H5Dclose,(dset_id)); 112235f7792SMatthew G. Knepley PetscFunctionReturn(0); 113235f7792SMatthew G. Knepley } 114235f7792SMatthew G. Knepley #endif 115235f7792SMatthew G. Knepley 116235f7792SMatthew G. Knepley #undef __FUNCT__ 117*ede126feSBarry Smith #define __FUNCT__ "ISLoad_Binary" 118*ede126feSBarry Smith PetscErrorCode ISLoad_Binary(IS is, PetscViewer viewer) 119*ede126feSBarry Smith { 120*ede126feSBarry Smith PetscErrorCode ierr; 121*ede126feSBarry Smith PetscBool isgeneral,skipheader; 122*ede126feSBarry Smith int fd; 123*ede126feSBarry Smith PetscInt tr[2],N,ln,*idx; 124*ede126feSBarry Smith MPI_Request request; 125*ede126feSBarry Smith MPI_Status status; 126*ede126feSBarry Smith MPI_Comm comm; 127*ede126feSBarry Smith PetscMPIInt rank,size,tag; 128*ede126feSBarry Smith 129*ede126feSBarry Smith PetscFunctionBegin; 130*ede126feSBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 131*ede126feSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 132*ede126feSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 133*ede126feSBarry Smith ierr = PetscObjectGetNewTag((PetscObject)viewer,&tag);CHKERRQ(ierr); 134*ede126feSBarry Smith /* force binary viewer to load .info file if it has not yet done so */ 135*ede126feSBarry Smith ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 136*ede126feSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISGENERAL,&isgeneral);CHKERRQ(ierr); 137*ede126feSBarry Smith if (!isgeneral) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"IS must be of type ISGENERAL to load into it"); 138*ede126feSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 139*ede126feSBarry Smith ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipheader);CHKERRQ(ierr); 140*ede126feSBarry Smith if (skipheader) SETERRQ(comm,PETSC_ERR_USER, "Currently no support for binary files without headers"); 141*ede126feSBarry Smith 142*ede126feSBarry Smith ierr = PetscViewerBinaryRead(viewer,tr,2,NULL,PETSC_INT);CHKERRQ(ierr); 143*ede126feSBarry Smith if (tr[0] != IS_FILE_CLASSID) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Not an IS next in file"); 144*ede126feSBarry Smith 145*ede126feSBarry Smith /* Has IS already had its layout defined */ 146*ede126feSBarry Smith ierr = PetscLayoutGetSize(is->map,&N);CHKERRQ(ierr); 147*ede126feSBarry Smith 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); 148*ede126feSBarry Smith if (N == -1) { 149*ede126feSBarry Smith N = tr[1]; 150*ede126feSBarry Smith ierr = PetscLayoutSetSize(is->map,N);CHKERRQ(ierr); 151*ede126feSBarry Smith ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); 152*ede126feSBarry Smith } 153*ede126feSBarry Smith ierr = PetscLayoutGetLocalSize(is->map,&ln);CHKERRQ(ierr); 154*ede126feSBarry Smith ierr = PetscMalloc1(ln,&idx);CHKERRQ(ierr); 155*ede126feSBarry Smith if (!rank) { 156*ede126feSBarry Smith ierr = PetscBinaryRead(fd,idx,ln,PETSC_INT);CHKERRQ(ierr); 157*ede126feSBarry Smith 158*ede126feSBarry Smith if (size > 1) { 159*ede126feSBarry Smith PetscInt *range,n,i,*idxwork; 160*ede126feSBarry Smith 161*ede126feSBarry Smith /* read in other chuncks and send to other processors */ 162*ede126feSBarry Smith /* determine maximum chunck owned by other */ 163*ede126feSBarry Smith range = is->map->range; 164*ede126feSBarry Smith n = 1; 165*ede126feSBarry Smith for (i=1; i<size; i++) n = PetscMax(n,range[i+1] - range[i]); 166*ede126feSBarry Smith 167*ede126feSBarry Smith ierr = PetscMalloc1(n,&idxwork);CHKERRQ(ierr); 168*ede126feSBarry Smith for (i=1; i<size; i++) { 169*ede126feSBarry Smith n = range[i+1] - range[i]; 170*ede126feSBarry Smith ierr = PetscBinaryRead(fd,idxwork,n,PETSC_INT);CHKERRQ(ierr); 171*ede126feSBarry Smith ierr = MPI_Isend(idxwork,n,MPIU_INT,i,tag,comm,&request);CHKERRQ(ierr); 172*ede126feSBarry Smith ierr = MPI_Wait(&request,&status);CHKERRQ(ierr); 173*ede126feSBarry Smith } 174*ede126feSBarry Smith ierr = PetscFree(idxwork);CHKERRQ(ierr); 175*ede126feSBarry Smith } 176*ede126feSBarry Smith } else { 177*ede126feSBarry Smith ierr = MPI_Recv(idx,ln,MPIU_INT,0,tag,comm,&status);CHKERRQ(ierr); 178*ede126feSBarry Smith } 179*ede126feSBarry Smith ierr = ISGeneralSetIndices(is,ln,idx,PETSC_OWN_POINTER);CHKERRQ(ierr); 180*ede126feSBarry Smith PetscFunctionReturn(0); 181*ede126feSBarry Smith } 182*ede126feSBarry Smith 183*ede126feSBarry Smith #undef __FUNCT__ 184235f7792SMatthew G. Knepley #define __FUNCT__ "ISLoad_Default" 185235f7792SMatthew G. Knepley PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer) 186235f7792SMatthew G. Knepley { 187235f7792SMatthew G. Knepley PetscBool isbinary; 188235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 189235f7792SMatthew G. Knepley PetscBool ishdf5; 190235f7792SMatthew G. Knepley #endif 191235f7792SMatthew G. Knepley PetscErrorCode ierr; 192235f7792SMatthew G. Knepley 193235f7792SMatthew G. Knepley PetscFunctionBegin; 194235f7792SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 19582be971eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 196235f7792SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 19782be971eSMatthew G. Knepley #endif 198235f7792SMatthew G. Knepley if (isbinary) { 199*ede126feSBarry Smith ierr = ISLoad_Binary(is, viewer);CHKERRQ(ierr); 200235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 201235f7792SMatthew G. Knepley } else if (ishdf5) { 202235f7792SMatthew G. Knepley ierr = ISLoad_HDF5(is, viewer);CHKERRQ(ierr); 203235f7792SMatthew G. Knepley #endif 204235f7792SMatthew G. Knepley } 205235f7792SMatthew G. Knepley PetscFunctionReturn(0); 206235f7792SMatthew G. Knepley } 207