diff options
author | tradke <tradke@7842ec3a-9562-4be5-9c5b-06ba18f2b668> | 2002-04-23 14:58:00 +0000 |
---|---|---|
committer | tradke <tradke@7842ec3a-9562-4be5-9c5b-06ba18f2b668> | 2002-04-23 14:58:00 +0000 |
commit | b31eef3fee54b3133265c466eec75714d34d4e99 (patch) | |
tree | b7ed2ac60935828bf93f92a829913e63d2352862 | |
parent | 1111ce1fb848e6490b311b1ec5ba4363765e0333 (diff) |
Code cleanup before moving into production mode.
git-svn-id: http://svn.cactuscode.org/arrangements/CactusPUGHIO/IOHDF5Util/trunk@58 7842ec3a-9562-4be5-9c5b-06ba18f2b668
-rw-r--r-- | src/DumpUtils.c | 306 | ||||
-rw-r--r-- | src/DumpVar.c | 926 | ||||
-rw-r--r-- | src/ParseVars.c | 269 | ||||
-rw-r--r-- | src/RecoverVar.c | 318 | ||||
-rw-r--r-- | src/Startup.c | 206 | ||||
-rw-r--r-- | src/ioHDF5UtilGH.h | 292 | ||||
-rw-r--r-- | src/make.configuration.defn | 20 |
7 files changed, 977 insertions, 1360 deletions
diff --git a/src/DumpUtils.c b/src/DumpUtils.c index 0234fea..4ab5688 100644 --- a/src/DumpUtils.c +++ b/src/DumpUtils.c @@ -28,12 +28,11 @@ CCTK_FILEVERSION(BetaThorns_IOHDF5Util_DumpUtils_c) @date Tue Oct 10 2000 @author Thomas Radke @desc - Dump all variables of the given GH along with - the global attributes and parameters - to the (already opened) HDF5 checkpoint file. + Dump all variables of the given GH along with the global + attributes and parameters to the given HDF5 checkpoint file. @enddesc @var GH - @vdesc Pointer to CCTK grid hierarchy + @vdesc pointer to CCTK grid hierarchy @vtype const cGH * @vio in @endvar @@ -54,50 +53,34 @@ CCTK_FILEVERSION(BetaThorns_IOHDF5Util_DumpUtils_c) (should be 0 for success, or negative if some error occured) @endreturndesc @@*/ -int IOHDF5Util_DumpGH (const cGH *GH, - const int *timers, - hid_t file) +int IOHDF5Util_DumpGH (const cGH *GH, const int *timers, hid_t file) { - int retval, maxdim; - int first_vindex, vindex, gindex; - int timelevel, last_timelevel; + int first_vindex, gindex, timelevels, retval; cGroup gdata; - int old_out_single; - ioGH *ioUtilGH; - ioHDF5Geo_t request; - /*** FIXME: can CCTK_SyncGroup() have a 'const cGH *' parameter ?? ***/ - union - { - const cGH *const_ptr; - cGH *non_const_ptr; - } GH_fake_const; + ioSlab slab; DECLARE_CCTK_PARAMETERS retval = 0; - GH_fake_const.const_ptr = GH; - - /* Get the GH extension for IOUtil */ - ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO"); - - maxdim = CCTK_MaxDim (); - request.origin = (int *) calloc (4 + maxdim, maxdim * sizeof (int)); - request.length = request.origin + 1 * maxdim; - request.downsample = request.origin + 2 * maxdim; - request.actlen = request.origin + 3 * maxdim; - request.direction = request.origin + 4 * maxdim; - - for (vindex = 0; vindex < maxdim; vindex++) + /* set up a hyperslab description for full hyperslabs */ + slab.vdim = CCTK_MaxDim (); + slab.vectors = (CCTK_INT *) calloc (slab.vdim + 6, + slab.vdim * sizeof(CCTK_INT)); + slab.hoffset = slab.vectors + 0*slab.vdim; + slab.hsize = slab.vectors + 1*slab.vdim; + slab.hsize_chunk = slab.vectors + 2*slab.vdim; + slab.origin = slab.vectors + 3*slab.vdim; + slab.extent = slab.vectors + 4*slab.vdim; + slab.downsample = slab.vectors + 5*slab.vdim; + slab.direction = slab.vectors + 6*slab.vdim; + + for (slab.hdim = 0; slab.hdim < slab.vdim; slab.hdim++) { - request.length[vindex] = -1; - request.downsample[vindex] = 1; + slab.extent[slab.hdim] = -1; + slab.downsample[slab.hdim] = 1; } - /* disable output in single precision */ - old_out_single = ioUtilGH->out_single; - ioUtilGH->out_single = 0; - /* start CP_PARAMETERS_TIMER timer */ if (timers) { @@ -105,7 +88,7 @@ int IOHDF5Util_DumpGH (const cGH *GH, CCTK_TimerStartI (timers[CP_PARAMETERS_TIMER]); } - /* Great; Now start dumping away! */ + /* now start dumping away */ if (file >= 0) { /* all GH extension variables and parameter stuff which is not @@ -130,47 +113,45 @@ int IOHDF5Util_DumpGH (const cGH *GH, /* ... now the variables, sorted by groups */ for (gindex = CCTK_NumGroups () - 1; gindex >= 0; gindex--) { - /* only dump groups which belong to an active implementation - and have storage assigned */ - if (! CCTK_IsImplementationActive (CCTK_ImpFromVarI (CCTK_FirstVarIndexI - (gindex))) || - CCTK_QueryGroupStorageI (GH, gindex) <= 0) + /* only dump groups which have storage assigned */ + if (CCTK_QueryGroupStorageI (GH, gindex) <= 0) { continue; } - /* sync the group */ - CCTK_SyncGroupI (GH_fake_const.non_const_ptr, gindex); - /* dump all timelevels except the oldest (for multi-level groups) */ CCTK_GroupData (gindex, &gdata); - last_timelevel = gdata.numtimelevels; - if (last_timelevel > 1) + timelevels = gdata.numtimelevels; + if (timelevels > 1) { - last_timelevel--; + timelevels--; } - request.sdim = request.vdim = gdata.dim; + slab.hdim = slab.vdim = gdata.dim; + slab.check_exist = 0; + slab.hdatatype = gdata.vartype; /* set the hyperslab directions (orthogonal to all axes) */ - memset (request.direction, 0, request.sdim * request.vdim * sizeof (int)); - for (vindex = 0; vindex < request.sdim; vindex++) + memset (slab.direction, 0, slab.hdim * slab.vdim * sizeof (int)); + for (slab.hdim = 0; slab.hdim < slab.vdim; slab.hdim++) { - request.direction[vindex * request.vdim + vindex] = 1; + slab.direction[slab.hdim * (slab.vdim + 1)] = 1; } /* loop over all variables in this group */ first_vindex = CCTK_FirstVarIndexI (gindex); - for (vindex = first_vindex; vindex < first_vindex + gdata.numvars; vindex++) + for (slab.vindex = first_vindex; + slab.vindex < first_vindex + gdata.numvars; + slab.vindex++) { if (verbose && file >= 0) { - CCTK_VInfo (CCTK_THORNSTRING, " %s", CCTK_VarName (vindex)); + CCTK_VInfo (CCTK_THORNSTRING, " %s", CCTK_VarName (slab.vindex)); } /* loop over all timelevels of this variable */ - for (timelevel = 0; timelevel < last_timelevel; timelevel++) + for (slab.timelevel = 0; slab.timelevel < timelevels; slab.timelevel++) { - retval += IOHDF5Util_DumpVar (GH, vindex, timelevel, &request, file, 0); + retval += IOHDF5Util_DumpVar (GH, &slab, file); } } /* end of loop over all variables */ @@ -182,11 +163,8 @@ int IOHDF5Util_DumpGH (const cGH *GH, CCTK_TimerStopI (timers[CP_VARIABLES_TIMER]); } - /* restore output precision flag */ - ioUtilGH->out_single = old_out_single; - /* free temporary resources */ - free (request.origin); + free (slab.vectors); return (retval); } @@ -210,45 +188,26 @@ int IOHDF5Util_DumpGH (const cGH *GH, </ul> @enddesc @var GH - @vdesc Pointer to CCTK grid hierarchy + @vdesc pointer to CCTK grid hierarchy @vtype const cGH * @vio in @endvar - @var vindex - @vdesc CCTK index of the variable to dump - @vtype int - @vio in - @endvar - @var timelevel - @vdesc timelevel of the variable to dump - @vtype int - @vio in - @endvar - @var global_shape - @vdesc global shape of the grid - @vtype CCTK_INT [] - @vio in - @endvar - @var request - @vdesc pointer to IO request structure describing the hyperslab - @vtype ioHDF5Geo_t * + @var slab + @vdesc reference to the I/O hyperslab description + @vtype const ioSlab * @vio in @endvar @var dataset - @vdesc the dataset handle where the attributes should be attached to + @vdesc the object handle where the attributes should be attached to @vtype hid_t @vio in @endvar @@*/ -void IOHDF5Util_DumpCommonAttributes (const cGH *GH, - int vindex, - int timelevel, - const CCTK_INT *global_shape, - const ioHDF5Geo_t *request, - hid_t dataset) +void IOHDF5Util_DumpCommonAttributes (const cGH *GH, const ioSlab *slab, + hid_t object) { - char *groupname; int dim, vdim; + char *groupname; CCTK_INT attr_int; CCTK_REAL *attr_real; ioHDF5UtilGH *myGH; @@ -256,27 +215,19 @@ void IOHDF5Util_DumpCommonAttributes (const cGH *GH, DECLARE_CCTK_PARAMETERS - /* prevent compiler warning about unused parameter */ - timelevel = timelevel; - - /* Get the handle for IOHDF5Util extensions */ myGH = (ioHDF5UtilGH *) CCTK_GHExtension (GH, "IOHDF5Util"); /* attributes describing the variable */ - groupname = CCTK_GroupNameFromVarI (vindex); - WRITE_ATTRIBUTE ("groupname", groupname, dataset, - myGH->scalar_dataspace, 0, myGH->IOHDF5_STRING); + groupname = CCTK_GroupNameFromVarI (slab->vindex); + WRITE_ATTRIBUTE ("groupname", groupname, object, myGH, 0, myGH->HDF5_STRING); free (groupname); - attr_int = CCTK_GroupTypeFromVarI (vindex); - WRITE_ATTRIBUTE ("grouptype", &attr_int, dataset, - myGH->scalar_dataspace, 0, IOHDF5_INT); - attr_int = CCTK_NumTimeLevelsFromVarI (vindex); - WRITE_ATTRIBUTE ("ntimelevels", &attr_int, dataset, - myGH->scalar_dataspace, 0, IOHDF5_INT); - WRITE_ATTRIBUTE ("global_size", global_shape, dataset, - myGH->array_dataspace, request->sdim, IOHDF5_INT); - WRITE_ATTRIBUTE ("time", &GH->cctk_time, dataset, - myGH->scalar_dataspace, 0, IOHDF5_REAL); + attr_int = CCTK_GroupTypeFromVarI (slab->vindex); + WRITE_ATTRIBUTE ("grouptype", &attr_int, object, myGH, 0, HDF5_INT); + attr_int = CCTK_NumTimeLevelsFromVarI (slab->vindex); + WRITE_ATTRIBUTE ("ntimelevels", &attr_int, object, myGH, 0, HDF5_INT); + WRITE_ATTRIBUTE ("global_size", slab->hsize, object, myGH, slab->hdim, + HDF5_INT); + WRITE_ATTRIBUTE ("time", &GH->cctk_time, object, myGH, 0, HDF5_REAL); /* attributes describing the underlying grid These are only stored for CCTK_GF variables if they are associated @@ -284,9 +235,9 @@ void IOHDF5Util_DumpCommonAttributes (const cGH *GH, /* FIXME: This is hardcoded for cartesian coordinate systems. A better solution would be to be able to query the coordinate system which is associated with the variable. */ - vdim = CCTK_GroupDimFromVarI (vindex); + vdim = CCTK_GroupDimFromVarI (slab->vindex); sprintf (coord_system_name, "cart%dd", vdim); - if (CCTK_GroupTypeFromVarI (vindex) == CCTK_GF && + if (CCTK_GroupTypeFromVarI (slab->vindex) == CCTK_GF && CCTK_CoordSystemHandle (coord_system_name) >= 0) { attr_real = (CCTK_REAL *) malloc (2 * vdim * sizeof (CCTK_REAL)); @@ -296,45 +247,42 @@ void IOHDF5Util_DumpCommonAttributes (const cGH *GH, NULL, coord_system_name); } - WRITE_ATTRIBUTE ("origin", attr_real, dataset, - myGH->array_dataspace, vdim, IOHDF5_REAL); - WRITE_ATTRIBUTE ("min_ext", attr_real, dataset, - myGH->array_dataspace, vdim, IOHDF5_REAL); - WRITE_ATTRIBUTE ("max_ext", attr_real + vdim, dataset, - myGH->array_dataspace, vdim, IOHDF5_REAL); - WRITE_ATTRIBUTE ("delta", GH->cctk_delta_space, dataset, - myGH->array_dataspace, vdim, IOHDF5_REAL); + WRITE_ATTRIBUTE ("origin", attr_real, object, myGH, vdim, HDF5_REAL); + WRITE_ATTRIBUTE ("min_ext", attr_real, object, myGH, vdim, HDF5_REAL); + WRITE_ATTRIBUTE ("max_ext", attr_real + vdim, object, myGH, vdim,HDF5_REAL); + WRITE_ATTRIBUTE ("delta", GH->cctk_delta_space, object, myGH, vdim, + HDF5_REAL); free (attr_real); } #if 0 /* attributes describing the hyperslab */ /* FIXME: what attributes are really needed here ?? ***/ - if (request) + if (slab) { - attr_real = (CCTK_REAL *) malloc (4 * request->sdim * sizeof (CCTK_REAL)); - for (dim = 0; dim < request->sdim; dim++) + attr_real = (CCTK_REAL *) malloc (4 * slab->hdim * sizeof (CCTK_REAL)); + for (dim = 0; dim < slab->hdim; dim++) { - attr_real[dim + 0*request->sdim] = - request->origin[request->direction[dim]] * - GH->cctk_delta_space[request->direction[dim]]; - attr_real[dim + 1*request->sdim] = - request->origin[dim] * GH->cctk_delta_space[dim]; - attr_real[dim + 2*request->sdim] = - (request->origin[dim] + request->actlen[dim]-1) * - GH->cctk_delta_space[dim] * request->downsample[dim]; - attr_real[dim + 3*request->sdim] = - GH->cctk_delta_space[request->direction[dim]] * - request->downsample[request->direction[dim]]; + attr_real[dim + 0*slab->hdim] = + slab->origin[slab->direction[dim]] * + GH->cctk_delta_space[slab->direction[dim]]; + attr_real[dim + 1*slab->hdim] = + slab->origin[dim] * GH->cctk_delta_space[dim]; + attr_real[dim + 2*slab->hdim] = + (slab->origin[dim] + slab->actlen[dim]-1) * + GH->cctk_delta_space[dim] * slab->downsample[dim]; + attr_real[dim + 3*slab->hdim] = + GH->cctk_delta_space[slab->direction[dim]] * + slab->downsample[slab->direction[dim]]; } - WRITE_ATTRIBUTE ("origin_slab", attr_real + 0*dim, dataset, - myGH->array_dataspace, dim, IOHDF5_REAL); - WRITE_ATTRIBUTE ("min_ext_slab", attr_real + 1*dim, dataset, - myGH->array_dataspace, dim, IOHDF5_REAL); - WRITE_ATTRIBUTE ("max_ext_slab", attr_real + 2*dim, dataset, - myGH->array_dataspace, dim, IOHDF5_REAL); - WRITE_ATTRIBUTE ("delta_slab", attr_real + 3*dim, dataset, - myGH->array_dataspace, dim, IOHDF5_REAL); + WRITE_ATTRIBUTE ("origin_slab", attr_real + 0*dim, object, myGH, dim, + HDF5_REAL); + WRITE_ATTRIBUTE ("min_ext_slab", attr_real + 1*dim, object, myGH, dim, + HDF5_REAL); + WRITE_ATTRIBUTE ("max_ext_slab", attr_real + 2*dim, object, myGH, dim, + HDF5_REAL); + WRITE_ATTRIBUTE ("delta_slab", attr_real + 3*dim, object, myGH, dim, + HDF5_REAL); free (attr_real); } #endif @@ -351,7 +299,7 @@ void IOHDF5Util_DumpCommonAttributes (const cGH *GH, attached to the CACTUS_PARAMETERS_GROUP group in the HDF5 file. @enddesc @var GH - @vdesc Pointer to CCTK grid hierarchy + @vdesc pointer to CCTK grid hierarchy @vtype const cGH * @vio in @endvar @@ -380,18 +328,16 @@ void IOHDF5Util_DumpParameters (const cGH *GH, int all, hid_t file) CCTK_INFO ("Dumping Parameters ..."); } - /* Get the parameter string buffer */ + /* get the parameter string buffer */ parameters = IOUtil_GetAllParameters (GH, all); if (parameters) { - /* Get the handle for IOHDF5Util extensions */ myGH = (ioHDF5UtilGH *) CCTK_GHExtension (GH, "IOHDF5Util"); - - IOHDF5_ERROR (group = H5Gcreate (file, CACTUS_PARAMETERS_GROUP, 0)); - WRITE_ATTRIBUTE (ALL_PARAMETERS, parameters, group, - myGH->scalar_dataspace, 0, myGH->IOHDF5_STRING); - IOHDF5_ERROR (H5Gclose (group)); + HDF5_ERROR (group = H5Gcreate (file, CACTUS_PARAMETERS_GROUP, 0)); + WRITE_ATTRIBUTE (ALL_PARAMETERS, parameters, group, myGH, 0, + myGH->HDF5_STRING); + HDF5_ERROR (H5Gclose (group)); free (parameters); } @@ -408,7 +354,7 @@ void IOHDF5Util_DumpParameters (const cGH *GH, int all, hid_t file) in the HDF5 file. @enddesc @var GH - @vdesc Pointer to CCTK grid hierarchy + @vdesc pointer to CCTK grid hierarchy @vtype const cGH * @vio in @endvar @@ -418,8 +364,7 @@ void IOHDF5Util_DumpParameters (const cGH *GH, int all, hid_t file) @vio in @endvar @@*/ -void IOHDF5Util_DumpGHExtensions (const cGH *GH, - hid_t file) +void IOHDF5Util_DumpGHExtensions (const cGH *GH, hid_t file) { int value; hid_t group; @@ -435,29 +380,24 @@ void IOHDF5Util_DumpGHExtensions (const cGH *GH, CCTK_INFO ("Dumping GH extensions ..."); } - /* Get the handles for IOUtil and IOHDF5 extensions */ ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO"); myGH = (ioHDF5UtilGH *) CCTK_GHExtension (GH, "IOHDF5Util"); - IOHDF5_ERROR (group = H5Gcreate (file, GLOBAL_ATTRIBUTES_GROUP, 0)); + HDF5_ERROR (group = H5Gcreate (file, GLOBAL_ATTRIBUTES_GROUP, 0)); value = CCTK_MainLoopIndex (); - WRITE_ATTRIBUTE ("main_loop_index", &value, group, - myGH->scalar_dataspace, 0, H5T_NATIVE_INT); + WRITE_ATTRIBUTE ("main_loop_index", &value, group, myGH, 0, H5T_NATIVE_INT); value = CCTK_nProcs (GH); - WRITE_ATTRIBUTE ("nprocs", &value, group, - myGH->scalar_dataspace, 0, H5T_NATIVE_INT); - WRITE_ATTRIBUTE ("ioproc_every", &ioUtilGH->ioproc_every, group, - myGH->scalar_dataspace, 0, H5T_NATIVE_INT); - WRITE_ATTRIBUTE ("unchunked", &ioUtilGH->unchunked, group, - myGH->scalar_dataspace, 0, H5T_NATIVE_INT); - WRITE_ATTRIBUTE ("cctk_time", &GH->cctk_time, group, - myGH->scalar_dataspace, 0, IOHDF5_REAL); - WRITE_ATTRIBUTE ("cctk_iteration", &GH->cctk_iteration, group, - myGH->scalar_dataspace, 0, H5T_NATIVE_INT); + WRITE_ATTRIBUTE ("nprocs", &value, group, myGH, 0, H5T_NATIVE_INT); + WRITE_ATTRIBUTE ("ioproc_every", &ioUtilGH->ioproc_every, group, myGH, 0, + H5T_NATIVE_INT); + WRITE_ATTRIBUTE ("unchunked", &ioUtilGH->unchunked, group, myGH, 0, + H5T_NATIVE_INT); + WRITE_ATTRIBUTE ("cctk_time", &GH->cctk_time, group, myGH, 0, HDF5_REAL); + WRITE_ATTRIBUTE ("cctk_iteration", &GH->cctk_iteration, group, myGH, 0, + H5T_NATIVE_INT); version = CCTK_FullVersion (); - WRITE_ATTRIBUTE ("Cactus version", version, group, - myGH->scalar_dataspace, 0, myGH->IOHDF5_STRING); + WRITE_ATTRIBUTE ("Cactus version", version, group, myGH, 0,myGH->HDF5_STRING); /* add the parameter filename and the creation date as file identification attributes */ @@ -466,8 +406,7 @@ void IOHDF5Util_DumpGHExtensions (const cGH *GH, { buffer[0] = 0; CCTK_ParameterFilename (sizeof (buffer), buffer); - WRITE_ATTRIBUTE ("parameter file", buffer, group, - myGH->scalar_dataspace, 0, myGH->IOHDF5_STRING); + WRITE_ATTRIBUTE ("parameter file", buffer, group, myGH,0,myGH->HDF5_STRING); } if (CCTK_Equals (out_fileinfo, "creation date") || CCTK_Equals (out_fileinfo, "all")) @@ -477,11 +416,10 @@ void IOHDF5Util_DumpGHExtensions (const cGH *GH, value = strlen (buffer) + 1; buffer[value-1] = ' '; Util_CurrentTime (sizeof (buffer) - value, buffer + value); - WRITE_ATTRIBUTE ("creation date", buffer, group, - myGH->scalar_dataspace, 0, myGH->IOHDF5_STRING); + WRITE_ATTRIBUTE ("creation date", buffer, group, myGH, 0,myGH->HDF5_STRING); } - IOHDF5_ERROR (H5Gclose (group)); + HDF5_ERROR (H5Gclose (group)); } @@ -494,7 +432,7 @@ void IOHDF5Util_DumpGHExtensions (const cGH *GH, @enddesc @var myGH - @vdesc Pointer to IOHDF5Util's GH extensions + @vdesc pointer to IOHDF5Util's GH extensions @vtype ioHDF5UtilGH * @vio in @endvar @@ -516,30 +454,30 @@ hid_t IOHDF5Util_DataType (const ioHDF5UtilGH *myGH, int cctk_type) switch (cctk_type) { - case CCTK_VARIABLE_CHAR: retval = IOHDF5_CHAR; break; - case CCTK_VARIABLE_INT: retval = IOHDF5_INT; break; - case CCTK_VARIABLE_REAL: retval = IOHDF5_REAL; break; - case CCTK_VARIABLE_COMPLEX: retval = myGH->IOHDF5_COMPLEX; break; + case CCTK_VARIABLE_CHAR: retval = HDF5_CHAR; break; + case CCTK_VARIABLE_INT: retval = HDF5_INT; break; + case CCTK_VARIABLE_REAL: retval = HDF5_REAL; break; + case CCTK_VARIABLE_COMPLEX: retval = myGH->HDF5_COMPLEX; break; #ifdef CCTK_INT2 - case CCTK_VARIABLE_INT2: retval = IOHDF5_INT2; break; + case CCTK_VARIABLE_INT2: retval = HDF5_INT2; break; #endif #ifdef CCTK_INT4 - case CCTK_VARIABLE_INT4: retval = IOHDF5_INT4; break; + case CCTK_VARIABLE_INT4: retval = HDF5_INT4; break; #endif #ifdef CCTK_INT8 - case CCTK_VARIABLE_INT8: retval = IOHDF5_INT8; break; + case CCTK_VARIABLE_INT8: retval = HDF5_INT8; break; #endif #ifdef CCTK_REAL4 - case CCTK_VARIABLE_REAL4: retval = IOHDF5_REAL4; break; - case CCTK_VARIABLE_COMPLEX8: retval = myGH->IOHDF5_COMPLEX8; break; + case CCTK_VARIABLE_REAL4: retval = HDF5_REAL4; break; + case CCTK_VARIABLE_COMPLEX8: retval = myGH->HDF5_COMPLEX8; break; #endif #ifdef CCTK_REAL8 - case CCTK_VARIABLE_REAL8: retval = IOHDF5_REAL8; break; - case CCTK_VARIABLE_COMPLEX16: retval = myGH->IOHDF5_COMPLEX16; break; + case CCTK_VARIABLE_REAL8: retval = HDF5_REAL8; break; + case CCTK_VARIABLE_COMPLEX16: retval = myGH->HDF5_COMPLEX16; break; #endif #ifdef CCTK_REAL16 - case CCTK_VARIABLE_REAL16: retval = IOHDF5_REAL16; break; - case CCTK_VARIABLE_COMPLEX32: retval = myGH->IOHDF5_COMPLEX32; break; + case CCTK_VARIABLE_REAL16: retval = HDF5_REAL16; break; + case CCTK_VARIABLE_COMPLEX32: retval = myGH->HDF5_COMPLEX32; break; #endif default: CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, diff --git a/src/DumpVar.c b/src/DumpVar.c index 109df75..96148d9 100644 --- a/src/DumpVar.c +++ b/src/DumpVar.c @@ -2,9 +2,9 @@ @file DumpVar.c @date Fri May 21 1999 @author Thomas Radke - @desc + @desc Routines for writing variables into HDF5 data or checkpoint files. - These routines are used by other HDF5 IO methods. + These routines are used by other HDF5 I/O methods. @enddesc @version $Id$ @@*/ @@ -15,77 +15,40 @@ #include "cctk.h" #include "cctk_Parameters.h" #include "CactusPUGH/PUGH/src/include/pugh.h" -#include "CactusPUGH/PUGHSlab/src/NewPUGHSlab.h" +#include "CactusPUGH/PUGHSlab/src/NewPUGHSlab.h" #include "CactusBase/IOUtil/src/ioGH.h" #include "ioHDF5UtilGH.h" - /* the rcs ID and its dummy function to use it */ static const char *rcsid = "$Header$"; CCTK_FILEVERSION(BetaThorns_IOHDF5Util_DumpVar_c) -/* #define DEBUG_ME 1 */ - -#define IOTAGBASE 20000 /* This may break on more than 2000 processors */ - -/* info structure describing how to dump a given CCTK variable type */ -typedef struct -{ - int iohdf5_type; /* the HDF5 type to use */ - int element_size; /* size of a single data element */ -#ifdef CCTK_MPI - MPI_Datatype mpi_type; /* the data type for MPI communication */ +/******************************************************************** + ******************** Macro Definitions ************************ + ********************************************************************/ +/* uncomment the following line to enable some debugging output */ +/* #define IOHDF5UTIL_DEBUG 1 */ + +/* tag base for MPI messages (this may break on more than 2000 processors) */ +#define MPITAGBASE 20000 + + +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ +static int WriteGS (const cGH *GH, const ioSlab *slab, const char *name, + hid_t file); +static int WriteGA (const cGH *GH, const ioSlab *slab, const char *name, + hid_t file); +static int GetLocalHyperslab (const cGH *GH, const ioSlab *slab, void **data, + int *free_data); +static void WriteData (const cGH *GH, const ioSlab *slab, const char *name, + const void *data, int proc, hid_t file); +#if defined(CCTK_MPI) && defined(H5_HAVE_PARALLEL) +static void WriteDataCollective (const cGH *GH, const ioSlab *slab, + const char *name, const void *data,hid_t file); #endif -} dumpInfo; - - -/* prototypes of routines defined in this source file */ -static int IOHDF5Util_DumpGS (const cGH *GH, - int vindex, - int timelevel, - int iohdf5_type, - const ioHDF5Geo_t *request, - int check_exisiting_objects, - hid_t file); -static int IOHDF5Util_DumpGA (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *request, - const dumpInfo *info, - int check_exisiting_objects, - hid_t file); -static int IOHDF5Util_getDumpData (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *request, - void **outme, - int *free_outme, - CCTK_INT *geom); -static void IOHDF5Util_procDump (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *request, - const void *outme, - const CCTK_INT *geom, - int proc, - int iohdf5_type, - int check_exisiting_objects, - hid_t file); -#ifdef CCTK_MPI -#ifdef H5_HAVE_PARALLEL -static void IOHDF5Util_collectiveDump (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *request, - const void *outme, - const CCTK_INT *geom, - int hdf5io_type, - int check_exisiting_objects, - hid_t file); -#endif /* H5_HAVE_PARALLEL */ -#endif /* MPI */ - /*@@ @@ -96,27 +59,17 @@ static void IOHDF5Util_collectiveDump (const cGH *GH, Generic dump routine, just calls the type-specific dump routine. @enddesc - @calls IOHDF5Util_DumpGS - IOHDF5Util_DumpGA + @calls WriteGS + WriteGA @var GH - @vdesc Pointer to CCTK grid hierarchy + @vdesc pointer to CCTK grid hierarchy @vtype const cGH * @vio in @endvar - @var vindex - @vdesc index of the variable to be dumped - @vtype int - @vio in - @endvar - @var timelevel - @vdesc the timelevel to dump - @vtype int - @vio in - @endvar - @var request - @vdesc pointer to the IO request structure - @vtype const ioHDF5Geo_t * + @var slab + @vdesc reference to the I/O hyperslab description + @vtype const ioSlab * @vio in @endvar @var file @@ -124,141 +77,83 @@ static void IOHDF5Util_collectiveDump (const cGH *GH, @vtype hid_t @vio in @endvar - @var check_exisiting_objects - @vdesc flag indicating if we should check for already existing objects - before these are created anew - This might happen for existing files reopened after recovery. - @vtype int - @vio in - @endvar @returntype int @returndesc - -1 if variable has unknown type - or return code of either - @seeroutine IOHDF5Util_DumpGS or - @seeroutine IOHDF5Util_DumpGA + -1 if variable has unknown group type + or return code of either @seeroutine WriteGS or + @seeroutine WriteGA @endreturndesc @@*/ -int IOHDF5Util_DumpVar (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *request, - hid_t file, - int check_exisiting_objects) +int IOHDF5Util_DumpVar (const cGH *GH, const ioSlab *slab, hid_t file) { - int vtype, gtype; - pGH *pughGH; - ioHDF5UtilGH *myGH; - ioGH *ioUtilGH; - dumpInfo info; - int retval; + int gtype, retval; + char *fullname, *objectname; - /* Get the handle for PUGH, IOUtil, and IOHDF5Util extensions */ - pughGH = PUGH_pGH (GH); - ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO"); - myGH = (ioHDF5UtilGH *) CCTK_GHExtension (GH, "IOHDF5Util"); + /* build the unique name for the file object to write */ + fullname = CCTK_FullName (slab->vindex); + objectname = (char *) malloc (strlen (fullname) + 80); + sprintf (objectname, "%s timelevel %d at iteration %d", + fullname, slab->timelevel, GH->cctk_iteration); - vtype = CCTK_VarTypeI (vindex); - /* downgrade the output precision if requested */ - if (ioUtilGH->out_single) + /* check whether the object already exists */ + if (slab->check_exist && file >= 0) { - /* Do we only want to downgrade generic CCTK types ? */ -#ifdef CCTK_REAL4 - if (vtype == CCTK_VARIABLE_REAL) - { - vtype = CCTK_VARIABLE_REAL4; - } - else if (vtype == CCTK_VARIABLE_COMPLEX) - { - vtype = CCTK_VARIABLE_COMPLEX8; - } -#endif -#ifdef CCTK_INT4 - if (vtype == CCTK_VARIABLE_INT) + H5E_BEGIN_TRY { - vtype = CCTK_VARIABLE_INT4; - } -#endif - } - info.element_size = CCTK_VarTypeSize (vtype); -#ifdef CCTK_MPI - info.mpi_type = PUGH_MPIDataType (pughGH, vtype); -#endif - info.iohdf5_type = IOHDF5Util_DataType (myGH, vtype); - - if (info.element_size <= 0 || -#ifdef CCTK_MPI - info.mpi_type == MPI_DATATYPE_NULL || -#endif - info.iohdf5_type < 0) - { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Unsupported variable type %d", vtype); - return (-1); + H5Gunlink (file, objectname); + } H5E_END_TRY; } - /* now branch to the appropriate dump routine */ - gtype = CCTK_GroupTypeFromVarI (vindex); + /* branch to the appropriate dump routine */ + gtype = CCTK_GroupTypeFromVarI (slab->vindex); if (gtype == CCTK_SCALAR) { - retval = IOHDF5Util_DumpGS (GH, vindex, timelevel, info.iohdf5_type, - request, check_exisiting_objects, file); + retval = WriteGS (GH, slab, objectname, file); } else if (gtype == CCTK_ARRAY || gtype == CCTK_GF) { - retval = IOHDF5Util_DumpGA (GH, vindex, timelevel, request, &info, - check_exisiting_objects, file); + retval = WriteGA (GH, slab, objectname, file); } else { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Invalid group type %d", gtype); + "Invalid group type %d for variable '%s'", gtype, fullname); retval = -1; } + /* clean up */ + free (objectname); + free (fullname); + return (retval); } +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ /*@@ - @routine IOHDF5Util_DumpGS + @routine WriteGS @date May 21 1999 @author Thomas Radke @desc - Dumps a CCTK_SCALAR type variable into a HDF5 file. - @enddesc + Writes a CCTK_SCALAR type variable into a HDF5 file. + @enddesc @var GH - @vdesc Pointer to CCTK grid hierarchy + @vdesc pointer to CCTK grid hierarchy @vtype const cGH * @vio in @endvar - @var vindex - @vdesc index of the variable to be dumped - @vtype int - @vio in - @endvar - @var timelevel - @vdesc the timelevel to dump - @vtype int - @vio in - @endvar - @var iohdf5_type - @vdesc the HDF5 datatype - @vtype int - @vio in - @endvar - @var request - @vdesc pointer to the IO request structure - @vtype const ioHDF5Geo_t * + @var slab + @vdesc reference to the I/O hyperslab description + @vtype const ioSlab * @vio in @endvar - @var check_exisiting_objects - @vdesc flag indicating if we should check for already existing objects - before these are created anew - This might happen for existing files reopened after recovery. - @vtype int + @var name + @vdesc name of the dataset to write + @vtype const char * @vio in @endvar @var file @@ -272,113 +167,68 @@ int IOHDF5Util_DumpVar (const cGH *GH, 0 for success, or -1 if file handle is invalid @endreturndesc @@*/ -static int IOHDF5Util_DumpGS (const cGH *GH, - int vindex, - int timelevel, - int iohdf5_type, - const ioHDF5Geo_t *request, - int check_exisiting_objects, - hid_t file) +static int WriteGS (const cGH *GH, const ioSlab *slab, const char *name, + hid_t file) { ioGH *ioUtilGH; ioHDF5UtilGH *myGH; - hid_t dataset; - char *fullname; - char *datasetname; - static CCTK_INT global_shape[1] = {0}; - + hid_t dataset, hdf5type; - /* immediately return if file handle is invalid */ - if (file < 0) - { - return (-1); - } - /* Get the handles for IOHDF5Util and IOUtil extensions */ ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO"); myGH = (ioHDF5UtilGH *) CCTK_GHExtension (GH, "IOHDF5Util"); + /* only I/O processors write data */ if (CCTK_MyProc (GH) != ioUtilGH->ioproc) { return (0); } - fullname = CCTK_FullName (vindex); - datasetname = (char *) malloc (strlen (fullname) + 80); - sprintf (datasetname, "%s timelevel %d at iteration %d", - fullname, timelevel, GH->cctk_iteration); - - /* if restart from recovery delete an already existing dataset - so that it can be created as anew */ - if (check_exisiting_objects) + /* check if file handle is invalid */ + if (file < 0) { - IOHDF5_ERROR (H5Eset_auto (NULL, NULL)); - H5Gunlink (file, datasetname); - IOHDF5_ERROR (H5Eset_auto (myGH->print_error_fn, myGH->print_error_fn_arg)); + return (-1); } - IOHDF5_ERROR (dataset = H5Dcreate (file, datasetname, iohdf5_type, - myGH->scalar_dataspace, H5P_DEFAULT)); - IOHDF5_ERROR (H5Dwrite (dataset, iohdf5_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, - CCTK_VarDataPtrI (GH, timelevel, vindex))); - - IOHDF5Util_DumpCommonAttributes (GH, vindex, timelevel, global_shape, - request, dataset); + hdf5type = IOHDF5Util_DataType (myGH, slab->hdatatype); + HDF5_ERROR (dataset = H5Dcreate (file, name, hdf5type, myGH->scalar_dataspace, + H5P_DEFAULT)); + HDF5_ERROR (H5Dwrite (dataset, hdf5type, H5S_ALL, H5S_ALL, H5P_DEFAULT, + CCTK_VarDataPtrI (GH, slab->timelevel, slab->vindex))); - IOHDF5_ERROR (H5Dclose (dataset)); + IOHDF5Util_DumpCommonAttributes (GH, slab, dataset); - free (datasetname); - free (fullname); + HDF5_ERROR (H5Dclose (dataset)); return (0); } /*@@ - @routine IOHDF5Util_DumpGA + @routine WriteGA @date May 21 1999 @author Paul Walker @desc - Dumps a CCTK_GF or CCTK_ARRAY type variable into a HDF5 file. - @enddesc + Writes a grid array into a HDF5 file. + @enddesc - @calls IOHDF5Util_getDumpData - IOHDF5Util_procDump - IOHDF5Util_collectiveDump + @calls GetLocalHyperslab + WriteData + WriteDataCollective @var GH - @vdesc Pointer to CCTK grid hierarchy + @vdesc pointer to CCTK grid hierarchy @vtype const cGH * @vio in @endvar - @var vindex - @vdesc index of the variable to be dumped - @vtype int - @vio in - @endvar - @var timelevel - @vdesc the timelevel to dump - @vtype int - @vio in - @endvar - @var request - @vdesc pointer to the IO request structure - @vtype const ioHDF5Geo_t * - @vio in - @endvar - @var info - @vdesc info structure describing - - the HDF5 datatype to store - - the size of an element of variable - - the MPI datatype to communicate - @vtype const dumpInfo * + @var slab + @vdesc reference to the I/O hyperslab description + @vtype const ioSlab * @vio in @endvar - @var check_exisiting_objects - @vdesc flag indicating if we should check for already existing objects - before these are created anew - This might happen for existing files reopened after recovery. - @vtype int + @var name + @vdesc name of the dataset to write + @vtype const char * @vio in @endvar @var file @@ -390,45 +240,36 @@ static int IOHDF5Util_DumpGS (const cGH *GH, @returntype int @returndesc 0 for success - or returncode of @seeroutine IOHDF5Util_getDumpData + or returncode of @seeroutine GetLocalHyperslab @endreturndesc @@*/ -static int IOHDF5Util_DumpGA (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *request, - const dumpInfo *info, - int check_exisiting_objects, - hid_t file) +static int WriteGA (const cGH *GH, const ioSlab *slab, const char *name, + hid_t file) { ioGH *ioUtilGH; - pGH *pughGH; - int myproc; - int nprocs; - CCTK_INT *geom; /* Lower bounds, sizes and global shape of data */ - void *outme; /* The data pointer to dump ... */ - int free_outme; /* and whether it needs freeing */ - int retval; + ioHDF5UtilGH *myGH; + int myproc, nprocs, retval; + void *data; /* The data pointer to dump ... */ + int free_data; /* and whether it needs freeing */ #ifdef CCTK_MPI void *tmpd; - int incoming; - int outgoing; - int i, j; + int i, j, incoming, outgoing; + MPI_Comm comm; MPI_Status ms; + MPI_Datatype mpitype; #endif DECLARE_CCTK_PARAMETERS - /* Get the handles for PUGH and IOUtil extensions */ - pughGH = PUGH_pGH (GH); + myGH = (ioHDF5UtilGH *) CCTK_GHExtension (GH, "IOHDF5Util"); ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO"); - /* allocate the geometry buffer */ - geom = (CCTK_INT *) malloc (3 * request->sdim * sizeof (CCTK_INT)); - - /* Get the pointer to the data we want to output (includes downsampling) */ - retval = IOHDF5Util_getDumpData (GH, vindex, timelevel, request, &outme, - &free_outme, geom); +#ifdef CCTK_MPI + mpitype = PUGH_MPIDataType (PUGH_pGH (GH), slab->hdatatype); +#endif + + /* get the pointer to the data we want to output (includes downsampling) */ + retval = GetLocalHyperslab (GH, slab, &data, &free_data); if (retval < 0) { return (retval); @@ -441,87 +282,82 @@ static int IOHDF5Util_DumpGA (const cGH *GH, #ifdef H5_HAVE_PARALLEL if (ioUtilGH->unchunked) { - IOHDF5Util_collectiveDump (GH, vindex, timelevel, request, outme, geom, - info->iohdf5_type, check_exisiting_objects,file); - if (free_outme) + WriteDataCollective (GH, slab, name, data, file); + if (free_data) { - free (outme); + free (data); } - free (geom); return (0); } #endif #endif - /* Dump data held on IO processor */ + /* dump data held on I/O processor */ if (myproc == ioUtilGH->ioproc) { - IOHDF5Util_procDump (GH, vindex, timelevel, request, outme, geom, - myproc, info->iohdf5_type, check_exisiting_objects, - file); + WriteData (GH, slab, name, data, myproc, file); } #ifdef CCTK_MPI + comm = PUGH_pGH (GH)->PUGH_COMM_WORLD; if (myproc == ioUtilGH->ioproc) { - /* Dump data from all other processors */ + /* dump data from all other processors */ for (i = myproc+1; i < myproc+ioUtilGH->ioproc_every && i < nprocs; i++) { - /* receive geometry */ - CACTUS_MPI_ERROR (MPI_Recv (geom, 3*request->sdim, PUGH_MPI_INT, i, - 2*i + IOTAGBASE + 1, pughGH->PUGH_COMM_WORLD, - &ms)); + /* receive geometry (this assumes the geometry arrays + to be contiguous starting at hoffset */ + CACTUS_MPI_ERROR (MPI_Recv (slab->hoffset, 3*slab->hdim, PUGH_MPI_INT, i, + 2*i + MPITAGBASE + 1, comm, &ms)); - incoming = geom[request->sdim]; - for (j = 1; j < request->sdim; j++) + incoming = 1; + for (j = 0; j < slab->hdim; j++) { - incoming *= geom[request->sdim + j]; + incoming *= slab->hsize_chunk[slab->hdim + j]; } /* receive data */ + tmpd = NULL; if (incoming > 0) { - tmpd = malloc (incoming * info->element_size); - CACTUS_MPI_ERROR (MPI_Recv (tmpd, incoming, info->mpi_type, i, - 2*i + IOTAGBASE, pughGH->PUGH_COMM_WORLD, - &ms)); + tmpd = malloc (incoming * CCTK_VarTypeSize (slab->hdatatype)); + CACTUS_MPI_ERROR (MPI_Recv (tmpd, incoming, mpitype, i, + 2*i + MPITAGBASE, comm, &ms)); } - else - { - tmpd = NULL; - } - IOHDF5Util_procDump (GH, vindex, timelevel, request, tmpd, geom, i, - info->iohdf5_type, check_exisiting_objects, file); + + /* write data */ + WriteData (GH, slab, name, tmpd, i, file); + if (tmpd) { free (tmpd); } - } /* End loop over processors */ + } /* end loop over processors */ } else { - - /* Send the geometry and data from the non-IO processors - * to the IO processors + /* + * send the geometry and data from non-I/O processors to the I/O processors */ - outgoing = geom[request->sdim]; - for (i = 1; i < request->sdim; i++) + outgoing = 1; + for (i = 0; i < slab->hdim; i++) { - outgoing *= geom[request->sdim + i]; + outgoing *= slab->hsize_chunk[slab->hdim + i]; } - /* send geometry */ - CACTUS_MPI_ERROR (MPI_Send (geom, 3*request->sdim, PUGH_MPI_INT, - ioUtilGH->ioproc, 2*myproc + IOTAGBASE + 1, - pughGH->PUGH_COMM_WORLD)); + /* send geometry (this assumes the geometry arrays + to be contiguous starting at hoffset */ + CACTUS_MPI_ERROR (MPI_Send (slab->hoffset, 3*slab->hdim, PUGH_MPI_INT, + ioUtilGH->ioproc, 2*myproc + MPITAGBASE + 1, + comm)); + /* send data */ if (outgoing > 0) { - /* send data if outgoing>0 */ - CACTUS_MPI_ERROR (MPI_Send (outme, outgoing, info->mpi_type, - ioUtilGH->ioproc, 2*myproc + IOTAGBASE, - pughGH->PUGH_COMM_WORLD)); -#ifdef DEBUG_ME + CACTUS_MPI_ERROR (MPI_Send (data, outgoing, mpitype, + ioUtilGH->ioproc, 2*myproc + MPITAGBASE, + comm)); +#ifdef IOHDF5UTIL_DEBUG printf ("Processor %d sent %d data points\n", myproc, outgoing); #endif } @@ -532,118 +368,95 @@ static int IOHDF5Util_DumpGA (const cGH *GH, #endif /* free allocated resources */ - if (free_outme) + if (free_data) { - free (outme); + free (data); } - free (geom); return (retval); } -/**************************************************************************/ -/* local functions */ -/**************************************************************************/ -static int IOHDF5Util_getDumpData (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *request, - void **outme, - int *free_outme, - CCTK_INT *geom) +static int GetLocalHyperslab (const cGH *GH, const ioSlab *slab, void **data, + int *free_data) { int i, retval; - int cctk_output_type; - ioGH *ioUtilGH; - int *hsizes, *hsizes_global, *hsizes_offset; /* geometry information */ char *fullname; - - - /* get GH extension for IOUtil */ - ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO"); - - /* determine the datatype for the hyperslab */ - cctk_output_type = CCTK_VarTypeI (vindex); - if (ioUtilGH->out_single) - { -#ifdef CCTK_INT4 - if (cctk_output_type == CCTK_VARIABLE_INT) - { - cctk_output_type = CCTK_VARIABLE_INT4; - } -#endif -#ifdef CCTK_REAL4 - if (cctk_output_type == CCTK_VARIABLE_REAL) - { - cctk_output_type = CCTK_VARIABLE_REAL4; - } - else if (cctk_output_type == CCTK_VARIABLE_COMPLEX) - { - cctk_output_type = CCTK_VARIABLE_COMPLEX8; - } -#endif - } - /* FIXME */ - /* allocate array to hold size information of request */ - hsizes = (int *) malloc (3 * request->sdim * sizeof (int)); - hsizes_global = hsizes + 1*request->sdim; - hsizes_offset = hsizes + 2*request->sdim; #if 0 - FIXME: what is this for ??? - /* Get the start indeces for the request from origin. */ - /* Slab_start from the geo structure is not a true start index, - it is currently used as the intersection point of three surfaces, - that's why two entries have to be set to zero in the case of a - surface (one entry for line) - FIXME */ - for (i = 0; i < vdim; i++) + mapping = Hyperslab_DefineLocalMappingByIndex (GH, vindex, slab->hdim, + slab->direction, slab->origin, + slab->extent, slab->downsample, + -1, NULL, slab->hsize_local, + slab->hsize_global, + slab->hoffset_global); + const cGH *GH, + CCTK_INT vindex, + CCTK_INT hdim, + const CCTK_INT *direction /* vdim*hdim */, + const CCTK_INT *origin /* vdim */, + const CCTK_INT *extent /* hdim */, + const CCTK_INT *downsample /* hdim */, + CCTK_INT table_handle, + t_hslabConversionFn conversion_fn, + CCTK_INT *hsize_local, /* hdim */ + CCTK_INT *hsize_global, /* hdim */ + CCTK_INT *hoffset_global /* hdim */); + + if (mapping < 0) { - slabstart[i] = request->origin[i]; + fullname = CCTK_FullName (vindex); + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Failed to extract hyperslab for variable '%s'", fullname); + free (fullname); } - for (i = 0; i < request->sdim; i++) - { - slabstart[request->direction[i]] = 0; - } -#endif - retval = NewHyperslab_GetLocalHyperslab (GH, vindex, timelevel, request->sdim, - cctk_output_type, NULL, request->origin, - request->direction, request->length, - request->downsample, outme, free_outme, +#else +{ + int *hsizes, *hsizes_global, *hsizes_offset; /* geometry information */ + + /* allocate array to hold size information of request */ + hsizes = (int *) malloc (3 * slab->hdim * sizeof (int)); + hsizes_global = hsizes + 1*slab->hdim; + hsizes_offset = hsizes + 2*slab->hdim; + + retval = NewHyperslab_GetLocalHyperslab (GH, slab->vindex, slab->timelevel, slab->hdim, + slab->hdatatype, NULL, slab->origin, + slab->direction, slab->extent, + slab->downsample, data, free_data, hsizes, hsizes_global, hsizes_offset); if (retval == 0) { - for (i = 0; i < request->sdim; i++) + for (i = 0; i < slab->hdim; i++) { - geom[i + 0*request->sdim] = hsizes_offset[i]; - geom[i + 1*request->sdim] = hsizes[i]; - geom[i + 2*request->sdim] = hsizes_global[i]; - request->actlen[i] = hsizes_global[i]; + slab->hoffset[i] = hsizes_offset[i]; + slab->hsize[i] = hsizes_global[i]; + slab->hsize_chunk[i] = hsizes[i]; } } else { - fullname = CCTK_FullName (vindex); + fullname = CCTK_FullName (slab->vindex); CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "Failed to extract hyperslab for variable '%s'", fullname); free (fullname); } free (hsizes); +} +#endif return (retval); } /*@@ - @routine IOHDF5Util_procDump + @routine WriteData @author Thomas Radke @date May 21 1999 @desc - All IO processors dump the data of their group into the file, + All I/O processors dump the data of their group into the file, either as one chunk per processor or unchunked (depending on parameter "unchunked"). @enddesc @@ -651,78 +464,44 @@ static int IOHDF5Util_getDumpData (const cGH *GH, @calls IOHDF5Util_DumpCommonAttributes @var GH - @vdesc Pointer to CCTK grid hierarchy + @vdesc pointer to CCTK grid hierarchy @vtype const cGH * @vio in @endvar - @var vindex - @vdesc global index of the variable to be dumped - @vtype int - @vio in - @endvar - @var timelevel - @vdesc the timelevel to store - @vtype int + @var slab + @vdesc reference to the I/O hyperslab description + @vtype const ioSlab * @vio in @endvar - @var request - @vdesc pointer to the IO request structure - @vtype const ioHDF5Geo_t * + @var name + @vdesc name of the dataset to write + @vtype const char * @vio in @endvar - @var outme + @var data @vdesc pointer to the chunk to dump @vtype const void * @vio in @endvar - @var geom - @vdesc bounds and sizes of the output - @vtype const CCTK_INT[3*dim] - @vio in - @vcomment geom[0*dim..1*dim-1]: lower bounds - geom[1*dim..2*dim-1]: (local) data sizes - geom[2*dim..3*dim-1]: global space - @endvar @var proc @vdesc the processor which's chunk is to be dumped @vtype int @vio in @endvar - @var hdf5io_type - @vdesc the HDF5 datatype identifier - @vtype int - @vio in - @endvar - @var check_exisiting_objects - @vdesc flag indicating if we should check for already existing objects - before these are created anew - This might happen for existing files reopened after recovery. - @vtype int - @vio in - @endvar @var file @vdesc the HDF5 file handle @vtype hid_t @vio in @endvar @@*/ -static void IOHDF5Util_procDump (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *request, - const void *outme, - const CCTK_INT *geom, - int proc, - int iohdf5_type, - int check_exisiting_objects, - hid_t file) +static void WriteData (const cGH *GH, const ioSlab *slab, const char *name, + const void *data, int proc, hid_t file) { - int i, sdim; - int myproc; + int i, myproc; ioGH *ioUtilGH; ioHDF5UtilGH *myGH; - hid_t group, dataset, memspace, filespace, plist; - char *fullname, *datasetname, *chunkname; + hid_t hdf5type, group, dataset, memspace, filespace, plist; + char *chunkname; hssize_t *chunk_origin; hsize_t *chunk_dims, *file_dims; hsize_t buffersize; @@ -738,160 +517,132 @@ static void IOHDF5Util_procDump (const cGH *GH, ioUtilGH = (ioGH *) CCTK_GHExtension (GH, "IO"); myGH = (ioHDF5UtilGH *) CCTK_GHExtension (GH, "IOHDF5Util"); - sdim = request->sdim; - myproc = CCTK_MyProc (GH); - - chunk_origin = (hssize_t *) malloc (sdim * sizeof (hssize_t)); - chunk_dims = (hsize_t *) malloc (2*sdim * sizeof (hsize_t)); - file_dims = chunk_dims + sdim; - - /* HDF5 needs it in reverse order */ - for (i = 0; i < sdim; i++) + /* copy the size arrays from CCTK_INT to appropriate types + note that HDF5 wants elements in reverse order */ + chunk_origin = (hssize_t *) malloc (slab->hdim * sizeof (hssize_t)); + chunk_dims = (hsize_t *) malloc (2*slab->hdim * sizeof (hsize_t)); + file_dims = chunk_dims + slab->hdim; + for (i = 0; i < slab->hdim; i++) { - chunk_origin[i] = geom[1*sdim - 1 - i]; - chunk_dims [i] = geom[2*sdim - 1 - i]; - file_dims [i] = geom[3*sdim - 1 - i]; + chunk_origin[i] = slab->hoffset[slab->hdim - 1 - i]; + file_dims [i] = slab->hsize[slab->hdim - 1 - i]; + chunk_dims [i] = slab->hsize_chunk[slab->hdim - 1 - i]; } - /* build the unique dataset name from the variable's full name, - the timelevel and the current iteration number */ - fullname = CCTK_FullName (vindex); - datasetname = (char *) malloc (strlen (fullname) + 80); - sprintf (datasetname, "%s timelevel %d at iteration %d", - fullname, timelevel, GH->cctk_iteration); - - /* if restart from recovery delete an already existing dataset - so that it can be created as anew */ - if (proc == myproc && check_exisiting_objects) - { - IOHDF5_ERROR (H5Eset_auto (NULL, NULL)); - H5Gunlink (file, datasetname); - IOHDF5_ERROR (H5Eset_auto (myGH->print_error_fn, myGH->print_error_fn_arg)); - } + myproc = CCTK_MyProc (GH); - if (outme) + memspace = -1; + if (data) { /* create the memspace according to chunk dims */ - IOHDF5_ERROR (memspace = H5Screate_simple (sdim, chunk_dims, NULL)); - } - else - { - memspace = -1; + HDF5_ERROR (memspace = H5Screate_simple (slab->hdim, chunk_dims, NULL)); } + hdf5type = IOHDF5Util_DataType (myGH, slab->hdatatype); if (ioUtilGH->unchunked) { /* create the (global) filespace and set the hyperslab for the chunk */ - IOHDF5_ERROR (filespace = H5Screate_simple (sdim, file_dims, NULL)); - IOHDF5_ERROR (H5Sselect_hyperslab (filespace, H5S_SELECT_SET, - chunk_origin, NULL, chunk_dims, NULL)); - - /* the IO processor creates the dataset and adds the common attributes + HDF5_ERROR (filespace = H5Screate_simple (slab->hdim, file_dims, NULL)); + HDF5_ERROR (H5Sselect_hyperslab (filespace, H5S_SELECT_SET, chunk_origin, + NULL, chunk_dims, NULL)); + + /* the I/O processor creates the dataset and adds the common attributes when writing its own data, otherwise the dataset is reopened */ if (proc == myproc) { - IOHDF5_ERROR (plist = H5Pcreate (H5P_DATASET_CREATE)); + HDF5_ERROR (plist = H5Pcreate (H5P_DATASET_CREATE)); /* enable compression for chunked dataset if compression was requested */ if (compression_level) { - IOHDF5_ERROR (H5Pset_chunk (plist, sdim, chunk_dims)); - IOHDF5_ERROR (H5Pset_deflate (plist, compression_level)); + HDF5_ERROR (H5Pset_chunk (plist, slab->hdim, chunk_dims)); + HDF5_ERROR (H5Pset_deflate (plist, compression_level)); } - IOHDF5_ERROR (dataset = H5Dcreate (file, datasetname, - iohdf5_type, filespace, plist)); - IOHDF5_ERROR (H5Pclose (plist)); - IOHDF5Util_DumpCommonAttributes (GH, vindex, timelevel, &geom[2*sdim], - request, dataset); + HDF5_ERROR (dataset = H5Dcreate (file, name, hdf5type, filespace, plist)); + HDF5_ERROR (H5Pclose (plist)); + IOHDF5Util_DumpCommonAttributes (GH, slab, dataset); } else { - IOHDF5_ERROR (dataset = H5Dopen (file, datasetname)); + HDF5_ERROR (dataset = H5Dopen (file, name)); } if (memspace >= 0) { /* increase the buffer size if the default isn't sufficient */ - IOHDF5_ERROR (plist = H5Pcreate (H5P_DATASET_XFER)); + HDF5_ERROR (plist = H5Pcreate (H5P_DATASET_XFER)); buffersize = H5Dget_storage_size (dataset); if (buffersize > H5Pget_buffer (plist, NULL, NULL)) { - IOHDF5_ERROR (H5Pset_buffer (plist, buffersize, NULL, NULL)); + HDF5_ERROR (H5Pset_buffer (plist, buffersize, NULL, NULL)); } /* write the data */ - IOHDF5_ERROR (H5Dwrite (dataset, iohdf5_type, memspace, filespace, - plist, outme)); + HDF5_ERROR (H5Dwrite (dataset, hdf5type, memspace, filespace, plist, + data)); /* close the transfer property list */ - IOHDF5_ERROR (H5Pclose (plist)); + HDF5_ERROR (H5Pclose (plist)); } /* close the file dataspace */ - IOHDF5_ERROR (H5Sclose (filespace)); + HDF5_ERROR (H5Sclose (filespace)); } else { - /* the IO processor creates the chunk group and adds common attributes */ + /* the I/O processor creates the chunk group and adds common attributes */ if (proc == myproc) { - IOHDF5_ERROR (group = H5Gcreate (file, datasetname, 0)); - IOHDF5Util_DumpCommonAttributes (GH, vindex, timelevel, &geom[2*sdim], - request, group); - IOHDF5_ERROR (H5Gclose (group)); + HDF5_ERROR (group = H5Gcreate (file, name, 0)); + IOHDF5Util_DumpCommonAttributes (GH, slab, group); + HDF5_ERROR (H5Gclose (group)); } + dataset = -1; if (memspace >= 0) { /* now the chunk dataset for each processor is created within the group */ - chunkname = (char *) malloc (strlen (datasetname) + 20); - sprintf (chunkname, "%s/chunk%d", datasetname, proc - myproc); - IOHDF5_ERROR (plist = H5Pcreate (H5P_DATASET_CREATE)); + chunkname = (char *) malloc (strlen (name) + 20); + sprintf (chunkname, "%s/chunk%d", name, proc - myproc); + HDF5_ERROR (plist = H5Pcreate (H5P_DATASET_CREATE)); /* enable compression for chunked dataset if compression was requested */ if (compression_level) { - IOHDF5_ERROR (H5Pset_chunk (plist, sdim, chunk_dims)); - IOHDF5_ERROR (H5Pset_deflate (plist, compression_level)); - } + HDF5_ERROR (H5Pset_chunk (plist, slab->hdim, chunk_dims)); + HDF5_ERROR (H5Pset_deflate (plist, compression_level)); + } /* create the chunk dataset and dump the chunk data */ - IOHDF5_ERROR (dataset = H5Dcreate (file, chunkname, - iohdf5_type, memspace, plist)); - IOHDF5_ERROR (H5Pclose (plist)); - IOHDF5_ERROR (H5Dwrite (dataset, iohdf5_type, H5S_ALL, H5S_ALL, - H5P_DEFAULT, outme)); + HDF5_ERROR (dataset = H5Dcreate (file, chunkname, hdf5type, memspace, + plist)); + HDF5_ERROR (H5Pclose (plist)); + HDF5_ERROR (H5Dwrite (dataset, hdf5type, H5S_ALL, H5S_ALL, H5P_DEFAULT, + data)); /* add the "origin" attribute for the chunk */ - WRITE_ATTRIBUTE ("chunk_origin", geom, dataset, myGH->array_dataspace, - sdim, IOHDF5_INT); + WRITE_ATTRIBUTE ("chunk_origin", slab->hoffset, dataset, myGH, slab->hdim, + HDF5_INT); free (chunkname); } - else - { - dataset = -1; - } } /* close the dataset and the memspace */ if (dataset >= 0) { - IOHDF5_ERROR (H5Dclose (dataset)); + HDF5_ERROR (H5Dclose (dataset)); } if (memspace >= 0) { - IOHDF5_ERROR (H5Sclose (memspace)); + HDF5_ERROR (H5Sclose (memspace)); } /* free allocated resources */ - free (datasetname); - free (fullname); free (chunk_origin); free (chunk_dims); } -#ifdef CCTK_MPI -#ifdef H5_HAVE_PARALLEL +#if defined(CCTK_MPI) && defined(H5_HAVE_PARALLEL) /*@@ - @routine IOHDF5Util_collectiveDump + @routine WriteDataCollective @author Thomas Radke @date May 21 1999 @desc @@ -901,70 +652,36 @@ static void IOHDF5Util_procDump (const cGH *GH, @calls IOHDF5Util_DumpCommonAttributes @var GH - @vdesc Pointer to CCTK grid hierarchy + @vdesc pointer to CCTK grid hierarchy @vtype const cGH * @vio in @endvar - @var vindex - @vdesc global index of the variable to be dumped - @vtype int + @var slab + @vdesc reference to the I/O hyperslab description + @vtype const ioSlab * @vio in @endvar - @var timelevel - @vdesc the timelevel to store - @vtype int + @var name + @vdesc name of the dataset to write + @vtype const char * @vio in @endvar - @var request - @vdesc pointer to the IO request structure - @vtype const ioHDF5Geo_t * - @vio in - @endvar - @var outme + @var data @vdesc pointer to the chunk to dump @vtype const void * @vio in @endvar - @var geom - @vdesc bounds and sizes of the output - @vtype const CCTK_INT[3*dim] - @vio in - @vcomment geom[0*dim..1*dim-1]: lower bounds - geom[1*dim..2*dim-1]: (local) data sizes - geom[2*dim..3*dim-1]: global space - @endvar - @var hdf5io_type - @vdesc the HDF5 datatype identifier - @vtype int - @vio in - @endvar - @var check_exisiting_objects - @vdesc flag indicating if we should check for already existing objects - before these are created anew - This might happen for existing files reopened after recovery. - @vtype int - @vio in - @endvar @var file @vdesc the HDF5 file handle @vtype hid_t @vio in @endvar @@*/ -static void IOHDF5Util_collectiveDump (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *request, - const void *outme, - const CCTK_INT *geom, - int hdf5io_type, - int check_exisiting_objects, - hid_t file) +static void WriteDataCollective (const cGH *GH, const ioSlab *slab, + const char *name, const void *data, hid_t file) { int i, dim; - ioHDF5UtilGH *myGH; - hid_t dataset, memspace, filespace, plist; - char *fullname, *datasetname; + hid_t hdf5type, dataset, memspace, filespace, plist; hssize_t *chunk_origin; hsize_t *chunk_dims, *file_dims; hsize_t buffersize; @@ -977,84 +694,63 @@ static void IOHDF5Util_collectiveDump (const cGH *GH, return; } - myGH = (ioHDF5UtilGH *) CCTK_GHExtension (GH, "IOHDF5Util"); - - /* get the dimension of the variable */ - chunk_origin = (hssize_t *) malloc (request->sdim * sizeof (hssize_t)); - chunk_dims = (hsize_t *) malloc (2*request->sdim * sizeof (hsize_t)); - file_dims = chunk_dims + request->sdim; - - /* HDF5 needs it in reverse order */ - for (i = 0; i < request->sdim; i++) + /* copy the size arrays from CCTK_INT to appropriate types + note that HDF5 wants elements in reverse order */ + chunk_origin = (hssize_t *) malloc (slab->hdim * sizeof (hssize_t)); + chunk_dims = (hsize_t *) malloc (2*slab->hdim * sizeof (hsize_t)); + file_dims = chunk_dims + slab->hdim; + for (i = 0; i < slab->hdim; i++) { - chunk_origin[i] = geom[1*request->sdim - 1 - i]; - chunk_dims [i] = geom[2*request->sdim - 1 - i]; - file_dims [i] = geom[3*request->sdim - 1 - i]; + chunk_origin[i] = slab->hoffset[slab->hdim - 1 - i]; + chunk_dims [i] = slab->hsize_chunk[slab->hdim - 1 - i]; + file_dims [i] = slab->hsize_global[slab->hdim - 1 - i]; } - /* build the unique dataset name */ - fullname = CCTK_FullName (vindex); - datasetname = (char *) malloc (strlen (fullname) + 80); - sprintf (datasetname, "%s timelevel %d at iteration %d", - fullname, timelevel, GH->cctk_iteration); - /* create the memspace according to chunk dims */ - IOHDF5_ERROR (memspace = H5Screate_simple (request->sdim, chunk_dims, NULL)); + HDF5_ERROR (memspace = H5Screate_simple (slab->hdim, chunk_dims, NULL)); /* create the (global) filespace and set the hyperslab for the chunk */ - IOHDF5_ERROR (filespace = H5Screate_simple (request->sdim, file_dims, NULL)); - IOHDF5_ERROR (H5Sselect_hyperslab (filespace, H5S_SELECT_SET, - chunk_origin, NULL, chunk_dims, NULL)); + HDF5_ERROR (filespace = H5Screate_simple (slab->hdim, file_dims, NULL)); + HDF5_ERROR (H5Sselect_hyperslab (filespace, H5S_SELECT_SET, chunk_origin, + NULL, chunk_dims, NULL)); - /* the IO processor creates the dataset and adds the common attributes + /* the I/O processor creates the dataset and adds the common attributes when writing its own data, otherwise the dataset is reopened */ - /* if restart from recovery delete an already existing group - so that it can be created as anew */ - if (check_exisiting_objects) - { - IOHDF5_ERROR (H5Eset_auto (NULL, NULL)); - H5Gunlink (file, datasetname); - IOHDF5_ERROR (H5Eset_auto (myGH->print_error_fn, myGH->print_error_fn_arg)); - } + hdf5type = IOHDF5Util_DataType (myGH, slab->hdatatype); + /* enable compression for chunked dataset if compression was requested */ - IOHDF5_ERROR (plist = H5Pcreate (H5P_DATASET_CREATE)); + HDF5_ERROR (plist = H5Pcreate (H5P_DATASET_CREATE)); if (compression_level) { - IOHDF5_ERROR (H5Pset_chunk (plist, request->sdim, chunk_dims)); - IOHDF5_ERROR (H5Pset_deflate (plist, compression_level)); + HDF5_ERROR (H5Pset_chunk (plist, slab->hdim, chunk_dims)); + HDF5_ERROR (H5Pset_deflate (plist, compression_level)); } - IOHDF5_ERROR (dataset = H5Dcreate (file, datasetname, hdf5io_type, filespace, - plist)); - IOHDF5_ERROR (H5Pclose (plist)); + HDF5_ERROR (dataset = H5Dcreate (file, name, hdf5type, filespace, plist)); + HDF5_ERROR (H5Pclose (plist)); if (CCTK_MyProc (GH) == 0) { - IOHDF5Util_DumpCommonAttributes (GH, vindex, timelevel, - &geom[2*request->sdim], request, dataset); + IOHDF5Util_DumpCommonAttributes (GH, slab, dataset); } /* increase the buffer size if the default isn't sufficient */ - IOHDF5_ERROR (plist = H5Pcreate (H5P_DATASET_XFER)); + HDF5_ERROR (plist = H5Pcreate (H5P_DATASET_XFER)); buffersize = H5Dget_storage_size (dataset); if (buffersize > H5Pget_buffer (plist, NULL, NULL)) { - IOHDF5_ERROR (H5Pset_buffer (plist, buffersize, NULL, NULL)); + HDF5_ERROR (H5Pset_buffer (plist, buffersize, NULL, NULL)); } /* write the data */ - IOHDF5_ERROR (H5Dwrite (dataset, hdf5io_type, memspace, filespace, plist, - outme)); + HDF5_ERROR (H5Dwrite (dataset, hdf5type, memspace, filespace, plist, data)); /* close resources */ - IOHDF5_ERROR (H5Pclose (plist)); - IOHDF5_ERROR (H5Sclose (filespace)); - IOHDF5_ERROR (H5Dclose (dataset)); - IOHDF5_ERROR (H5Sclose (memspace)); + HDF5_ERROR (H5Pclose (plist)); + HDF5_ERROR (H5Sclose (filespace)); + HDF5_ERROR (H5Dclose (dataset)); + HDF5_ERROR (H5Sclose (memspace)); /* free allocated resources */ - free (datasetname); - free (fullname); free (chunk_origin); free (chunk_dims); } -#endif /* H5_HAVE_PARALLEL */ -#endif /* MPI */ +#endif /* CCTK_MPI && H5_HAVE_PARALLEL */ diff --git a/src/ParseVars.c b/src/ParseVars.c index fb70525..de99c3e 100644 --- a/src/ParseVars.c +++ b/src/ParseVars.c @@ -10,12 +10,12 @@ #include <stdlib.h> #include <string.h> -#include <stdio.h> #include "cctk.h" #include "util_String.h" #include "cctk_Parameters.h" #include "cctk_GNU.h" +#include "CactusBase/IOUtil/src/ioGH.h" #include "ioHDF5UtilGH.h" @@ -24,13 +24,15 @@ static const char *rcsid = "$Id$"; CCTK_FILEVERSION(BetaThorns_IOHDF5Util_ParseVars_c) +typedef struct +{ + const cGH *GH; + ioSlab **slablist; +} info_t; + /* prototypes of routines defined in this source file */ -void IOHDF5Util_ParseVarsForOutput (const char *output_varstring, - ioHDF5Geo_t *output_request_list[]); -static void IOHDF5Util_ParseOutputRequest (int vindex, - const char *optstring, - void *arg); -static ioHDF5Geo_t *IOHDF5Util_DefaultIORequest (int vindex); +static void SetOutputVar (int vindex, const char *optstring, void *arg); +static ioSlab *DefaultIOHyperslab (const cGH *GH, int vindex); /* prototypes of external routines for which no header files exist */ int CCTK_RegexMatch (const char *string, @@ -54,9 +56,8 @@ int CCTK_RegexMatch (const char *string, special keyword "all" which indicates that output is requested on all variables. @enddesc - @history - @endhistory - @var var_list + + @var out_vars @vdesc list of variables and/or group names @vtype const char * @vio in @@ -67,50 +68,50 @@ int CCTK_RegexMatch (const char *string, @vio out @endvar @@*/ - -void IOHDF5Util_ParseVarsForOutput (const char *output_varstring, - ioHDF5Geo_t *output_request_list[]) +void IOHDF5Util_ParseVarsForOutput (const cGH *GH, const char *out_vars, + ioSlab *slablist[]) { int i; + info_t info; - /* free current list of output requests */ + /* free current list of hyperslabs */ for (i = CCTK_NumVars () - 1; i >= 0; i--) { - if (output_request_list[i]) + if (slablist[i]) { - free (output_request_list[i]->origin); - free (output_request_list[i]); - output_request_list[i] = NULL; + free (slablist[i]->vectors); + free (slablist[i]); + slablist[i] = NULL; } } - /* generate new list of output requests */ - CCTK_TraverseString (output_varstring, IOHDF5Util_ParseOutputRequest, - output_request_list, CCTK_GROUP_OR_VAR); + /* generate new list of hyperslabs */ + info.GH = GH; + info.slablist = slablist; + CCTK_TraverseString (out_vars, SetOutputVar, &info, CCTK_GROUP_OR_VAR); } -static void IOHDF5Util_ParseOutputRequest (int vindex, - const char *optstring, - void *arg) +static void SetOutputVar (int vindex, const char *optstring, void *arg) { + info_t *info; regmatch_t gmatch[6], *dmatch; int i, j, bytes, matched; char *token, *separator, *fullname; char *substring, *parsestring, *regexstring; - ioHDF5Geo_t **output_requests, *new_request; + ioSlab *slab; DECLARE_CCTK_PARAMETERS - output_requests = (ioHDF5Geo_t **) arg; + info = (info_t *) arg; - /* allocate a new IO request structure and initialize it with defaults */ - new_request = IOHDF5Util_DefaultIORequest (vindex); + /* allocate a new I/O hyperslab structure and initialize it with defaults */ + slab = DefaultIOHyperslab (info->GH, vindex); if (! optstring) { - output_requests[vindex] = new_request; + info->slablist[vindex] = slab; return; } @@ -119,7 +120,7 @@ static void IOHDF5Util_ParseOutputRequest (int vindex, "\\{([0-9]*)\\}" /* dimension */ "\\{([0-9,()]+)*\\}" /* direction */ "\\{([0-9,]+)*\\}" /* origin */ - "\\{([-0-9,]+)*\\}" /* length */ + "\\{([-0-9,]+)*\\}" /* extent */ "\\{([0-9,]+)*\\}", /* downsample */ 6, gmatch); if (matched <= 0) @@ -129,7 +130,7 @@ static void IOHDF5Util_ParseOutputRequest (int vindex, "Couldn't parse hyperslab options '%s' for variable '%s'", optstring, fullname); free (fullname); - free (new_request); + free (slab); return; } @@ -137,15 +138,15 @@ static void IOHDF5Util_ParseOutputRequest (int vindex, bytes = (int) (gmatch[1].rm_eo - gmatch[1].rm_so); if (gmatch[1].rm_so != -1 && bytes > 0) { - new_request->sdim = atoi (optstring + gmatch[1].rm_so); - if (new_request->sdim <= 0 || new_request->sdim > new_request->vdim) + slab->hdim = atoi (optstring + gmatch[1].rm_so); + if (slab->hdim <= 0 || slab->hdim > slab->vdim) { fullname = CCTK_FullName (vindex); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Invalid dimension given %d in hyperslab options '%s' " - "for variable '%s'", new_request->sdim, optstring, fullname); + "for variable '%s'", slab->hdim, optstring, fullname); free (fullname); - free (new_request); + free (slab); return; } } @@ -157,15 +158,15 @@ static void IOHDF5Util_ParseOutputRequest (int vindex, substring = strdup (optstring + gmatch[2].rm_so); substring[bytes] = 0; - dmatch = (regmatch_t *) malloc ((new_request->sdim + 1) * + dmatch = (regmatch_t *) malloc ((slab->hdim + 1) * sizeof (regmatch_t)); - regexstring = (char *) malloc (new_request->sdim * sizeof ("\\(([0-9,]+)\\)")); + regexstring = (char *) malloc (slab->hdim * sizeof ("\\(([0-9,]+)\\)")); regexstring[0] = 0; - for (i = 0; i < new_request->sdim; i++) + for (i = 0; i < slab->hdim; i++) { strcat (regexstring, "\\(([0-9,]+)\\)"); } - matched = CCTK_RegexMatch (substring, regexstring, new_request->sdim + 1, + matched = CCTK_RegexMatch (substring, regexstring, slab->hdim + 1, dmatch); free (regexstring); if (matched <= 0) @@ -176,11 +177,11 @@ static void IOHDF5Util_ParseOutputRequest (int vindex, "for variable '%s'.", optstring, fullname); free (fullname); free (dmatch); - free (new_request); + free (slab); return; } - for (j = 0; j < new_request->sdim; j++) + for (j = 0; j < slab->hdim; j++) { i = 0; bytes = (int) (dmatch[j + 1].rm_eo - dmatch[j + 1].rm_so); @@ -193,25 +194,25 @@ static void IOHDF5Util_ParseOutputRequest (int vindex, while ((separator = strchr (token, ',')) != NULL) { *separator = 0; - new_request->direction[j * new_request->vdim + i] = atoi (token); - if (++i >= new_request->vdim) + slab->direction[j * slab->vdim + i] = atoi (token); + if (++i >= slab->vdim) { break; } token = separator + 1; } - new_request->direction[j * new_request->vdim + i++] = atoi (token); + slab->direction[j * slab->vdim + i++] = atoi (token); free (parsestring); } free (substring); - if (i < new_request->vdim) + if (i < slab->vdim) { fullname = CCTK_FullName (vindex); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Direction vectors are incomplete or missing in hyperslab " "options '%s' for variable '%s'.", optstring, fullname); free (fullname); - free (new_request); + free (slab); return; } } @@ -229,24 +230,24 @@ static void IOHDF5Util_ParseOutputRequest (int vindex, while ((separator = strchr (token, ',')) != NULL) { *separator = 0; - new_request->origin[i] = atoi (token); - if (++i >= new_request->vdim) + slab->origin[i] = atoi (token); + if (++i >= slab->vdim) { break; } token = separator + 1; } - new_request->origin[i++] = atoi (token); + slab->origin[i++] = atoi (token); free (substring); - if (i < new_request->vdim) + if (i < slab->vdim) { fullname = CCTK_FullName (vindex); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Origin vector is incomplete or missing in hyperslab " "options '%s' for variable '%s'.", optstring, fullname); free (fullname); - free (new_request); + free (slab); return; } } @@ -263,24 +264,24 @@ static void IOHDF5Util_ParseOutputRequest (int vindex, while ((separator = strchr (token, ',')) != NULL) { *separator = 0; - new_request->length[i] = atoi (token); - if (++i >= new_request->sdim) + slab->extent[i] = atoi (token); + if (++i >= slab->hdim) { break; } token = separator + 1; } - new_request->length[i++] = atoi (token); + slab->extent[i++] = atoi (token); free (substring); - if (i < new_request->sdim) + if (i < slab->hdim) { fullname = CCTK_FullName (vindex); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Length vector is incomplete or missing in hyperslab " "options '%s' for variable '%s'.", optstring, fullname); free (fullname); - free (new_request); + free (slab); return; } } @@ -297,134 +298,114 @@ static void IOHDF5Util_ParseOutputRequest (int vindex, while ((separator = strchr (token, ',')) != NULL) { *separator = 0; - new_request->downsample[i] = atoi (token); - if (++i >= new_request->sdim) + slab->downsample[i] = atoi (token); + if (++i >= slab->hdim) { break; } token = separator + 1; } - new_request->downsample[i++] = atoi (token); + slab->downsample[i++] = atoi (token); free (substring); - if (i < new_request->sdim) + if (i < slab->hdim) { fullname = CCTK_FullName (vindex); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Downsampling vector is incomplete or missing in hyperslab " "options '%s' for variable '%s'.", optstring, fullname); free (fullname); - free (new_request); + free (slab); return; } } - /* assign the output request */ - output_requests[vindex] = new_request; - - -#ifdef IOHDF5UTIL_DEBUG - printf("Geometry Data: \n"); - printf(" Argument/Slab dimension: %d / %d \n", new_request->vdim,new_request->sdim); - printf(" Origin: "); - for (i=0;i<new_request->vdim;i++) - printf("%s %d ", new_request->origin[i]); - printf("\n Downs : "); - for (i=0;i<new_request->sdim;i++) - printf(" %d ", new_request->downsample[i]); - printf("\n Length: "); - for (i=0;i<new_request->sdim;i++) - printf(" %d ", new_request->length[i]); - printf("\n Dirs : "); - for (i=0;i<new_request->sdim;i++) - printf(" %d ", new_request->direction[i]); - printf("\n\n"); -#endif + /* assign the new hyperslab */ + info->slablist[vindex] = slab; } -static ioHDF5Geo_t *IOHDF5Util_DefaultIORequest (int vindex) +static ioSlab *DefaultIOHyperslab (const cGH *GH, int vindex) { + ioSlab *slab; + int *extent_int; + const ioGH *ioUtilGH; DECLARE_CCTK_PARAMETERS - int i; - ioHDF5Geo_t *request; -#if 0 - const char *argument, *token; -#endif - /* allocate a new IO request structure */ - request = (ioHDF5Geo_t *) malloc (sizeof (ioHDF5Geo_t)); + ioUtilGH = (const ioGH *) CCTK_GHExtension (GH, "IO"); - /* get the variable's dimension - set it also to be the default hyperslab dimension */ - request->vdim = request->sdim = CCTK_GroupDimFromVarI (vindex); + /* allocate a new I/O hyperslab structure */ + slab = (ioSlab *) malloc (sizeof (ioSlab)); - request->origin = (int *) calloc (4 + request->sdim, - request->vdim * sizeof (int)); - request->length = request->origin + 1 * request->vdim; - request->downsample = request->origin + 2 * request->vdim; - request->actlen = request->origin + 3 * request->vdim; - request->direction = request->origin + 4 * request->vdim; + /* fill out the basics */ + slab->vindex = vindex; + slab->timelevel = 0; + slab->check_exist = ioUtilGH->recovered; - for (i = 0; i < request->vdim; i++) + /* get the hyperslab datatype (will be single-precision if requested) */ + slab->hdatatype = CCTK_VarTypeI (vindex); + if (ioUtilGH->out_single) { - request->length[i] = -1; - request->direction[i * request->vdim + i] = 1; + if (slab->hdatatype == CCTK_VARIABLE_REAL) + { + slab->hdatatype = CCTK_VARIABLE_REAL4; + } + else if (slab->hdatatype == CCTK_VARIABLE_COMPLEX) + { + slab->hdatatype = CCTK_VARIABLE_COMPLEX8; + } +#ifdef CCTK_INT2 + else if (slab->hdatatype == CCTK_VARIABLE_INT) + { + slab->hdatatype = CCTK_VARIABLE_INT2; + } +#endif + } + + /* get the variable's dimension and extents */ + slab->vdim = CCTK_GroupDimFromVarI (vindex); + extent_int = (int *) malloc (slab->vdim * sizeof (int)); + CCTK_GroupgshVI (GH, slab->vdim, extent_int, vindex); + + /* allocate the arrays all in one go + only initialize those which are mandatory for the Hyperslab API */ + slab->vectors = (CCTK_INT *) calloc (slab->vdim + 6, + slab->vdim * sizeof (CCTK_INT)); + slab->hoffset = slab->vectors + 0*slab->vdim; + slab->hsize = slab->vectors + 1*slab->vdim; + slab->hsize_chunk = slab->vectors + 2*slab->vdim; + slab->origin = slab->vectors + 3*slab->vdim; + slab->extent = slab->vectors + 4*slab->vdim; + slab->downsample = slab->vectors + 5*slab->vdim; + slab->direction = slab->vectors + 6*slab->vdim; + + for (slab->hdim = 0; slab->hdim < slab->vdim; slab->hdim++) + { + slab->extent[slab->hdim] = extent_int[slab->hdim]; + slab->direction[slab->hdim] = slab->hdim * (slab->vdim + 1); /* take the downsampling parameters from IOUtil */ - if (i == 0) + if (slab->hdim == 0) { - request->downsample[i] = out3D_downsample_x; + slab->downsample[slab->hdim] = out3D_downsample_x; } - else if (i == 1) + else if (slab->hdim == 1) { - request->downsample[i] = out3D_downsample_y; + slab->downsample[slab->hdim] = out3D_downsample_y; } - else if (i == 2) + else if (slab->hdim == 2) { - request->downsample[i] = out3D_downsample_z; + slab->downsample[slab->hdim] = out3D_downsample_z; } else { - request->downsample[i] = 1; + slab->downsample[slab->hdim] = 1; } } -#if 0 - FIXME: parse default hyperslab parameters - /* Origin */ - i=0; - argument = origin; - while((token = Util_StrSep(&argument,","))) { - request->origin[i++]=atoi(token); - } - request->downsample[i] = atoi(argument); - - /* Direction */ - i=0; - argument = direction; - while((token = Util_StrSep(&argument,","))) { - request->direction[i++]=atoi(token); - } - request->downsample[i] = atoi(argument); - - /* Downsample */ - i=0; - argument = downsampling; - while((token = Util_StrSep(&argument,","))) { - request->downsample[i++]=atoi(token); - } - request->downsample[i] = atoi(argument); - - /* Length */ - i=0; - argument = length; - while((token = Util_StrSep(&argument,","))) { - request->length[i++]=atoi(token); - } - request->length[i] = atoi(argument); -#endif + /* clean up */ + free (extent_int); - return (request); + return (slab); } diff --git a/src/RecoverVar.c b/src/RecoverVar.c index 852a78e..95d9835 100644 --- a/src/RecoverVar.c +++ b/src/RecoverVar.c @@ -20,15 +20,21 @@ #include "CactusPUGH/PUGH/src/include/pugh.h" #include "ioHDF5UtilGH.h" - /* the rcs ID and its dummy function to use it */ static const char *rcsid = "$Id$"; CCTK_FILEVERSION(BetaThorns_IOHDF5Util_RecoverVar_c) -/* MPI tag base */ -#define STARTUPBASE 1001 + +/******************************************************************** + ******************** Macro Definitions ************************ + ********************************************************************/ +/* tag base for MPI messages */ +#define MPITAGBASE 1001 +/******************************************************************** + ******************** Internal Typedefs ************************ + ********************************************************************/ typedef struct { cGH *GH; @@ -42,47 +48,53 @@ typedef struct { iterate_info_t *it_info; int element_size; - int iohdf5_type; + int hdf5type; #ifdef CCTK_MPI MPI_Datatype mpi_type; #endif } recover_info_t; -/* local function prototypes */ -static herr_t processDataset (hid_t group, - const char *datasetname, - void *arg); +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ +static herr_t processDataset (hid_t group, const char *datasetname, void *arg); /*@@ - @routine IOHDF5Util_RecoverVariables - @date Fri Jun 19 09:19:48 1998 - @author Tom Goodale - @desc - Reads in data from an open HDF5 file. - @enddesc - @var GH - @vdesc Pointer to CCTK grid hierarchy - @vtype cGH * - @vio in - @endvar - @var fileinfo - @vdesc pointer to info structure describing the HDF5 file - @vtype const fileinfo_t * - @vio in - @endvar + @routine IOHDF5Util_RecoverVariables + @date Fri Jun 19 09:19:48 1998 + @author Tom Goodale + @desc + Reads in data from an open HDF5 file. + @enddesc + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH * + @vio in + @endvar + @var fileinfo + @vdesc pointer to info structure describing the HDF5 file + @vtype const fileinfo_t * + @vio in + @endvar + + @returntype int + @returndesc + 0 for success + @endreturndesc @@*/ -int IOHDF5Util_RecoverVariables (cGH *GH, - const fileinfo_t *fileinfo) +int IOHDF5Util_RecoverVariables (cGH *GH, const fileinfo_t *fileinfo) { - DECLARE_CCTK_PARAMETERS + iterate_info_t info; #ifdef CCTK_MPI - pGH *pughGH; /* PUGH extension handle */ - int proc; /* looper */ - CCTK_INT var_info[3]; /* communication buffer for MPI */ + pGH *pughGH; + CCTK_INT var_info[3]; + MPI_Status ms; + MPI_Datatype mpi_type; + int vindex, timelevel, proc, npoints; #endif - iterate_info_t info; /* info to pass down to the iterator routine */ + DECLARE_CCTK_PARAMETERS info.GH = GH; @@ -92,12 +104,11 @@ int IOHDF5Util_RecoverVariables (cGH *GH, info.has_version = fileinfo->has_version; #ifdef CCTK_MPI - /* Get the handle for PUGH extensions */ pughGH = PUGH_pGH (GH); - /* Now process the datasets. + /* now process the datasets: All IO processors read the datasets from their checkpoint file, - verify their contents and communicate them to the non-IO processors. */ + verify their contents and communicate them to the non-I/O processors. */ /* At first the code for the IO processors. This holds also for the single processor case. */ @@ -106,7 +117,7 @@ int IOHDF5Util_RecoverVariables (cGH *GH, #endif /* CCTK_MPI */ /* iterate over all datasets starting from "/" in the HDF5 file */ - IOHDF5_ERROR (H5Giterate (fileinfo->file, "/", NULL, processDataset,&info)); + HDF5_ERROR (H5Giterate (fileinfo->file, "/", NULL, processDataset, &info)); #ifdef CCTK_MPI /* To signal completion to the non-IO processors @@ -119,28 +130,23 @@ int IOHDF5Util_RecoverVariables (cGH *GH, proc++) { CACTUS_MPI_ERROR (MPI_Send (var_info, 3, PUGH_MPI_INT, proc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD)); + MPITAGBASE, pughGH->PUGH_COMM_WORLD)); } } else { - - /* And here the code for non-IO processors: */ - MPI_Datatype mpi_type; - MPI_Status ms; - int vindex, timelevel, npoints; - - /* They don't know how many datasets there are, because the IO processors + /* And here the code for non-I/O processors: */ + /* They don't know how many datasets there are, because the I/O processors could skip some on the fly during their consistency checks. - The IO Processor sends the index of the variable to be processed next. - So, all non-IO processors execute a loop where the termination condition + The I/O Processor sends the index of the variable to be processed next. + So, all non-I/O processors execute a loop where the termination condition is when an invalid index was received. */ while (1) { /* receive the next variable index from my IO processor */ CACTUS_MPI_ERROR (MPI_Recv (var_info, 3, PUGH_MPI_INT, fileinfo->ioproc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD, &ms)); + MPITAGBASE, pughGH->PUGH_COMM_WORLD, &ms)); vindex = var_info[0]; timelevel = var_info[1]; npoints = var_info[2]; /* check for termination condition */ @@ -159,7 +165,7 @@ int IOHDF5Util_RecoverVariables (cGH *GH, /* receive following data from my IO processor */ CACTUS_MPI_ERROR (MPI_Recv (GH->data[vindex][timelevel], npoints, - mpi_type, fileinfo->ioproc, STARTUPBASE, + mpi_type, fileinfo->ioproc, MPITAGBASE, pughGH->PUGH_COMM_WORLD, &ms)); } } @@ -172,10 +178,9 @@ int IOHDF5Util_RecoverVariables (cGH *GH, /* NOTE: Although we could read the GH extensions from multiple recovery files in parallel, this is done only on by processor 0 here. Broadcasting the GH extensions is found faster than - sending it in a loop from each IO processor to all the non IOs + sending it in a loop from each I/O processor to all the non I/Os (don't have subcommunicators yet) */ -int IOHDF5Util_RecoverGHextensions (cGH *GH, - const fileinfo_t *fileinfo) +int IOHDF5Util_RecoverGHextensions (cGH *GH, const fileinfo_t *fileinfo) { hid_t group; CCTK_REAL4 real4Buffer; @@ -191,13 +196,11 @@ int IOHDF5Util_RecoverGHextensions (cGH *GH, if (int4Buffer[0]) { + READ_ATTRIBUTE (group, "cctk_iteration", HDF5_INT4, &int4Buffer[1]); + READ_ATTRIBUTE (group, "main_loop_index", HDF5_INT4, &int4Buffer[2]); + READ_ATTRIBUTE (group, "cctk_time", HDF5_REAL4, &real4Buffer); - READ_ATTRIBUTE (group, "cctk_iteration", IOHDF5_INT4, &int4Buffer[1]); - READ_ATTRIBUTE (group, "main_loop_index", IOHDF5_INT4, &int4Buffer[2]); - READ_ATTRIBUTE (group, "cctk_time", IOHDF5_REAL4, &real4Buffer); - - IOHDF5_ERROR (H5Gclose (group)); - + HDF5_ERROR (H5Gclose (group)); } else { @@ -226,7 +229,7 @@ int IOHDF5Util_RecoverGHextensions (cGH *GH, CCTK_SetMainLoopIndex ((int) int4Buffer[2]); } - /* Return 0 for success otherwise negative */ + /* return 0 for success otherwise negative */ return (int4Buffer[0] ? 0 : -1); } @@ -238,19 +241,18 @@ int IOHDF5Util_RecoverGHextensions (cGH *GH, (don't have subcommunicators yet) */ int IOHDF5Util_RecoverParameters (const fileinfo_t *fileinfo) { - DECLARE_CCTK_PARAMETERS hid_t group, attr, atype; char *parameters; CCTK_INT4 parameterSize; - cGH *GH = NULL; /* There's no cGH set up yet so we pass - a NULL pointer to CCTK_MyProc() */ + DECLARE_CCTK_PARAMETERS + /* To make the compiler happy */ group = attr = 0; parameters = NULL; parameterSize = 0; - if (CCTK_MyProc (GH) == 0) + if (CCTK_MyProc (NULL) == 0) { if (verbose) { @@ -268,12 +270,12 @@ int IOHDF5Util_RecoverParameters (const fileinfo_t *fileinfo) if (group > 0 && attr > 0) { - IOHDF5_ERROR (atype = H5Aget_type (attr)); + HDF5_ERROR (atype = H5Aget_type (attr)); parameterSize = H5Tget_size (atype); parameters = (char *) malloc (parameterSize + 1); - IOHDF5_ERROR (H5Aread (attr, atype, parameters)); + HDF5_ERROR (H5Aread (attr, atype, parameters)); parameters[parameterSize] = 0; - IOHDF5_ERROR (H5Tclose (atype)); + HDF5_ERROR (H5Tclose (atype)); } else { @@ -283,11 +285,11 @@ int IOHDF5Util_RecoverParameters (const fileinfo_t *fileinfo) if (attr > 0) { - IOHDF5_ERROR (H5Aclose (attr)); + HDF5_ERROR (H5Aclose (attr)); } if (group > 0) { - IOHDF5_ERROR (H5Gclose (group)); + HDF5_ERROR (H5Gclose (group)); } } @@ -303,7 +305,7 @@ int IOHDF5Util_RecoverParameters (const fileinfo_t *fileinfo) if (parameterSize > 0) { #ifdef CCTK_MPI - if (CCTK_MyProc (GH) != 0) + if (CCTK_MyProc (NULL) != 0) { parameters = (char *) malloc (parameterSize + 1); } @@ -317,14 +319,14 @@ int IOHDF5Util_RecoverParameters (const fileinfo_t *fileinfo) free (parameters); } - /* Return positive value for success otherwise negative */ + /* return positive value for success otherwise negative */ return (parameterSize > 0 ? 1 : -1); } -/************************************************************************/ -/* local routines */ -/************************************************************************/ +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ /* local routine GetCommonAttributes() reads in the next dataset's attributes and verifies them: @@ -341,7 +343,6 @@ int IOHDF5Util_RecoverParameters (const fileinfo_t *fileinfo) If successful, the global variable index, the group type and the timelevel to restore are stored in {*vindex, *gtype, *timelevel}, and 0 is returned. */ - static int GetCommonAttributes (cGH *GH, hid_t dataset, const char *datasetname, @@ -426,9 +427,9 @@ static int GetCommonAttributes (cGH *GH, if the dataset is a chunk group */ if (is_group) { - IOHDF5_ERROR (dataset = H5Dopen (dataset, "chunk0")); + HDF5_ERROR (dataset = H5Dopen (dataset, "chunk0")); } - IOHDF5_ERROR (datatype = H5Dget_type (dataset)); + HDF5_ERROR (datatype = H5Dget_type (dataset)); /* The CCTK variable type defines do not correlate with the HDF5 defines so compare them explicitely here. */ @@ -444,7 +445,7 @@ static int GetCommonAttributes (cGH *GH, strncmp (CCTK_VarTypeName (group_static_data.vartype), "CCTK_VARIABLE_COMPLEX", 21) == 0); - IOHDF5_ERROR (H5Tclose (datatype)); + HDF5_ERROR (H5Tclose (datatype)); if (! flag) { CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, @@ -453,44 +454,36 @@ static int GetCommonAttributes (cGH *GH, } /* verify the dims and sizes */ - IOHDF5_ERROR (dataspace = H5Dget_space (dataset)); - IOHDF5_ERROR (ndims_stored = H5Sget_simple_extent_ndims (dataspace)); + HDF5_ERROR (dataspace = H5Dget_space (dataset)); + HDF5_ERROR (ndims_stored = H5Sget_simple_extent_ndims (dataspace)); dims_stored = (hsize_t *) malloc (ndims_stored * sizeof (hsize_t)); - IOHDF5_ERROR (rank_stored = H5Sget_simple_extent_dims (dataspace, + HDF5_ERROR (rank_stored = H5Sget_simple_extent_dims (dataspace, dims_stored, NULL)); /* scalars are stored as rank 0 in HDF5 but have rank 1 in Cactus */ if (rank_stored == 0) { rank_stored = 1; } - IOHDF5_ERROR (H5Sclose (dataspace)); + HDF5_ERROR (H5Sclose (dataspace)); - flag = 0; - if (group_static_data.dim != (int) rank_stored) - { - flag = 1; - } - switch (group_static_data.grouptype) + flag = group_static_data.dim != (int) rank_stored; + if (group_static_data.grouptype == CCTK_ARRAY || + group_static_data.grouptype == CCTK_GF) { - case CCTK_SCALAR: - break; - case CCTK_ARRAY: - case CCTK_GF: - if (CCTK_GroupDynamicData (GH, groupindex, &group_dynamic_data) != 0) - { - CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, - "Cannot get dynamic group data for '%s'", fullvarname); - return (-1); - } - dims = unchunked ? group_dynamic_data.gsh : group_dynamic_data.lsh; - for (i = 0; i < group_static_data.dim; i++) + if (CCTK_GroupDynamicData (GH, groupindex, &group_dynamic_data) != 0) + { + CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, + "Cannot get dynamic group data for '%s'", fullvarname); + return (-1); + } + dims = unchunked ? group_dynamic_data.gsh : group_dynamic_data.lsh; + for (i = 0; i < group_static_data.dim; i++) + { + if (dims[group_static_data.dim - i - 1] != (int) dims_stored[i]) { - if (dims[group_static_data.dim - i - 1] != (int) dims_stored[i]) - { - flag = 1; - } + flag = 1; } - break; + } } free (dims_stored); @@ -511,7 +504,7 @@ static int GetCommonAttributes (cGH *GH, /* close the first chunk if the dataset is a chunk group */ if (is_group) { - IOHDF5_ERROR (H5Dclose (dataset)); + HDF5_ERROR (H5Dclose (dataset)); } *grouptype = group_static_data.grouptype; @@ -520,30 +513,27 @@ static int GetCommonAttributes (cGH *GH, } -static int IOHDF5Util_RestoreGS (hid_t dataset, - int vindex, - int timelevel, +static int IOHDF5Util_RestoreGS (hid_t dataset, int vindex, int timelevel, recover_info_t *rec_info) { void *data; #ifdef CCTK_MPI int proc; CCTK_INT var_info[3]; - pGH *pughGH; + MPI_Comm comm; #endif data = CCTK_VarDataPtrI (rec_info->it_info->GH, timelevel, vindex); /* read the data into the local variable ... */ - IOHDF5_ERROR (H5Dread (dataset, rec_info->iohdf5_type, H5S_ALL, H5S_ALL, - H5P_DEFAULT, data)); + HDF5_ERROR (H5Dread (dataset, rec_info->hdf5type, H5S_ALL, H5S_ALL, + H5P_DEFAULT, data)); #ifdef CCTK_MPI /* ... and communicate it for the MPI case */ - /* Get the handle for PUGH extensions */ - pughGH = PUGH_pGH (rec_info->it_info->GH); + comm = PUGH_pGH (rec_info->it_info->GH)->PUGH_COMM_WORLD; /* set the variable's index and the timelevel */ var_info[0] = vindex; var_info[1] = timelevel; var_info[2] = 1; @@ -554,10 +544,10 @@ static int IOHDF5Util_RestoreGS (hid_t dataset, proc < CCTK_nProcs (rec_info->it_info->GH); proc++) { - CACTUS_MPI_ERROR (MPI_Send (var_info, 3, PUGH_MPI_INT, proc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD)); - CACTUS_MPI_ERROR (MPI_Send (data, 1, rec_info->mpi_type, proc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD)); + CACTUS_MPI_ERROR (MPI_Send (var_info, 3, PUGH_MPI_INT, proc, MPITAGBASE, + comm)); + CACTUS_MPI_ERROR (MPI_Send (data, 1, rec_info->mpi_type, proc, MPITAGBASE, + comm)); } #endif /* CCTK_MPI */ @@ -565,26 +555,28 @@ static int IOHDF5Util_RestoreGS (hid_t dataset, } -static int IOHDF5Util_RestoreGA (hid_t dataset, - int vindex, - int timelevel, +static int IOHDF5Util_RestoreGA (hid_t dataset, int vindex, int timelevel, recover_info_t *rec_info) { #ifdef CCTK_MPI - int proc, npoints; + int i, dim, proc, npoints; CCTK_INT var_info[3]; pGH *pughGH; void *buffer, *data; - hid_t filespace, memspace; + hid_t filespace, memspace, chunk; pGExtras *extras; + char chunkname[32]; + hssize_t *chunk_origin; + hsize_t *chunk_dims; #endif /* single processor case is easy: just read the whole dataset */ if (CCTK_nProcs (rec_info->it_info->GH) == 1) { - IOHDF5_ERROR (H5Dread (dataset, rec_info->iohdf5_type, H5S_ALL, - H5S_ALL, H5P_DEFAULT, rec_info->it_info->GH->data[vindex][timelevel])); + HDF5_ERROR (H5Dread (dataset, rec_info->hdf5type, H5S_ALL, H5S_ALL, + H5P_DEFAULT, + rec_info->it_info->GH->data[vindex][timelevel])); return (0); } @@ -628,24 +620,17 @@ static int IOHDF5Util_RestoreGA (hid_t dataset, if (! rec_info->it_info->unchunked) { - hid_t chunk; - char chunkname[32]; - /* Chunked data is stored as separate chunk datasets within a group. So open, read and close the separate chunks here. */ sprintf (chunkname, "chunk%d", proc - rec_info->it_info->ioproc); - IOHDF5_ERROR (chunk = H5Dopen (dataset, chunkname)); - IOHDF5_ERROR (H5Dread (chunk, rec_info->iohdf5_type, H5S_ALL, - H5S_ALL, H5P_DEFAULT, data)); - IOHDF5_ERROR (H5Dclose (chunk)); + HDF5_ERROR (chunk = H5Dopen (dataset, chunkname)); + HDF5_ERROR (H5Dread (chunk, rec_info->hdf5type, H5S_ALL, H5S_ALL, + H5P_DEFAULT, data)); + HDF5_ERROR (H5Dclose (chunk)); } else { - int i, dim; - hssize_t *chunk_origin; - hsize_t *chunk_dims; - /* get the dimension of the variable */ dim = CCTK_GroupDimI (CCTK_GroupIndexFromVarI (vindex)); chunk_origin = (hssize_t *) malloc (dim * sizeof (hssize_t)); @@ -659,16 +644,16 @@ static int IOHDF5Util_RestoreGA (hid_t dataset, chunk_origin[dim - 1 - i] = extras->lb[proc][i]; } - IOHDF5_ERROR (filespace = H5Dget_space (dataset)); - IOHDF5_ERROR (memspace = H5Screate_simple (dim, chunk_dims, NULL)); - IOHDF5_ERROR (H5Sselect_hyperslab (filespace, H5S_SELECT_SET, + HDF5_ERROR (filespace = H5Dget_space (dataset)); + HDF5_ERROR (memspace = H5Screate_simple (dim, chunk_dims, NULL)); + HDF5_ERROR (H5Sselect_hyperslab (filespace, H5S_SELECT_SET, chunk_origin, NULL, chunk_dims, NULL)); - IOHDF5_ERROR (H5Dread (dataset, rec_info->iohdf5_type, memspace, - filespace, H5P_DEFAULT, data)); + HDF5_ERROR (H5Dread (dataset, rec_info->hdf5type, memspace, filespace, + H5P_DEFAULT, data)); - IOHDF5_ERROR (H5Sclose (memspace)); - IOHDF5_ERROR (H5Sclose (filespace)); + HDF5_ERROR (H5Sclose (memspace)); + HDF5_ERROR (H5Sclose (filespace)); free (chunk_dims); free (chunk_origin); @@ -679,9 +664,9 @@ static int IOHDF5Util_RestoreGA (hid_t dataset, { var_info[2] = extras->rnpoints[proc]; CACTUS_MPI_ERROR (MPI_Send (var_info, 3, PUGH_MPI_INT, proc, - STARTUPBASE, pughGH->PUGH_COMM_WORLD)); + MPITAGBASE, pughGH->PUGH_COMM_WORLD)); CACTUS_MPI_ERROR (MPI_Send (data, extras->rnpoints[proc], - rec_info->mpi_type, proc, STARTUPBASE, + rec_info->mpi_type, proc, MPITAGBASE, pughGH->PUGH_COMM_WORLD)); } } @@ -693,20 +678,17 @@ static int IOHDF5Util_RestoreGA (hid_t dataset, } -static herr_t processDataset (hid_t group, - const char *datasetname, - void *arg) +static herr_t processDataset (hid_t group, const char *datasetname, void *arg) { - DECLARE_CCTK_PARAMETERS - pGH *pughGH; ioGH *ioUtilGH; ioHDF5UtilGH *myGH; - int vindex, vtype, gtype, timelevel; + int vindex, vtype, gtype, timelevel, is_group; iterate_info_t *it_info = (iterate_info_t *) arg; recover_info_t rec_info; hid_t dataset; H5G_stat_t object_info; - int is_group; + char *fullname; + DECLARE_CCTK_PARAMETERS /* skip the global attributes and GH extensions groups */ @@ -716,20 +698,15 @@ static herr_t processDataset (hid_t group, return (0); } - /* Get the handle for PUGH, IOUtil, and IOHDF5Util extensions */ - pughGH = PUGH_pGH (it_info->GH); - ioUtilGH = (ioGH *) CCTK_GHExtension (it_info->GH, "IO"); - myGH = (ioHDF5UtilGH *) CCTK_GHExtension (it_info->GH, "IOHDF5Util"); - - IOHDF5_ERROR (H5Gget_objinfo (group, datasetname, 0, &object_info)); + HDF5_ERROR (H5Gget_objinfo (group, datasetname, 0, &object_info)); is_group = object_info.type == H5G_GROUP; if (is_group) { - IOHDF5_ERROR (dataset = H5Gopen (group, datasetname)); + HDF5_ERROR (dataset = H5Gopen (group, datasetname)); } else { - IOHDF5_ERROR (dataset = H5Dopen (group, datasetname)); + HDF5_ERROR (dataset = H5Dopen (group, datasetname)); } /* read in the dataset's attributes and verify them */ @@ -742,42 +719,43 @@ static herr_t processDataset (hid_t group, return (0); } + ioUtilGH = (ioGH *) CCTK_GHExtension (it_info->GH, "IO"); + myGH = (ioHDF5UtilGH *) CCTK_GHExtension (it_info->GH, "IOHDF5Util"); + /* if we read in initial data via the file reader interface check whether the user wants to have this variable restored */ if (ioUtilGH->do_inVars && ! ioUtilGH->do_inVars[vindex]) { if (verbose) { - char *varname = CCTK_FullName (vindex); - + fullname = CCTK_FullName (vindex); CCTK_VInfo (CCTK_THORNSTRING, "Ignoring variable '%s' for file reader " - "recovery", varname); - free (varname); + "recovery", fullname); + free (fullname); } return (0); } if (verbose) { - char *varname = CCTK_FullName (vindex); - + fullname = CCTK_FullName (vindex); CCTK_VInfo (CCTK_THORNSTRING, "Restoring variable '%s' (timelevel %d)", - varname, timelevel); - free (varname); + fullname, timelevel); + free (fullname); } vtype = CCTK_VarTypeI (vindex); rec_info.it_info = it_info; rec_info.element_size = CCTK_VarTypeSize (vtype); #ifdef CCTK_MPI - rec_info.mpi_type = PUGH_MPIDataType (pughGH, vtype); + rec_info.mpi_type = PUGH_MPIDataType (PUGH_pGH (it_info->GH), vtype); #endif - rec_info.iohdf5_type = IOHDF5Util_DataType (myGH, vtype); + rec_info.hdf5type = IOHDF5Util_DataType (myGH, vtype); if (rec_info.element_size <= 0 || #ifdef CCTK_MPI rec_info.mpi_type == MPI_DATATYPE_NULL || #endif - rec_info.iohdf5_type < 0) + rec_info.hdf5type < 0) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "Unsupported variable datatype %d", vtype); @@ -802,11 +780,11 @@ static herr_t processDataset (hid_t group, if (is_group) { - IOHDF5_ERROR (H5Gclose (dataset)); + HDF5_ERROR (H5Gclose (dataset)); } else { - IOHDF5_ERROR (H5Dclose (dataset)); + HDF5_ERROR (H5Dclose (dataset)); } return (0); diff --git a/src/Startup.c b/src/Startup.c index 710e35c..9fe875c 100644 --- a/src/Startup.c +++ b/src/Startup.c @@ -2,9 +2,9 @@ @file Startup.c @date Fri Oct 6 2000 @author Thomas Radke - @desc + @desc Startup and termination routines for IOHDF5Util. - @enddesc + @enddesc @version $Id$ @@*/ @@ -20,25 +20,32 @@ static const char *rcsid = "$Id$"; CCTK_FILEVERSION(BetaThorns_IOHDF5Util_Startup_c) -/* prototypes of routines defined in this source file */ + +/******************************************************************** + ******************** External Routines ************************ + ********************************************************************/ void IOHDF5Util_Startup (void); -void IOHDF5Util_Terminate (cGH *GH); -static void *IOHDF5Util_SetupGH (tFleshConfig *config, - int convergence_level, - cGH *GH); +void IOHDF5Util_Terminate (const cGH *GH); - /*@@ - @routine IOHDF5Util_Startup - @date Fri Oct 6 2000 - @author Thomas Radke - @desc - The startup registration routine for IOHDF5Util. - Registers the GH extensions needed for IOHDF5Util - and the routine to set it up. - @enddesc +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ +static void *IOHDF5Util_SetupGH (tFleshConfig *config, int conv_level, cGH *GH); + - @calls CCTK_RegisterGHExtensionSetupGH + /*@@ + @routine IOHDF5Util_Startup + @date Fri Oct 6 2000 + @author Thomas Radke + @desc + The startup registration routine for IOHDF5Util. + Registers the GH extensions needed for IOHDF5Util + and the routine to set it up. + @enddesc + + @calls CCTK_RegisterGHExtension + CCTK_RegisterGHExtensionSetupGH @@*/ void IOHDF5Util_Startup (void) { @@ -62,20 +69,21 @@ void IOHDF5Util_Startup (void) /*@@ - @routine IOHDF5Util_Terminate - @date Fri Oct 6 2000 - @author Thomas Radke - @desc - The termination registration routine for IOHDF5Util. - It frees any resources kept on the GH extensions. - @enddesc + @routine IOHDF5Util_Terminate + @date Fri Oct 6 2000 + @author Thomas Radke + @desc + The termination registration routine for IOHDF5Util. + It frees any resources kept on the GH extensions. + @enddesc + @var GH - @vdesc Pointer to CCTK GH - @vtype cGH * + @vdesc Pointer to CCTK grid hierarchy + @vtype const cGH * @vio in @endvar @@*/ -void IOHDF5Util_Terminate (cGH *GH) +void IOHDF5Util_Terminate (const cGH *GH) { ioHDF5UtilGH *myGH; @@ -86,117 +94,135 @@ void IOHDF5Util_Terminate (cGH *GH) /* close the dataspaces used to write scalar and array attributes */ if (myGH->scalar_dataspace >= 0) { - IOHDF5_ERROR (H5Sclose (myGH->scalar_dataspace)); + HDF5_ERROR (H5Sclose (myGH->scalar_dataspace)); } if (myGH->array_dataspace >= 0) { - IOHDF5_ERROR (H5Sclose (myGH->array_dataspace)); + HDF5_ERROR (H5Sclose (myGH->array_dataspace)); } /* close the predefined complex and string datatypes */ - if (myGH->IOHDF5_COMPLEX >= 0) + if (myGH->HDF5_COMPLEX >= 0) { - IOHDF5_ERROR (H5Tclose (myGH->IOHDF5_COMPLEX)); + HDF5_ERROR (H5Tclose (myGH->HDF5_COMPLEX)); } #ifdef CCTK_REAL4 - if (myGH->IOHDF5_COMPLEX8 >= 0) + if (myGH->HDF5_COMPLEX8 >= 0) { - IOHDF5_ERROR (H5Tclose (myGH->IOHDF5_COMPLEX8)); + HDF5_ERROR (H5Tclose (myGH->HDF5_COMPLEX8)); } #endif #ifdef CCTK_REAL8 - if (myGH->IOHDF5_COMPLEX16 >= 0) + if (myGH->HDF5_COMPLEX16 >= 0) { - IOHDF5_ERROR (H5Tclose (myGH->IOHDF5_COMPLEX16)); + HDF5_ERROR (H5Tclose (myGH->HDF5_COMPLEX16)); } #endif #ifdef CCTK_REAL16 - if (myGH->IOHDF5_COMPLEX32 >= 0) + if (myGH->HDF5_COMPLEX32 >= 0) { - IOHDF5_ERROR (H5Tclose (myGH->IOHDF5_COMPLEX32)); + HDF5_ERROR (H5Tclose (myGH->HDF5_COMPLEX32)); } #endif - if (myGH->IOHDF5_STRING >= 0) + if (myGH->HDF5_STRING >= 0) { - IOHDF5_ERROR (H5Tclose (myGH->IOHDF5_STRING)); + HDF5_ERROR (H5Tclose (myGH->HDF5_STRING)); } } } -/****************************************************************************/ -/* local routines */ -/****************************************************************************/ +/******************************************************************** + ******************** Internal Routines ************************ + ********************************************************************/ /*@@ - @routine IOHDF5Util_SetupGH - @date Fri Oct 6 2000 - @author Thomas Radke - @desc - Allocate a GH extension structure for IOHDF5Util and set it up. - @enddesc - - @returntype void * + @routine IOHDF5Util_SetupGH + @date Fri Oct 6 2000 + @author Thomas Radke + @desc + Allocates and sets up IOHDF5Util's GH extension structure. + @enddesc + + @calls CCTK_RegisterIOMethod + CCTK_RegisterIOMethodOutputGH + CCTK_RegisterIOMethodOutputVarAs + CCTK_RegisterIOMethodTimeToOutput + CCTK_RegisterIOMethodTriggerOutput + + @var config + @vdesc the CCTK configuration as provided by the flesh + @vtype tFleshConfig * + @vio unused + @endvar + @var conv_level + @vdesc the convergence level + @vtype int + @vio unused + @endvar + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH * + @vio unused + @endvar + + @returntype void * @returndesc - pointer to the allocated GH extension structure + pointer to the allocated GH extension structure @endreturndesc @@*/ -static void *IOHDF5Util_SetupGH (tFleshConfig *config, - int convergence_level, - cGH *GH) +static void *IOHDF5Util_SetupGH (tFleshConfig *config, int conv_level, cGH *GH) { - DECLARE_CCTK_PARAMETERS ioHDF5UtilGH *myGH; + DECLARE_CCTK_PARAMETERS /* suppress compiler warnings about unused variables */ - config = config; - convergence_level = convergence_level; - GH = GH; + (void) (config + 0); + (void) (conv_level + 0); + (void) (GH + 0); + /* allocate the GH extension */ myGH = (ioHDF5UtilGH *) malloc (sizeof (ioHDF5UtilGH)); - /* save the original error printing routine and its argument */ - IOHDF5_ERROR (H5Eget_auto (&myGH->print_error_fn, &myGH->print_error_fn_arg)); - /* predefine dataspaces for writing scalar and array attributes */ /* the dimension of the array dataspace is set when used */ - IOHDF5_ERROR (myGH->scalar_dataspace = H5Screate (H5S_SCALAR)); - IOHDF5_ERROR (myGH->array_dataspace = H5Screate (H5S_SIMPLE)); - - /* predefine IOHDF5_COMPLEX datatypes */ - IOHDF5_ERROR (myGH->IOHDF5_COMPLEX = - H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX))); - IOHDF5_ERROR (H5Tinsert (myGH->IOHDF5_COMPLEX, "real", - offsetof (CCTK_COMPLEX, Re), IOHDF5_REAL)); - IOHDF5_ERROR (H5Tinsert (myGH->IOHDF5_COMPLEX, "imag", - offsetof (CCTK_COMPLEX, Im), IOHDF5_REAL)); + HDF5_ERROR (myGH->scalar_dataspace = H5Screate (H5S_SCALAR)); + HDF5_ERROR (myGH->array_dataspace = H5Screate (H5S_SIMPLE)); + + /* predefine HDF5_COMPLEX datatypes */ + HDF5_ERROR (myGH->HDF5_COMPLEX = + H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX))); + HDF5_ERROR (H5Tinsert (myGH->HDF5_COMPLEX, "real", + offsetof (CCTK_COMPLEX, Re), HDF5_REAL)); + HDF5_ERROR (H5Tinsert (myGH->HDF5_COMPLEX, "imag", + offsetof (CCTK_COMPLEX, Im), HDF5_REAL)); #ifdef CCTK_REAL4 - IOHDF5_ERROR (myGH->IOHDF5_COMPLEX8 = - H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX8))); - IOHDF5_ERROR (H5Tinsert (myGH->IOHDF5_COMPLEX8, "real", - offsetof (CCTK_COMPLEX8, Re), IOHDF5_REAL4)); - IOHDF5_ERROR (H5Tinsert (myGH->IOHDF5_COMPLEX8, "imag", - offsetof (CCTK_COMPLEX8, Im), IOHDF5_REAL4)); + HDF5_ERROR (myGH->HDF5_COMPLEX8 = + H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX8))); + HDF5_ERROR (H5Tinsert (myGH->HDF5_COMPLEX8, "real", + offsetof (CCTK_COMPLEX8, Re), HDF5_REAL4)); + HDF5_ERROR (H5Tinsert (myGH->HDF5_COMPLEX8, "imag", + offsetof (CCTK_COMPLEX8, Im), HDF5_REAL4)); #endif #ifdef CCTK_REAL8 - IOHDF5_ERROR (myGH->IOHDF5_COMPLEX16 = - H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX16))); - IOHDF5_ERROR (H5Tinsert (myGH->IOHDF5_COMPLEX16, "real", - offsetof (CCTK_COMPLEX16, Re), IOHDF5_REAL8)); - IOHDF5_ERROR (H5Tinsert (myGH->IOHDF5_COMPLEX16, "imag", - offsetof (CCTK_COMPLEX16, Im), IOHDF5_REAL8)); + HDF5_ERROR (myGH->HDF5_COMPLEX16 = + H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX16))); + HDF5_ERROR (H5Tinsert (myGH->HDF5_COMPLEX16, "real", + offsetof (CCTK_COMPLEX16, Re), HDF5_REAL8)); + HDF5_ERROR (H5Tinsert (myGH->HDF5_COMPLEX16, "imag", + offsetof (CCTK_COMPLEX16, Im), HDF5_REAL8)); #endif #ifdef CCTK_REAL16 - IOHDF5_ERROR (myGH->IOHDF5_COMPLEX32 = - H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX32))); - IOHDF5_ERROR (H5Tinsert (myGH->IOHDF5_COMPLEX32, "real", - offsetof (CCTK_COMPLEX32, Re), IOHDF5_REAL16)); - IOHDF5_ERROR (H5Tinsert (myGH->IOHDF5_COMPLEX32, "imag", - offsetof (CCTK_COMPLEX32, Im), IOHDF5_REAL16)); + HDF5_ERROR (myGH->HDF5_COMPLEX32 = + H5Tcreate (H5T_COMPOUND, sizeof (CCTK_COMPLEX32))); + HDF5_ERROR (H5Tinsert (myGH->HDF5_COMPLEX32, "real", + offsetof (CCTK_COMPLEX32, Re), HDF5_REAL16)); + HDF5_ERROR (H5Tinsert (myGH->HDF5_COMPLEX32, "imag", + offsetof (CCTK_COMPLEX32, Im), HDF5_REAL16)); #endif /* predefine a C string datatype */ - IOHDF5_ERROR (myGH->IOHDF5_STRING = H5Tcopy (H5T_C_S1)); + HDF5_ERROR (myGH->HDF5_STRING = H5Tcopy (H5T_C_S1)); return (myGH); } diff --git a/src/ioHDF5UtilGH.h b/src/ioHDF5UtilGH.h index dfdb31e..62dc98a 100644 --- a/src/ioHDF5UtilGH.h +++ b/src/ioHDF5UtilGH.h @@ -3,88 +3,87 @@ @date Fri Oct 6 2000 @author Thomas Radke @desc - The GH extensions structure for IOHDF5Util. + The GH extensions structure for thorn IOHDF5Util. @enddesc - @version $Id$ + @version $Header$ @@*/ #ifndef _IOUTILHDF5_IOUTILHDF5GH_H_ -#define _IOUTILHDF5_IOUTILHDF5GH_H_ +#define _IOUTILHDF5_IOUTILHDF5GH_H_ 1 -/* include the HDF5 header file */ #include <hdf5.h> -/*****************************************************************************/ -/* some useful macros */ -/*****************************************************************************/ -/* Check error flags from HDF5 calls */ -#define IOHDF5_ERROR(fn_call) \ - do \ - { \ - int _error_code = fn_call; \ +/******************************************************************** + ******************** Macro Definitions ************************ + ********************************************************************/ +/* check return code of HDF5 call and print a warning in case of an error */ +#define HDF5_ERROR(fn_call) \ + { \ + int _error_code = fn_call; \ \ \ - if (_error_code < 0) \ - { \ - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, \ - "HDF5 call '%s' returned error code %d\n", \ - #fn_call, _error_code); \ - } \ - } while (0) - -/* macro for writing an attribute */ -#define WRITE_ATTRIBUTE(name, value, dataset, dataspace, dim, datatype) \ - do \ + if (_error_code < 0) \ { \ - int _len; \ - hid_t _attr; \ - /* this union is only there to fix a bug in the HDF5 API */ \ - union \ - { \ - const void *const_val; \ - void *non_const_val; \ - } _v; \ - hsize_t _arrayDim = dim; \ + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, \ + "HDF5 call '%s' returned error code %d", \ + #fn_call, _error_code); \ + } \ + } + +/* append an attribute to a given file object */ +#define WRITE_ATTRIBUTE(name, value, object, ioHDF5UtilGH, dim, datatype) \ + { \ + int _len; \ + hid_t _attr, _dataspace; \ + /* this union is only there to fix a bug in the HDF5 API */ \ + union \ + { \ + const void *const_val; \ + void *non_const_val; \ + } _v; \ + hsize_t _dim = dim; \ \ \ - _v.const_val = value; \ - if (H5Tget_class (datatype) == H5T_STRING) \ - { \ - _len = strlen ((const char *) _v.const_val); \ - if (_len == 0) /* HDF5 doesn't like zero-len strings */ \ - { \ - _len++; \ - } \ - IOHDF5_ERROR (H5Tset_size (datatype, _len)); \ - } \ - if (_arrayDim > 0) \ + _v.const_val = value; \ + if (H5Tget_class (datatype) == H5T_STRING) \ + { \ + _len = strlen ((const char *) _v.const_val); \ + if (_len == 0) /* HDF5 doesn't like zero-len strings */ \ { \ - IOHDF5_ERROR (H5Sset_extent_simple (dataspace, 1, \ - &_arrayDim, NULL)); \ + _len++; \ } \ - IOHDF5_ERROR (_attr = H5Acreate (dataset, name, datatype, \ - dataspace, H5P_DEFAULT)); \ - IOHDF5_ERROR (H5Awrite (_attr, datatype, _v.non_const_val)); \ - IOHDF5_ERROR (H5Aclose (_attr)); \ - } while (0); - -/* macro for reading an attribute */ -#define READ_ATTRIBUTE(dataset, attrname, requested_type, buffer) \ - do \ + HDF5_ERROR (H5Tset_size (datatype, _len)); \ + } \ + if (_dim > 0) \ { \ - hid_t _attr, _attrtype; \ - hsize_t _asize = 0; \ + _dataspace = ioHDF5UtilGH->array_dataspace; \ + HDF5_ERROR (H5Sset_extent_simple (_dataspace, 1, &_dim, NULL)); \ + } \ + else \ + { \ + _dataspace = ioHDF5UtilGH->scalar_dataspace; \ + } \ + HDF5_ERROR (_attr = H5Acreate (object, name, datatype, _dataspace, \ + H5P_DEFAULT)); \ + HDF5_ERROR (H5Awrite (_attr, datatype, _v.non_const_val)); \ + HDF5_ERROR (H5Aclose (_attr)); \ + } + +/* read an attribute in a given file object */ +#define READ_ATTRIBUTE(object, attrname, requested_type, buffer) \ + { \ + hid_t _attr, _attrtype; \ + hsize_t _asize = 0; \ \ \ - if ((_attr = H5Aopen_name (dataset, attrname)) < 0) \ - { \ - CCTK_WARN (1, "Can't find " attrname " attribute"); \ - } \ + _attr = H5Aopen_name (object, attrname); \ + if (_attr >= 0) \ + { \ if (requested_type == H5T_C_S1) \ { \ - IOHDF5_ERROR (_attrtype = H5Aget_type (_attr)); \ - IOHDF5_ERROR (_asize = H5Tget_size (_attrtype)); \ + HDF5_ERROR (_attrtype = H5Aget_type (_attr)); \ + HDF5_ERROR (_asize = H5Tget_size (_attrtype)); \ if (_asize + 1 >= sizeof (buffer)) \ { \ CCTK_WARN (1, "Can't read " attrname " attribute (too long)");\ @@ -96,81 +95,84 @@ } \ if (H5Aread (_attr, _attrtype, buffer) < 0) \ { \ - CCTK_WARN (1, "Can't read " attrname " attribute"); \ + CCTK_WARN (1, "Can't read '" attrname "' attribute"); \ } \ if (requested_type == H5T_C_S1) \ { \ ((char *) buffer)[_asize] = 0; \ - IOHDF5_ERROR (H5Tclose (_attrtype)); \ + HDF5_ERROR (H5Tclose (_attrtype)); \ } \ - IOHDF5_ERROR (H5Aclose (_attr)); \ - } while (0) + HDF5_ERROR (H5Aclose (_attr)); \ + } \ + else \ + { \ + CCTK_WARN (1, "Can't find '" attrname "' attribute"); \ + } \ + } -/*** - Define the different datatypes used for HDF5 I/O - NOTE: the complex datatype is defined dynamically at runtime in Startup.c +/*** Define the different datatypes used for HDF5 I/O + NOTE: the complex datatype is defined dynamically at runtime in Startup.c ***/ /* char type is easy */ -#define IOHDF5_CHAR H5T_NATIVE_CHAR +#define HDF5_CHAR H5T_NATIVE_CHAR /* floating point types are architecture-independent, ie. a float has always 4 bytes, and a double has 8 bytes - - IOHDF5_REAL is used for storing reals of the generic CCTK_REAL type - IOHDF5_REALn is used to explicitely store n-byte reals */ + HDF5_REAL is used for storing reals of the generic CCTK_REAL type + HDF5_REALn is used to explicitely store n-byte reals */ #ifdef CCTK_REAL4 -#define IOHDF5_REAL4 H5T_NATIVE_FLOAT +#define HDF5_REAL4 H5T_NATIVE_FLOAT #endif #ifdef CCTK_REAL8 -#define IOHDF5_REAL8 H5T_NATIVE_DOUBLE +#define HDF5_REAL8 H5T_NATIVE_DOUBLE #endif #ifdef CCTK_REAL16 -#define IOHDF5_REAL16 (sizeof (CCTK_REAL16) == sizeof (long double) ? \ - H5T_NATIVE_LDOUBLE : -1) +#define HDF5_REAL16 (sizeof (CCTK_REAL16) == sizeof (long double) ? \ + H5T_NATIVE_LDOUBLE : -1) #endif #ifdef CCTK_REAL_PRECISION_16 -#define IOHDF5_REAL IOHDF5_REAL16 +#define HDF5_REAL HDF5_REAL16 #elif CCTK_REAL_PRECISION_8 -#define IOHDF5_REAL IOHDF5_REAL8 +#define HDF5_REAL HDF5_REAL8 #elif CCTK_REAL_PRECISION_4 -#define IOHDF5_REAL IOHDF5_REAL4 +#define HDF5_REAL HDF5_REAL4 #endif /* integer types are architecture-dependent: - IOHDF5_INT is used for communicating integers of the generic CCTK_INT type - IOHDF5_INTn is used to explicitely communicate n-byte integers */ + HDF5_INT is used for communicating integers of the generic CCTK_INT type + HDF5_INTn is used to explicitely communicate n-byte integers */ #ifdef CCTK_INT8 -#define IOHDF5_INT8 (sizeof (CCTK_INT8) == sizeof (int) ? H5T_NATIVE_INT : \ - sizeof (CCTK_INT8) == sizeof (long) ? H5T_NATIVE_LONG :\ - sizeof (CCTK_INT8) == sizeof (long long) ? \ - H5T_NATIVE_LLONG : -1) +#define HDF5_INT8 (sizeof (CCTK_INT8) == sizeof (int) ? H5T_NATIVE_INT : \ + sizeof (CCTK_INT8) == sizeof (long) ? H5T_NATIVE_LONG : \ + sizeof (CCTK_INT8) == sizeof (long long) ? \ + H5T_NATIVE_LLONG : -1) #endif #ifdef CCTK_INT4 -#define IOHDF5_INT4 (sizeof (CCTK_INT4) == sizeof (int) ? H5T_NATIVE_INT : \ - sizeof (CCTK_INT4) == sizeof (short) ? \ - H5T_NATIVE_SHORT : -1) +#define HDF5_INT4 (sizeof (CCTK_INT4) == sizeof (int) ? H5T_NATIVE_INT : \ + sizeof (CCTK_INT4) == sizeof (short) ? \ + H5T_NATIVE_SHORT : -1) #endif #ifdef CCTK_INT2 -#define IOHDF5_INT2 (sizeof (CCTK_INT2) == sizeof (short) ? \ - H5T_NATIVE_SHORT : -1) +#define HDF5_INT2 (sizeof (CCTK_INT2) == sizeof (short) ? \ + H5T_NATIVE_SHORT : -1) #endif #ifdef CCTK_INTEGER_PRECISION_8 -#define IOHDF5_INT IOHDF5_INT8 +#define HDF5_INT HDF5_INT8 #elif CCTK_INTEGER_PRECISION_4 -#define IOHDF5_INT IOHDF5_INT4 +#define HDF5_INT HDF5_INT4 #elif CCTK_INTEGER_PRECISION_2 -#define IOHDF5_INT IOHDF5_INT2 +#define HDF5_INT HDF5_INT2 #endif -/* Constants to index timers within the timers array */ +/* constants to index timers within the timers array */ #define CP_PARAMETERS_TIMER 0 #define CP_VARIABLES_TIMER 1 #define CP_TOTAL_TIMER 2 @@ -188,82 +190,86 @@ extern "C" { #endif -/* Geometry information structure for output variable */ +/* structure for hyperslab descriptions of output variables */ typedef struct { - int vdim; - int sdim; - int *direction; - int *origin; - int *length; - int *downsample; - int *actlen; /* actual index slab length (by PUGHSlab)*/ -} ioHDF5Geo_t; + /* index and timelevel of the variable */ + int vindex, timelevel; + + /* dimensionality of the variable and the hyperslab */ + int vdim, hdim; + /* CCTK datatype for the hyperslab */ + int hdatatype; -/* Structure describing a given recovery file */ + /* flag indicating wheter check whether an object to be written already + exists (and remove it in that case) */ + int check_exist; + + /* pointer to allocated buffers */ + CCTK_INT *vectors; + + /* hyperslab mapping parameters */ + CCTK_INT *origin, *direction, *extent, *downsample; + + /* offset and sizes of hyperslab into the variable's dataspace */ + CCTK_INT *hoffset, *hsize, *hsize_chunk; + +} ioSlab; + + +/* structure describing a given recovery file */ typedef struct { - int is_HDF5_file; /* flag indicating valid file info */ - hid_t file; /* HDF5 file handle */ - char *filename; /* complete file name for recovery */ - int nprocs; /* number of total processors */ - int ioproc; /* the associated IO processor */ - int ioproc_every; /* how many IO processors there are */ - int unchunked; /* whether data was written chunked or unchunked */ - int has_version; /* whether file contains a Cactus version ID - (this is used to distinguish checkpoint files - with old/new timelevel naming scheme) */ + /* flag indicating valid file info */ + int is_HDF5_file; + + /* HDF5 file handle */ + hid_t file; + + /* complete file name for recovery */ + char *filename; + + /* number of total and I/O processors, the associated IO processor, + flag telling whether data was written chunked or unchunked */ + int nprocs, ioproc_every, ioproc, unchunked; + + /* whether file contains a Cactus version ID (used to distinguish checkpoint + files with old/new timelevel naming scheme) */ + int has_version; + } fileinfo_t; -/* IOHDF5Util GH extension structure */ +/* IOHDF5Util's GH extension structure */ typedef struct { - /* while HDF5 error output is disabled - we keep the original error printing routine and its argument in here */ - H5E_auto_t print_error_fn; - void *print_error_fn_arg; - /* predefined dataspaces for writing scalar and array attributes */ hid_t scalar_dataspace, array_dataspace; /* predefined datatype for writing CCTK_COMPLEX types */ - hid_t IOHDF5_COMPLEX, - IOHDF5_COMPLEX8, - IOHDF5_COMPLEX16, - IOHDF5_COMPLEX32; + hid_t HDF5_COMPLEX, HDF5_COMPLEX8, HDF5_COMPLEX16, HDF5_COMPLEX32; /* predefined datatype for writing C string string attributes */ - hid_t IOHDF5_STRING; + hid_t HDF5_STRING; } ioHDF5UtilGH; /* exported functions */ hid_t IOHDF5Util_DataType (const ioHDF5UtilGH *myGH, int cctk_type); -void IOHDF5Util_ParseVarsForOutput (const char *output_varstring, - ioHDF5Geo_t *output_request_list[]); +void IOHDF5Util_ParseVarsForOutput (const cGH *GH, const char *output_varstring, + ioSlab *output_request_list[]); void IOHDF5Util_DumpParameters (const cGH *GH, int all, hid_t group); void IOHDF5Util_DumpGHExtensions (const cGH *GH, hid_t group); int IOHDF5Util_DumpGH (const cGH *GH, const int *timers, hid_t file); -void IOHDF5Util_DumpCommonAttributes (const cGH *GH, - int vindex, - int timelevel, - const CCTK_INT *global_shape, - const ioHDF5Geo_t *slab, +void IOHDF5Util_DumpCommonAttributes (const cGH *GH, const ioSlab *slab, hid_t dataset); -int IOHDF5Util_DumpVar (const cGH *GH, - int vindex, - int timelevel, - const ioHDF5Geo_t *slab, - hid_t file, - int check_exisiting_objects); +int IOHDF5Util_DumpVar (const cGH *GH, const ioSlab *slab, hid_t file); + int IOHDF5Util_RecoverParameters (const fileinfo_t *filenfo); -int IOHDF5Util_RecoverGHextensions (cGH *GH, - const fileinfo_t *filenfo); -int IOHDF5Util_RecoverVariables (cGH *GH, - const fileinfo_t *filenfo); +int IOHDF5Util_RecoverGHextensions (cGH *GH, const fileinfo_t *filenfo); +int IOHDF5Util_RecoverVariables (cGH *GH, const fileinfo_t *filenfo); #ifdef __cplusplus } // extern "C" diff --git a/src/make.configuration.defn b/src/make.configuration.defn index 135342a..8879748 100644 --- a/src/make.configuration.defn +++ b/src/make.configuration.defn @@ -1,20 +1,12 @@ # make.configuration.defn for IOHDF5Util +# $Header$ -# make sure that IOHDF5Util was configured with HDF5 and PUGH - -ifeq ($(strip $(HDF5_LIBS)), ) -$(NAME): MissingHDF5 -.pseudo: MissingHDF5 -MissingHDF5: - @echo "IOHDF5Util: requires HDF5" - @echo "IOHDF5Util: Please configure with HDF5 or remove IOHDF5Util from Thornlist !" - exit 2 +# make sure that IOHDF5Util was configured with HDF5 +ifeq ($(strip $(HDF5_LIBS)),) + $(error "IOHDF5Util requires HDF5. Please configure with HDF5 or remove IOHDF5Util from Thornlist !" endif +# make sure that IOHDF5Util was configured with PUGH ifeq ($(findstring CactusPUGH/PUGH,$(THORNS)),) -.pseudo: MissingPUGHinIOHDF5Util -MissingPUGHinIOHDF5Util: - @echo "IOHDF5Util: requires PUGH" - @echo "IOHDF5Util: Please add CactusPUGH/PUGH or remove IOHDF5Util from Thornlist !" - exit 2 + $(error "IOHDF5Util requires PUGH. Please add CactusPUGH/PUGH or remove IOHDF5Util from Thornlist !" endif |