Skip to content

Commit

Permalink
Merge remote-tracking branch 'gh/develop' into feature/gunney/bluepri…
Browse files Browse the repository at this point in the history
…nt-mesh-shaping
  • Loading branch information
gunney1 committed Jan 27, 2025
2 parents 88c6531 + b68514e commit 97b531c
Show file tree
Hide file tree
Showing 5 changed files with 451 additions and 49 deletions.
34 changes: 33 additions & 1 deletion src/axom/sidre/core/Group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2266,7 +2266,7 @@ bool Group::load(const hid_t& h5_id,
*
* Load External Data from an hdf5 file
*
* Note: this ASSUMES uses the "sidre_hdf5" protocol
* Note: this ASSUMES usage of the "sidre_hdf5" protocol
*************************************************************************
*/
bool Group::loadExternalData(const hid_t& h5_id)
Expand All @@ -2281,6 +2281,38 @@ bool Group::loadExternalData(const hid_t& h5_id)
return !(getDataStore()->getConduitErrorOccurred());
}

/*
*************************************************************************
*
* Load External Data from a path within an hdf5 file
*
* Note: this ASSUMES usage of the "sidre_hdf5" protocol
*************************************************************************
*/
bool Group::loadExternalData(const hid_t& h5_id, const std::string& group_path)
{
bool success;
std::string delim(1, getPathDelimiter());
if(group_path.empty() || group_path == delim)
{
// An empty or trivial path means the load should read from the start of
// the file.
success = loadExternalData(h5_id);
}
else
{
Node n;
createExternalLayout(n);
ConduitErrorSuppressor checkConduitCall(getDataStore());

std::string read_path("sidre/external/" + group_path);

checkConduitCall([&] { conduit::relay::io::hdf5_read(h5_id, read_path, n); });
success = !(getDataStore()->getConduitErrorOccurred());
}
return success;
}

#endif /* AXOM_USE_HDF5 */

////////////////////////////////////////////////////////////////////////
Expand Down
18 changes: 17 additions & 1 deletion src/axom/sidre/core/Group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1650,7 +1650,7 @@ class Group
std::string& name_from_file);

/*!
* \brief Load data into the Group's external views from a hdf5 handle.
* \brief Load data into the Group's external views from an hdf5 handle.
*
* No protocol argument is needed, as this only is used with the sidre_hdf5
* protocol. Returns true (success) if no Conduit I/O error occurred since
Expand All @@ -1662,6 +1662,22 @@ class Group
*/
bool loadExternalData(const hid_t& h5_id);

/*!
* \brief Load data into the Group's external views from a path into
* hdf5 handle
*
* No protocol argument is needed, as this only is used with the sidre_hdf5
* protocol. Returns true (success) if no Conduit I/O error occurred since
* this Group's DataStore was created or had its error flag cleared; false,
* if an error occurred at some point.
*
* \param h5_id hdf5 handle
* \param group_path Path pointing to this Group. This path must be the
* relative path from the top Group that was written
* to a file to this Group.
*/
bool loadExternalData(const hid_t& h5_id, const std::string& group_path);

#endif /* AXOM_USE_HDF5 */

//@}
Expand Down
155 changes: 155 additions & 0 deletions src/axom/sidre/spio/IOManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,161 @@ void IOManager::loadExternalData(sidre::Group* datagroup,
(void)m_baton->pass();
}

void IOManager::loadExternalData(sidre::Group* parent_group,
sidre::Group* load_group,
const std::string& root_file)
{
int num_files = getNumFilesFromRoot(root_file);
int num_groups = getNumGroupsFromRoot(root_file);
SLIC_ASSERT(num_files > 0);
SLIC_ASSERT(num_groups > 0);

if(m_baton)
{
if(m_baton->getNumFiles() != num_files)
{
delete m_baton;
m_baton = nullptr;
}
}

if(!m_baton)
{
m_baton = new IOBaton(m_mpi_comm, num_files, num_groups);
}

#ifdef AXOM_USE_HDF5
std::string file_pattern = getHDF5FilePattern(root_file);

std::string parent_name(parent_group->getPathName());
std::string load_name(load_group->getPathName());
axom::Path parent_path(parent_name);
axom::Path load_path(load_name);
std::vector<std::string> parent_parts(parent_path.parts());
std::vector<std::string> load_parts(load_path.parts());

size_t parent_size = parent_parts.size();
bool can_load = true;
if(load_parts.size() < parent_size)
{
can_load = false;
}

for(size_t i = 0; i < parent_size; ++i)
{
if(parent_parts[i] != load_parts[i])
{
can_load = false;
}
}

std::string subpath = load_name.substr(parent_name.size());
char delimiter = parent_group->getPathDelimiter();
if(!subpath.empty() && subpath[0] == delimiter)
{
subpath.erase(0, 1);
}

if(!subpath.empty() && !parent_group->hasGroup(subpath))
{
can_load = false;
}

int set_id = m_baton->wait();

if(can_load)
{
if(num_groups <= m_comm_size)
{
if(m_my_rank < num_groups)
{
herr_t errv;
AXOM_UNUSED_VAR(errv);

std::string hdf5_name =
getFileNameForRank(file_pattern, root_file, set_id);

hdf5_name = getSCRPath(hdf5_name);

hid_t h5_file_id = conduit::relay::io::hdf5_open_file_for_read(hdf5_name);
SLIC_ASSERT(h5_file_id >= 0);

std::string group_name = "datagroup";
if(H5Lexists(h5_file_id, group_name.c_str(), 0) <= 0)
{
group_name = fmt::sprintf("datagroup_%07d", m_my_rank);
}

hid_t h5_group_id = H5Gopen(h5_file_id, group_name.c_str(), 0);
SLIC_ASSERT(h5_group_id >= 0);

load_group->loadExternalData(h5_group_id, subpath);

errv = H5Gclose(h5_group_id);
SLIC_ASSERT(errv >= 0);

errv = H5Fclose(h5_file_id);
SLIC_ASSERT(errv >= 0);
}
}
else
{
for(int input_rank = m_my_rank; input_rank < num_groups;
input_rank += m_comm_size)
{
herr_t errv;
AXOM_UNUSED_VAR(errv);

std::string hdf5_name =
getFileNameForRank(file_pattern, root_file, input_rank);

hdf5_name = getSCRPath(hdf5_name);

hid_t h5_file_id = conduit::relay::io::hdf5_open_file_for_read(hdf5_name);
SLIC_ASSERT(h5_file_id >= 0);

std::string group_name = "datagroup";
if(H5Lexists(h5_file_id, group_name.c_str(), 0) <= 0)
{
group_name = fmt::sprintf("datagroup_%07d", input_rank);
}

hid_t h5_group_id = H5Gopen(h5_file_id, group_name.c_str(), 0);
SLIC_ASSERT(h5_group_id >= 0);

std::string input_name = fmt::sprintf("rank_%07d", input_rank);

input_name = input_name + delimiter + "sidre_input" + delimiter + subpath;

Group* one_rank_input = parent_group->getGroup(input_name);

one_rank_input->loadExternalData(h5_group_id, subpath);

errv = H5Gclose(h5_group_id);
SLIC_ASSERT(errv >= 0);

errv = H5Fclose(h5_file_id);
SLIC_ASSERT(errv >= 0);
}
}
}
else
{
SLIC_WARNING("Path from parent group "
<< parent_group->getPathName() << " to group "
<< load_group->getPathName()
<< " was not found. No external data will be loaded.");
}

#else
AXOM_UNUSED_VAR(datagroup);
SLIC_WARNING("Loading external data only only available "
<< "when Axom is configured with hdf5");
#endif /* AXOM_USE_HDF5 */

(void)m_baton->pass();
}

/*
*************************************************************************
*
Expand Down
37 changes: 37 additions & 0 deletions src/axom/sidre/spio/IOManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,48 @@ class IOManager
* This currently only works if the root file was created for protocol
* sidre_hdf5.
*
* The call to this method must follow a call to the IOManager::read with the
* same group and root file.
*
* This is intended as the third step of the three step process to load
* external data. The first step is the call to IOManager::read; the
* second step is to set valid pointers on all external views in the
* hierarchy under the passed-in group; the third step is the call to
* this method.
*
* \param group Group to fill with external data from input
* \param root_file root file containing input data
*/
void loadExternalData(sidre::Group* group, const std::string& root_file);

/*!
* \brief piecewise load of external data into a group
*
* This currently only works if the root file was created for protocol
* sidre_hdf5.
*
* This is intended as an alternative way to load external data, in a
* piecewise manner rather than loading all external data of a Sidre
* hierarchy at once. load_group is a Group somewhere in the hierarchy
* under parent_group, and only the external data for views in the
* subtree under load_group will be loaded. In the second step of the
* three step process, the calling code should set valid pointers on all
* external views in the subtree under load_group. The third step is
* to call this method. parent_group must be the same group that was
* passed to IOManager::read with the same root file.
*
* This method may be called multiple times with different instances of
* load_group representing different subtrees of the hierachy under
* parent_group.
*
* \param parent_group Group that was passed to IOManager::read
* \param load_group Group holding views to be filled with external data
* \param root_file root file containing input data
*/
void loadExternalData(sidre::Group* parent_group,
sidre::Group* load_group,
const std::string& root_file);

/*!
* \brief gets the number of files in the dataset from the specified root file
*/
Expand Down
Loading

0 comments on commit 97b531c

Please sign in to comment.