aboutsummaryrefslogtreecommitdiff
path: root/Carpet
diff options
context:
space:
mode:
authorcott <>2004-03-08 21:50:00 +0000
committercott <>2004-03-08 21:50:00 +0000
commit450f9fd95391ab6099bcb8f216d34ae7344d8797 (patch)
tree6399e42cbcdebd7582bd54bfd9fb55d39f2fefe7 /Carpet
parent6c6892fe6ccba736be94274b0061a10e7352034e (diff)
Make the file reader work.
Make the file reader work. There is one strange bug: Eventhough I correctly close the file with H5Fclose(reader), one gets an H5 error when trying to open the same file for writing at a later point. Hence input and output files have to be different for the moment. darcs-hash:20040308215041-19929-89c8378965a1ee7ec4d0d466a071069f7235f41c.gz
Diffstat (limited to 'Carpet')
-rw-r--r--Carpet/CarpetIOHDF5/src/iohdf5.cc350
-rw-r--r--Carpet/CarpetIOHDF5/src/iohdf5.hh4
-rw-r--r--Carpet/CarpetIOHDF5/src/iohdf5utils.cc79
3 files changed, 246 insertions, 187 deletions
diff --git a/Carpet/CarpetIOHDF5/src/iohdf5.cc b/Carpet/CarpetIOHDF5/src/iohdf5.cc
index f8ba7a252..2e676081c 100644
--- a/Carpet/CarpetIOHDF5/src/iohdf5.cc
+++ b/Carpet/CarpetIOHDF5/src/iohdf5.cc
@@ -17,7 +17,7 @@
#include "cctk_Parameters.h"
extern "C" {
- static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetIOHDF5/src/iohdf5.cc,v 1.4 2004/03/08 09:43:41 cott Exp $";
+ static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetIOHDF5/src/iohdf5.cc,v 1.5 2004/03/08 22:50:41 cott Exp $";
CCTK_FILEVERSION(Carpet_CarpetIOHDF5_iohdf5_cc);
}
@@ -496,7 +496,7 @@ namespace CarpetIOHDF5 {
-#if 0
+
int InputGH (const cGH* const cctkGH) {
int retval = 0;
for (int vindex=0; vindex<CCTK_NumVars(); ++vindex) {
@@ -512,7 +512,7 @@ namespace CarpetIOHDF5 {
- int InputVarAs (const cGH* const cctkGH, const char* const varname,
+ int InputVarAs (const cGH* const cctkGH, const char* const varname,
const char* const alias) {
DECLARE_CCTK_PARAMETERS;
@@ -525,7 +525,18 @@ namespace CarpetIOHDF5 {
const int var = n - n0;
assert (var>=0 && var<CCTK_NumVars());
const int tl = 0;
-
+
+ herr_t herr;
+ int have_dataset = 0;
+ int want_dataset = 0;
+ int did_read_something = 0;
+ int ndatasets = 0;
+ hid_t dataset = 0;
+
+ char datasetname[1024];
+
+ CCTK_REAL *h5data = NULL;
+
// Check for storage
if (! CCTK_QueryGroupStorageI(cctkGH, group)) {
CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
@@ -548,13 +559,7 @@ namespace CarpetIOHDF5 {
hid_t reader = -1;
-// const int gpdim = CCTK_GroupDimI(group);
-
-// int have_dataset;
-
-// int rank;
-// int dims[dim];
-// int nbytes;
+ const int gpdim = CCTK_GroupDimI(group);
// Read the file only on the root processor
if (CCTK_MyProc(cctkGH)==0) {
@@ -567,204 +572,181 @@ namespace CarpetIOHDF5 {
"Could not open file \"%s\" for reading", filename);
}
assert (reader>=0);
-
+ // get the number of datasets in the file
+ ndatasets=GetnDatasets(reader);
}
vector<ibset> regions_read(Carpet::maps);
- // Traverse all components on all levels
- BEGIN_MAP_LOOP(cctkGH, grouptype) {
- BEGIN_COMPONENT_LOOP(cctkGH, grouptype) {
-
- // Read data
- if (CCTK_MyProc(cctkGH)==0) {
-
- ostringstream datasetnamebuf;
- datasetnamebuf << varname
- << " it=" << cctk_iteration
- << " ml=" << mglevel
- << " rl=" << rl
- << " m=" << Carpet::map
- << " c=" << component;
- string datasetnamestr = datasetnamebufs.str();
- const char * const datasetname = datasetnamestr.c_str();
- const hid_t dataset = H5Dopen (reader, datasetname);
- have_dataset = dataset>=0;
-
-// // Check rank
-// assert (rank==gpdim);
-
-// // Check datatype
-// assert (true
-// || (CCTK_VarTypeI(n) == CCTK_VARIABLE_REAL8
-// && sizeof(CCTK_REAL8) == sizeof(double))
-// || (CCTK_VarTypeI(n) == CCTK_VARIABLE_REAL
-// && sizeof(CCTK_REAL) == sizeof(double)));
-// // TODO: Check datatype correctly
-// assert (CCTK_VarTypeI(n) == CCTK_VARIABLE_REAL8
-// || (sizeof(CCTK_REAL) == sizeof(double)
-// && CCTK_VarTypeI(n) == CCTK_VARIABLE_REAL));
+ // Broadcast number of datasets
+ MPI_Bcast (&ndatasets, 1, MPI_INT, 0, dist::comm);
+ assert (ndatasets>=0);
-// // TODO: check grid spacing
- }
-// // Broadcast rank, dimensions, and nbytes
-// MPI_Bcast (&rank, 1, MPI_INT, 0, dist::comm);
-// assert (rank>=1);
-// MPI_Bcast (&dims, rank, MPI_INT, 0, dist::comm);
-// for (int d=0; d<rank; ++d) assert (dims[d]>=0);
-// MPI_Bcast (&nbytes, 1, MPI_INT, 0, dist::comm);
-// assert (nbytes>=0);
-
-// // Broadcast number of datasets
-// MPI_Bcast (&ndatasets, 1, MPI_INT, 0, dist::comm);
-// assert (ndatasets>=0);
-
- // Broadcast dataset
- MPI_Bcast (&have_dataset, 1, MPI_INT, 0, dist::comm);
+ for (int datasetid=0; datasetid<ndatasets; ++datasetid) {
+ if (verbose) CCTK_VInfo (CCTK_THORNSTRING, "Handling dataset #%d", datasetid);
+
- if (have_dataset) {
-
- ###
- // Read grid
+ // Read data
+ if (CCTK_MyProc(cctkGH)==0) {
+ GetDatasetName(reader,datasetid,datasetname);
+ cout << datasetname << "\n";
+
+ dataset = H5Dopen (reader, datasetname);
+ assert(dataset);
+ }
+
+
int amr_level;
int amr_origin[dim];
int amr_dims[dim];
-
+
if (CCTK_MyProc(cctkGH)==0) {
-
- // Read data
- const hid_t dataset
-
- {
- char * name;
- ReadAttribute (reader, "name", name);
- if (verbose) {
- if (name) {
- CCTK_VInfo (CCTK_THORNSTRING, "Dataset name is \"%s\"", name);
- }
- }
- want_dataset = name && CCTK_EQUALS(name, varname);
- free (name);
- }
-
- // If iorigin attribute is absent, assume file has unigrid
- // data.
- {
- IObase::DataType atype;
- int alength;
- if (reader->readAttributeInfo("iorigin", atype, alength) < 0) {
- amrgrid->level = 0;
- for (int d=0; d<gpdim; ++d) {
- amrgrid->iorigin[d] = 0;
- }
- }
- }
-
- amr_level = amrgrid->level;
- for (int d=0; d<gpdim; ++d) {
- amr_origin[d] = amrgrid->iorigin[d];
- amr_dims[d] = amrgrid->dims[d];
- }
- for (int d=gpdim; d<dim; ++d) {
- amr_origin[d] = 0;
- amr_dims[d] = 1;
- }
-
- } // MyProc == 0
-
- MPI_Bcast (&want_dataset, 1, MPI_INT, 0, dist::comm);
- MPI_Bcast (&amr_level, 1, MPI_INT, 0, dist::comm);
- MPI_Bcast (amr_origin, dim, MPI_INT, 0, dist::comm);
- MPI_Bcast (amr_dims, dim, MPI_INT, 0, dist::comm);
-
- if (want_dataset && amr_level == reflevel) {
- did_read_something = true;
-
- // Traverse all components on all levels
- BEGIN_MAP_LOOP(cctkGH, grouptype) {
- BEGIN_COMPONENT_LOOP(cctkGH, grouptype) {
-
- ggf<dim>* ff = 0;
-
- assert (var < (int)arrdata.at(group).at(Carpet::map).data.size());
- ff = (ggf<dim>*)arrdata.at(group).at(Carpet::map).data.at(var);
-
- gdata<dim>* const data = (*ff) (tl, rl, component, mglevel);
-
- // Create temporary data storage on processor 0
- const vect<int,dim> str
- = vect<int,dim>(maxreflevelfact/reflevelfact);
- const vect<int,dim> lb = vect<int,dim>::ref(amr_origin) * str;
- const vect<int,dim> ub
- = lb + (vect<int,dim>::ref(amr_dims) - 1) * str;
- const bbox<int,dim> ext(lb,ub,str);
-
- gdata<dim>* const tmp = data->make_typed (n);
-
- if (CCTK_MyProc(cctkGH)==0) {
- tmp->allocate (ext, 0, amrgrid->data);
- } else {
- tmp->allocate (ext, 0);
- }
+
+ // Read data
+ char * name;
+ // cout << "reading name" << "\n";
+ ReadAttribute (dataset, "name", name);
+ // cout << "done reading name" << "\n";
+ if (verbose) {
+ if (name) {
+ CCTK_VInfo (CCTK_THORNSTRING, "Dataset name is \"%s\"", name);
+ }
+ }
+ want_dataset = name && CCTK_EQUALS(name, varname);
+ free (name);
+
+ if(want_dataset) {
+
+ // get dataset dimensions
+ const hid_t dataspace = H5Dget_space(dataset);
+ assert (dataspace>=0);
+ hsize_t rank=H5Sget_simple_extent_ndims(dataspace);
+ hsize_t shape[rank];
+ int rank2 = H5Sget_simple_extent_dims (dataspace, shape, NULL);
+ herr = H5Sclose(dataspace);
+ assert(!herr);
+ assert (rank2 == rank);
+ assert (gpdim == rank);
+
+ int datalength=1;
+
+ for(int i=0;i<rank;i++) {
+ datalength=datalength*shape[i];
+ }
+ const hid_t datatype = H5T_NATIVE_DOUBLE;
+
+ // cout << "datalength: " << datalength << " rank: " << rank << "\n";
+ // cout << shape[0] << " " << shape[1] << " " << shape[2] << "\n";
+
+ h5data = (CCTK_REAL*) malloc(sizeof(double)*datalength);
+ herr = H5Dread(dataset,datatype,H5S_ALL, H5S_ALL, H5P_DEFAULT,(void*)h5data);
+ assert(!herr);
+
+ ReadAttribute(dataset,"level",amr_level);
+ //cout << amr_level << "," << gpdim << "\n";
+ ReadAttribute(dataset,"iorigin",amr_origin,dim);
+ // cout << amr_origin[0] << "\n";
+
+ herr = H5Dclose(dataset);
+ assert(!herr);
+
+ for (int d=0; d<gpdim; ++d) {
+ amr_dims[d] = shape[d];
+ }
+
+ } // want_dataset
+ } // MyProc == 0
+
+ MPI_Bcast (&want_dataset, 1, MPI_INT, 0, dist::comm);
+ MPI_Bcast (&amr_level, 1, MPI_INT, 0, dist::comm);
+ MPI_Bcast (amr_origin, dim, MPI_INT, 0, dist::comm);
+ MPI_Bcast (amr_dims, dim, MPI_INT, 0, dist::comm);
+
+ if (want_dataset && amr_level == reflevel) {
+ did_read_something = true;
+
+ // Traverse all components on all levels
+ BEGIN_MAP_LOOP(cctkGH, grouptype) {
+ BEGIN_COMPONENT_LOOP(cctkGH, grouptype) {
- // Initialise with what is found in the file -- this does
- // not guarantee that everything is initialised.
- const bbox<int,dim> overlap = tmp->extent() & data->extent();
- regions_read.at(Carpet::map) |= overlap;
+ ggf<dim>* ff = 0;
+
+ assert (var < (int)arrdata.at(group).at(Carpet::map).data.size());
+ ff = (ggf<dim>*)arrdata.at(group).at(Carpet::map).data.at(var);
- // Copy into grid function
- for (comm_state<dim> state; !state.done(); state.step()) {
- data->copy_from (state, tmp, overlap);
- }
+ gdata<dim>* const data = (*ff) (tl, rl, component, mglevel);
+
+ // Create temporary data storage on processor 0
+ const vect<int,dim> str
+ = vect<int,dim>(maxreflevelfact/reflevelfact);
+ const vect<int,dim> lb = vect<int,dim>::ref(amr_origin) * str;
+ const vect<int,dim> ub
+ = lb + (vect<int,dim>::ref(amr_dims) - 1) * str;
+ const bbox<int,dim> ext(lb,ub,str);
+
+ gdata<dim>* const tmp = data->make_typed (n);
+
+ if (CCTK_MyProc(cctkGH)==0) {
+ tmp->allocate (ext, 0, h5data);
+ } else {
+ tmp->allocate (ext, 0);
+ }
- // Delete temporary copy
- delete tmp;
-
- } END_COMPONENT_LOOP;
- } END_MAP_LOOP;
-
- } // if want_dataset && level == reflevel
-
- if (CCTK_MyProc(cctkGH)==0) {
- free (amrgrid->data);
- free (amrgrid);
- amrgrid = 0;
- }
-
+ // Initialise with what is found in the file -- this does
+ // not guarantee that everything is initialised.
+ const bbox<int,dim> overlap = tmp->extent() & data->extent();
+ regions_read.at(Carpet::map) |= overlap;
+
+ // Copy into grid function
+ for (comm_state<dim> state; !state.done(); state.step()) {
+ data->copy_from (state, tmp, overlap);
+ }
+
+ // Delete temporary copy
+ delete tmp;
+
+ } END_COMPONENT_LOOP;
+ } END_MAP_LOOP;
+
+ } // if want_dataset && level == reflevel
+
+ if (CCTK_MyProc(cctkGH)==0) {
+ free (h5data);
+ }
+
} // loop over datasets
-
+
// Close the file
if (CCTK_MyProc(cctkGH)==0) {
- if (verbose) CCTK_VInfo (CCTK_THORNSTRING, "Deleting AMR info");
- delete amrreader;
-
- amrreader = 0;
if (verbose) CCTK_VInfo (CCTK_THORNSTRING, "Closing file");
- delete reader;
- reader = 0;
+ herr = H5Fclose(reader);
+ // cout << "blah! " << reader << "\n";
+ // cout << "closing file " << herr << "\n";
+ assert(!herr);
+ reader=-1;
}
-
+
// Was everything initialised?
if (did_read_something) {
for (int m=0; m<Carpet::maps; ++m) {
- dh<dim>& thedd = *arrdata.at(group).at(m).dd;
- ibset all_exterior;
- for (size_t c=0; c<thedd.boxes.at(rl).size(); ++c) {
- all_exterior |= thedd.boxes.at(rl).at(c).at(mglevel).exterior;
- }
- if (regions_read.at(m) != all_exterior) {
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Variable \"%s\" could not be initialised from file -- the file may be missing data",
- varname);
- }
+ dh<dim>& thedd = *arrdata.at(group).at(m).dd;
+ ibset all_exterior;
+ for (size_t c=0; c<thedd.boxes.at(rl).size(); ++c) {
+ all_exterior |= thedd.boxes.at(rl).at(c).at(mglevel).exterior;
+ }
+ if (regions_read.at(m) != all_exterior) {
+ CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Variable \"%s\" could not be initialised from file -- the file may be missing data",
+ varname);
+ }
}
} // if did_read_something
return did_read_something ? 0 : -1;
+// CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,"stop!");
}
-
-
+
/** returns the number of recovered variables */
int Recover (cGH* const cctkGH, const char *basefilename,
@@ -800,7 +782,7 @@ namespace CarpetIOHDF5 {
return num_vars_read;
}
-
+
int CarpetIOHDF5ReadData (CCTK_ARGUMENTS)
@@ -808,7 +790,7 @@ namespace CarpetIOHDF5 {
DECLARE_CCTK_ARGUMENTS;
return InputGH(cctkGH);
}
-#endif
+
} // namespace CarpetIOHDF5
diff --git a/Carpet/CarpetIOHDF5/src/iohdf5.hh b/Carpet/CarpetIOHDF5/src/iohdf5.hh
index 2bbec776d..db4e995da 100644
--- a/Carpet/CarpetIOHDF5/src/iohdf5.hh
+++ b/Carpet/CarpetIOHDF5/src/iohdf5.hh
@@ -1,4 +1,4 @@
-// $Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetIOHDF5/src/iohdf5.hh,v 1.2 2004/03/08 09:43:41 cott Exp $
+// $Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetIOHDF5/src/iohdf5.hh,v 1.3 2004/03/08 22:50:41 cott Exp $
#ifndef CARPETIOHDF5_HH
#define CARPETIOHDF5_HH
@@ -61,6 +61,8 @@ namespace CarpetIOHDF5 {
int ReadAttribute (const hid_t dataset, const char* name, char*& values);
int ReadAttribute (const hid_t dataset, const char* name, char* values, int nvalues);
+ int GetnDatasets (const hid_t reader);
+ void GetDatasetName (const hid_t reader, const int _index, char* name);
} // namespace CarpetIOHDF5
diff --git a/Carpet/CarpetIOHDF5/src/iohdf5utils.cc b/Carpet/CarpetIOHDF5/src/iohdf5utils.cc
index d0e00266a..f7c8f07a0 100644
--- a/Carpet/CarpetIOHDF5/src/iohdf5utils.cc
+++ b/Carpet/CarpetIOHDF5/src/iohdf5utils.cc
@@ -17,7 +17,7 @@
#include "cctk_Parameters.h"
extern "C" {
- static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetIOHDF5/src/iohdf5utils.cc,v 1.1 2004/03/08 09:43:41 cott Exp $";
+ static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetIOHDF5/src/iohdf5utils.cc,v 1.2 2004/03/08 22:50:41 cott Exp $";
CCTK_FILEVERSION(Carpet_CarpetIOHDF5_iohdf5utils_cc);
}
@@ -234,7 +234,7 @@ namespace CarpetIOHDF5 {
shape[0] = 1;
} else if (rank==1) {
herr = H5Sget_simple_extent_dims (dataspace, shape, NULL);
- assert (!herr);
+ assert (herr >= 0);
} else {
assert (0);
}
@@ -416,7 +416,82 @@ namespace CarpetIOHDF5 {
return length;
}
+
+ herr_t DatasetCounter(hid_t group_id, const char *member_name, void *operator_data)
+ /* Counts datasets. Used by GetnDatasets; straight from John Shalf's FlexIO library */
+ {
+ int *count = (int*)operator_data;
+ H5G_stat_t objinfo;
+ // request info about the type of objects in root group
+ if(H5Gget_objinfo(group_id,member_name,1 /* follow links */,&objinfo)<0) {
+ return 0;
+ }
+ // only count objects that are datasets (not subgroups)
+ if(objinfo.type==H5G_DATASET) {
+ (*count)++;
+ }
+ return 0;
+ }
+
+ int GetnDatasets(const hid_t reader)
+ {
+ //this is straight from John Shalf's FlexIO library
+
+ int count=0;
+ int idx=0;
+ while(H5Giterate(reader, /* hid_t loc_id, */
+ "/", /*const char *name, */
+ &idx, /* int *idx, */
+ DatasetCounter,
+ &count)<0){}
+ return count;
+ }
+
+ struct H5IO_getname_t {
+ //this is straight from John Shalf's FlexIO library
+ int index,count;
+ char *name;
+ };
+
+
+ herr_t GetName(hid_t group_id, const char *member_name, void *operator_data)
+ {
+ //this is straight from John Shalf's FlexIO library
+ H5IO_getname_t *getn = (H5IO_getname_t*)operator_data;
+ // check type first (only respond if it is a dataset)
+ H5G_stat_t objinfo;
+ // request info about the type of objects in root group
+ if(H5Gget_objinfo(group_id,
+ member_name,
+ 1 /* follow links */,
+ &objinfo)<0) return 0; // error (probably bad symlink)
+ // only count objects that are datasets (not subgroups)
+ if(objinfo.type!=H5G_DATASET)
+ return 0; // do not increment count if it isn't a dataset.
+ if(getn->index==getn->count){
+ strcpy(getn->name,member_name);
+ return 1; // success
+ }
+ getn->count++;
+ return 0;
+ }
+
+
+ void GetDatasetName(const hid_t reader, const int _index, char *name)
+ {
+ //this is straight from John Shalf's FlexIO library
+ H5IO_getname_t getn;
+ int idx=_index;
+ getn.index=_index; getn.name=name; getn.count=_index;
+ while(H5Giterate(reader, /* hid_t loc_id, */
+ "/", /*const char *name, */
+ &idx, /* int *idx, */
+ GetName,
+ &getn)<0){}
+ }
+
+
} // namespace CarpetIOHDF5