#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.16 2004/03/14 15:14:00 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 () { DECLARE_CCTK_PARAMETERS; 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); // Christian's Recovery routine if ( !(CCTK_Equals(recover,"no")) ) { ierr = IOUtil_RegisterRecover ("CarpetIOHDF5 recovery", CarpetIOHDF5_Recover); assert (! ierr); } else { // Erik's Recovery routine ierr = IOUtil_RegisterRecover ("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); } 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; void * h5data; 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); if ( !((cgdata.disttype == CCTK_DISTRIB_CONSTANT) && (arrdata[group][Carpet::map].hh->processors[reflevel][component]!=0))) { if (cgdata.disttype == CCTK_DISTRIB_CONSTANT) { assert(grouptype == CCTK_ARRAY || grouptype == CCTK_SCALAR); if(component!=0) continue; h5data = CCTK_VarDataPtrI(cctkGH,tl,n); } else { for (comm_state state; !state.done(); state.step()) { tmp->copy_from (state, data, ext); } } // Write data if (CCTK_MyProc(cctkGH)==0) { int ldim; if ( grouptype==CCTK_SCALAR ) { ldim = 1; } else { ldim = gpdim; } hsize_t shape[ldim]; for (int d=0; d=0); //cout << varname << endl; // if ( CCTK_Equals("CARPETIOASCII::next_output_iteration",varname) ) { // const int * testdata = (int * ) tmp->storage(); // cout << "testdata: " << ((int *)h5data)[0] << endl; //} // 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); if (cgdata.disttype != CCTK_DISTRIB_CONSTANT) { h5data = (void*)tmp->storage(); } herr = H5Dwrite (dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, h5data); 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; } //if( !((CCTK_DISTRIB_BLAH) } 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=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); if(grouptype == CCTK_SCALAR) { assert (gpdim+1 == rank); } else { assert (gpdim == rank); } int datalength=1; for(int i=0;i=0); ReadAttribute(dataset,"iorigin",amr_origin,dim); assert(herr>=0); if(called_from_recovery) { recovery_rl = amr_level; ReadAttribute(dataset,"carpet_component",recovery_comp); ReadAttribute(dataset,"group_timelevel",recovery_tl); ReadAttribute(dataset,"carpet_mglevel",recovery_mglevel); } } // MyProc == 0 if(called_from_recovery) { MPI_Bcast (&recovery_rl, 1, MPI_INT, 0, dist::comm); MPI_Bcast (&recovery_tl, 1, MPI_INT, 0, dist::comm); MPI_Bcast (&recovery_mglevel, 1, MPI_INT, 0, dist::comm); MPI_Bcast (&recovery_comp, 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 ((grouptype == CCTK_SCALAR || grouptype == CCTK_ARRAY) && reflevel != 0) { return 0; } cout << "amr_level: " << amr_level << " reflevel: " << reflevel << endl; if (amr_level == rl) { // Traverse all components on all levels BEGIN_MAP_LOOP(cctkGH, grouptype) { BEGIN_COMPONENT_LOOP(cctkGH, grouptype) { did_read_something = true; ggf* ff = 0; assert (var < (int)arrdata.at(group).at(Carpet::map).data.size()); ff = (ggf*)arrdata.at(group).at(Carpet::map).data.at(var); if(called_from_recovery) tl = recovery_tl; gdata* const data = (*ff) (tl, rl, component, mglevel); // Create temporary data storage on processor 0 vect str = vect(maxreflevelfact/reflevelfact); if(grouptype == CCTK_SCALAR || grouptype == CCTK_ARRAY) str = vect (1); vect lb = vect::ref(amr_origin) * str; vect ub = lb + (vect::ref(amr_dims) - 1) * str; gdata* const tmp = data->make_typed (n); cGroup cgdata; int ierr = CCTK_GroupData(group,&cgdata); assert(ierr==0); if (cgdata.disttype == CCTK_DISTRIB_CONSTANT) { assert(grouptype == CCTK_ARRAY || grouptype == CCTK_SCALAR); if (grouptype == CCTK_SCALAR) { lb[0] = arrdata[group][Carpet::map].hh->processors.at(rl).at(component); ub[0] = arrdata[group][Carpet::map].hh->processors.at(rl).at(component); for(int i=1;iprocessors.at(rl).at(component)); ub[dim-1] = ub[dim-1] + (ub[dim-1]-lb[dim-1]+1)*(arrdata[group][Carpet::map].hh->processors.at(rl).at(component)); // cout << "lb: " << lb << endl; // cout << "ub: " << ub << endl; } } const bbox ext(lb,ub,str); // cout << ext << endl; 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 << "working on component: " << component << endl; cout << "tmp->extent " << tmp->extent() << endl; cout << "data->extent " << data->extent() << endl; cout << "overlap " << overlap << endl; cout << "-----------------------------------------------------" << endl; MPI_Barrier(MPI_COMM_WORLD); // 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; if (called_from_recovery) { arrdata[group][Carpet::map].tt->set_time(reflevel,mglevel, (CCTK_REAL) ((cctkGH->cctk_time - cctk_initial_time) / (delta_time * mglevelfact)) ); } } END_MAP_LOOP; } // if amr_level == rl if (CCTK_MyProc(cctkGH)==0) { free (h5data); } return did_read_something; } 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& 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