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

replace Ascent's blueprint read with conduit read #1064

Merged
merged 5 commits into from
Dec 19, 2022
Merged
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
200 changes: 9 additions & 191 deletions src/libs/ascent/hola/ascent_hola.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <conduit_relay_io.hpp>
#include <conduit_relay_io_handle.hpp>
#include <conduit_blueprint.hpp>
#include <conduit_relay_io_blueprint.hpp>

//-----------------------------------------------------------------------------
// ascent includes
Expand All @@ -30,6 +31,7 @@
#if defined(ASCENT_MPI_ENABLED)
#include "ascent_hola_mpi.hpp"
#include <conduit_relay_mpi.hpp>
#include <conduit_relay_mpi_io_blueprint.hpp>
#endif

using namespace conduit;
Expand Down Expand Up @@ -202,196 +204,6 @@ class BlueprintTreePathGenerator

};

//-----------------------------------------------------------------------------
void relay_blueprint_mesh_read(const Node &options,
Node &data)
{
std::string root_fname = options["root_file"].as_string();

// read the root file, it can be either json or hdf5

// assume hdf5, but check for json file
std::string root_protocol = "hdf5";

// we will read only 5 bytes + keep the buffer null termed.
char buff[6] = {0,0,0,0,0,0};

// heuristic, if json, we expect to see "{" in the first 5 chars of the file.
ifstream ifs;
ifs.open(root_fname.c_str());
if(!ifs.is_open())
{
ASCENT_ERROR("failed to open relay root file: " << root_fname);
}
ifs.read((char *)buff,5);
ifs.close();

std::string test_str(buff);

if(test_str.find("{") != std::string::npos)
{
root_protocol = "json";
}

Node root_node;
relay::io::load(root_fname, root_protocol, root_node);


if(!root_node.has_child("file_pattern"))
{
ASCENT_ERROR("Root file missing 'file_pattern'");
}

if(!root_node.has_child("blueprint_index"))
{
ASCENT_ERROR("Root file missing 'blueprint_index'");
}

NodeConstIterator itr = root_node["blueprint_index"].children();
Node verify_info;
// TODO, for now lets verify the first mesh index

const Node &mesh_index = itr.next();

if( !blueprint::mesh::index::verify(mesh_index,
verify_info[itr.name()]))
{
ASCENT_ERROR("Mesh Blueprint index verify failed" << std::endl
<< verify_info.to_json());
}

std::string data_protocol = "hdf5";

if(root_node.has_child("protocol"))
{
data_protocol = root_node["protocol/name"].as_string();
}

// read the first mesh (all domains ...)

int num_domains = root_node["number_of_trees"].to_int();

BlueprintTreePathGenerator gen(root_node["file_pattern"].as_string(),
root_node["tree_pattern"].as_string(),
root_node["number_of_files"].to_int(),
num_domains,
data_protocol,
mesh_index);

std::ostringstream oss;

int domain_start = 0;
int domain_end = num_domains;

#if defined(ASCENT_MPI_ENABLED)
MPI_Comm comm = MPI_Comm_f2c(options["mpi_comm"].to_int());
int rank = relay::mpi::rank(comm);
int total_size = relay::mpi::size(comm);

int read_size = num_domains / total_size;
int rem = num_domains % total_size;
if(rank < rem)
{
read_size++;
}

conduit::Node n_read_size;
conduit::Node n_doms_per_rank;

n_read_size.set_int32(read_size);

relay::mpi::all_gather_using_schema(n_read_size,
n_doms_per_rank,
comm);
int *counts = (int*)n_doms_per_rank.data_ptr();

int rank_offset = 0;
for(int i = 0; i < rank; ++i)
{
rank_offset += counts[i];
}

domain_start = rank_offset;
domain_end = rank_offset + read_size;
#endif

relay::io::IOHandle hnd;
for(int i = domain_start ; i < domain_end; i++)
{
char domain_fmt_buff[64];
snprintf(domain_fmt_buff, sizeof(domain_fmt_buff), "%06d",i);
oss.str("");
oss << "domain_" << std::string(domain_fmt_buff);

std::string current, next;
utils::rsplit_file_path (root_fname, current, next);
std::string domain_file = utils::join_path(next, gen.GenerateFilePath(i));

hnd.open(domain_file, data_protocol);

// also need the tree path
std::string tree_path = gen.GenerateTreePath(i);

//std::string mesh_path = conduit_fmt::format("domain_{:06d}",i);
std::string mesh_path = oss.str();

Node &mesh_out = data[mesh_path];

// read components of the mesh according to the mesh index
// for each child in the index
NodeConstIterator outer_itr = mesh_index.children();
while(outer_itr.has_next())
{
const Node &outer = outer_itr.next();
std::string outer_name = outer_itr.name();

// special logic for state, since it was not included in the index
if(outer_name == "state" )
{
// we do need to read the state!
if(outer.has_child("path"))
{
hnd.read(utils::join_path(tree_path,outer["path"].as_string()),
mesh_out[outer_name]);
}
else
{
if(outer.has_child("cycle"))
{
mesh_out[outer_name]["cycle"] = outer["cycle"];
}

if(outer.has_child("time"))
{
mesh_out[outer_name]["time"] = outer["time"];
}
}
}

NodeConstIterator itr = outer.children();
while(itr.has_next())
{
const Node &entry = itr.next();
// check if it has a path
if(entry.has_child("path"))
{
std::string entry_name = itr.name();
std::string entry_path = entry["path"].as_string();
std::string fetch_path = utils::join_path(tree_path,
entry_path);
// some parts may not exist in all domains
// only read if they are there
if(hnd.has_path(fetch_path))
{
hnd.read(fetch_path,
mesh_out[outer_name][entry_name]);
}
}
}
}
}
}

//-----------------------------------------------------------------------------
void hola(const std::string &source,
const Node &options,
Expand All @@ -400,7 +212,13 @@ void hola(const std::string &source,
data.reset();
if(source == "relay/blueprint/mesh")
{
relay_blueprint_mesh_read(options,data);
std::string root_file = options["root_file"].as_string();
#if defined(ASCENT_MPI_ENABLED)
MPI_Comm comm = MPI_Comm_f2c(options["mpi_comm"].to_int());
conduit::relay::mpi::io::blueprint::load_mesh(root_file,data,comm);
#else
conduit::relay::io::blueprint::load_mesh(root_file,data);
#endif
}
else if(source == "hola_mpi")
{
Expand Down
121 changes: 10 additions & 111 deletions src/libs/dray/io/blueprint_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
#include <conduit.hpp>
#include <conduit_blueprint.hpp>
#include <conduit_relay.hpp>
#include <conduit_relay_io_blueprint.hpp>

#include <fstream>

#ifdef DRAY_MPI_ENABLED
#include <mpi.h>
#include <conduit_relay_mpi.hpp>
#include <conduit_relay_mpi_io_blueprint.hpp>
#endif

using namespace conduit;
Expand Down Expand Up @@ -171,115 +173,6 @@ class BlueprintTreePathGenerator
Node m_mesh_index;
};

void relay_blueprint_mesh_read (const Node &options, Node &data)
{
std::string full_root_fname = options["root_file"].as_string ();

// read the root file, it can be either json or hdf5

// assume hdf5, but check for json file
std::string root_protocol = "hdf5";
char buff[6] = { 0, 0, 0, 0, 0, 0};

// heuristic, if json, we expect to see "{" in the first 5 chars of the file.
std::ifstream ifs;
ifs.open (full_root_fname.c_str ());
if (!ifs.is_open ())
{
DRAY_ERROR ("failed to open relay root file: " + full_root_fname);
}
ifs.read ((char *)buff, 5);
ifs.close ();

std::string test_str (buff);

if (test_str.find ("{") != std::string::npos)
{
root_protocol = "json";
}

Node root_node;
relay::io::load (full_root_fname, root_protocol, root_node);

if (!root_node.has_child ("file_pattern"))
{
DRAY_ERROR ("Root file missing 'file_pattern'");
}

if (!root_node.has_child ("blueprint_index"))
{
DRAY_ERROR ("Root file missing 'blueprint_index'");
}

NodeConstIterator itr = root_node["blueprint_index"].children ();
Node verify_info;
// TODO, for now lets verify the first mesh index

const Node &mesh_index = itr.next ();

if (!blueprint::mesh::index::verify (mesh_index, verify_info[itr.name ()]))
{
std::cout << "Mesh Blueprint index verify failed" << std::endl
<< verify_info.to_json () << "\n";
}

std::string data_protocol = "hdf5";

if (root_node.has_child ("protocol"))
{
data_protocol = root_node["protocol/name"].as_string ();
}

// read the first mesh (all domains ...)

int num_domains = root_node["number_of_trees"].to_int ();
//if (num_domains != 1)
//{
// DRAY_ERROR ("only supports single domain");
//}

BlueprintTreePathGenerator gen (root_node["file_pattern"].as_string (),
root_node["tree_pattern"].as_string (),
root_node["number_of_files"].to_int (),
num_domains, data_protocol, mesh_index);

std::ostringstream oss;

int32 rank = dray::mpi_rank();
int32 size = dray::mpi_size();

int32 chunk = num_domains / size;
int32 rem = num_domains % size;

int32 domain_start;
int32 domain_end;
if(rank < rem)
{
domain_start = rank * (chunk + 1);
domain_end = domain_start + chunk + 1;
}
else
{
domain_start = rem * (chunk + 1) + (rank - rem) * chunk;
domain_end = domain_start + chunk;
}

domain_end = std::min(num_domains,domain_end);

for(int domain_id = domain_start; domain_id < domain_end; ++domain_id)
{
char domain_fmt_buff[64];
snprintf (domain_fmt_buff, sizeof (domain_fmt_buff), "%06d", domain_id);
oss.str ("");
oss << "domain_" << std::string (domain_fmt_buff);

std::string current, next;
utils::rsplit_file_path (full_root_fname, current, next);
std::string domain_file = utils::join_path (next, gen.GenerateFilePath (domain_id));
conduit::Node &domain = data.append();
relay::io::load (domain_file, data_protocol, domain);
}
}

bool is_high_order(const conduit::Node &domain)
{
Expand Down Expand Up @@ -428,7 +321,8 @@ Collection load_bp(const std::string &root_file)
DRAY_LOG_OPEN("load_bp");
Node options, data;
options["root_file"] = root_file;
detail::relay_blueprint_mesh_read (options, data);
conduit::relay::io::blueprint::load_mesh(root_file, data);

const int num_domains = data.number_of_children();
Collection collection;
DRAY_LOG_OPEN("convert_bp");
Expand All @@ -453,7 +347,12 @@ BlueprintReader::load_blueprint(const std::string &root_file,
{
conduit::Node options;
options["root_file"] = root_file;
detail::relay_blueprint_mesh_read (options, dataset);
#ifdef DRAY_MPI_ENABLED
MPI_Comm mpi_comm = MPI_Comm_f2c(dray::mpi_comm());
conduit::relay::mpi::io::blueprint::load_mesh(root_file, dataset, mpi_comm);
#else
conduit::relay::io::blueprint::load_mesh(root_file, dataset);
#endif
}

void
Expand Down
Binary file modified src/tests/_baseline_images/dray/balanced.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/tests/_baseline_images/dray/tg_mpi_volume.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.