Skip to Content.
Sympa Menu

h5part - Re: [H5part] Patch#2 : bux fix plus couple of additionsr

h5part AT lists.psi.ch

Subject: H5Part development and discussion

List archive

Re: [H5part] Patch#2 : bux fix plus couple of additionsr


Chronological Thread 
  • From: John Biddiscombe <biddisco AT cscs.ch>
  • To: Achim Gsell <achim.gsell AT psi.ch>, h5part AT lists.psi.ch
  • Subject: Re: [H5part] Patch#2 : bux fix plus couple of additionsr
  • Date: Fri, 11 May 2007 10:44:04 +0200
  • List-archive: <https://lists.web.psi.ch/pipermail/h5part/>
  • List-id: H5Part development and discussion <h5part.lists.psi.ch>

Fix 1 : If you run using MPI and Parallel IO, (mpirun -np 1 ...) but only have one processor there is a small bug which causes a crash, the f->pnparticles array is set to null (because 1 proc), but MPI_AllGather is still called. This patch fixes it by skipping the MPI_AllGather and setting the total to N prior to setting mem/dataspaces etc. (can we just use H5_ALL instead of creating a simple dataspace in this case).

Addition 1 : H5PartGetNativeDatasetType
I've added a function which returns a type, I need this because I'm storing int/float/double/byte/char/long/long long/ etc all possible types signed/unsigned into H5Part files and querying types when reading the data back. I have not yet integrated my 'all types' support into H5Part itself, but I would like to eventually, In the meantime this functions is useful, small and does no harm, so it'd be nice to add it it.

Additon 2: H5PartHasStep
I use H5Part files to cache results when loadiing from other file formats as well as storing from simulation, To check if a step exists this function is convenient (I am aware that I could use SetStep which fails if the step exists, but from a puerist's viewpoint having a specific H5HasStep is more appealing).

Thanks in anticipation

JB
Index: src/H5Part.c
===================================================================
--- src/H5Part.c (revision 2908)
+++ src/H5Part.c (working copy)
@@ -535,36 +535,42 @@
/*
acquire the number of particles to be written from each MPI process
*/
- r = MPI_Allgather (
- &nparticles, 1, MPI_LONG_LONG,
- f->pnparticles, 1, MPI_LONG_LONG,
- f->comm);
- if ( r != MPI_SUCCESS) {
- return HANDLE_MPI_ALLGATHER_ERR;
- }
- if ( f->myproc == 0 ) {
- _H5Part_print_debug ( "Particle offsets:" );
- for(i=0;i<f->nprocs;i++)
- _H5Part_print_debug ( "\tnp=%lld",
- (long long) f->pnparticles[i] );
- }
- /* should I create a selection here? */
+ if (f->nprocs==1) {
+ /* serial mode f->pnparticles is NULL */
+ total = nparticles;
+ }
+ else {
+ r = MPI_Allgather (
+ &nparticles, 1, MPI_LONG_LONG,
+ f->pnparticles, 1, MPI_LONG_LONG,
+ f->comm);
+ if ( r != MPI_SUCCESS) {
+ return HANDLE_MPI_ALLGATHER_ERR;
+ }
+ if ( f->myproc == 0 ) {
+ _H5Part_print_debug ( "Particle offsets:" );
+ for(i=0;i<f->nprocs;i++)
+ _H5Part_print_debug ( "\tnp=%lld",
+ (long long) f->pnparticles[i]
);
+ }
+ /* should I create a selection here? */
+
+ /* compute start offsets */
+ stride[0] = 1;
+ start[0] = 0;
+ for (i=0; i<f->myproc; i++) {
+ start[0] += f->pnparticles[i];
+ }
+

- /* compute start offsets */
- stride[0] = 1;
- start[0] = 0;
- for (i=0; i<f->myproc; i++) {
- start[0] += f->pnparticles[i];
- }
-

+ /* compute total nparticles */
+ total = 0;
+ for (i=0; i < f->nprocs; i++) {
+ total += f->pnparticles[i];
+ }
+ }

- /* compute total nparticles */
- total = 0;
- for (i=0; i < f->nprocs; i++) {
- total += f->pnparticles[i];
- }
-
/* declare overall datasize */
f->shape = H5Screate_simple (1, &total, &total);
if (f->shape < 0) return HANDLE_H5S_CREATE_SIMPLE_ERR ( total );
@@ -579,14 +585,16 @@
if (f->memshape < 0)
return HANDLE_H5S_CREATE_SIMPLE_ERR ( f->nparticles );

- count[0] = nparticles;
- r = H5Sselect_hyperslab (
- f->diskshape,
- H5S_SELECT_SET,
- start,
- stride,
- count, NULL );
- if ( r < 0 ) return HANDLE_H5S_SELECT_HYPERSLAB_ERR;
+ if (f->nprocs>1) {
+ count[0] = nparticles;
+ r = H5Sselect_hyperslab (
+ f->diskshape,
+ H5S_SELECT_SET,
+ start,
+ stride,
+ count, NULL );
+ if ( r < 0 ) return HANDLE_H5S_SELECT_HYPERSLAB_ERR;
+ }

if ( f->timegroup < 0 ) {
r = _H5Part_set_step ( f, 0 );
@@ -1506,6 +1514,35 @@
/*!
\ingroup h5part_read

+ Query whether a particular step already exists in the file
+ \c f.
+
+ It works for both reading and writing of files
+
+ \return 1 or 0 for true or false
+*/
+h5part_int64_t
+H5PartHasStep (
+ H5PartFile *f, /*!< [in] Handle to open file */
+ h5part_int64_t step /*!< [in] Step number to query */
+ ) {
+
+ SET_FNAME ( "H5PartHasStep" );
+
+ CHECK_FILEHANDLE( f );
+
+ char name[128];
+ sprintf ( name, "%s#%0*lld", f->groupname_step, f->stepno_width,
(long long) step );
+ herr_t herr = H5Gget_objinfo( f->file, name, 1, NULL );
+ if ( herr >= 0 ) {
+ return 1;
+ }
+ return 0;
+}
+
+/*!
+ \ingroup h5part_read
+
Get the number of time-steps that are currently stored in the file
\c f.

@@ -2283,6 +2320,29 @@
return H5PART_SUCCESS;
}

+/*!
+ \ingroup h5part_utility
+
+ This function can be used to query the Type of a dataset
+ It is not used by the core H5Part library but is useful when
+ reading generic data from the file.
+ An example of usage would be (H5Tequal(datatype,H5T_NATIVE_FLOAT))
+ any NATIVE type can be used to test.
+
+ \return \c an hdf5 handle to the native type of the data
+*/
+hid_t H5PartGetNativeDatasetType(H5PartFile *f, const char *name)
+{
+ hid_t dataset, datatype, datatypen;
+ if(!f->timegroup) H5PartSetStep(f,f->timestep); /* choose current step */
+ dataset=H5Dopen(f->timegroup,name);
+ datatype = H5Dget_type(dataset);
+ datatypen = H5Tget_native_type(datatype, H5T_DIR_DEFAULT);
+ H5Tclose(datatype);
+ H5Dclose(dataset);
+ return datatypen;
+}
+
/****************** error handling ******************/

/*!
Index: src/H5Part.h
===================================================================
--- src/H5Part.h (revision 2908)
+++ src/H5Part.h (working copy)
@@ -97,6 +97,12 @@
);

h5part_int64_t
+H5PartHasStep (
+ H5PartFile *f,
+ h5part_int64_t step
+ );
+
+h5part_int64_t
H5PartGetNumSteps (
H5PartFile *f
);
@@ -306,6 +312,13 @@
...
);

+/*================== Utility Routines =================*/
+hid_t
+H5PartGetNativeDatasetType(
+ H5PartFile *f,
+ const char *name
+);
+
#ifdef __cplusplus
}
#endif
Index: src/H5PartTypes.h
===================================================================
--- src/H5PartTypes.h (revision 2908)
+++ src/H5PartTypes.h (working copy)
@@ -6,7 +6,7 @@
#define _H5PARTTYPES_H_

#ifdef WIN32
-typdef __int64 int64_t;
+typedef __int64 int64_t;
#endif /* WIN32 */

typedef int64_t h5part_int64_t;



Archive powered by MHonArc 2.6.19.

Top of Page