Skip to content

Commit 97b531c

Browse files
committed
Merge remote-tracking branch 'gh/develop' into feature/gunney/blueprint-mesh-shaping
2 parents 88c6531 + b68514e commit 97b531c

File tree

5 files changed

+451
-49
lines changed

5 files changed

+451
-49
lines changed

src/axom/sidre/core/Group.cpp

+33-1
Original file line numberDiff line numberDiff line change
@@ -2266,7 +2266,7 @@ bool Group::load(const hid_t& h5_id,
22662266
*
22672267
* Load External Data from an hdf5 file
22682268
*
2269-
* Note: this ASSUMES uses the "sidre_hdf5" protocol
2269+
* Note: this ASSUMES usage of the "sidre_hdf5" protocol
22702270
*************************************************************************
22712271
*/
22722272
bool Group::loadExternalData(const hid_t& h5_id)
@@ -2281,6 +2281,38 @@ bool Group::loadExternalData(const hid_t& h5_id)
22812281
return !(getDataStore()->getConduitErrorOccurred());
22822282
}
22832283

2284+
/*
2285+
*************************************************************************
2286+
*
2287+
* Load External Data from a path within an hdf5 file
2288+
*
2289+
* Note: this ASSUMES usage of the "sidre_hdf5" protocol
2290+
*************************************************************************
2291+
*/
2292+
bool Group::loadExternalData(const hid_t& h5_id, const std::string& group_path)
2293+
{
2294+
bool success;
2295+
std::string delim(1, getPathDelimiter());
2296+
if(group_path.empty() || group_path == delim)
2297+
{
2298+
// An empty or trivial path means the load should read from the start of
2299+
// the file.
2300+
success = loadExternalData(h5_id);
2301+
}
2302+
else
2303+
{
2304+
Node n;
2305+
createExternalLayout(n);
2306+
ConduitErrorSuppressor checkConduitCall(getDataStore());
2307+
2308+
std::string read_path("sidre/external/" + group_path);
2309+
2310+
checkConduitCall([&] { conduit::relay::io::hdf5_read(h5_id, read_path, n); });
2311+
success = !(getDataStore()->getConduitErrorOccurred());
2312+
}
2313+
return success;
2314+
}
2315+
22842316
#endif /* AXOM_USE_HDF5 */
22852317

22862318
////////////////////////////////////////////////////////////////////////

src/axom/sidre/core/Group.hpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -1650,7 +1650,7 @@ class Group
16501650
std::string& name_from_file);
16511651

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

1665+
/*!
1666+
* \brief Load data into the Group's external views from a path into
1667+
* hdf5 handle
1668+
*
1669+
* No protocol argument is needed, as this only is used with the sidre_hdf5
1670+
* protocol. Returns true (success) if no Conduit I/O error occurred since
1671+
* this Group's DataStore was created or had its error flag cleared; false,
1672+
* if an error occurred at some point.
1673+
*
1674+
* \param h5_id hdf5 handle
1675+
* \param group_path Path pointing to this Group. This path must be the
1676+
* relative path from the top Group that was written
1677+
* to a file to this Group.
1678+
*/
1679+
bool loadExternalData(const hid_t& h5_id, const std::string& group_path);
1680+
16651681
#endif /* AXOM_USE_HDF5 */
16661682

16671683
//@}

src/axom/sidre/spio/IOManager.cpp

+155
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,161 @@ void IOManager::loadExternalData(sidre::Group* datagroup,
465465
(void)m_baton->pass();
466466
}
467467

468+
void IOManager::loadExternalData(sidre::Group* parent_group,
469+
sidre::Group* load_group,
470+
const std::string& root_file)
471+
{
472+
int num_files = getNumFilesFromRoot(root_file);
473+
int num_groups = getNumGroupsFromRoot(root_file);
474+
SLIC_ASSERT(num_files > 0);
475+
SLIC_ASSERT(num_groups > 0);
476+
477+
if(m_baton)
478+
{
479+
if(m_baton->getNumFiles() != num_files)
480+
{
481+
delete m_baton;
482+
m_baton = nullptr;
483+
}
484+
}
485+
486+
if(!m_baton)
487+
{
488+
m_baton = new IOBaton(m_mpi_comm, num_files, num_groups);
489+
}
490+
491+
#ifdef AXOM_USE_HDF5
492+
std::string file_pattern = getHDF5FilePattern(root_file);
493+
494+
std::string parent_name(parent_group->getPathName());
495+
std::string load_name(load_group->getPathName());
496+
axom::Path parent_path(parent_name);
497+
axom::Path load_path(load_name);
498+
std::vector<std::string> parent_parts(parent_path.parts());
499+
std::vector<std::string> load_parts(load_path.parts());
500+
501+
size_t parent_size = parent_parts.size();
502+
bool can_load = true;
503+
if(load_parts.size() < parent_size)
504+
{
505+
can_load = false;
506+
}
507+
508+
for(size_t i = 0; i < parent_size; ++i)
509+
{
510+
if(parent_parts[i] != load_parts[i])
511+
{
512+
can_load = false;
513+
}
514+
}
515+
516+
std::string subpath = load_name.substr(parent_name.size());
517+
char delimiter = parent_group->getPathDelimiter();
518+
if(!subpath.empty() && subpath[0] == delimiter)
519+
{
520+
subpath.erase(0, 1);
521+
}
522+
523+
if(!subpath.empty() && !parent_group->hasGroup(subpath))
524+
{
525+
can_load = false;
526+
}
527+
528+
int set_id = m_baton->wait();
529+
530+
if(can_load)
531+
{
532+
if(num_groups <= m_comm_size)
533+
{
534+
if(m_my_rank < num_groups)
535+
{
536+
herr_t errv;
537+
AXOM_UNUSED_VAR(errv);
538+
539+
std::string hdf5_name =
540+
getFileNameForRank(file_pattern, root_file, set_id);
541+
542+
hdf5_name = getSCRPath(hdf5_name);
543+
544+
hid_t h5_file_id = conduit::relay::io::hdf5_open_file_for_read(hdf5_name);
545+
SLIC_ASSERT(h5_file_id >= 0);
546+
547+
std::string group_name = "datagroup";
548+
if(H5Lexists(h5_file_id, group_name.c_str(), 0) <= 0)
549+
{
550+
group_name = fmt::sprintf("datagroup_%07d", m_my_rank);
551+
}
552+
553+
hid_t h5_group_id = H5Gopen(h5_file_id, group_name.c_str(), 0);
554+
SLIC_ASSERT(h5_group_id >= 0);
555+
556+
load_group->loadExternalData(h5_group_id, subpath);
557+
558+
errv = H5Gclose(h5_group_id);
559+
SLIC_ASSERT(errv >= 0);
560+
561+
errv = H5Fclose(h5_file_id);
562+
SLIC_ASSERT(errv >= 0);
563+
}
564+
}
565+
else
566+
{
567+
for(int input_rank = m_my_rank; input_rank < num_groups;
568+
input_rank += m_comm_size)
569+
{
570+
herr_t errv;
571+
AXOM_UNUSED_VAR(errv);
572+
573+
std::string hdf5_name =
574+
getFileNameForRank(file_pattern, root_file, input_rank);
575+
576+
hdf5_name = getSCRPath(hdf5_name);
577+
578+
hid_t h5_file_id = conduit::relay::io::hdf5_open_file_for_read(hdf5_name);
579+
SLIC_ASSERT(h5_file_id >= 0);
580+
581+
std::string group_name = "datagroup";
582+
if(H5Lexists(h5_file_id, group_name.c_str(), 0) <= 0)
583+
{
584+
group_name = fmt::sprintf("datagroup_%07d", input_rank);
585+
}
586+
587+
hid_t h5_group_id = H5Gopen(h5_file_id, group_name.c_str(), 0);
588+
SLIC_ASSERT(h5_group_id >= 0);
589+
590+
std::string input_name = fmt::sprintf("rank_%07d", input_rank);
591+
592+
input_name = input_name + delimiter + "sidre_input" + delimiter + subpath;
593+
594+
Group* one_rank_input = parent_group->getGroup(input_name);
595+
596+
one_rank_input->loadExternalData(h5_group_id, subpath);
597+
598+
errv = H5Gclose(h5_group_id);
599+
SLIC_ASSERT(errv >= 0);
600+
601+
errv = H5Fclose(h5_file_id);
602+
SLIC_ASSERT(errv >= 0);
603+
}
604+
}
605+
}
606+
else
607+
{
608+
SLIC_WARNING("Path from parent group "
609+
<< parent_group->getPathName() << " to group "
610+
<< load_group->getPathName()
611+
<< " was not found. No external data will be loaded.");
612+
}
613+
614+
#else
615+
AXOM_UNUSED_VAR(datagroup);
616+
SLIC_WARNING("Loading external data only only available "
617+
<< "when Axom is configured with hdf5");
618+
#endif /* AXOM_USE_HDF5 */
619+
620+
(void)m_baton->pass();
621+
}
622+
468623
/*
469624
*************************************************************************
470625
*

src/axom/sidre/spio/IOManager.hpp

+37
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,48 @@ class IOManager
289289
* This currently only works if the root file was created for protocol
290290
* sidre_hdf5.
291291
*
292+
* The call to this method must follow a call to the IOManager::read with the
293+
* same group and root file.
294+
*
295+
* This is intended as the third step of the three step process to load
296+
* external data. The first step is the call to IOManager::read; the
297+
* second step is to set valid pointers on all external views in the
298+
* hierarchy under the passed-in group; the third step is the call to
299+
* this method.
300+
*
292301
* \param group Group to fill with external data from input
293302
* \param root_file root file containing input data
294303
*/
295304
void loadExternalData(sidre::Group* group, const std::string& root_file);
296305

306+
/*!
307+
* \brief piecewise load of external data into a group
308+
*
309+
* This currently only works if the root file was created for protocol
310+
* sidre_hdf5.
311+
*
312+
* This is intended as an alternative way to load external data, in a
313+
* piecewise manner rather than loading all external data of a Sidre
314+
* hierarchy at once. load_group is a Group somewhere in the hierarchy
315+
* under parent_group, and only the external data for views in the
316+
* subtree under load_group will be loaded. In the second step of the
317+
* three step process, the calling code should set valid pointers on all
318+
* external views in the subtree under load_group. The third step is
319+
* to call this method. parent_group must be the same group that was
320+
* passed to IOManager::read with the same root file.
321+
*
322+
* This method may be called multiple times with different instances of
323+
* load_group representing different subtrees of the hierachy under
324+
* parent_group.
325+
*
326+
* \param parent_group Group that was passed to IOManager::read
327+
* \param load_group Group holding views to be filled with external data
328+
* \param root_file root file containing input data
329+
*/
330+
void loadExternalData(sidre::Group* parent_group,
331+
sidre::Group* load_group,
332+
const std::string& root_file);
333+
297334
/*!
298335
* \brief gets the number of files in the dataset from the specified root file
299336
*/

0 commit comments

Comments
 (0)