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 /* 7235f7792SMatthew 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 8235f7792SMatthew G. Knepley checks back and forth between the two types of variables. 9235f7792SMatthew G. Knepley */ 10235f7792SMatthew G. Knepley PetscErrorCode ISLoad_HDF5(IS is, PetscViewer viewer) 11235f7792SMatthew G. Knepley { 12235f7792SMatthew G. Knepley hid_t inttype; /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */ 13235f7792SMatthew G. Knepley hid_t file_id, group, dset_id, filespace, memspace, plist_id; 14794a961bSBarry Smith int rdim, dim; 15235f7792SMatthew G. Knepley hsize_t dims[3], count[3], offset[3]; 1633334011SMatthew G. Knepley PetscInt n, N, bs, bsInd, lenInd, low, timestep; 17235f7792SMatthew G. Knepley const PetscInt *ind; 18235f7792SMatthew G. Knepley const char *isname; 19235f7792SMatthew G. Knepley PetscErrorCode ierr; 20235f7792SMatthew G. Knepley 21235f7792SMatthew G. Knepley PetscFunctionBegin; 22ede126feSBarry 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()"); 23235f7792SMatthew G. Knepley ierr = PetscViewerHDF5OpenGroup(viewer, &file_id, &group);CHKERRQ(ierr); 24235f7792SMatthew G. Knepley ierr = PetscViewerHDF5GetTimestep(viewer, ×tep);CHKERRQ(ierr); 25235f7792SMatthew G. Knepley ierr = ISGetBlockSize(is, &bs);CHKERRQ(ierr); 26235f7792SMatthew G. Knepley /* Create the dataset with default properties and close filespace */ 27235f7792SMatthew G. Knepley ierr = PetscObjectGetName((PetscObject) is, &isname);CHKERRQ(ierr); 28235f7792SMatthew G. Knepley #if (H5_VERS_MAJOR * 10000 + H5_VERS_MINOR * 100 + H5_VERS_RELEASE >= 10800) 29729ab6d9SBarry Smith PetscStackCallHDF5Return(dset_id,H5Dopen2,(group, isname, H5P_DEFAULT)); 30235f7792SMatthew G. Knepley #else 31729ab6d9SBarry Smith PetscStackCallHDF5Return(dset_id,H5Dopen,(group, isname)); 32235f7792SMatthew G. Knepley #endif 33235f7792SMatthew G. Knepley /* Retrieve the dataspace for the dataset */ 34729ab6d9SBarry Smith PetscStackCallHDF5Return(filespace,H5Dget_space,(dset_id)); 35235f7792SMatthew G. Knepley dim = 0; 36235f7792SMatthew G. Knepley if (timestep >= 0) ++dim; 37235f7792SMatthew G. Knepley ++dim; 3833334011SMatthew G. Knepley ++dim; 39729ab6d9SBarry Smith PetscStackCallHDF5Return(rdim,H5Sget_simple_extent_dims,(filespace, dims, NULL)); 40235f7792SMatthew G. Knepley bsInd = rdim-1; 41235f7792SMatthew G. Knepley lenInd = timestep >= 0 ? 1 : 0; 4233334011SMatthew 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); 4333334011SMatthew G. Knepley else if (bs != (PetscInt) dims[bsInd]) { 4433334011SMatthew G. Knepley ierr = ISSetBlockSize(is, dims[bsInd]); 45235f7792SMatthew 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]); 46235f7792SMatthew G. Knepley bs = dims[bsInd]; 47235f7792SMatthew G. Knepley } 48235f7792SMatthew G. Knepley 49235f7792SMatthew G. Knepley /* Set Vec sizes,blocksize,and type if not already set */ 50235f7792SMatthew G. Knepley ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr); 51235f7792SMatthew G. Knepley ierr = ISGetSize(is, &N);CHKERRQ(ierr); 52235f7792SMatthew G. Knepley if (n < 0 && N < 0) {ierr = PetscLayoutSetSize(is->map, dims[lenInd]*bs);CHKERRQ(ierr);} 53235f7792SMatthew G. Knepley ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); 54235f7792SMatthew G. Knepley /* If sizes and type already set,check if the vector global size is correct */ 55235f7792SMatthew G. Knepley ierr = ISGetSize(is, &N);CHKERRQ(ierr); 56235f7792SMatthew 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); 57235f7792SMatthew G. Knepley 58235f7792SMatthew G. Knepley /* Each process defines a dataset and reads it from the hyperslab in the file */ 59235f7792SMatthew G. Knepley ierr = ISGetLocalSize(is, &n);CHKERRQ(ierr); 60235f7792SMatthew G. Knepley dim = 0; 61235f7792SMatthew G. Knepley if (timestep >= 0) { 62235f7792SMatthew G. Knepley count[dim] = 1; 63235f7792SMatthew G. Knepley ++dim; 64235f7792SMatthew G. Knepley } 65235f7792SMatthew G. Knepley ierr = PetscHDF5IntCast(n/bs,count + dim);CHKERRQ(ierr); 66235f7792SMatthew G. Knepley ++dim; 67235f7792SMatthew G. Knepley if (bs >= 1) { 68235f7792SMatthew G. Knepley count[dim] = bs; 69235f7792SMatthew G. Knepley ++dim; 70235f7792SMatthew G. Knepley } 71729ab6d9SBarry Smith PetscStackCallHDF5Return(memspace,H5Screate_simple,(dim, count, NULL)); 72235f7792SMatthew G. Knepley 73235f7792SMatthew G. Knepley /* Select hyperslab in the file */ 74235f7792SMatthew G. Knepley ierr = PetscLayoutGetRange(is->map, &low, NULL);CHKERRQ(ierr); 75235f7792SMatthew G. Knepley dim = 0; 76235f7792SMatthew G. Knepley if (timestep >= 0) { 77235f7792SMatthew G. Knepley offset[dim] = timestep; 78235f7792SMatthew G. Knepley ++dim; 79235f7792SMatthew G. Knepley } 80235f7792SMatthew G. Knepley ierr = PetscHDF5IntCast(low/bs,offset + dim);CHKERRQ(ierr); 81235f7792SMatthew G. Knepley ++dim; 82235f7792SMatthew G. Knepley if (bs >= 1) { 83235f7792SMatthew G. Knepley offset[dim] = 0; 84235f7792SMatthew G. Knepley ++dim; 85235f7792SMatthew G. Knepley } 86729ab6d9SBarry Smith PetscStackCallHDF5(H5Sselect_hyperslab,(filespace, H5S_SELECT_SET, offset, NULL, count, NULL)); 87235f7792SMatthew G. Knepley 88235f7792SMatthew G. Knepley /* Create property list for collective dataset read */ 89729ab6d9SBarry Smith PetscStackCallHDF5Return(plist_id,H5Pcreate,(H5P_DATASET_XFER)); 90235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO) 91729ab6d9SBarry Smith PetscStackCallHDF5(H5Pset_dxpl_mpio,(plist_id, H5FD_MPIO_COLLECTIVE)); 92235f7792SMatthew G. Knepley #endif 93235f7792SMatthew G. Knepley /* To write dataset independently use H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_INDEPENDENT) */ 94235f7792SMatthew G. Knepley 95235f7792SMatthew G. Knepley #if defined(PETSC_USE_64BIT_INDICES) 96235f7792SMatthew G. Knepley inttype = H5T_NATIVE_LLONG; 97235f7792SMatthew G. Knepley #else 98235f7792SMatthew G. Knepley inttype = H5T_NATIVE_INT; 99235f7792SMatthew G. Knepley #endif 100235f7792SMatthew G. Knepley ierr = PetscMalloc1(n,&ind);CHKERRQ(ierr); 101729ab6d9SBarry Smith PetscStackCallHDF5(H5Dread,(dset_id, inttype, memspace, filespace, plist_id, (void *) ind)); 102235f7792SMatthew G. Knepley ierr = ISGeneralSetIndices(is, n, ind, PETSC_OWN_POINTER);CHKERRQ(ierr); 103235f7792SMatthew G. Knepley 104235f7792SMatthew G. Knepley /* Close/release resources */ 105729ab6d9SBarry Smith if (group != file_id) PetscStackCallHDF5(H5Gclose,(group)); 106729ab6d9SBarry Smith PetscStackCallHDF5(H5Pclose,(plist_id)); 107729ab6d9SBarry Smith PetscStackCallHDF5(H5Sclose,(filespace)); 108729ab6d9SBarry Smith PetscStackCallHDF5(H5Sclose,(memspace)); 109729ab6d9SBarry Smith PetscStackCallHDF5(H5Dclose,(dset_id)); 110235f7792SMatthew G. Knepley PetscFunctionReturn(0); 111235f7792SMatthew G. Knepley } 112235f7792SMatthew G. Knepley #endif 113235f7792SMatthew G. Knepley 114ede126feSBarry Smith PetscErrorCode ISLoad_Binary(IS is, PetscViewer viewer) 115ede126feSBarry Smith { 116ede126feSBarry Smith PetscErrorCode ierr; 117*de8a3bf8SLisandro Dalcin PetscBool isgeneral,skipHeader,useMPIIO; 118ede126feSBarry Smith int fd; 119ede126feSBarry Smith PetscInt tr[2],N,ln,*idx; 120ede126feSBarry Smith MPI_Request request; 121ede126feSBarry Smith MPI_Status status; 122ede126feSBarry Smith MPI_Comm comm; 123ede126feSBarry Smith PetscMPIInt rank,size,tag; 124ede126feSBarry Smith 125ede126feSBarry Smith PetscFunctionBegin; 126ede126feSBarry Smith ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr); 127ede126feSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)is,ISGENERAL,&isgeneral);CHKERRQ(ierr); 128ede126feSBarry Smith if (!isgeneral) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"IS must be of type ISGENERAL to load into it"); 129*de8a3bf8SLisandro Dalcin ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr); 130*de8a3bf8SLisandro Dalcin if (skipHeader) SETERRQ(comm,PETSC_ERR_USER, "Currently no support for binary files without headers"); 131*de8a3bf8SLisandro Dalcin /* force binary viewer to load .info file if it has not yet done so */ 132*de8a3bf8SLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 133ede126feSBarry Smith 134ede126feSBarry Smith ierr = PetscViewerBinaryRead(viewer,tr,2,NULL,PETSC_INT);CHKERRQ(ierr); 135ede126feSBarry Smith if (tr[0] != IS_FILE_CLASSID) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Not an IS next in file"); 136ede126feSBarry Smith 137ede126feSBarry Smith /* Has IS already had its layout defined */ 138*de8a3bf8SLisandro Dalcin /* ierr = ISGetLayout(is,&map);CHKERRQ(ierr); */ 139ede126feSBarry Smith ierr = PetscLayoutGetSize(is->map,&N);CHKERRQ(ierr); 140ede126feSBarry 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); 141ede126feSBarry Smith if (N == -1) { 142ede126feSBarry Smith N = tr[1]; 143ede126feSBarry Smith ierr = PetscLayoutSetSize(is->map,N);CHKERRQ(ierr); 144ede126feSBarry Smith ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr); 145ede126feSBarry Smith } 146ede126feSBarry Smith ierr = PetscLayoutGetLocalSize(is->map,&ln);CHKERRQ(ierr); 147ede126feSBarry Smith ierr = PetscMalloc1(ln,&idx);CHKERRQ(ierr); 148*de8a3bf8SLisandro Dalcin 149*de8a3bf8SLisandro Dalcin ierr = PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);CHKERRQ(ierr); 150*de8a3bf8SLisandro Dalcin #if defined(PETSC_HAVE_MPIIO) 151*de8a3bf8SLisandro Dalcin if (useMPIIO) { 152*de8a3bf8SLisandro Dalcin MPI_File mfdes; 153*de8a3bf8SLisandro Dalcin MPI_Offset off; 154*de8a3bf8SLisandro Dalcin PetscMPIInt lsize; 155*de8a3bf8SLisandro Dalcin PetscInt rstart; 156*de8a3bf8SLisandro Dalcin 157*de8a3bf8SLisandro Dalcin ierr = PetscMPIIntCast(ln,&lsize);CHKERRQ(ierr); 158*de8a3bf8SLisandro Dalcin ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr); 159*de8a3bf8SLisandro Dalcin ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr); 160*de8a3bf8SLisandro Dalcin ierr = PetscLayoutGetRange(is->map,&rstart,NULL);CHKERRQ(ierr); 161*de8a3bf8SLisandro Dalcin off += rstart*(MPI_Offset)sizeof(PetscInt); 162*de8a3bf8SLisandro Dalcin ierr = MPI_File_set_view(mfdes,off,MPIU_INT,MPIU_INT,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr); 163*de8a3bf8SLisandro Dalcin ierr = MPIU_File_read_all(mfdes,idx,lsize,MPIU_INT,MPI_STATUS_IGNORE);CHKERRQ(ierr); 164*de8a3bf8SLisandro Dalcin ierr = PetscViewerBinaryAddMPIIOOffset(viewer,N*(MPI_Offset)sizeof(PetscInt));CHKERRQ(ierr); 165*de8a3bf8SLisandro Dalcin ierr = ISGeneralSetIndices(is,ln,idx,PETSC_OWN_POINTER);CHKERRQ(ierr); 166*de8a3bf8SLisandro Dalcin PetscFunctionReturn(0); 167*de8a3bf8SLisandro Dalcin } 168*de8a3bf8SLisandro Dalcin #endif 169*de8a3bf8SLisandro Dalcin 170*de8a3bf8SLisandro Dalcin ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 171*de8a3bf8SLisandro Dalcin ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 172*de8a3bf8SLisandro Dalcin ierr = PetscObjectGetNewTag((PetscObject)viewer,&tag);CHKERRQ(ierr); 173*de8a3bf8SLisandro Dalcin ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 174*de8a3bf8SLisandro Dalcin 175ede126feSBarry Smith if (!rank) { 176ede126feSBarry Smith ierr = PetscBinaryRead(fd,idx,ln,PETSC_INT);CHKERRQ(ierr); 177ede126feSBarry Smith 178ede126feSBarry Smith if (size > 1) { 179ede126feSBarry Smith PetscInt *range,n,i,*idxwork; 180ede126feSBarry Smith 181ede126feSBarry Smith /* read in other chuncks and send to other processors */ 182ede126feSBarry Smith /* determine maximum chunck owned by other */ 183ede126feSBarry Smith range = is->map->range; 184ede126feSBarry Smith n = 1; 185ede126feSBarry Smith for (i=1; i<size; i++) n = PetscMax(n,range[i+1] - range[i]); 186ede126feSBarry Smith 187ede126feSBarry Smith ierr = PetscMalloc1(n,&idxwork);CHKERRQ(ierr); 188ede126feSBarry Smith for (i=1; i<size; i++) { 189ede126feSBarry Smith n = range[i+1] - range[i]; 190ede126feSBarry Smith ierr = PetscBinaryRead(fd,idxwork,n,PETSC_INT);CHKERRQ(ierr); 191ede126feSBarry Smith ierr = MPI_Isend(idxwork,n,MPIU_INT,i,tag,comm,&request);CHKERRQ(ierr); 192ede126feSBarry Smith ierr = MPI_Wait(&request,&status);CHKERRQ(ierr); 193ede126feSBarry Smith } 194ede126feSBarry Smith ierr = PetscFree(idxwork);CHKERRQ(ierr); 195ede126feSBarry Smith } 196ede126feSBarry Smith } else { 197ede126feSBarry Smith ierr = MPI_Recv(idx,ln,MPIU_INT,0,tag,comm,&status);CHKERRQ(ierr); 198ede126feSBarry Smith } 199ede126feSBarry Smith ierr = ISGeneralSetIndices(is,ln,idx,PETSC_OWN_POINTER);CHKERRQ(ierr); 200ede126feSBarry Smith PetscFunctionReturn(0); 201ede126feSBarry Smith } 202ede126feSBarry Smith 203235f7792SMatthew G. Knepley PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer) 204235f7792SMatthew G. Knepley { 205235f7792SMatthew G. Knepley PetscBool isbinary; 206235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 207235f7792SMatthew G. Knepley PetscBool ishdf5; 208235f7792SMatthew G. Knepley #endif 209235f7792SMatthew G. Knepley PetscErrorCode ierr; 210235f7792SMatthew G. Knepley 211235f7792SMatthew G. Knepley PetscFunctionBegin; 212235f7792SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 21382be971eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 214235f7792SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr); 21582be971eSMatthew G. Knepley #endif 216235f7792SMatthew G. Knepley if (isbinary) { 217ede126feSBarry Smith ierr = ISLoad_Binary(is, viewer);CHKERRQ(ierr); 218235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 219235f7792SMatthew G. Knepley } else if (ishdf5) { 220235f7792SMatthew G. Knepley ierr = ISLoad_HDF5(is, viewer);CHKERRQ(ierr); 221235f7792SMatthew G. Knepley #endif 222235f7792SMatthew G. Knepley } 223235f7792SMatthew G. Knepley PetscFunctionReturn(0); 224235f7792SMatthew G. Knepley } 225