xref: /petsc/src/vec/is/utils/isio.c (revision de8a3bf87eaa666847d4d614ad9bc31a1e65bf10)
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, &timestep);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