#include #include #include #include #include #include #include #include #include #include #include #include #include "cctk.h" #include "cctk_Parameters.h" extern "C" { static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetIOHDF5/src/iohdf5.cc,v 1.13 2004/03/11 11:50:51 cott Exp $"; CCTK_FILEVERSION(Carpet_CarpetIOHDF5_iohdf5_cc); } #include "CactusBase/IOUtil/src/ioGH.h" #include "CactusBase/IOUtil/src/ioutil_CheckpointRecovery.h" #include "bbox.hh" #include "data.hh" #include "gdata.hh" #include "ggf.hh" #include "vect.hh" #include "carpet.hh" #include "iohdf5.hh" #include "iohdf5GH.h" namespace CarpetIOHDF5 { using namespace std; using namespace Carpet; // Variable definitions int GHExtension; int IOMethod; vector do_truncate; // [var] vector > > last_output; // [ml][rl][var] int CarpetIOHDF5Startup () { int ierr; CCTK_RegisterBanner ("AMR 3D HDF5 I/O provided by CarpetIOHDF5"); GHExtension = CCTK_RegisterGHExtension ("CarpetIOHDF5"); CCTK_RegisterGHExtensionSetupGH (GHExtension, SetupGH); IOMethod = CCTK_RegisterIOMethod ("CarpetIOHDF5"); CCTK_RegisterIOMethodOutputGH (IOMethod, OutputGH); CCTK_RegisterIOMethodOutputVarAs (IOMethod, OutputVarAs); CCTK_RegisterIOMethodTimeToOutput (IOMethod, TimeToOutput); CCTK_RegisterIOMethodTriggerOutput (IOMethod, TriggerOutput); // Erik's Recovery routine ierr = IOUtil_RegisterRecover ("CarpetIOHDF5", Recover); assert (! ierr); // Christian's Recovery routine ierr = IOUtil_RegisterRecover ("CarpetIOHDF5 recovery", CarpetIOHDF5_Recover); assert (! ierr); return 0; } void* SetupGH (tFleshConfig* const fc, const int convLevel, cGH* const cctkGH) { DECLARE_CCTK_PARAMETERS; CarpetIOHDF5GH* myGH; // Truncate all files if this is not a restart do_truncate.resize(CCTK_NumVars(), true); // No iterations have yet been output last_output.resize(mglevels); for (int ml=0; mlout_last = (int *) malloc (numvars * sizeof (int)); myGH->requests = (ioRequest **) calloc (numvars, sizeof (ioRequest *)); myGH->cp_filename_list = (char **) calloc (abs (checkpoint_keep), sizeof (char *)); myGH->cp_filename_index = 0; myGH->out_vars = strdup (""); myGH->out_every_default = out_every - 1; for (int i = 0; i < numvars; i++) { myGH->out_last [i] = -1; } myGH->open_output_files = NULL; return (myGH); } int OutputGH (const cGH* const cctkGH) { for (int vindex=0; vindex=0 && n=0 && group<(int)Carpet::arrdata.size()); const int n0 = CCTK_FirstVarIndexI(group); assert (n0>=0 && n0=0 && varrecovered || stat(filename, &fileinfo)!=0) { writer = H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); assert (writer>=0); herr = H5Fclose (writer); assert (!herr); writer = -1; } } // Open the file writer = H5Fopen (filename, H5F_ACC_RDWR, H5P_DEFAULT); assert (writer>=0); // const int gpdim = CCTK_GroupDimI(group); // // Set coordinate information // double origin[dim], delta[dim], timestep; // for (int d=0; dcctk_origin_space[d]; // delta[d] = cctkGH->cctk_delta_space[d]; // } // timestep = cctkGH->cctk_delta_time; // amrwriter->setTopLevelParameters // (gpdim, origin, delta, timestep, maxreflevels); // // Set refinement information // int interlevel_timerefinement; // int interlevel_spacerefinement[dim]; // int initial_gridplacementrefinement[dim]; // interlevel_timerefinement = reffact; // for (int d=0; dsetRefinement // (interlevel_timerefinement, interlevel_spacerefinement, // initial_gridplacementrefinement); // // Set level // amrwriter->setLevel (rl); // // Set current time // amrwriter->setTime (cctk_iteration); } WriteVar(cctkGH,writer,request,0); // Close the file if (CCTK_MyProc(cctkGH)==0) { herr = H5Fclose (writer); assert (!herr); writer = -1; } // Don't truncate again do_truncate.at(n) = false; return 0; } int WriteVar (const cGH* const cctkGH, const hid_t writer, const ioRequest* request, const int called_from_checkpoint) { DECLARE_CCTK_ARGUMENTS; DECLARE_CCTK_PARAMETERS; herr_t herr; const int n = request->vindex; assert (n>=0 && n=0 && group<(int)Carpet::arrdata.size()); const int n0 = CCTK_FirstVarIndexI(group); assert (n0>=0 && n0=0 && vartimelevel==0) tl = 0; else tl = - request->timelevel; // Traverse all components BEGIN_MAP_LOOP(cctkGH, grouptype) { BEGIN_COMPONENT_LOOP(cctkGH, grouptype) { const ggf* ff = 0; ff = (ggf*)arrdata.at(group).at(Carpet::map).data.at(var); const gdata* const data = (*ff) (tl, rl, component, mglevel); // Make temporary copy on processor 0 const ibbox ext = data->extent(); // vect lo = ext.lower(); // vect hi = ext.upper(); // vect str = ext.stride(); gdata* const tmp = data->make_typed (n); tmp->allocate (ext, 0); for (comm_state state; !state.done(); state.step()) { tmp->copy_from (state, data, ext); } // Write data if (CCTK_MyProc(cctkGH)==0) { hsize_t shape[dim]; for (int d=0; d=0); // Select datatype #if 0 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: Set datatype correctly #endif const hid_t datatype = h5DataType(CCTK_VarTypeI(n)); ostringstream datasetnamebuf; datasetnamebuf << varname << " it=" << cctk_iteration << " tl=" << tl << " ml=" << mglevel << " rl=" << rl << " m=" << Carpet::map << " c=" << component; string datasetnamestr = datasetnamebuf.str(); const char * const datasetname = datasetnamestr.c_str(); const hid_t dataset = H5Dcreate (writer, datasetname, datatype, dataspace, H5P_DEFAULT); assert (dataset>=0); const void * const data = (void*)tmp->storage(); herr = H5Dwrite (dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data); assert (!herr); // Write FlexIO attributes WriteAttribute (dataset, "level", rl); { CCTK_REAL origin[dim], delta[dim]; CCTK_REAL min_ext[dim], max_ext[dim]; for (int d=0; dcomponents(reflevel)); herr = H5Dclose (dataset); assert (!herr); herr = H5Sclose (dataspace); assert (!herr); } // if on root processor // Delete temporary copy delete tmp; } END_COMPONENT_LOOP; } END_MAP_LOOP; return 0; } int TimeToOutput (const cGH* const cctkGH, const int vindex) { DECLARE_CCTK_ARGUMENTS; DECLARE_CCTK_PARAMETERS; assert (vindex>=0 && vindex=0 && vindexcctk_iteration; return retval; } int InputGH (const cGH* const cctkGH) { int retval = 0; for (int vindex=0; vindex ®ions_read, const int called_from_recovery) { DECLARE_CCTK_PARAMETERS; const int n = CCTK_VarIndex(varname); assert (n>=0 && n=0 && group<(int)Carpet::arrdata.size()); const int n0 = CCTK_FirstVarIndexI(group); assert (n0>=0 && n0=0 && var regions_read(Carpet::maps); int amr_level; int amr_origin[dim]; int amr_dims[dim]; if (CCTK_MyProc(cctkGH)==0) { // 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=0); //cout << "amr_level " << amr_level << " rl " << rl << endl; ReadAttribute(dataset,"iorigin",amr_origin,dim); assert(herr>=0); // cout << "amr_origin[0] " << amr_origin[0] << "\n"; herr = H5Dclose(dataset); assert(!herr); for (int d=0; d* ff = 0; assert (var < (int)arrdata.at(group).at(Carpet::map).data.size()); ff = (ggf*)arrdata.at(group).at(Carpet::map).data.at(var); gdata* const data = (*ff) (tl, rl, component, mglevel); // Create temporary data storage on processor 0 const vect str = vect(maxreflevelfact/reflevelfact); const vect lb = vect::ref(amr_origin) * str; const vect ub = lb + (vect::ref(amr_dims) - 1) * str; const bbox ext(lb,ub,str); gdata* const tmp = data->make_typed (n); if (CCTK_MyProc(cctkGH)==0) { tmp->allocate (ext, 0, h5data); } else { tmp->allocate (ext, 0); } // Initialise with what is found in the file -- this does // not guarantee that everything is initialised. const bbox overlap = tmp->extent() & data->extent(); regions_read.at(Carpet::map) |= overlap; //cout << "overlap " << overlap << endl; //cout << "tmp->extent " << tmp->extent() << endl; //cout << "data->extent " << data->extent() << endl; // Copy into grid function for (comm_state 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 == rl if (CCTK_MyProc(cctkGH)==0) { free (h5data); } return did_read_something; } #endif int InputVarAs (const cGH* const cctkGH, const char* const varname, const char* const alias) { DECLARE_CCTK_PARAMETERS; const int n = CCTK_VarIndex(varname); assert (n>=0 && n=0 && group<(int)Carpet::arrdata.size()); const int n0 = CCTK_FirstVarIndexI(group); assert (n0>=0 && n0=0 && var=0); // get the number of datasets in the file ndatasets=GetnDatasets(reader); } vector regions_read(Carpet::maps); // Broadcast number of datasets MPI_Bcast (&ndatasets, 1, MPI_INT, 0, dist::comm); assert (ndatasets>=0); for (int datasetid=0; datasetid=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=0); //cout << "amr_level " << amr_level << " rl " << rl << endl; ReadAttribute(dataset,"iorigin",amr_origin,dim); assert(herr>=0); // cout << "amr_origin[0] " << amr_origin[0] << "\n"; herr = H5Dclose(dataset); assert(!herr); for (int d=0; d* ff = 0; assert (var < (int)arrdata.at(group).at(Carpet::map).data.size()); ff = (ggf*)arrdata.at(group).at(Carpet::map).data.at(var); gdata* const data = (*ff) (tl, rl, component, mglevel); // Create temporary data storage on processor 0 const vect str = vect(maxreflevelfact/reflevelfact); const vect lb = vect::ref(amr_origin) * str; const vect ub = lb + (vect::ref(amr_dims) - 1) * str; const bbox ext(lb,ub,str); gdata* const tmp = data->make_typed (n); if (CCTK_MyProc(cctkGH)==0) { tmp->allocate (ext, 0, h5data); } else { tmp->allocate (ext, 0); } // Initialise with what is found in the file -- this does // not guarantee that everything is initialised. const bbox overlap = tmp->extent() & data->extent(); regions_read.at(Carpet::map) |= overlap; //cout << "overlap " << overlap << endl; //cout << "tmp->extent " << tmp->extent() << endl; //cout << "data->extent " << data->extent() << endl; // Copy into grid function for (comm_state 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 == rl if (CCTK_MyProc(cctkGH)==0 && want_dataset) { free (h5data); } #endif } // loop over datasets // Close the file if (CCTK_MyProc(cctkGH)==0) { if (verbose) CCTK_VInfo (CCTK_THORNSTRING, "Closing file"); 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& thedd = *arrdata.at(group).at(m).dd; ibset all_exterior; for (size_t c=0; cdo_inVars); for (int n=0; ndo_inVars[n]) { char * const fullname = CCTK_FullName(n); assert (fullname); const int ierr = InputVarAs (cctkGH, fullname, basefilename); if (! ierr) { ++ num_vars_read; } free (fullname); } } return num_vars_read; } int CarpetIOHDF5ReadData (CCTK_ARGUMENTS) { DECLARE_CCTK_ARGUMENTS; return InputGH(cctkGH); } } // namespace CarpetIOHDF5