xref: /petsc/src/vec/is/utils/isio.c (revision 7eda4a2b655d50ced66764fb8992052c2fd6e7d7)
1 #include <petscis.h>         /*I  "petscis.h"  I*/
2 #include <petsc/private/isimpl.h>
3 #include <petsc/private/viewerimpl.h>
4 #include <petscviewerhdf5.h>
5 
6 #if defined(PETSC_HAVE_HDF5)
7 /*
8      This should handle properly the cases where PetscInt is 32 or 64 and hsize_t is 32 or 64. These means properly casting with
9    checks back and forth between the two types of variables.
10 */
11 PetscErrorCode ISLoad_HDF5(IS is, PetscViewer viewer)
12 {
13   hid_t           inttype;    /* int type (H5T_NATIVE_INT or H5T_NATIVE_LLONG) */
14   PetscInt       *ind;
15   const char     *isname;
16   PetscErrorCode  ierr;
17 
18   PetscFunctionBegin;
19   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()");
20 #if defined(PETSC_USE_64BIT_INDICES)
21   inttype = H5T_NATIVE_LLONG;
22 #else
23   inttype = H5T_NATIVE_INT;
24 #endif
25   ierr = PetscObjectGetName((PetscObject)is, &isname);CHKERRQ(ierr);
26   ierr = PetscViewerHDF5Load(viewer, isname, is->map, inttype, (void**)&ind);CHKERRQ(ierr);
27   ierr = ISGeneralSetIndices(is, is->map->n, ind, PETSC_OWN_POINTER);CHKERRQ(ierr);
28   PetscFunctionReturn(0);
29 }
30 #endif
31 
32 PetscErrorCode ISLoad_Binary(IS is, PetscViewer viewer)
33 {
34   PetscErrorCode ierr;
35   PetscBool      isgeneral,skipHeader,useMPIIO;
36   int            fd;
37   PetscInt       tr[2],N,ln,*idx;
38   MPI_Request    request;
39   MPI_Status     status;
40   MPI_Comm       comm;
41   PetscMPIInt    rank,size,tag;
42 
43   PetscFunctionBegin;
44   ierr = PetscObjectGetComm((PetscObject)is,&comm);CHKERRQ(ierr);
45   ierr = PetscObjectTypeCompare((PetscObject)is,ISGENERAL,&isgeneral);CHKERRQ(ierr);
46   if (!isgeneral) SETERRQ(comm,PETSC_ERR_ARG_INCOMP,"IS must be of type ISGENERAL to load into it");
47   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
48   if (skipHeader) SETERRQ(comm,PETSC_ERR_USER, "Currently no support for binary files without headers");
49   /* force binary viewer to load .info file if it has not yet done so */
50   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
51 
52   ierr = PetscViewerBinaryRead(viewer,tr,2,NULL,PETSC_INT);CHKERRQ(ierr);
53   if (tr[0] != IS_FILE_CLASSID) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"Not an IS next in file");
54 
55   /* Has IS already had its layout defined */
56   /* ierr = ISGetLayout(is,&map);CHKERRQ(ierr); */
57   ierr = PetscLayoutGetSize(is->map,&N);CHKERRQ(ierr);
58   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);
59   if (N == -1) {
60     N = tr[1];
61     ierr = PetscLayoutSetSize(is->map,N);CHKERRQ(ierr);
62     ierr = PetscLayoutSetUp(is->map);CHKERRQ(ierr);
63   }
64   ierr = PetscLayoutGetLocalSize(is->map,&ln);CHKERRQ(ierr);
65   ierr = PetscMalloc1(ln,&idx);CHKERRQ(ierr);
66 
67   ierr = PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);CHKERRQ(ierr);
68 #if defined(PETSC_HAVE_MPIIO)
69   if (useMPIIO) {
70     MPI_File    mfdes;
71     MPI_Offset  off;
72     PetscMPIInt lsize;
73     PetscInt    rstart;
74 
75     ierr = PetscMPIIntCast(ln,&lsize);CHKERRQ(ierr);
76     ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr);
77     ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr);
78     ierr = PetscLayoutGetRange(is->map,&rstart,NULL);CHKERRQ(ierr);
79     off += rstart*(MPI_Offset)sizeof(PetscInt);
80     ierr = MPI_File_set_view(mfdes,off,MPIU_INT,MPIU_INT,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr);
81     ierr = MPIU_File_read_all(mfdes,idx,lsize,MPIU_INT,MPI_STATUS_IGNORE);CHKERRQ(ierr);
82     ierr = PetscViewerBinaryAddMPIIOOffset(viewer,N*(MPI_Offset)sizeof(PetscInt));CHKERRQ(ierr);
83     ierr = ISGeneralSetIndices(is,ln,idx,PETSC_OWN_POINTER);CHKERRQ(ierr);
84     PetscFunctionReturn(0);
85   }
86 #endif
87 
88   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
89   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
90   ierr = PetscObjectGetNewTag((PetscObject)viewer,&tag);CHKERRQ(ierr);
91   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
92 
93   if (!rank) {
94     ierr = PetscBinaryRead(fd,idx,ln,PETSC_INT);CHKERRQ(ierr);
95 
96     if (size > 1) {
97       PetscInt *range,n,i,*idxwork;
98 
99       /* read in other chuncks and send to other processors */
100       /* determine maximum chunck owned by other */
101       range = is->map->range;
102       n = 1;
103       for (i=1; i<size; i++) n = PetscMax(n,range[i+1] - range[i]);
104 
105       ierr = PetscMalloc1(n,&idxwork);CHKERRQ(ierr);
106       for (i=1; i<size; i++) {
107         n    = range[i+1] - range[i];
108         ierr = PetscBinaryRead(fd,idxwork,n,PETSC_INT);CHKERRQ(ierr);
109         ierr = MPI_Isend(idxwork,n,MPIU_INT,i,tag,comm,&request);CHKERRQ(ierr);
110         ierr = MPI_Wait(&request,&status);CHKERRQ(ierr);
111       }
112       ierr = PetscFree(idxwork);CHKERRQ(ierr);
113     }
114   } else {
115     ierr = MPI_Recv(idx,ln,MPIU_INT,0,tag,comm,&status);CHKERRQ(ierr);
116   }
117   ierr = ISGeneralSetIndices(is,ln,idx,PETSC_OWN_POINTER);CHKERRQ(ierr);
118   PetscFunctionReturn(0);
119 }
120 
121 PetscErrorCode ISLoad_Default(IS is, PetscViewer viewer)
122 {
123   PetscBool      isbinary;
124 #if defined(PETSC_HAVE_HDF5)
125   PetscBool      ishdf5;
126 #endif
127   PetscErrorCode ierr;
128 
129   PetscFunctionBegin;
130   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
131 #if defined(PETSC_HAVE_HDF5)
132   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,&ishdf5);CHKERRQ(ierr);
133 #endif
134   if (isbinary) {
135     ierr = ISLoad_Binary(is, viewer);CHKERRQ(ierr);
136 #if defined(PETSC_HAVE_HDF5)
137   } else if (ishdf5) {
138     ierr = ISLoad_HDF5(is, viewer);CHKERRQ(ierr);
139 #endif
140   }
141   PetscFunctionReturn(0);
142 }
143