IOR
aiori-HDF5.c
Go to the documentation of this file.
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  */
4 /******************************************************************************\
5 * *
6 * Copyright (c) 2003, The Regents of the University of California *
7 * See the file COPYRIGHT for a complete copyright notice and license. *
8 * *
9 ********************************************************************************
10 *
11 * Implement abstract I/O interface for HDF5.
12 *
13 \******************************************************************************/
14 
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18 
19 #include <stdio.h> /* only for fprintf() */
20 #include <stdlib.h>
21 #include <sys/stat.h>
22 /* HDF5 routines here still use the old 1.6 style. Nothing wrong with that but
23  * save users the trouble of passing this flag through configure */
24 #define H5_USE_16_API
25 #include <hdf5.h>
26 #include <mpi.h>
27 
28 #include "aiori.h" /* abstract IOR interface */
29 #include "utilities.h"
30 #include "iordef.h"
31 
32 #define NUM_DIMS 1 /* number of dimensions to data set */
33 
34 /******************************************************************************/
35 /*
36  * HDF5_CHECK will display a custom error message and then exit the program
37  */
38 
39 /*
40  * should use MPI_Abort(), not exit(), in this macro; some versions of
41  * MPI, however, hang with HDF5 property lists et al. left unclosed
42  */
43 
44 /*
45  * for versions later than hdf5-1.6, the H5Eget_[major|minor]() functions
46  * have been deprecated and replaced with H5Eget_msg()
47  */
48 #if H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6
49 #define HDF5_CHECK(HDF5_RETURN, MSG) do { \
50  char resultString[1024]; \
51  \
52  if (HDF5_RETURN < 0) { \
53  fprintf(stdout, "** error **\n"); \
54  fprintf(stdout, "ERROR in %s (line %d): %s.\n", \
55  __FILE__, __LINE__, MSG); \
56  strcpy(resultString, H5Eget_major((H5E_major_t)HDF5_RETURN)); \
57  if (strcmp(resultString, "Invalid major error number") != 0) \
58  fprintf(stdout, "HDF5 %s\n", resultString); \
59  strcpy(resultString, H5Eget_minor((H5E_minor_t)HDF5_RETURN)); \
60  if (strcmp(resultString, "Invalid minor error number") != 0) \
61  fprintf(stdout, "%s\n", resultString); \
62  fprintf(stdout, "** exiting **\n"); \
63  exit(-1); \
64  } \
65 } while(0)
66 #else /* ! (H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6) */
67 #define HDF5_CHECK(HDF5_RETURN, MSG) do { \
68  \
69  if (HDF5_RETURN < 0) { \
70  fprintf(stdout, "** error **\n"); \
71  fprintf(stdout, "ERROR in %s (line %d): %s.\n", \
72  __FILE__, __LINE__, MSG); \
73  /* \
74  * H5Eget_msg(hid_t mesg_id, H5E_type_t* mesg_type, \
75  * char* mesg, size_t size) \
76  */ \
77  fprintf(stdout, "** exiting **\n"); \
78  exit(-1); \
79  } \
80 } while(0)
81 #endif /* H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6 */
82 /**************************** P R O T O T Y P E S *****************************/
83 
85 static void SetupDataSet(void *, int flags, aiori_mod_opt_t *);
86 static aiori_fd_t *HDF5_Create(char *, int flags, aiori_mod_opt_t *);
87 static aiori_fd_t *HDF5_Open(char *, int flags, aiori_mod_opt_t *);
90 static void HDF5_Close(aiori_fd_t *, aiori_mod_opt_t *);
91 static void HDF5_Delete(char *, aiori_mod_opt_t *);
92 static char* HDF5_GetVersion();
93 static void HDF5_Fsync(aiori_fd_t *, aiori_mod_opt_t *);
95 static int HDF5_Access(const char *, int, aiori_mod_opt_t *);
96 static void HDF5_init_xfer_options(aiori_xfer_hint_t * params);
98 
99 /************************** O P T I O N S *****************************/
100 typedef struct{
102  char * hintsFileName; /* full name for hints file */
103  int showHints; /* show hints */
104  int individualDataSets; /* datasets not shared by all procs */
105  int noFill; /* no fill in file creation */
106  IOR_offset_t setAlignment; /* alignment in bytes */
108 /***************************** F U N C T I O N S ******************************/
109 
110 static option_help * HDF5_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values){
111  HDF5_options_t * o = malloc(sizeof(HDF5_options_t));
112 
113  if (init_values != NULL){
114  memcpy(o, init_values, sizeof(HDF5_options_t));
115  }else{
116  memset(o, 0, sizeof(HDF5_options_t));
117  /* initialize the options properly */
118  o->collective_md = 0;
119  o->setAlignment = 1;
120  }
121 
122  *init_backend_options = (aiori_mod_opt_t*) o;
123 
124  option_help h [] = {
125  {0, "hdf5.collectiveMetadata", "Use collectiveMetadata (available since HDF5-1.10.0)", OPTION_FLAG, 'd', & o->collective_md},
126  {0, "hdf5.hintsFileName","Full name for hints file", OPTION_OPTIONAL_ARGUMENT, 's', & o->hintsFileName},
127  {0, "hdf5.showHints", "Show MPI hints", OPTION_FLAG, 'd', & o->showHints},
128  {0, "hdf5.individualDataSets", "Datasets not shared by all procs [not working]", OPTION_FLAG, 'd', & o->individualDataSets},
129  {0, "hdf5.setAlignment", "HDF5 alignment in bytes (e.g.: 8, 4k, 2m, 1g)", OPTION_OPTIONAL_ARGUMENT, 'd', & o->setAlignment},
130  {0, "hdf5.noFill", "No fill in HDF5 file creation", OPTION_FLAG, 'd', & o->noFill},
132  };
133  option_help * help = malloc(sizeof(h));
134  memcpy(help, h, sizeof(h));
135  return help;
136 }
137 
138 
139 /************************** D E C L A R A T I O N S ***************************/
140 
142  .name = "HDF5",
143  .name_legacy = NULL,
144  .create = HDF5_Create,
145  .open = HDF5_Open,
146  .xfer = HDF5_Xfer,
147  .close = HDF5_Close,
148  .delete = HDF5_Delete,
149  .get_version = HDF5_GetVersion,
150  .xfer_hints = HDF5_init_xfer_options,
151  .fsync = HDF5_Fsync,
152  .get_file_size = HDF5_GetFileSize,
153  .statfs = aiori_posix_statfs,
154  .mkdir = aiori_posix_mkdir,
155  .rmdir = aiori_posix_rmdir,
156  .access = HDF5_Access,
157  .stat = aiori_posix_stat,
158  .get_options = HDF5_options,
159  .check_params = HDF5_check_params
160 };
161 
162 static hid_t xferPropList; /* xfer property list */
163 hid_t dataSet; /* data set id */
164 hid_t dataSpace; /* data space id */
165 hid_t fileDataSpace; /* file data space id */
166 hid_t memDataSpace; /* memory data space id */
167 int newlyOpenedFile; /* newly opened file */
168 
169 /***************************** F U N C T I O N S ******************************/
171 
173  hints = params;
175  MPIIO_xfer_hints(params);
176 }
177 
179  HDF5_options_t *o = (HDF5_options_t*) options;
180  if (o->setAlignment < 0)
181  ERR("alignment must be non-negative integer");
182  if (o->individualDataSets)
183  ERR("individual data sets not implemented");
184  if (o->noFill) {
185  /* check if hdf5 available */
186 #if defined (H5_VERS_MAJOR) && defined (H5_VERS_MINOR)
187  /* no-fill option not available until hdf5-1.6.x */
188 #if (H5_VERS_MAJOR > 0 && H5_VERS_MINOR > 5)
189 #else
190  ERRF("'no fill' option not available in HDF5");
191 #endif
192 #else
193  WARN("unable to determine HDF5 version for 'no fill' usage");
194 #endif
195  }
196  return 0;
197 }
198 
199 /*
200  * Create and open a file through the HDF5 interface.
201  */
202 static aiori_fd_t *HDF5_Create(char *testFileName, int flags, aiori_mod_opt_t * param)
203 {
204  return HDF5_Open(testFileName, flags, param);
205 }
206 
207 /*
208  * Open a file through the HDF5 interface.
209  */
210 static aiori_fd_t *HDF5_Open(char *testFileName, int flags, aiori_mod_opt_t * param)
211 {
212  HDF5_options_t *o = (HDF5_options_t*) param;
213  hid_t accessPropList, createPropList;
214  hsize_t memStart[NUM_DIMS],
215  dataSetDims[NUM_DIMS],
216  memStride[NUM_DIMS],
217  memCount[NUM_DIMS], memBlock[NUM_DIMS], memDataSpaceDims[NUM_DIMS];
218  int tasksPerDataSet;
219  unsigned fd_mode = (unsigned)0;
220  hid_t *fd;
221  MPI_Comm comm;
222  MPI_Info mpiHints = MPI_INFO_NULL;
223 
224  fd = (hid_t *) malloc(sizeof(hid_t));
225  if (fd == NULL)
226  ERR("malloc() failed");
227  /*
228  * HDF5 uses different flags than those for POSIX/MPIIO
229  */
230  /* set IOR file flags to HDF5 flags */
231  /* -- file open flags -- */
232  if (flags & IOR_RDONLY) {
233  fd_mode |= H5F_ACC_RDONLY;
234  }
235  if (flags & IOR_WRONLY || flags & IOR_RDWR) {
236  fd_mode |= H5F_ACC_RDWR;
237  }
238  if (flags & IOR_APPEND) {
239  fprintf(stdout, "File append not implemented in HDF5\n");
240  }
241  if (flags & IOR_CREAT) {
242  fd_mode |= H5F_ACC_CREAT;
243  }
244  if (flags & IOR_EXCL) {
245  fd_mode |= H5F_ACC_EXCL;
246  }
247  if (flags & IOR_TRUNC) {
248  fd_mode |= H5F_ACC_TRUNC;
249  }
250  if (flags & IOR_DIRECT) {
251  fprintf(stdout, "O_DIRECT not implemented in HDF5\n");
252  }
253 
254  /* set up file creation property list */
255  createPropList = H5Pcreate(H5P_FILE_CREATE);
256  HDF5_CHECK(createPropList, "cannot create file creation property list");
257  /* set size of offset and length used to address HDF5 objects */
258  HDF5_CHECK(H5Pset_sizes
259  (createPropList, sizeof(hsize_t), sizeof(hsize_t)),
260  "cannot set property list properly");
261 
262  /* set up file access property list */
263  accessPropList = H5Pcreate(H5P_FILE_ACCESS);
264  HDF5_CHECK(accessPropList, "cannot create file access property list");
265 
266  /*
267  * someday HDF5 implementation will allow subsets of MPI_COMM_WORLD
268  */
269  /* store MPI communicator info for the file access property list */
270  if (hints->filePerProc) {
271  comm = MPI_COMM_SELF;
272  } else {
273  comm = testComm;
274  }
275 
276  SetHints(&mpiHints, o->hintsFileName);
277  /*
278  * note that with MP_HINTS_FILTERED=no, all key/value pairs will
279  * be in the info object. The info object that is attached to
280  * the file during MPI_File_open() will only contain those pairs
281  * deemed valid by the implementation.
282  */
283  /* show hints passed to file */
284  if (rank == 0 && o->showHints) {
285  fprintf(stdout, "\nhints passed to access property list {\n");
286  ShowHints(&mpiHints);
287  fprintf(stdout, "}\n");
288  }
289  HDF5_CHECK(H5Pset_fapl_mpio(accessPropList, comm, mpiHints),
290  "cannot set file access property list");
291 
292  /* set alignment */
293  HDF5_CHECK(H5Pset_alignment(accessPropList, o->setAlignment, o->setAlignment),
294  "cannot set alignment");
295 
296 #ifdef HAVE_H5PSET_ALL_COLL_METADATA_OPS
297 
298  if (o->collective_md) {
299  /* more scalable metadata */
300 
301  HDF5_CHECK(H5Pset_all_coll_metadata_ops(accessPropList, 1),
302  "cannot set collective md read");
303  HDF5_CHECK(H5Pset_coll_metadata_write(accessPropList, 1),
304  "cannot set collective md write");
305  }
306 #endif
307 
308  /* open file */
309  if(! hints->dryRun){
310  if (flags & IOR_CREAT) { /* WRITE */
311  *fd = H5Fcreate(testFileName, H5F_ACC_TRUNC, createPropList, accessPropList);
312  HDF5_CHECK(*fd, "cannot create file");
313  } else { /* READ or CHECK */
314  *fd = H5Fopen(testFileName, fd_mode, accessPropList);
315  HDF5_CHECK(*fd, "cannot open file");
316  }
317  }
318 
319  /* show hints actually attached to file handle */
320  if (o->showHints || (1) /* WEL - this needs fixing */ ) {
321  if (rank == 0 && (o->showHints) /* WEL - this needs fixing */ ) {
322  WARN("showHints not working for HDF5");
323  }
324  } else {
325  MPI_Info mpiHintsCheck = MPI_INFO_NULL;
326  hid_t apl;
327  apl = H5Fget_access_plist(*fd);
328  HDF5_CHECK(H5Pget_fapl_mpio(apl, &comm, &mpiHintsCheck),
329  "cannot get info object through HDF5");
330  if (rank == 0) {
331  fprintf(stdout,
332  "\nhints returned from opened file (HDF5) {\n");
333  ShowHints(&mpiHintsCheck);
334  fprintf(stdout, "}\n");
335  if (1 == 1) { /* request the MPIIO file handle and its hints */
336  MPI_File *fd_mpiio;
337  HDF5_CHECK(H5Fget_vfd_handle
338  (*fd, apl, (void **)&fd_mpiio),
339  "cannot get MPIIO file handle");
340  if (mpiHintsCheck != MPI_INFO_NULL)
341  MPI_Info_free(&mpiHintsCheck);
342  MPI_CHECK(MPI_File_get_info
343  (*fd_mpiio, &mpiHintsCheck),
344  "cannot get info object through MPIIO");
345  fprintf(stdout,
346  "\nhints returned from opened file (MPIIO) {\n");
347  ShowHints(&mpiHintsCheck);
348  fprintf(stdout, "}\n");
349  if (mpiHintsCheck != MPI_INFO_NULL)
350  MPI_Info_free(&mpiHintsCheck);
351  }
352  }
353  MPI_CHECK(MPI_Barrier(testComm), "barrier error");
354  }
355 
356  /* this is necessary for resetting various parameters
357  needed for reopening and checking the file */
359 
360  HDF5_CHECK(H5Pclose(createPropList),
361  "cannot close creation property list");
362  HDF5_CHECK(H5Pclose(accessPropList),
363  "cannot close access property list");
364 
365  /* create property list for serial/parallel access */
366  xferPropList = H5Pcreate(H5P_DATASET_XFER);
367  HDF5_CHECK(xferPropList, "cannot create transfer property list");
368 
369  /* set data transfer mode */
370  if (hints->collective) {
371  HDF5_CHECK(H5Pset_dxpl_mpio(xferPropList, H5FD_MPIO_COLLECTIVE),
372  "cannot set collective data transfer mode");
373  } else {
374  HDF5_CHECK(H5Pset_dxpl_mpio
375  (xferPropList, H5FD_MPIO_INDEPENDENT),
376  "cannot set independent data transfer mode");
377  }
378 
379  /* set up memory data space for transfer */
380  memStart[0] = (hsize_t) 0;
381  memCount[0] = (hsize_t) 1;
382  memStride[0] = (hsize_t) (hints->transferSize / sizeof(IOR_size_t));
383  memBlock[0] = (hsize_t) (hints->transferSize / sizeof(IOR_size_t));
384  memDataSpaceDims[0] = (hsize_t) hints->transferSize;
385  memDataSpace = H5Screate_simple(NUM_DIMS, memDataSpaceDims, NULL);
386  HDF5_CHECK(memDataSpace, "cannot create simple memory data space");
387 
388  /* define hyperslab for memory data space */
389  HDF5_CHECK(H5Sselect_hyperslab(memDataSpace, H5S_SELECT_SET,
390  memStart, memStride, memCount,
391  memBlock), "cannot create hyperslab");
392 
393  /* set up parameters for fpp or different dataset count */
394  if (hints->filePerProc) {
395  tasksPerDataSet = 1;
396  } else {
397  if (o->individualDataSets) {
398  /* each task in segment has single data set */
399  tasksPerDataSet = 1;
400  } else {
401  /* share single data set across all tasks in segment */
402  tasksPerDataSet = hints->numTasks;
403  }
404  }
405  dataSetDims[0] = (hsize_t) ((hints->blockSize / sizeof(IOR_size_t))
406  * tasksPerDataSet);
407 
408  /* create a simple data space containing information on size
409  and shape of data set, and open it for access */
410  dataSpace = H5Screate_simple(NUM_DIMS, dataSetDims, NULL);
411  HDF5_CHECK(dataSpace, "cannot create simple data space");
412  if (mpiHints != MPI_INFO_NULL)
413  MPI_Info_free(&mpiHints);
414 
415  return (aiori_fd_t*)(fd);
416 }
417 
418 /*
419  * Write or read access to file using the HDF5 interface.
420  */
421 static IOR_offset_t HDF5_Xfer(int access, aiori_fd_t *fd, IOR_size_t * buffer,
423 {
424  static int firstReadCheck = FALSE, startNewDataSet;
425  IOR_offset_t segmentPosition, segmentSize;
426 
427  /*
428  * this toggle is for the read check operation, which passes through
429  * this function twice; note that this function will open a data set
430  * only on the first read check and close only on the second
431  */
432  if (access == READCHECK) {
433  if (firstReadCheck == TRUE) {
434  firstReadCheck = FALSE;
435  } else {
436  firstReadCheck = TRUE;
437  }
438  }
439 
440  /* determine by offset if need to start new data set */
441  if (hints->filePerProc == TRUE) {
442  segmentPosition = (IOR_offset_t) 0;
443  segmentSize = hints->blockSize;
444  } else {
445  segmentPosition =
446  (IOR_offset_t) ((rank + rankOffset) % hints->numTasks)
447  * hints->blockSize;
448  segmentSize = (IOR_offset_t) (hints->numTasks) * hints->blockSize;
449  }
450  if ((IOR_offset_t) ((offset - segmentPosition) % segmentSize) ==
451  0) {
452  /*
453  * ordinarily start a new data set, unless this is the
454  * second pass through during a read check
455  */
456  startNewDataSet = TRUE;
457  if (access == READCHECK && firstReadCheck != TRUE) {
458  startNewDataSet = FALSE;
459  }
460  }
461 
462  if(hints->dryRun)
463  return length;
464 
465  /* create new data set */
466  if (startNewDataSet == TRUE) {
467  /* if just opened this file, no data set to close yet */
468  if (newlyOpenedFile != TRUE) {
469  HDF5_CHECK(H5Dclose(dataSet), "cannot close data set");
470  HDF5_CHECK(H5Sclose(fileDataSpace),
471  "cannot close file data space");
472  }
473  SetupDataSet(fd, access == WRITE ? IOR_CREAT : IOR_RDWR, param);
474  }
475 
476  SeekOffset(fd, offset, param);
477 
478  /* this is necessary to reset variables for reaccessing file */
479  startNewDataSet = FALSE;
481 
482  /* access the file */
483  if (access == WRITE) { /* WRITE */
484  HDF5_CHECK(H5Dwrite(dataSet, H5T_NATIVE_LLONG,
486  xferPropList, buffer),
487  "cannot write to data set");
488  } else { /* READ or CHECK */
489  HDF5_CHECK(H5Dread(dataSet, H5T_NATIVE_LLONG,
491  xferPropList, buffer),
492  "cannot read from data set");
493  }
494  return (length);
495 }
496 
497 /*
498  * Perform fsync().
499  */
500 static void HDF5_Fsync(aiori_fd_t *fd, aiori_mod_opt_t * param)
501 {
502 }
503 
504 /*
505  * Close a file through the HDF5 interface.
506  */
507 static void HDF5_Close(aiori_fd_t *fd, aiori_mod_opt_t * param)
508 {
509  if(hints->dryRun)
510  return;
511  //if (hints->fd_fppReadCheck == NULL) {
512  HDF5_CHECK(H5Dclose(dataSet), "cannot close data set");
513  HDF5_CHECK(H5Sclose(dataSpace), "cannot close data space");
514  HDF5_CHECK(H5Sclose(fileDataSpace),
515  "cannot close file data space");
516  HDF5_CHECK(H5Sclose(memDataSpace),
517  "cannot close memory data space");
518  HDF5_CHECK(H5Pclose(xferPropList),
519  " cannot close transfer property list");
520  //}
521  HDF5_CHECK(H5Fclose(*(hid_t *) fd), "cannot close file");
522  free(fd);
523 }
524 
525 /*
526  * Delete a file through the HDF5 interface.
527  */
528 static void HDF5_Delete(char *testFileName, aiori_mod_opt_t * param)
529 {
530  if(hints->dryRun)
531  return
532  MPIIO_Delete(testFileName, param);
533  return;
534 }
535 
536 /*
537  * Determine api version.
538  */
539 static char * HDF5_GetVersion()
540 {
541  static char version[1024] = {0};
542  if(version[0]) return version;
543 
544  unsigned major, minor, release;
545  if (H5get_libversion(&major, &minor, &release) < 0) {
546  WARN("cannot get HDF5 library version");
547  } else {
548  sprintf(version, "%u.%u.%u", major, minor, release);
549  }
550 #ifndef H5_HAVE_PARALLEL
551  strcat(version, " (Serial)");
552 #else /* H5_HAVE_PARALLEL */
553  strcat(version, " (Parallel)");
554 #endif /* not H5_HAVE_PARALLEL */
555  return version;
556 }
557 
558 /*
559  * Seek to offset in file using the HDF5 interface and set up hyperslab.
560  */
562  aiori_mod_opt_t * param)
563 {
564  HDF5_options_t *o = (HDF5_options_t*) param;
565  IOR_offset_t segmentSize;
566  hsize_t hsStride[NUM_DIMS], hsCount[NUM_DIMS], hsBlock[NUM_DIMS];
567  hsize_t hsStart[NUM_DIMS];
568 
569  if (hints->filePerProc == TRUE) {
570  segmentSize = (IOR_offset_t) hints->blockSize;
571  } else {
572  segmentSize =
573  (IOR_offset_t) (hints->numTasks) * hints->blockSize;
574  }
575 
576  /* create a hyperslab representing the file data space */
577  if (o->individualDataSets) {
578  /* start at zero offset if not */
579  hsStart[0] = (hsize_t) ((offset % hints->blockSize)
580  / sizeof(IOR_size_t));
581  } else {
582  /* start at a unique offset if shared */
583  hsStart[0] =
584  (hsize_t) ((offset % segmentSize) / sizeof(IOR_size_t));
585  }
586  hsCount[0] = (hsize_t) 1;
587  hsStride[0] = (hsize_t) (hints->transferSize / sizeof(IOR_size_t));
588  hsBlock[0] = (hsize_t) (hints->transferSize / sizeof(IOR_size_t));
589 
590  /* retrieve data space from data set for hyperslab */
591  fileDataSpace = H5Dget_space(dataSet);
592  HDF5_CHECK(fileDataSpace, "cannot get data space from data set");
593  HDF5_CHECK(H5Sselect_hyperslab(fileDataSpace, H5S_SELECT_SET,
594  hsStart, hsStride, hsCount, hsBlock),
595  "cannot select hyperslab");
596  return (offset);
597 }
598 
599 /*
600  * Create HDF5 data set.
601  */
602 static void SetupDataSet(void *fd, int flags, aiori_mod_opt_t * param)
603 {
604  HDF5_options_t *o = (HDF5_options_t*) param;
605  char dataSetName[MAX_STR];
606  hid_t dataSetPropList;
607  int dataSetID;
608  static int dataSetSuffix = 0;
609 
610  /* may want to use an extendable dataset (H5S_UNLIMITED) someday */
611  /* may want to use a chunked dataset (H5S_CHUNKED) someday */
612 
613  /* need to reset suffix counter if newly-opened file */
614  if (newlyOpenedFile)
615  dataSetSuffix = 0;
616 
617  /* may want to use individual access to each data set someday */
618  if (o->individualDataSets) {
619  dataSetID = (rank + rankOffset) % hints->numTasks;
620  } else {
621  dataSetID = 0;
622  }
623 
624  sprintf(dataSetName, "%s-%04d.%04d", "Dataset", dataSetID,
625  dataSetSuffix++);
626 
627  if (flags & IOR_CREAT) { /* WRITE */
628  /* create data set */
629  dataSetPropList = H5Pcreate(H5P_DATASET_CREATE);
630  /* check if hdf5 available */
631 #if defined (H5_VERS_MAJOR) && defined (H5_VERS_MINOR)
632  /* no-fill option not available until hdf5-1.6.x */
633 #if (H5_VERS_MAJOR > 0 && H5_VERS_MINOR > 5)
634  if (o->noFill == TRUE) {
635  if (rank == 0 && verbose >= VERBOSE_1) {
636  fprintf(stdout, "\nusing 'no fill' option\n");
637  }
638  HDF5_CHECK(H5Pset_fill_time(dataSetPropList,
639  H5D_FILL_TIME_NEVER),
640  "cannot set fill time for property list");
641  }
642 #else
643  char errorString[MAX_STR];
644  sprintf(errorString, "'no fill' option not available in %s",
645  test->apiVersion);
646  ERR(errorString);
647 #endif
648 #else
649  WARN("unable to determine HDF5 version for 'no fill' usage");
650 #endif
651  dataSet =
652  H5Dcreate(*(hid_t *) fd, dataSetName, H5T_NATIVE_LLONG,
653  dataSpace, dataSetPropList);
654  HDF5_CHECK(dataSet, "cannot create data set");
655  } else { /* READ or CHECK */
656  dataSet = H5Dopen(*(hid_t *) fd, dataSetName);
657  HDF5_CHECK(dataSet, "cannot create data set");
658  }
659 }
660 
661 /*
662  * Use MPIIO call to get file size.
663  */
664 static IOR_offset_t
665 HDF5_GetFileSize(aiori_mod_opt_t * test, char *testFileName)
666 {
667  if(hints->dryRun)
668  return 0;
669  return(MPIIO_GetFileSize(test, testFileName));
670 }
671 
672 /*
673  * Use MPIIO call to check for access.
674  */
675 static int HDF5_Access(const char *path, int mode, aiori_mod_opt_t *param)
676 {
677  if(hints->dryRun)
678  return 0;
679  return(MPIIO_Access(path, mode, param));
680 }
static void SetupDataSet(void *, int flags, aiori_mod_opt_t *)
Definition: aiori-HDF5.c:602
#define ERRF(FORMAT,...)
Definition: aiori-debug.h:77
static aiori_fd_t * HDF5_Create(char *, int flags, aiori_mod_opt_t *)
Definition: aiori-HDF5.c:202
static void HDF5_init_xfer_options(aiori_xfer_hint_t *params)
Definition: aiori-HDF5.c:172
void ShowHints(MPI_Info *mpiHints)
Definition: utilities.c:572
static void HDF5_Close(aiori_fd_t *, aiori_mod_opt_t *)
Definition: aiori-HDF5.c:507
#define LAST_OPTION
Definition: option.h:39
struct benchmark_options o
Definition: md-workbench.c:128
IOR_offset_t blockSize
Definition: aiori.h:72
char * hintsFileName
Definition: aiori-HDF5.c:102
ior_aiori_t hdf5_aiori
Definition: aiori-HDF5.c:141
#define READCHECK
Definition: iordef.h:89
#define HDF5_CHECK(HDF5_RETURN, MSG)
Definition: aiori-HDF5.c:67
#define IOR_APPEND
Definition: aiori.h:31
IOR_offset_t MPIIO_GetFileSize(aiori_mod_opt_t *module_options, char *testFileName)
Definition: aiori-MPIIO.c:588
#define IOR_RDONLY
Definition: aiori.h:28
IOR_offset_t setAlignment
Definition: aiori-HDF5.c:106
#define MPI_CHECK(MPI_STATUS, MSG)
Definition: aiori-debug.h:127
#define WRITE
Definition: iordef.h:86
#define NUM_DIMS
Definition: aiori-HDF5.c:32
int aiori_posix_stat(const char *path, struct stat *buf, aiori_mod_opt_t *module_options)
Definition: aiori.c:227
static aiori_xfer_hint_t * hints
Definition: aiori-HDF5.c:170
static option_help * HDF5_options(aiori_mod_opt_t **init_backend_options, aiori_mod_opt_t *init_values)
Definition: aiori-HDF5.c:110
#define IOR_CREAT
Definition: aiori.h:32
static int HDF5_Access(const char *, int, aiori_mod_opt_t *)
Definition: aiori-HDF5.c:675
#define IOR_EXCL
Definition: aiori.h:34
int MPIIO_Access(const char *path, int mode, aiori_mod_opt_t *module_options)
Definition: aiori-MPIIO.c:139
int individualDataSets
Definition: aiori-HDF5.c:104
MPI_Comm testComm
Definition: utilities.c:71
static option_help options[]
Definition: aiori-CEPHFS.c:54
#define IOR_TRUNC
Definition: aiori.h:33
#define WARN(MSG)
Definition: aiori-debug.h:32
int collective
Definition: aiori.h:66
static hid_t xferPropList
Definition: aiori-HDF5.c:162
static void HDF5_Fsync(aiori_fd_t *, aiori_mod_opt_t *)
Definition: aiori-HDF5.c:500
static int HDF5_check_params(aiori_mod_opt_t *options)
Definition: aiori-HDF5.c:178
hid_t dataSet
Definition: aiori-HDF5.c:163
void MPIIO_xfer_hints(aiori_xfer_hint_t *params)
Definition: aiori-MPIIO.c:111
Definition: ior.h:56
IOR_offset_t transferSize
Definition: aiori.h:73
static void HDF5_Delete(char *, aiori_mod_opt_t *)
Definition: aiori-HDF5.c:528
#define IOR_WRONLY
Definition: aiori.h:29
static char * HDF5_GetVersion()
Definition: aiori-HDF5.c:539
#define FALSE
Definition: iordef.h:62
int rankOffset
Definition: utilities.c:69
int newlyOpenedFile
Definition: aiori-HDF5.c:167
hid_t dataSpace
Definition: aiori-HDF5.c:164
long long int IOR_size_t
Definition: iordef.h:110
int aiori_posix_rmdir(const char *path, aiori_mod_opt_t *module_options)
Definition: aiori.c:217
hid_t memDataSpace
Definition: aiori-HDF5.c:166
static aiori_fd_t * HDF5_Open(char *, int flags, aiori_mod_opt_t *)
Definition: aiori-HDF5.c:210
int aiori_posix_mkdir(const char *path, mode_t mode, aiori_mod_opt_t *module_options)
Definition: aiori.c:212
static IOR_offset_t HDF5_Xfer(int, aiori_fd_t *, IOR_size_t *, IOR_offset_t, IOR_offset_t, aiori_mod_opt_t *)
Definition: aiori-HDF5.c:421
int verbose
Definition: utilities.c:70
#define MAX_STR
Definition: iordef.h:99
int aiori_posix_statfs(const char *path, ior_aiori_statfs_t *stat_buf, aiori_mod_opt_t *module_options)
Definition: aiori.c:166
void SetHints(MPI_Info *mpiHints, char *hintsFileName)
Definition: utilities.c:511
#define ERR(MSG)
Definition: aiori-debug.h:92
#define IOR_RDWR
Definition: aiori.h:30
void MPIIO_Delete(char *testFileName, aiori_mod_opt_t *module_options)
Definition: aiori-MPIIO.c:521
#define VERBOSE_1
Definition: iordef.h:93
char * name
Definition: aiori.h:88
static IOR_offset_t HDF5_GetFileSize(aiori_mod_opt_t *, char *)
Definition: aiori-HDF5.c:665
int filePerProc
Definition: aiori.h:65
long long int IOR_offset_t
Definition: iordef.h:109
hid_t fileDataSpace
Definition: aiori-HDF5.c:165
int rank
Definition: utilities.c:68
#define TRUE
Definition: iordef.h:66
#define IOR_DIRECT
Definition: aiori.h:35
#define NULL
Definition: iordef.h:70
static IOR_offset_t SeekOffset(void *, IOR_offset_t, aiori_mod_opt_t *)
Definition: aiori-HDF5.c:561