xref: /petsc/src/vec/is/utils/isio.c (revision 20e823e8f171d6e0d2c046e5f5908358eb84e2db)
1235f7792SMatthew G. Knepley #include <petscis.h>         /*I  "petscis.h"  I*/
2af0996ceSBarry Smith #include <petsc/private/isimpl.h>
390e28553SVaclav Hapla #include <petsc/private/viewerimpl.h>
4*20e823e8SBarry Smith #include <petsclayouthdf5.h>
5235f7792SMatthew G. Knepley 
6235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
7235f7792SMatthew G. Knepley /*
8235f7792SMatthew 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
9235f7792SMatthew G. Knepley    checks back and forth between the two types of variables.
10235f7792SMatthew G. Knepley */
11235f7792SMatthew G. Knepley PetscErrorCode ISLoad_HDF5(IS is, PetscViewer viewer)
12235f7792SMatthew G. Knepley {
13235f7792SMatthew G. Knepley   hid_t           inttype;    /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */
1490e28553SVaclav Hapla   PetscInt       *ind;
15235f7792SMatthew G. Knepley   const char     *isname;
16235f7792SMatthew G. Knepley   PetscErrorCode  ierr;
17235f7792SMatthew G. Knepley 
18235f7792SMatthew G. Knepley   PetscFunctionBegin;
19ede126feSBarry 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()");
20235f7792SMatthew G. Knepley #if defined(PETSC_USE_64BIT_INDICES)
21235f7792SMatthew G. Knepley   inttype = H5T_NATIVE_LLONG;
22235f7792SMatthew G. Knepley #else
23235f7792SMatthew G. Knepley   inttype = H5T_NATIVE_INT;
24235f7792SMatthew G. Knepley #endif
2590e28553SVaclav Hapla   ierr = PetscObjectGetName((PetscObject)is, &isname);CHKERRQ(ierr);
261c92607dSVaclav Hapla   ierr = PetscViewerHDF5Load(viewer, isname, is->map, inttype, (void**)&ind);CHKERRQ(ierr);
2790e28553SVaclav Hapla   ierr = ISGeneralSetIndices(is, is->map->n, ind, PETSC_OWN_POINTER);CHKERRQ(ierr);
28235f7792SMatthew G. Knepley   PetscFunctionReturn(0);
29235f7792SMatthew G. Knepley }
30235f7792SMatthew G. Knepley #endif
31235f7792SMatthew G. Knepley 
32ede126feSBarry Smith PetscErrorCode ISLoad_Binary(IS is, PetscViewer viewer)
33ede126feSBarry Smith {
34ede126feSBarry Smith   PetscErrorCode ierr;
35de8a3bf8SLisandro Dalcin   PetscBool      isgeneral,skipHeader,useMPIIO;
36ede126feSBarry Smith   int            fd;
37ede126feSBarry Smith   PetscInt       tr[2],N,ln,*idx;
38ede126feSBarry Smith   MPI_Request    request;
39ede126feSBarry Smith   MPI_Status     status;
40ede126feSBarry Smith   MPI_Comm       comm;
41ede126feSBarry Smith   PetscMPIInt    rank,size,tag;
42ede126feSBarry Smith 
43ede126feSBarry Smith   PetscFunctionBegin;
44ede126feSBarry Smith   ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr);
45ede126feSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)is,ISGENERAL,&isgeneral);CHKERRQ(ierr);
46ede126feSBarry Smith   if (!isgeneral) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"IS must be of type ISGENERAL to load into it");
47de8a3bf8SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
48de8a3bf8SLisandro Dalcin   if (skipHeader) SETERRQ(comm,PETSC_ERR_USER, "Currently no support for binary files without headers");
49de8a3bf8SLisandro Dalcin   /* force binary viewer to load .info file if it has not yet done so */
50de8a3bf8SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
51ede126feSBarry Smith 
52ede126feSBarry Smith   ierr = PetscViewerBinaryRead(viewer,tr,2,NULL,PETSC_INT);CHKERRQ(ierr);
53ede126feSBarry Smith   if (tr[0] != IS_FILE_CLASSID) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Not an IS next in file");
54ede126feSBarry Smith 
55ede126feSBarry Smith   /* Has IS already had its layout defined */
56de8a3bf8SLisandro Dalcin   /* ierr = ISGetLayout(is,&map);CHKERRQ(ierr); */
57ede126feSBarry Smith   ierr = PetscLayoutGetSize(is->map,&N);CHKERRQ(ierr);
58ede126feSBarry 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);
59ede126feSBarry Smith   if (N == -1) {
60ede126feSBarry Smith     N = tr[1];
61ede126feSBarry Smith     ierr = PetscLayoutSetSize(is->map,N);CHKERRQ(ierr);
62ede126feSBarry Smith     ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr);
63ede126feSBarry Smith   }
64ede126feSBarry Smith   ierr = PetscLayoutGetLocalSize(is->map,&ln);CHKERRQ(ierr);
65ede126feSBarry Smith   ierr = PetscMalloc1(ln,&idx);CHKERRQ(ierr);
66de8a3bf8SLisandro Dalcin 
67de8a3bf8SLisandro Dalcin   ierr = PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);CHKERRQ(ierr);
68de8a3bf8SLisandro Dalcin #if defined(PETSC_HAVE_MPIIO)
69de8a3bf8SLisandro Dalcin   if (useMPIIO) {
70de8a3bf8SLisandro Dalcin     MPI_File    mfdes;
71de8a3bf8SLisandro Dalcin     MPI_Offset  off;
72de8a3bf8SLisandro Dalcin     PetscMPIInt lsize;
73de8a3bf8SLisandro Dalcin     PetscInt    rstart;
74de8a3bf8SLisandro Dalcin 
75de8a3bf8SLisandro Dalcin     ierr = PetscMPIIntCast(ln,&lsize);CHKERRQ(ierr);
76de8a3bf8SLisandro Dalcin     ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr);
77de8a3bf8SLisandro Dalcin     ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr);
78de8a3bf8SLisandro Dalcin     ierr = PetscLayoutGetRange(is->map,&rstart,NULL);CHKERRQ(ierr);
79de8a3bf8SLisandro Dalcin     off += rstart*(MPI_Offset)sizeof(PetscInt);
80de8a3bf8SLisandro Dalcin     ierr = MPI_File_set_view(mfdes,off,MPIU_INT,MPIU_INT,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr);
81de8a3bf8SLisandro Dalcin     ierr = MPIU_File_read_all(mfdes,idx,lsize,MPIU_INT,MPI_STATUS_IGNORE);CHKERRQ(ierr);
82de8a3bf8SLisandro Dalcin     ierr = PetscViewerBinaryAddMPIIOOffset(viewer,N*(MPI_Offset)sizeof(PetscInt));CHKERRQ(ierr);
83de8a3bf8SLisandro Dalcin     ierr = ISGeneralSetIndices(is,ln,idx,PETSC_OWN_POINTER);CHKERRQ(ierr);
84de8a3bf8SLisandro Dalcin     PetscFunctionReturn(0);
85de8a3bf8SLisandro Dalcin   }
86de8a3bf8SLisandro Dalcin #endif
87de8a3bf8SLisandro Dalcin 
88de8a3bf8SLisandro Dalcin   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
89de8a3bf8SLisandro Dalcin   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
90de8a3bf8SLisandro Dalcin   ierr = PetscObjectGetNewTag((PetscObject)viewer,&tag);CHKERRQ(ierr);
91de8a3bf8SLisandro Dalcin   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
92de8a3bf8SLisandro Dalcin 
93ede126feSBarry Smith   if (!rank) {
949860990eSLisandro Dalcin     ierr = PetscBinaryRead(fd,idx,ln,NULL,PETSC_INT);CHKERRQ(ierr);
95ede126feSBarry Smith 
96ede126feSBarry Smith     if (size > 1) {
97ede126feSBarry Smith       PetscInt *range,n,i,*idxwork;
98ede126feSBarry Smith 
99ede126feSBarry Smith       /* read in other chuncks and send to other processors */
100ede126feSBarry Smith       /* determine maximum chunck owned by other */
101ede126feSBarry Smith       range = is->map->range;
102ede126feSBarry Smith       n = 1;
103ede126feSBarry Smith       for (i=1; i<size; i++) n = PetscMax(n,range[i+1] - range[i]);
104ede126feSBarry Smith 
105ede126feSBarry Smith       ierr = PetscMalloc1(n,&idxwork);CHKERRQ(ierr);
106ede126feSBarry Smith       for (i=1; i<size; i++) {
107ede126feSBarry Smith         n    = range[i+1] - range[i];
1089860990eSLisandro Dalcin         ierr = PetscBinaryRead(fd,idxwork,n,NULL,PETSC_INT);CHKERRQ(ierr);
109ede126feSBarry Smith         ierr = MPI_Isend(idxwork,n,MPIU_INT,i,tag,comm,&request);CHKERRQ(ierr);
110ede126feSBarry Smith         ierr = MPI_Wait(&request,&status);CHKERRQ(ierr);
111ede126feSBarry Smith       }
112ede126feSBarry Smith       ierr = PetscFree(idxwork);CHKERRQ(ierr);
113ede126feSBarry Smith     }
114ede126feSBarry Smith   } else {
115ede126feSBarry Smith     ierr = MPI_Recv(idx,ln,MPIU_INT,0,tag,comm,&status);CHKERRQ(ierr);
116ede126feSBarry Smith   }
117ede126feSBarry Smith   ierr = ISGeneralSetIndices(is,ln,idx,PETSC_OWN_POINTER);CHKERRQ(ierr);
118ede126feSBarry Smith   PetscFunctionReturn(0);
119ede126feSBarry Smith }
120ede126feSBarry Smith 
121235f7792SMatthew G. Knepley PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer)
122235f7792SMatthew G. Knepley {
123235f7792SMatthew G. Knepley   PetscBool      isbinary;
124235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
125235f7792SMatthew G. Knepley   PetscBool      ishdf5;
126235f7792SMatthew G. Knepley #endif
127235f7792SMatthew G. Knepley   PetscErrorCode ierr;
128235f7792SMatthew G. Knepley 
129235f7792SMatthew G. Knepley   PetscFunctionBegin;
130235f7792SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
13182be971eSMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
132235f7792SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr);
13382be971eSMatthew G. Knepley #endif
134235f7792SMatthew G. Knepley   if (isbinary) {
135ede126feSBarry Smith     ierr = ISLoad_Binary(is, viewer);CHKERRQ(ierr);
136235f7792SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5)
137235f7792SMatthew G. Knepley   } else if (ishdf5) {
138235f7792SMatthew G. Knepley     ierr = ISLoad_HDF5(is, viewer);CHKERRQ(ierr);
139235f7792SMatthew G. Knepley #endif
140235f7792SMatthew G. Knepley   }
141235f7792SMatthew G. Knepley   PetscFunctionReturn(0);
142235f7792SMatthew G. Knepley }
143