Skip to content

Commit

Permalink
Merge pull request #51 from LLNL/feature/elliott/bp-generate
Browse files Browse the repository at this point in the history
Make blueprint index generation accept mesh path instead of mesh name
  • Loading branch information
nselliott committed Jun 11, 2019
2 parents 1043eee + 6978b2c commit 14fb05c
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 38 deletions.
4 changes: 3 additions & 1 deletion src/axom/sidre/core/DataStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,9 @@ bool DataStore::generateBlueprintIndex(const std::string& domain_path,
conduit::Node mesh_node;
domain->createNativeLayout(mesh_node);

Group* bpindex = getRoot()->createGroup(index_path);
Group* bpindex = getRoot()->hasGroup(index_path)
? getRoot()->getGroup(index_path)
: getRoot()->createGroup(index_path);

bool success = false;
conduit::Node info;
Expand Down
146 changes: 140 additions & 6 deletions src/axom/sidre/examples/sidre_createdatastore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,34 @@
* visualization.
*/

/*
* Summary of the functions called by main this example:
*
* create_datastore -- Builds a DataStore containing various Groups,
* Views, Buffers, and Attributes
*
* create_tiny_datastore -- Builds a DataStore that holds a small 3D mesh
* conforming to the conduit mesh blueprint
*
* access_datastore -- Exercises access methods that get data from
* the DataStore created by create_datastore
*
* save_as_blueprint -- Generates a blueprint index and writes data
* to file using direct calls to conduit
*
* generate_blueprint -- Generates a blueprint index and writes data
* to file using Sidre DataStore and Group calls
*
* generate_blueprint_to_path -- Similar to above, but uses path arguments to
* find data deeper in Sidre hierarchy
*
* generate_spio_blueprint -- Uses SPIO/IOManager calls to write data to
* file and generate blueprint index
*
* generate_blueprint_to_path -- Similar to above, but uses path arguments to
* find data deeper in Sidre hierarchy
*/

/* This example code contains snippets used in the Sidre Sphinx documentation.
* They begin and end with comments
*
Expand All @@ -29,8 +57,8 @@
* serial_io_save_end
* tiny_create_start
* tiny_create_end
* blueprint_restructure_start
* blueprint_restructure_end
* blueprint_restructure_save_start
* blueprint_restructure_save_end
* blueprint_save_start
* blueprint_save_end
*
Expand Down Expand Up @@ -329,7 +357,8 @@ void save_as_blueprint(DataStore* ds) {
// _blueprint_restructure_save_start
conduit::Node info, mesh_node, root_node;
cds.getRoot()->createNativeLayout(mesh_node);
if (conduit::blueprint::verify("mesh", mesh_node[mesh_name], info))
std::string bp_protocol = "mesh";
if (conduit::blueprint::verify(bp_protocol, mesh_node[mesh_name], info))
{
// Generate the Conduit index
conduit::Node & index = root_node["blueprint_index"];
Expand Down Expand Up @@ -389,7 +418,8 @@ void generate_blueprint(DataStore* ds) {
// _blueprint_generate_save_start
conduit::Node info, mesh_node, root_node;
cds.getRoot()->createNativeLayout(mesh_node);
if (conduit::blueprint::verify("mesh", mesh_node[domain_mesh], info))
std::string bp_protocol = "mesh";
if (conduit::blueprint::verify(bp_protocol, mesh_node[domain_mesh], info))
{
std::string bp("rootfile_data/blueprint_index/automesh");

Expand All @@ -415,6 +445,61 @@ void generate_blueprint(DataStore* ds) {
// _blueprint_generate_save_end
}

void generate_blueprint_to_path(DataStore* ds) {
// _blueprint_generate_path_start
// Conduit needs a specific hierarchy.
// For this example, we locate the domain data at a path
// that is not the top level of its Sidre heirarchy.
DataStore cds;
std::string domain_name = "domain";
std::string domain_location = "domain_data/level/domains/" + domain_name;
std::string mesh_name = "pathmesh";
std::string domain_mesh = domain_location + "/" + mesh_name;

Group* mroot = cds.getRoot()->createGroup(domain_location);
Group* coords = mroot->createGroup(mesh_name + "/coordsets/coords");
Group* topos = mroot->createGroup(mesh_name + "/topologies");
// no material sets in this example
Group* fields = mroot->createGroup(mesh_name + "/fields");
// no adjacency sets in this (single-domain) example
// _blueprint_generate_path_end

setup_blueprint_coords(ds, coords);

setup_blueprint_topos(ds, topos);

setup_blueprint_fields(ds, fields);

// _blueprint_generate_path_save_start
conduit::Node info, mesh_node, root_node;
cds.getRoot()->createNativeLayout(mesh_node);
std::string bp_protocol = "mesh";
if (conduit::blueprint::verify(bp_protocol, mesh_node[domain_mesh], info))
{
std::string bp("rootfile_data/blueprint_index/automesh");

cds.generateBlueprintIndex(domain_mesh, mesh_name, bp, 1);

Group* rootfile_grp = cds.getRoot()->getGroup("rootfile_data");
rootfile_grp->createViewString("protocol/name", "json");
rootfile_grp->createViewString("protocol/version", "0.1");
rootfile_grp->createViewScalar("number_of_files", 1);
rootfile_grp->createViewScalar("number_of_trees", 1);
rootfile_grp->createViewScalar("file_pattern", "pathbp.json");
rootfile_grp->createViewScalar("tree_pattern", "level/domains/domain");
rootfile_grp->save("pathbp.root", "json");

cds.getRoot()->getGroup("domain_data")->save("pathbp.json", "json");
}
else
{
std::cout << "does not conform to Mesh Blueprint: ";
info.print();
std::cout << std::endl;
}
// _blueprint_generate_path_save_end
}

#ifdef AXOM_USE_MPI
void generate_spio_blueprint(DataStore* ds) {
// _blueprint_spio_toplevel_start
Expand Down Expand Up @@ -443,10 +528,10 @@ void generate_spio_blueprint(DataStore* ds) {

conduit::Node info, mesh_node, root_node;
cds.getRoot()->createNativeLayout(mesh_node);
if (conduit::blueprint::verify("mesh", mesh_node[domain_mesh], info))
std::string bp_protocol = "mesh";
if (conduit::blueprint::verify(bp_protocol, mesh_node[domain_mesh], info))
{

std::string bp("rootfile_data/blueprint_index/automesh");
std::string bp_rootfile("bpspio.root");

writer.write(cds.getRoot()->getGroup(
Expand All @@ -458,6 +543,50 @@ void generate_spio_blueprint(DataStore* ds) {
}
// _blueprint_generate_spio_end
}


void generate_spio_blueprint_to_path(DataStore* ds) {
// _blueprint_spio_path_start
DataStore cds;
std::string domain_name = "domain";
std::string domain_location = "domain_data/level/domains/" + domain_name;
std::string mesh_name = "spiopathmesh";
std::string domain_mesh = domain_location + "/" + mesh_name;

Group* mroot = cds.getRoot()->createGroup(domain_location);
Group* coords = mroot->createGroup(mesh_name + "/coordsets/coords");
Group* topos = mroot->createGroup(mesh_name + "/topologies");
// no material sets in this example
Group* fields = mroot->createGroup(mesh_name + "/fields");
// no adjacency sets in this (single-domain) example
// _blueprint_spio_path_end

setup_blueprint_coords(ds, coords);

setup_blueprint_topos(ds, topos);

setup_blueprint_fields(ds, fields);

// _blueprint_generate_spio_path_start
IOManager writer(MPI_COMM_WORLD);

conduit::Node info, mesh_node, root_node;
cds.getRoot()->createNativeLayout(mesh_node);
std::string bp_protocol = "mesh";
if (conduit::blueprint::verify(bp_protocol, mesh_node[domain_mesh], info))
{

std::string bp_rootfile("pathbpspio.root");

writer.write(cds.getRoot()->getGroup(
"domain_data"), 1, "pathbpspio", "sidre_hdf5");

writer.writeBlueprintIndexToRootFile(&cds, domain_mesh, bp_rootfile,
"level/domains/domain/" + mesh_name);

}
// _blueprint_generate_spio_path_end
}
#endif

void serial_save_datastore_and_load_copy_lower(DataStore* ds)
Expand Down Expand Up @@ -494,10 +623,15 @@ int main(int argc, char** argv)
DataStore* bds = create_tiny_datastore();
generate_blueprint(bds);

DataStore* pds = create_tiny_datastore();
generate_blueprint_to_path(pds);

#ifdef AXOM_USE_MPI
DataStore* sds = create_tiny_datastore();
DataStore* spds = create_tiny_datastore();
MPI_Init(&argc, &argv);
generate_spio_blueprint(sds);
generate_spio_blueprint_to_path(spds);
MPI_Finalize();
#endif

Expand Down
17 changes: 13 additions & 4 deletions src/axom/sidre/spio/IOManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,7 @@ void IOManager::writeViewToRootFileAtPath(sidre::View* view,
void IOManager::writeBlueprintIndexToRootFile(DataStore* datastore,
const std::string& domain_path,
const std::string& file_name,
const std::string& mesh_name)
const std::string& mesh_path)
{
#ifdef AXOM_USE_HDF5
hid_t root_file_id =
Expand All @@ -1086,10 +1086,18 @@ void IOManager::writeBlueprintIndexToRootFile(DataStore* datastore,
AXOM_DEBUG_VAR(root_file_id);
SLIC_ASSERT(root_file_id >= 0);

std::string bp_index("blueprint_index/" + mesh_name);
std::string blueprint_name;
std::string path_to_mesh;
std::string delimiter(1, datastore->getRoot()->getPathDelimiter());

//The final name in mesh_path will be used as the name of the
//blueprint index.
conduit::utils::rsplit_string(mesh_path, delimiter, blueprint_name, path_to_mesh);

std::string bp_index("blueprint_index/" + blueprint_name);

bool success = datastore->generateBlueprintIndex(domain_path,
mesh_name, bp_index,
mesh_path, bp_index,
m_comm_size);

if (success)
Expand All @@ -1108,7 +1116,8 @@ void IOManager::writeBlueprintIndexToRootFile(DataStore* datastore,
AXOM_DEBUG_VAR(datastore);
AXOM_DEBUG_VAR(domain_path);
AXOM_DEBUG_VAR(file_name);
AXOM_DEBUG_VAR(mesh_name);
AXOM_DEBUG_VAR(mesh_path);
AXOM_DEBUG_VAR(blueprint_name);

SLIC_WARNING("Axom configured without hdf5. "
<<"writeBlueprintIndexToRootFile() only currently implemented "
Expand Down
45 changes: 41 additions & 4 deletions src/axom/sidre/spio/IOManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,19 +172,56 @@ class IOManager
* DataStore specified by domain_path argument.
*
* This currently only works if the root file was created for protocol
* sidre_hdf5.
* sidre_hdf5. This must be called after calling write().
*
* The parameters domain_path and mesh_path are related. domain_path is the
* path from the root of the DataStore to the domain that is being used to
* generate the index. mesh_path is the path from the group that was
* passed into the preceding write() call to the same domain. If write()
* was called using the root group of the DataStore, then domain_path and
* mesh_path will be identical. Otherwise mesh_path is a sub-path of
* domain_path.
*
* For example, the DataStore may contain a hierarchy of data that looks
* like this, and we want to generate a blueprint index based on the mesh
* located at "/hierarchy/domain_data/domain/blueprint_mesh":
*
* <root>
* |--hierarchy
* | |--domain_data
* | |--domain
* | | |--blueprint_mesh
* | | |--coordsets
* | | | |--...
* | | |--topologies
* | | | |--...
* | | |--fields
* | | |--...
* | |--...
* |--
*
* If write() is called using the Group located at "/hierarchy/domain_data",
* then only the Groups and Views descending from that Group are written
* to the file. To call this method, we would choose the full path in
* the DataStore "hierarchy/domain_data/domain/blueprint_mesh" for
* domain_path. For the mesh_path argument, we choose only the path that
* exists in the file: "domain/blueprint_mesh".
*
* This is not an MPI collective call. One rank writes a blueprint index
* to one root file.
*
* \param datastore DataStore containing Groups that hold domains
* that adhere to the Blueprint format
* \param domain_path path to the domain in the DataStore that will be
* \param domain_path path in the DataStore to the domain that will be
* used to generate a Blueprint index
* \param file_name name of existing root file
* \param mesh_name name of the mesh described by the Blueprint index
* \param mesh_path path in the data file to the domain that will be
* used to generate a Blueprint index
*/
void writeBlueprintIndexToRootFile(DataStore* datastore,
const std::string& domain_path,
const std::string& file_name,
const std::string& mesh_name);
const std::string& mesh_path);

/*!
* \brief read from input files
Expand Down
3 changes: 2 additions & 1 deletion src/axom/sidre/spio/interface/c_fortran/typesSPIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and
// other Axom Project Developers. See the top-level COPYRIGHT file for details.
//
// SPDX-License-Identifier: (BSD-3-Clause)
// SPDX-License-Identifier (BSD-3-Clause)
//
// For C users and C++ implementation

#ifndef TYPESSPIO_H
Expand Down
15 changes: 8 additions & 7 deletions src/axom/sidre/spio/interface/c_fortran/wrapIOManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
// Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and
// other Axom Project Developers. See the top-level COPYRIGHT file for details.
//
// SPDX-License-Identifier: (BSD-3-Clause)
// SPDX-License-Identifier (BSD-3-Clause)
//
#include "wrapIOManager.h"
#include <stdlib.h>
#include <string>
Expand Down Expand Up @@ -121,7 +122,7 @@ void SPIO_iomanager_write_group_to_root_file_bufferify(SPIO_iomanager* self,

void SPIO_iomanager_write_blueprint_index_to_root_file(SPIO_iomanager* self,
SIDRE_datastore* datastore, const char* domain_path, const char* file_name,
const char* mesh_name)
const char* mesh_path)
{
// splicer begin class.IOManager.method.write_blueprint_index_to_root_file
axom::sidre::IOManager* SH_this =
Expand All @@ -130,17 +131,17 @@ void SPIO_iomanager_write_blueprint_index_to_root_file(SPIO_iomanager* self,
static_cast<axom::sidre::DataStore*>(datastore->addr);
const std::string SH_domain_path(domain_path);
const std::string SH_file_name(file_name);
const std::string SH_mesh_name(mesh_name);
const std::string SH_mesh_path(mesh_path);
SH_this->writeBlueprintIndexToRootFile(SHCXX_datastore, SH_domain_path,
SH_file_name, SH_mesh_name);
SH_file_name, SH_mesh_path);
return;
// splicer end class.IOManager.method.write_blueprint_index_to_root_file
}

void SPIO_iomanager_write_blueprint_index_to_root_file_bufferify(
SPIO_iomanager* self, SIDRE_datastore* datastore, const char* domain_path,
int Ldomain_path, const char* file_name, int Lfile_name,
const char* mesh_name, int Lmesh_name)
const char* mesh_path, int Lmesh_path)
{
// splicer begin
// class.IOManager.method.write_blueprint_index_to_root_file_bufferify
Expand All @@ -150,9 +151,9 @@ void SPIO_iomanager_write_blueprint_index_to_root_file_bufferify(
static_cast<axom::sidre::DataStore*>(datastore->addr);
const std::string SH_domain_path(domain_path, Ldomain_path);
const std::string SH_file_name(file_name, Lfile_name);
const std::string SH_mesh_name(mesh_name, Lmesh_name);
const std::string SH_mesh_path(mesh_path, Lmesh_path);
SH_this->writeBlueprintIndexToRootFile(SHCXX_datastore, SH_domain_path,
SH_file_name, SH_mesh_name);
SH_file_name, SH_mesh_path);
return;
// splicer end
// class.IOManager.method.write_blueprint_index_to_root_file_bufferify
Expand Down

0 comments on commit 14fb05c

Please sign in to comment.