Just like the familiar FILE*
type for C stdio operations, all
H5Part file operations require a file handle. The type of this handle is
(H5PartFile*)
.
H5PartOpenFile()
is
used to open a serial file and
HDFPartOpenFileParallel()
is used to open a file for
Parallel I/O (in an MPI program).
After you open the file handle you can use the same set of
subroutines for operations on the file regardless of whether the
file is a parallel or serial I/O file.
The libraries manage all of this internally.
C Prototypes
Serial File
H5PartFile *H5PartOpenFile(const char *filename, unsigned
accessmode);
Parallel File
H5PartFile *H5PartOpenFileParallel(char *filename,int
accessmode,MPI_Comm communicator);
H5PART_READ
: Opens a file in read-only mode.H5PART_WRITE
: Opens a file in write-only mode.
If the
file does not exist, it will be created. If it does
exist, it will be
truncated.
PARALLEL_IO
C-preprocessor flag
defined. It is used to pass in the communicator that will be
used for all collective I/O operations that target the same
file on disk.#include < H5Part.h > . . . code . . . /* Open an HDF5 file for writing */ H5PartFile *writer = H5PartOpenFile("datafileout.h5",H5PART_WRITE); /* Open an HDF5 file for Parallel I/O */ H5PartFile *writer = H5PartOpenFileParallel("datafileout.h5",H5PART_WRITE,MPI_COMM_WORLD); /* open HDF5 file for reading */ H5PartFile *reader = H5PartOpenFile("datafilein.h5",H5PART_READ); /* open HDF5 file for parallel reads */ H5PartFile *reader = H5PartOpenFileParallel("datafilein.h5",H5PART_READ,MPI_COMM_WORLD); . . . more code . . .
To close the file, you simply use H5PartCloseFile() for both parallel and serial files. You must call H5PartCloseFile() on any file descriptor created by H5PartFileOpen() regardless of whether the file turns out to be valid or not.
C Prototypes
void H5PartCloseFile(H5PartFile *fileID);
#include < H5Part.h > H5PartFile *file; ... code ... file=H5PartOpenFileParallel("parttest.h5",H5PART_WRITE,comm); ... more code ... H5PartCloseFile(file);
You can test if the file was opened successfully using the H5PartFileIsValid() function. It returns 1 if valid, 0 if invalid.
C Prototype
int H5PartFileIsValid(H5PartFile *fileID);
Here is an example of validating a newly opened file. Even if the file is invalid, you must use H5PartCloseFile() to reclaim the file handle.
#include < H5Part.h > . . . code . . . H5PartFile *fileID = H5PartOpenFile("datafileout.h5",H5PART_WRITE); if(!H5PartFileIsValid(fileID)){ puts("The file you specified does not exist or is not in a readable format"); H5PartClose(fileID); /* must reclaim fileID even if file is invalid */ . . . do other cleanup . . . } . . . more code . . .
When writing data to a file the current time step must be set (even if there is only one). In a file with N time steps, the steps are numbered from 0 to N-1.
C Prototype
void H5PartSetStep((H5PartFile *fileID,int step);
#include < H5Part.h > H5PartFile *fileID; int timeStep; .... H5PartSetStep(fileID,timeStep); ....
H5PartSetNumParticles: This function's sole purpose is to prevent needless creation of new HDF5 DataSpace handles if the number of particles is invariant throughout the sim. That's its only reason for existence. After you call this subroutine, all subsequent operations will assume this number of particles will be written.
C Prototype
void H5PartSetNumParticles(H5PartFile *fileID,long long nparticles);
#include < H5Part.h > H5PartFile *fileID; long long nparticles; .... H5PartSetStep(fileID,nparticles); ....
After setting the number of particles with H5PartSetNumParticles() and the current timestep using H5PartSetStep(), you can start writing datasets into the file. Each dataset has a name associated with it (chosen by the user) in order to facilitate later retrieval. The writing routines also implicitly store the datatype of the array so that the array can be reconstructed properly on other systems with incompatible type representations. The data is committed to disk before the routine returns. All data that is written after setting the timestep is associated with that timestep. While the number of particles can change for each timestep, you cannot change the number of particles in the middle of a given timestep.
C Prototypes
int H5PartWriteDataFloat64(H5PartFile *fileID,char
*name,double *array);
int H5PartWriteDataInt64(H5PartFile *fileID,char
*name,double *array);
#include < H5Part.h > H5PartFile *fileID; double *x,*y,*z; int timeStep; long long nparticles; ... H5PartSetStep(fileID,timeStep); /* must set the current timestep in file */ H5PartSetNumParticles(fileID,nparticles); /* then set number of particles to store */ /* now write different tuples of data into this timestep of the file */ H5PartWriteDataFloat64(fileID,"x",x); H5PartWriteDataFloat64(fileID,"y",y); H5PartWriteDataFloat64(file,"z",z); ..
This reads the number of datasteps that are currently stored in the datafile. It works for both reading and writing of files, but is probably only typically used when you are reading.
C Prototype
int H5PartGetNumSteps (H5PartFile *fileID);
This reads the number of particles that are currently stored in the current time step. It will arbitrarily select a timestep if you haven't already set the timestep with H5PartSetStep().
C Prototype
long long H5PartGetNumParticles (H5PartFile *fileID);
#include < H5Part.h > H5PartFile *fileID; int timeStep; long long nparticles; H5PartSetStep(fileID,0); nparticles=H5PartGetNumParticles(fileID); ...
After setting the time step and getting the number of particles to allocate the data arrays, you can start to read the data.
C Prototypes
int H5PartReadDataFloat64(H5PartFile *fileID,char *name,double *array);
int H5PartReadDataInt64(H5PartFile *fileID,char *name,long long *array);
#include < H5Part.h > H5PartFile *fileID; double *x,*y,*z; int timeStep; long long nparticles; H5PartSetStep(fileID,0); nparticles=H5PartGetNumParticles(fileID); ... H5PartReadDataFloat64(file,"x",x); H5PartReadDataFloat64(file,"y",y); H5PartReadDataFloat64(file,"z",z); ...
H5Part provides funtions to find out how many datasets are stored at a particular timestep and what their names are if you don't know what they are a-priori.
C Prototypes
int H5PartGetNumDatasets(H5PartFile *fileID);
int H5PartGetDatasetName(H5PartFile *fileID,int index,char *name,int maxlen);
#include < H5Part.h > H5PartFile *fileID; char name[64]; int index, nds; ... nds=H5PartGetNumDatasets(fileID); for(index=0;index< nds;index++){ H5PartGetDatasetName(fileID,index,name,64); printf("\tDataset[%u] name=[%s]\n", index,name); } ...
In the current H5Part implemtation there are two types of attributes: file attributes which are bound to the file and step attributes which are bound to the current timestep. You must set the timestep explicitly before writing the attributes (just as you must do when you write a new dataset. Currently there are no attributes that are bound to a particular data array, but this could easily be done if required.
H5PartGetNumStepAttribs and H5PartGetNumFileAttribs return the number of attributes bound to a step and to a file respectively. H5PartGetStepAttribInfo and H5PartGetFileAttribInfo return the name, type and number of elements of type "type" bound to a step and a file respectively.
C Prototypes:int H5PartGetNumStepAttribs(H5PartFile *fileID);
int H5PartGetNumFileAttribs(H5PartFile *fileID);
void H5PartGetStepAttribInfo(H5PartFile *fileID,int idx, char *name,size_t maxnamelen,hid_t *type,int *nelem);
void H5PartGetFileAttribInfo(H5PartFile *fileID,int idx, char *name,size_t maxnamelen, hid_t *type,int *nelem);
An attribute can be bound to the file or after setting the time step to this time step.
C Prototypes: Generic Attributes
int H5PartWriteFileAttrib(H5PartFile *fileID,char *name, hid_t type,void *value,int nelem);
int H5PartWriteStepAttrib(H5PartFile *fileID,char *name, hid_t type,void *value,int nelem);
#include < H5Part.h > H5PartFile *fileID; double actPos; ... H5PartWriteStepAttrib(file_m,"Spos",H5T_NATIVE_DOUBLE,&actPos,1); ...C Prototypes: String Attributes
int H5PartWriteStepAttribString(H5PartFile *fileID,char *name, char *attrib);
int H5PartWriteFileAttribString(H5PartFile *fileID,char *name, char *attrib);
#include < H5Part.h > H5PartFile *fileID; char *newattrib; char *newname; ... H5PartWriteFileAttribString(fileID, newname,newattrib); ...
As with the writing of attributes, there are two basic reading interfaces one that reads file bound attributes and one that reads step bound attributes. If the step is not set the current one will be used.
C Prototypes
void H5PartReadStepAttrib(H5PartFile *fileID,char *name,void *value);
void H5PartReadAttrib(H5PartFile *fileID,char *name,void *value);
int H5PartReadFileAttrib(H5PartFile *fileID,char *name,void *value);
#include < H5Part.h > H5PartFile *fileID; int step; char name[MAXNAME]; ... H5PartSetStep(fileID, step); if (H5PartReadStepAttrib(file, "filename", &name[0]) == 1){ printf("Read step from file: %s\n", name); } ...