xref: /petsc/src/vec/is/utils/isio.c (revision 90e285536d6a076c95af1a2472cfcca9efe46dea)
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