00001 #ifndef _H5Part_H_ 00002 #define _H5Part_H_ 00003 00004 #include <hdf5.h> 00005 #ifdef PARALLEL_IO 00006 #include <mpi.h> 00007 #endif 00008 00009 /* 00010 H5PartFile: This is an essentially opaque datastructure that 00011 acts as the filehandle for all practical purposes. 00012 It is created by H5PartOpenFile<xx>() and destroyed by 00013 H5PartCloseFile(). 00014 */ 00015 typedef struct H5PartFile { 00016 hid_t file; 00017 int timestep; 00018 00019 hid_t timegroup; 00020 hid_t properties; 00021 hsize_t nparticles; 00022 hid_t shape; 00023 unsigned mode; 00024 int maxstep; 00025 hid_t xfer_prop,create_prop,access_prop; 00026 hid_t diskshape,memshape; /* for parallel I/O (this is on-disk) H5S_ALL 00027 if serial I/O */ 00028 long long viewstart,viewend; /* -1 if no view is available: A "view" looks at a subset of the data. */ 00029 00030 #ifdef PARALLEL_IO 00031 long long *pnparticles; /* the number of particles in each processor. 00032 With respect to the "VIEW", these numbers 00033 can be regarded as non-overlapping subsections 00034 of the particle array stored in the file. 00035 So they can be used to compute the offset of 00036 the view for each processor */ 00037 MPI_Comm comm; 00038 int nprocs,myproc; 00039 #endif 00040 }H5PartFile; 00041 00042 #define H5PART_READ 0x01 00043 #define H5PART_WRITE 0x02 00044 00045 /*========== File Opening/Closing ===============*/ 00046 /* 00047 H5PartOpenFile: Opens file with specified filename. 00048 If you open with flag H5PART_WRITE, it will truncate any 00049 file with the specified filename and start writing to it. 00050 If you open with H5PART_READ, then it will open the file 00051 readonly. I could probably do an APPEND mode as well, but 00052 just haven't done so yet. APPEND would need to check the 00053 file to determine its current state and modify the 00054 H5PartFile datastructure accordingly. 00055 00056 H5PartFile should be treated as an essentially opaque 00057 datastructure. It acts as the file handle, but internally 00058 it maintains several key state variables associated with 00059 the file. 00060 00061 returns: A new filehandle with an open file or NULL if error. 00062 */ 00063 #ifdef PARALLEL_IO 00064 #include <mpi.h> 00065 H5PartFile *H5PartOpenFileParallel(const char *filename, 00066 unsigned flags, 00067 MPI_Comm communicator); 00068 #endif 00069 /* the pure serial version */ 00070 #define H5PartOpenFileSerial(x,y) H5PartOpenFile(x,y) 00071 H5PartFile *H5PartOpenFile(const char *filename, /* name of datafile */ 00072 unsigned flags); /* H5PART_READ | H5PART_WRITE */ 00073 00074 int H5PartFileIsValid(H5PartFile *f); 00075 00076 /* 00077 H5PartCloseFile: Does what it says it does. 00078 */ 00079 void H5PartCloseFile(H5PartFile *f); 00080 00081 00082 /*============== File Writing Functions ==================== */ 00083 /* 00084 H5PartSetNumParticles: This function's sole purpose is to 00085 prevent needless creation of new HDF5 DataSpace handles if 00086 the number of particles is invariant throughout the sim. 00087 That's its only reason for existence. After you call this 00088 subroutine, all subsequent operations will assume this 00089 number of particles will be written. 00090 */ 00091 void H5PartSetNumParticles(H5PartFile *f,long long nparticles); 00092 /* 00093 H5PartWriteData: This writes a dataset with the indicated 00094 name to the currently selected Timestep in the datafile. 00095 It will be an error if you don't call 00096 H5PartSetStep() 00097 before you use this function (but once those things are set, they 00098 are persistent values... no need to call them before *every* write.) 00099 Also, you need to have set the 00100 number of particles that you are storing in this timestep using 00101 H5PartSetNumParticles() 00102 It returns a negative value if the write fails. This either 00103 indicates that the Timestep or number of particles were not 00104 set, *or* you are storing two datasets in the same timestep 00105 that have the same name (not allowed). 00106 */ 00107 int H5PartWriteDataFloat64(H5PartFile *f,char *name,double *array); 00108 /* same deal as above, but for 64bit integers */ 00109 int H5PartWriteDataInt64(H5PartFile *f,char *name,long long *array); 00110 00111 /*================== File Reading Routines =================*/ 00112 /* 00113 H5PartSetStep: This routine is *only* useful when you are reading 00114 data. Using it while you are writing will generate nonsense results! 00115 (This file format is only half-baked... robustness is not std equipment!) 00116 So you use this to random-access the file for a particular timestep. 00117 Failure to explicitly set the timestep on each read will leave you 00118 stuck on the same timestep for *all* of your reads. That is to say 00119 the writes auto-advance the file pointer, but the reads do not 00120 (they require explicit advancing by selecting a particular timestep). 00121 */ 00122 void H5PartSetStep(H5PartFile *f, /* file handle */ 00123 int step); /* current timestep to select (0 to n-1) */ 00124 00125 00126 /* 00127 H5PartGetNumSteps: This reads the number of datasteps that are 00128 currently stored in the datafile. (simple return of an int). 00129 It works for both reading and writing of files, but is probably 00130 only typically used when you are reading. 00131 00132 returns: number of timesteps currently stored in the file. 00133 */ 00134 int H5PartGetNumSteps(H5PartFile *f); 00135 00136 /* 00137 H5PartGetNumDatasets/H5PartGetDatasetName() are both used together 00138 to find out how many datasets are stored at a particular timestep 00139 and what their names are if you don't know what they are a-priori. 00140 */ 00141 int H5PartGetNumDatasets(H5PartFile *f); 00142 int H5PartGetDatasetName(H5PartFile *f,int index,char *name,int maxlen); 00143 /* 00144 H5PartGetNumParticles: This gets the number of particles 00145 that are stored in the current timestep. It will arbitrarily 00146 select a timestep if you haven't already set the timestep 00147 with H5PartSetStep(). 00148 00149 returns: number of particles in current timestep 00150 */ 00151 long long H5PartGetNumParticles(H5PartFile *f); 00152 00153 /* 00154 H5SetView: For parallel I/O or for subsetting operations on 00155 the datafile, the H5SetView subroutine allows you to define 00156 a subset of the total particle dataset to read. The concept 00157 of "view" works for both serial and for parallel I/O. The 00158 "view" will remain in effect until a new view is set, or the 00159 number of particles in a dataset changes, or the view is 00160 "unset" by calling H5SetView(file,-1,-1); 00161 00162 Before you set a view, the H5PartGetNumParticles will 00163 return the total number of particles in a file (even for 00164 the parallel reads). However, after you set a view, it 00165 will return the number of particles contained in the view. 00166 00167 The range is inclusive (the start and the end index). 00168 */ 00169 void H5PartSetView(H5PartFile *f,long long start,long long end); 00170 #define H5PartResetView(f) H5PartSetView(f,-1,-1) 00171 #define H5PartHasView(f) ((f->viewstart<0||f->viewend<0)?0:1) 00172 /* 00173 H5PartGetView: Allows you to query the current view. 00174 it will return 0 and np if there is no view established. 00175 Use H5PartHasView to see if the view is smaller than the 00176 total dataset. 00177 */ 00178 int H5PartGetView(H5PartFile *f,long long *start,long long *end); 00179 00180 /* 00181 H5SetCanonicalView: If it is too tedious to manually set the 00182 start and end coordinates for a view, the H5SetCanonicalView() 00183 will automatically select an appropriate domain decomposition of 00184 the data arrays for the degree of parallelism and set the "view" 00185 accordingly. 00186 */ 00187 void H5PartSetCanonicalView(H5PartFile *f); 00188 00189 /* 00190 H5PartReadArray: This reads in an individual array from a 00191 particlar timestep. Unlike its "Write" mode sibling, this routine 00192 is completely public and will not have any wacky state dependencies. 00193 If you haven't selected a particular timestep, it will pick 00194 the current one. Also, it assumes you allocated enough space to 00195 read in all of the particles in this timestep. 00196 00197 returns: ignore returnval for now (should be used for error handling) 00198 */ 00199 int H5PartReadDataFloat64(H5PartFile *f, 00200 char *name, /* name of the array to read 00201 "x"=position in x direction (y,z) 00202 "vx"=velocity in x directio (y,z) 00203 "px"=position in x dir (y,z) */ 00204 double *array); /* array to read data into */ 00205 int H5PartReadDataInt64(H5PartFile *f, 00206 char *name, /* name of the array to read 00207 "x"=position in x direction (y,z) 00208 "vx"=velocity in x directio (y,z) 00209 "px"=position in x dir (y,z) */ 00210 long long *array); /* array to read data into */ 00211 00212 /* the following is a back-door for extensions to the data writing */ 00213 #if 0 00214 int H5PartReadData(H5PartFile *f,char *name,void *array,hid_t type); 00215 int H5PartWriteData(H5PartFile *f,char *name,void *array,hid_t type); 00216 #endif 00217 /* 00218 H5PartReadParticleStep: This is the mongo read function that 00219 pulls in all of the data for a given timestep in one shot. 00220 It also takes the timestep as an argument and will call 00221 H5PartSetStep() internally so that you don't have to 00222 make that call separately. 00223 See also: H5PartReadArray() if you want to just 00224 read in one of the many arrays. 00225 00226 At this point, I don't think it will be used (too rigid), 00227 but it is for example purposes. 00228 */ 00229 int H5PartReadParticleStep(H5PartFile *f, /* filehandle */ 00230 int step, /* selects timestep to read from*/ 00231 double *x,double *y,double *z, /* particle positions */ 00232 double *px,double *py,double *pz, /* particle momenta */ 00233 long long *id); /* and phase */ 00234 /**********==============Attributes Interface============***************/ 00235 /* currently there is file attributes: Attributes bound to the file 00236 and step attributes which are bound to the current timestep. You 00237 must set the timestep explicitly before writing the attributes (just 00238 as you must do when you write a new dataset. Currently there are no 00239 attributes that are bound to a particular data array, but this could 00240 easily be done if requred. 00241 */ 00242 int H5PartWriteStepAttrib(H5PartFile *f,char *name, 00243 hid_t type,void *attrib,int nelem); 00244 int H5PartWriteFileAttrib(H5PartFile *f,char *name, 00245 hid_t type,void *attrib,int nelem); 00246 int H5PartWriteAttrib(H5PartFile *f,char *name, 00247 hid_t type,void *attrib,int nelem); /* this should be deprecated */ 00248 int H5PartWriteFileAttribString(H5PartFile *f,char *name, 00249 char *attrib); 00250 int H5PartWriteStepAttribString(H5PartFile *f,char *name, 00251 char *attrib); 00252 int H5PartGetNumStepAttribs(H5PartFile *f); /* for current filestep */ 00253 int H5PartGetNumFileAttribs(H5PartFile *f); 00254 void H5PartGetStepAttribInfo(H5PartFile *f,int idx, 00255 char *name,size_t maxnamelen, 00256 hid_t *type,int *nelem); 00257 void H5PartGetFileAttribInfo(H5PartFile *f,int idx, 00258 char *name,size_t maxnamelen, 00259 hid_t *type,int *nelem); 00260 int H5PartReadStepAttrib(H5PartFile *f,char *name,void *data); 00261 void H5PartReadAttrib(H5PartFile *f,char *name,void *data); 00262 int H5PartReadFileAttrib(H5PartFile *f,char *name,void *data); 00263 00264 00265 /**************** File Stashing Interfaces *************************/ 00266 int H5PartStashFile(H5PartFile *f,char *filename); 00267 int H5PartUnstashFile(H5PartFile *f, char *filename, char *outputpath); /* outputpath can be null for cwd */ 00268 int H5PartGetNumStashFiles(H5PartFile *f); 00269 int H5PartFileGetStashFileName(H5PartFile *f,int nameindex,char *filename,int maxnamelen); 00270 00271 #endif