1 #include <petsc-private/viewerimpl.h> /*I "petscsys.h" I*/ 2 #include <hdf5.h> 3 4 typedef struct GroupList { 5 const char *name; 6 struct GroupList *next; 7 } GroupList; 8 9 typedef struct { 10 char *filename; 11 PetscFileMode btype; 12 hid_t file_id; 13 PetscInt timestep; 14 GroupList *groups; 15 } PetscViewer_HDF5; 16 17 #undef __FUNCT__ 18 #define __FUNCT__ "PetscViewerFileClose_HDF5" 19 static PetscErrorCode PetscViewerFileClose_HDF5(PetscViewer viewer) 20 { 21 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5*)viewer->data; 22 PetscErrorCode ierr; 23 24 PetscFunctionBegin; 25 ierr = PetscFree(hdf5->filename);CHKERRQ(ierr); 26 if (hdf5->file_id) { 27 H5Fclose(hdf5->file_id); 28 } 29 PetscFunctionReturn(0); 30 } 31 32 #undef __FUNCT__ 33 #define __FUNCT__ "PetscViewerDestroy_HDF5" 34 PetscErrorCode PetscViewerDestroy_HDF5(PetscViewer viewer) 35 { 36 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 37 PetscErrorCode ierr; 38 39 PetscFunctionBegin; 40 ierr = PetscViewerFileClose_HDF5(viewer);CHKERRQ(ierr); 41 if (hdf5->groups) { 42 while (hdf5->groups) { 43 GroupList *tmp = hdf5->groups->next; 44 45 ierr = PetscFree(hdf5->groups->name);CHKERRQ(ierr); 46 ierr = PetscFree(hdf5->groups);CHKERRQ(ierr); 47 hdf5->groups = tmp; 48 } 49 } 50 ierr = PetscFree(hdf5);CHKERRQ(ierr); 51 PetscFunctionReturn(0); 52 } 53 54 EXTERN_C_BEGIN 55 #undef __FUNCT__ 56 #define __FUNCT__ "PetscViewerFileSetMode_HDF5" 57 PetscErrorCode PetscViewerFileSetMode_HDF5(PetscViewer viewer, PetscFileMode type) 58 { 59 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 60 61 PetscFunctionBegin; 62 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1); 63 hdf5->btype = type; 64 PetscFunctionReturn(0); 65 } 66 EXTERN_C_END 67 68 EXTERN_C_BEGIN 69 #undef __FUNCT__ 70 #define __FUNCT__ "PetscViewerFileSetName_HDF5" 71 PetscErrorCode PetscViewerFileSetName_HDF5(PetscViewer viewer, const char name[]) 72 { 73 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 74 #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO) 75 MPI_Info info = MPI_INFO_NULL; 76 #endif 77 hid_t plist_id; 78 herr_t herr; 79 PetscErrorCode ierr; 80 81 PetscFunctionBegin; 82 ierr = PetscStrallocpy(name, &hdf5->filename);CHKERRQ(ierr); 83 /* Set up file access property list with parallel I/O access */ 84 plist_id = H5Pcreate(H5P_FILE_ACCESS); 85 #if defined(PETSC_HAVE_H5PSET_FAPL_MPIO) 86 herr = H5Pset_fapl_mpio(plist_id, ((PetscObject)viewer)->comm, info);CHKERRQ(herr); 87 #endif 88 /* Create or open the file collectively */ 89 switch (hdf5->btype) { 90 case FILE_MODE_READ: 91 hdf5->file_id = H5Fopen(name, H5F_ACC_RDONLY, plist_id); 92 break; 93 case FILE_MODE_APPEND: 94 hdf5->file_id = H5Fopen(name, H5F_ACC_RDWR, plist_id); 95 break; 96 case FILE_MODE_WRITE: 97 hdf5->file_id = H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, plist_id); 98 break; 99 default: 100 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 101 } 102 if (hdf5->file_id < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB, "H5Fcreate failed for %s", name); 103 viewer->format = PETSC_VIEWER_NOFORMAT; 104 H5Pclose(plist_id); 105 PetscFunctionReturn(0); 106 } 107 EXTERN_C_END 108 109 EXTERN_C_BEGIN 110 #undef __FUNCT__ 111 #define __FUNCT__ "PetscViewerCreate_HDF5" 112 PetscErrorCode PetscViewerCreate_HDF5(PetscViewer v) 113 { 114 PetscViewer_HDF5 *hdf5; 115 PetscErrorCode ierr; 116 117 PetscFunctionBegin; 118 ierr = PetscNewLog(v, PetscViewer_HDF5, &hdf5);CHKERRQ(ierr); 119 120 v->data = (void *) hdf5; 121 v->ops->destroy = PetscViewerDestroy_HDF5; 122 v->ops->flush = 0; 123 v->iformat = 0; 124 hdf5->btype = (PetscFileMode) -1; 125 hdf5->filename = 0; 126 hdf5->timestep = -1; 127 hdf5->groups = PETSC_NULL; 128 129 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C","PetscViewerFileSetName_HDF5", 130 PetscViewerFileSetName_HDF5);CHKERRQ(ierr); 131 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_HDF5", 132 PetscViewerFileSetMode_HDF5);CHKERRQ(ierr); 133 PetscFunctionReturn(0); 134 } 135 EXTERN_C_END 136 137 #undef __FUNCT__ 138 #define __FUNCT__ "PetscViewerHDF5Open" 139 /*@C 140 PetscViewerHDF5Open - Opens a file for HDF5 input/output. 141 142 Collective on MPI_Comm 143 144 Input Parameters: 145 + comm - MPI communicator 146 . name - name of file 147 - type - type of file 148 $ FILE_MODE_WRITE - create new file for binary output 149 $ FILE_MODE_READ - open existing file for binary input 150 $ FILE_MODE_APPEND - open existing file for binary output 151 152 Output Parameter: 153 . hdf5v - PetscViewer for HDF5 input/output to use with the specified file 154 155 Level: beginner 156 157 Note: 158 This PetscViewer should be destroyed with PetscViewerDestroy(). 159 160 Concepts: HDF5 files 161 Concepts: PetscViewerHDF5^creating 162 163 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 164 VecView(), MatView(), VecLoad(), MatLoad(), 165 PetscFileMode, PetscViewer 166 @*/ 167 PetscErrorCode PetscViewerHDF5Open(MPI_Comm comm, const char name[], PetscFileMode type, PetscViewer *hdf5v) 168 { 169 PetscErrorCode ierr; 170 171 PetscFunctionBegin; 172 ierr = PetscViewerCreate(comm, hdf5v);CHKERRQ(ierr); 173 ierr = PetscViewerSetType(*hdf5v, PETSCVIEWERHDF5);CHKERRQ(ierr); 174 ierr = PetscViewerFileSetMode(*hdf5v, type);CHKERRQ(ierr); 175 ierr = PetscViewerFileSetName(*hdf5v, name);CHKERRQ(ierr); 176 PetscFunctionReturn(0); 177 } 178 179 #undef __FUNCT__ 180 #define __FUNCT__ "PetscViewerHDF5GetFileId" 181 /*@C 182 PetscViewerHDF5GetFileId - Retrieve the file id, this file ID then can be used in direct HDF5 calls 183 184 Not collective 185 186 Input Parameter: 187 . viewer - the PetscViewer 188 189 Output Parameter: 190 . file_id - The file id 191 192 Level: intermediate 193 194 .seealso: PetscViewerHDF5Open() 195 @*/ 196 PetscErrorCode PetscViewerHDF5GetFileId(PetscViewer viewer, hid_t *file_id) 197 { 198 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 199 200 PetscFunctionBegin; 201 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 202 if (file_id) *file_id = hdf5->file_id; 203 PetscFunctionReturn(0); 204 } 205 206 #undef __FUNCT__ 207 #define __FUNCT__ "PetscViewerHDF5PushGroup" 208 /*@C 209 PetscViewerHDF5PushGroup - Set the current HDF5 group for output 210 211 Not collective 212 213 Input Parameters: 214 + viewer - the PetscViewer 215 - name - The group name 216 217 Level: intermediate 218 219 .seealso: PetscViewerHDF5Open(),PetscViewerHDF5PopGroup(),PetscViewerHDF5GetGroup() 220 @*/ 221 PetscErrorCode PetscViewerHDF5PushGroup(PetscViewer viewer, const char *name) 222 { 223 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 224 GroupList *groupNode; 225 PetscErrorCode ierr; 226 227 PetscFunctionBegin; 228 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 229 PetscValidCharPointer(name,2); 230 ierr = PetscMalloc(sizeof(GroupList), &groupNode);CHKERRQ(ierr); 231 ierr = PetscStrallocpy(name, (char **) &groupNode->name);CHKERRQ(ierr); 232 groupNode->next = hdf5->groups; 233 hdf5->groups = groupNode; 234 PetscFunctionReturn(0); 235 } 236 237 #undef __FUNCT__ 238 #define __FUNCT__ "PetscViewerHDF5PopGroup" 239 /*@C 240 PetscViewerHDF5PopGroup - Return the current HDF5 group for output to the previous value 241 242 Not collective 243 244 Input Parameter: 245 . viewer - the PetscViewer 246 247 Level: intermediate 248 249 .seealso: PetscViewerHDF5Open(),PetscViewerHDF5PushGroup(),PetscViewerHDF5GetGroup() 250 @*/ 251 PetscErrorCode PetscViewerHDF5PopGroup(PetscViewer viewer) 252 { 253 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 254 GroupList *groupNode; 255 PetscErrorCode ierr; 256 257 PetscFunctionBegin; 258 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 259 if (!hdf5->groups) SETERRQ(((PetscObject) viewer)->comm, PETSC_ERR_ARG_WRONGSTATE, "HDF5 group stack is empty, cannot pop"); 260 groupNode = hdf5->groups; 261 hdf5->groups = hdf5->groups->next; 262 ierr = PetscFree(groupNode->name);CHKERRQ(ierr); 263 ierr = PetscFree(groupNode);CHKERRQ(ierr); 264 PetscFunctionReturn(0); 265 } 266 267 #undef __FUNCT__ 268 #define __FUNCT__ "PetscViewerHDF5GetGroup" 269 /*@C 270 PetscViewerHDF5GetGroup - Get the current HDF5 group for output. If none has been assigned, returns PETSC_NULL. 271 272 Not collective 273 274 Input Parameter: 275 . viewer - the PetscViewer 276 277 Output Parameter: 278 . name - The group name 279 280 Level: intermediate 281 282 .seealso: PetscViewerHDF5Open(),PetscViewerHDF5PushGroup(),PetscViewerHDF5PopGroup() 283 @*/ 284 PetscErrorCode PetscViewerHDF5GetGroup(PetscViewer viewer, const char **name) 285 { 286 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 287 288 PetscFunctionBegin; 289 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 290 PetscValidCharPointer(name,2); 291 if (hdf5->groups) { 292 *name = hdf5->groups->name; 293 } else { 294 *name = PETSC_NULL; 295 } 296 PetscFunctionReturn(0); 297 } 298 299 #undef __FUNCT__ 300 #define __FUNCT__ "PetscViewerHDF5IncrementTimestep" 301 /*@C 302 PetscViewerHDF5IncrementTimestep - Increments the current timestep for the HDF5 output. Fields are stacked in time. 303 304 Not collective 305 306 Input Parameter: 307 . viewer - the PetscViewer 308 309 Level: intermediate 310 311 .seealso: PetscViewerHDF5Open(), PetscViewerHDF5SetTimestep(), PetscViewerHDF5GetTimestep() 312 @*/ 313 PetscErrorCode PetscViewerHDF5IncrementTimestep(PetscViewer viewer) 314 { 315 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 316 317 PetscFunctionBegin; 318 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 319 ++hdf5->timestep; 320 PetscFunctionReturn(0); 321 } 322 323 #undef __FUNCT__ 324 #define __FUNCT__ "PetscViewerHDF5SetTimestep" 325 /*@C 326 PetscViewerHDF5SetTimestep - Set the current timestep for the HDF5 output. Fields are stacked in time. A timestep 327 of -1 disables blocking with timesteps. 328 329 Not collective 330 331 Input Parameters: 332 + viewer - the PetscViewer 333 - timestep - The timestep number 334 335 Level: intermediate 336 337 .seealso: PetscViewerHDF5Open(), PetscViewerHDF5IncrementTimestep(), PetscViewerHDF5GetTimestep() 338 @*/ 339 PetscErrorCode PetscViewerHDF5SetTimestep(PetscViewer viewer, PetscInt timestep) 340 { 341 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 342 343 PetscFunctionBegin; 344 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 345 hdf5->timestep = timestep; 346 PetscFunctionReturn(0); 347 } 348 349 #undef __FUNCT__ 350 #define __FUNCT__ "PetscViewerHDF5GetTimestep" 351 /*@C 352 PetscViewerHDF5GetTimestep - Get the current timestep for the HDF5 output. Fields are stacked in time. 353 354 Not collective 355 356 Input Parameter: 357 . viewer - the PetscViewer 358 359 Output Parameter: 360 . timestep - The timestep number 361 362 Level: intermediate 363 364 .seealso: PetscViewerHDF5Open(), PetscViewerHDF5IncrementTimestep(), PetscViewerHDF5SetTimestep() 365 @*/ 366 PetscErrorCode PetscViewerHDF5GetTimestep(PetscViewer viewer, PetscInt *timestep) 367 { 368 PetscViewer_HDF5 *hdf5 = (PetscViewer_HDF5 *) viewer->data; 369 370 PetscFunctionBegin; 371 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 372 PetscValidPointer(timestep,2); 373 *timestep = hdf5->timestep; 374 PetscFunctionReturn(0); 375 } 376 377 #if defined(oldhdf4stuff) 378 #undef __FUNCT__ 379 #define __FUNCT__ "PetscViewerHDF5WriteSDS" 380 PetscErrorCode PetscViewerHDF5WriteSDS(PetscViewer viewer, float *xf, int d, int *dims,int bs) 381 { 382 int i; 383 PetscViewer_HDF5 *vhdf5 = (PetscViewer_HDF5*)viewer->data; 384 int32 sds_id,zero32[3],dims32[3]; 385 386 PetscFunctionBegin; 387 for (i = 0; i < d; i++) { 388 zero32[i] = 0; 389 dims32[i] = dims[i]; 390 } 391 sds_id = SDcreate(vhdf5->sd_id, "Vec", DFNT_FLOAT32, d, dims32); 392 if (sds_id < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SDcreate failed"); 393 SDwritedata(sds_id, zero32, 0, dims32, xf); 394 SDendaccess(sds_id); 395 PetscFunctionReturn(0); 396 } 397 398 #endif 399