Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Dumping hdf5 parameters #409

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 2 additions & 15 deletions src/global/global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,9 @@ bool Old_Style_Parse_Param(const char *name, const char *value, struct Parameter

void Init_Param_Struct_Members(ParameterMap &param, struct Parameters *parms);

/*! \fn void Parse_Params(char *param_file, struct Parameters * parms);
* \brief Reads the parameters in the given file into a structure. */
void Parse_Params(char *param_file, struct Parameters *parms, int argc, char **argv)
{
FILE *fp = fopen(param_file, "r");
if (fp == NULL) {
chprintf("Exiting at file %s line %d: failed to read param file %s \n", __FILE__, __LINE__, param_file);
exit(1);
return;
}

// read/parse the parameters in the file and cmd-args into pmap
ParameterMap pmap(fp, argc, argv);
fclose(fp);
void Parse_Params(ParameterMap &pmap, struct Parameters *parms)
{

#ifdef COSMOLOGY
// Initialize file name as an empty string
Expand All @@ -141,8 +130,6 @@ void Parse_Params(char *param_file, struct Parameters *parms, int argc, char **a
Init_Param_Struct_Members(pmap, parms);

pmap.warn_unused_parameters(optionalParams);

// it may be useful to return pmap in the future so that we can use it to initialize individual modules
}

/*! \fn void Parse_Param(char *name,char *value, struct Parameters *parms);
Expand Down
13 changes: 10 additions & 3 deletions src/global/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,16 @@ struct Parameters {
#endif
};

/*! \fn void parse_params(char *param_file, struct Parameters * parms);
* \brief Reads the parameters in the given file into a structure. */
extern void Parse_Params(char *param_file, struct Parameters *parms, int argc, char **argv);
class ParameterMap;

/*! \brief Reads the from the ParameterMap into the primary Parameters structure.
*
* \note
* We opt to pass in an existing ParamterMap (by reference), rather than having this
* function return a ParameterMap, so that we can get away with simply forward-declaring
* ParameterMap (rather than including the full definition)
*/
void Parse_Params(ParameterMap& pmap, struct Parameters *parms);

/*! \fn int is_param_valid(char *name);
* \brief Verifies that a param is valid (even if not needed). Avoids
Expand Down
3 changes: 1 addition & 2 deletions src/grid/grid3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -813,8 +813,7 @@ class Grid3D
void Transfer_Particles_Density_Boundaries(struct Parameters P);
void Copy_Particles_Density_Buffer_Device_to_Host(int direction, int side, Real *buffer_d, Real *buffer_h);
// void Transfer_Particles_Boundaries( struct Parameters P );
void WriteData_Particles(struct Parameters P, int nfile);
void OutputData_Particles(struct Parameters P, int nfile);
void OutputData_Particles(struct Parameters P, const ParameterMap& pmap, int nfile);
void Load_Particles_Data(struct Parameters P);
#ifdef HDF5
void Write_Particles_Header_HDF5(hid_t file_id);
Expand Down
15 changes: 14 additions & 1 deletion src/io/ParameterMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ static char* my_trim(char* s)
return s;
}

ParameterMap::ParameterMap(std::FILE* fp, int argc, char** argv)
ParameterMap::ParameterMap(std::FILE* fp, int argc, char** argv, bool close_fp)
{
int buf;
char *s, buff[256];
Expand Down Expand Up @@ -164,8 +164,21 @@ ParameterMap::ParameterMap(std::FILE* fp, int argc, char** argv)
entries_[std::string(name)] = {std::string(value), false};
chprintf("Override with %s=%s\n", name, value);
}

if (close_fp) std::fclose(fp);
}

/*! try to open a file. */
static std::FILE* open_file_(const std::string& fname) {
std::FILE *fp = std::fopen(fname.c_str(), "r");
if (fp == nullptr) CHOLLA_ERROR("failed to read parameter file: %s", fname.c_str());
return fp;
}

ParameterMap::ParameterMap(const std::string& fname, int argc, char** argv)
: ParameterMap(open_file_(fname), argc, argv, true)
{ }

int ParameterMap::warn_unused_parameters(const std::set<std::string>& ignore_params, bool abort_on_warning,
bool suppress_warning_msg) const
{
Expand Down
26 changes: 25 additions & 1 deletion src/io/ParameterMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,35 @@ class ParameterMap
* We pass in a ``std::FILE`` object rather than a filename-string because that makes testing
* easier.
*/
ParameterMap(std::FILE* f, int argc, char** argv);
ParameterMap(std::FILE* fp, int argc, char** argv, bool close_fp = false);

/* An overload for the constructor */
ParameterMap(const std::string& fname, int argc, char** argv);

/* queries the number of parameters (mostly for testing purposes) */
std::size_t size() { return entries_.size(); }

/*! \brief Applies the given function object ``f`` on each parameter, parameter-value pair
*
* Since the parameter file-format doesn't have syntactic typing, the value is always
* provided as a string. The function object should have accept 2 arguments of type
* ``const std::string&``.
*
* \note
* This method has no impact on whether a value has been "accessed"
*
* \note
* In the future, it may be better to provide an iterator rather than this function.
*/
template<typename Fn>
void for_each(Fn f) const {
for (const auto& kv_pair : entries_) {
const std::string& key = kv_pair.first;
const std::string& val = kv_pair.second.param_str;
f(key, val);
}
}

/* queries whether the parameter exists. */
bool has_param(const std::string& param) { return entries_.find(param) != entries_.end(); }

Expand Down
85 changes: 79 additions & 6 deletions src/io/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ void Write_Message_To_Log_File(const char *message)
}

/* Write Cholla Output Data */
void Write_Data(Grid3D &G, struct Parameters P, int nfile)
void Write_Data(Grid3D &G, struct Parameters P, const ParameterMap& pmap, int nfile)
{
// we don't do anything with pmap yet
cudaMemcpy(G.C.density, G.C.device, G.H.n_fields * G.H.n_cells * sizeof(Real), cudaMemcpyDeviceToHost);

chprintf("\nSaving Snapshot: %d \n", nfile);
Expand Down Expand Up @@ -126,14 +127,14 @@ void Write_Data(Grid3D &G, struct Parameters P, int nfile)
#ifndef ONLY_PARTICLES
/*call the data output routine for Hydro data*/
if (nfile % P.n_hydro == 0) {
Output_Data(G, P, nfile);
Output_Data(G, P, pmap, nfile);
}
#endif

// This function does other checks to make sure it is valid (3D only)
#ifdef HDF5
if (P.n_out_float32 && nfile % P.n_out_float32 == 0) {
Output_Float32(G, P, nfile);
Output_Float32(G, P, pmap, nfile);
}
#endif

Expand All @@ -157,7 +158,7 @@ void Write_Data(Grid3D &G, struct Parameters P, int nfile)

#ifdef PARTICLES
if (nfile % P.n_particle == 0) {
G.WriteData_Particles(P, nfile);
G.OutputData_Particles(P, pmap, nfile);
}
#endif

Expand Down Expand Up @@ -195,7 +196,7 @@ void Write_Data(Grid3D &G, struct Parameters P, int nfile)
}

/* Output the grid data to file. */
void Output_Data(Grid3D &G, struct Parameters P, int nfile)
void Output_Data(Grid3D &G, struct Parameters P, const ParameterMap& pmap, int nfile)
{
// create the filename
std::string filename = FnameTemplate(P).format_fname(nfile, "");
Expand Down Expand Up @@ -233,6 +234,9 @@ void Output_Data(Grid3D &G, struct Parameters P, int nfile)
// Write the header (file attributes)
G.Write_Header_HDF5(file_id);

// Record a copy of the parameter values
Write_HDF5_pmap(file_id, pmap);

// write the conserved variables to the output file
G.Write_Grid_HDF5(file_id);

Expand Down Expand Up @@ -264,7 +268,7 @@ void Output_Data(Grid3D &G, struct Parameters P, int nfile)
#endif
}

void Output_Float32(Grid3D &G, struct Parameters P, int nfile)
void Output_Float32(Grid3D &G, struct Parameters P, const ParameterMap& pmap, int nfile)
{
#ifdef HDF5
Header H = G.H;
Expand Down Expand Up @@ -293,6 +297,9 @@ void Output_Float32(Grid3D &G, struct Parameters P, int nfile)
// Write the header (file attributes)
G.Write_Header_HDF5(file_id);

// Record a copy of the parameter values
Write_HDF5_pmap(file_id, pmap);

// write the conserved variables to the output file

// 3-D Case
Expand Down Expand Up @@ -1117,6 +1124,72 @@ void Grid3D::Write_Grid_Binary(FILE *fp)
}

#ifdef HDF5

/*! Writes a ParameterMap to a group within an hdf5 file called "parameters", which will be created by this function.
*
* @return
* This function simply returns true if everything went well or false if there was some kind of problem.
*
* @note
* While most functions of this style return a herr_t, it's pretty meaningless. In fact, returning an herr_t from
* any function that involves multiple hdf5 calls will be meaningless, unless you also find a way to also encode
* the exact context an error occured in within the return value. Until we come up with a more meaningful solution,
* returning true or false provides just as much information.
*/
bool Write_HDF5_pmap(hid_t file_id, const ParameterMap& pmap) {
const char* grp_name = "parameters";
const hid_t grp_id = H5Gcreate2(file_id, grp_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (grp_id == H5I_INVALID_HID){
fprintf(stderr, "problem creating the \"%s\" group\n", grp_name);
return H5I_INVALID_HID;
}

// because the parameter file format doesn't have syntactic typing, the only robust choice for
// recording parameter values is to treat them all as strings.

// it's unfortunate that the following piece of code crops up in like 3 different places.
hid_t stringType = H5Tcopy(H5T_C_S1);
if (H5Tset_size(stringType, H5T_VARIABLE) < 0) {
H5Gclose (grp_id); // close the group
return false;
}

// Create the data space for the attributes
hid_t dataspace_id = H5Screate(H5S_SCALAR);
if (dataspace_id == H5I_INVALID_HID) {
H5Gclose (grp_id); // close the group
return false;
}

// create a variable to track whether any errors occured
bool any_err = false;

// define a lambda function that get's called for each parameter
auto serialize_param_fn = [=, &any_err](const std::string& param_name,
const std::string& param_val) -> void {
if (any_err) return; // if we already recorded an error, let's move on!

// create the attribute
hid_t attr_id = H5Acreate1(grp_id, param_name.c_str(), stringType, dataspace_id, H5P_DEFAULT);
if (attr_id == H5I_INVALID_HID) {
any_err = true;
return;
}

// write the attribute
herr_t status = H5Awrite(attr_id, stringType, param_val.c_str());
any_err = (status < 0);

// close the attribue
H5Aclose(attr_id);
};

pmap.for_each(serialize_param_fn);

H5Gclose (grp_id); // close the group
return any_err;
}

herr_t Write_HDF5_Attribute(hid_t file_id, hid_t dataspace_id, double *attribute, const char *name)
{
hid_t attribute_id = H5Acreate(file_id, name, H5T_IEEE_F64BE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
Expand Down
9 changes: 6 additions & 3 deletions src/io/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@

#include "../global/global.h"
#include "../grid/grid3D.h"
#include "../io/ParameterMap.h"

/* Write the data */
void Write_Data(Grid3D& G, struct Parameters P, int nfile);
void Write_Data(Grid3D& G, struct Parameters P, const ParameterMap& pmap, int nfile);

/* Output the grid data to file. */
void Output_Data(Grid3D& G, struct Parameters P, int nfile);
void Output_Data(Grid3D& G, struct Parameters P, const ParameterMap& pmap, int nfile);

/* Output the grid data to file as 32-bit floats. */
void Output_Float32(Grid3D& G, struct Parameters P, int nfile);
void Output_Float32(Grid3D& G, struct Parameters P, const ParameterMap& pmap, int nfile);

/* Output a projection of the grid data to file. */
void Output_Projected_Data(Grid3D& G, struct Parameters P, int nfile);
Expand Down Expand Up @@ -124,6 +125,8 @@ herr_t Read_HDF5_Dataset(hid_t file_id, float* dataset_buffer, const char* name)
herr_t Write_HDF5_Dataset(hid_t file_id, hid_t dataspace_id, double* dataset_buffer, const char* name);
herr_t Write_HDF5_Dataset(hid_t file_id, hid_t dataspace_id, float* dataset_buffer, const char* name);

bool Write_HDF5_pmap(hid_t file_id, const ParameterMap& pmap);

/* \brief After HDF5 reads data into a buffer, remap and write to grid buffer. */
void Fill_Grid_From_HDF5_Buffer(int nx, int ny, int nz, int nx_real, int ny_real, int nz_real, int n_ghost,
Real* hdf5_buffer, Real* grid_buffer);
Expand Down
14 changes: 9 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "global/global.h"
#include "grid/grid3D.h"
#include "io/io.h"
#include "io/ParameterMap.h"
#include "utils/cuda_utilities.h"
#include "utils/error_handling.h"
#ifdef FEEDBACK
Expand Down Expand Up @@ -75,8 +76,11 @@ int main(int argc, char *argv[])
// create the grid
Grid3D G;

// read in the parameters
Parse_Params(param_file, &P, argc, argv);
// read in contents from the parameter file
ParameterMap pmap(param_file, argc, argv);

// use this parameter information to populate the Parameter object
Parse_Params(pmap, &P);
// and output to screen
chprintf("Git Commit Hash = %s\n", GIT_HASH);
chprintf("Macro Flags = %s\n", MACRO_FLAGS);
Expand Down Expand Up @@ -209,7 +213,7 @@ int main(int argc, char *argv[])
if (!is_restart || G.H.Output_Now) {
// write the initial conditions to file
chprintf("Writing initial conditions to file...\n");
Write_Data(G, P, nfile);
Write_Data(G, P, pmap, nfile);
}
// add one to the output file count
nfile++;
Expand Down Expand Up @@ -339,7 +343,7 @@ int main(int argc, char *argv[])
if (G.H.t == outtime || G.H.Output_Now) {
#ifdef OUTPUT
/*output the grid data*/
Write_Data(G, P, nfile);
Write_Data(G, P, pmap, nfile);
// add one to the output file count
nfile++;
#endif // OUTPUT
Expand All @@ -355,7 +359,7 @@ int main(int argc, char *argv[])
// Exit the loop when reached the limit number of steps (optional)
if (G.H.n_step >= P.n_steps_limit and P.n_steps_limit > 0) {
#ifdef OUTPUT
Write_Data(G, P, nfile);
Write_Data(G, P, pmap, nfile);
#endif // OUTPUT
break;
}
Expand Down
9 changes: 2 additions & 7 deletions src/particles/io_particles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,6 @@ void Particles3D::Load_Particles_Data(struct Parameters *P)
#endif
}

void Grid3D::WriteData_Particles(struct Parameters P, int nfile)
{
// Write the particles data to file
OutputData_Particles(P, nfile);
}

#ifdef HDF5

void Particles3D::Load_Particles_Data_HDF5(hid_t file_id, int nfile, struct Parameters *P)
Expand Down Expand Up @@ -754,7 +748,7 @@ void Grid3D::Write_Particles_Data_HDF5(hid_t file_id)
}
#endif // HDF5

void Grid3D::OutputData_Particles(struct Parameters P, int nfile)
void Grid3D::OutputData_Particles(struct Parameters P, const ParameterMap& pmap, int nfile)
{
FILE *out;
std::string filename = FnameTemplate(P).format_fname(nfile, "_particles");
Expand All @@ -773,6 +767,7 @@ void Grid3D::OutputData_Particles(struct Parameters P, int nfile)

// Write header (file attributes)
Write_Header_HDF5(file_id);
Write_HDF5_pmap(file_id, pmap);
Write_Particles_Header_HDF5(file_id);
Write_Particles_Data_HDF5(file_id);

Expand Down
Loading