Skip to content
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
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
21 changes: 21 additions & 0 deletions src/io/ParameterMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,27 @@ class ParameterMap
/* 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
6 changes: 3 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,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 @@ -343,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 @@ -359,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