Closed xjrc closed 3 years ago
After pondering this a bit more, I've come to the conclusion that the MPI-based generate_*
functions should be centered around an adjset
input rather than topology
input. The primary reason for this is that using an adjset
as input indicates that there are shared entities between domains that need to be coordinated, where a topology
input leaves this as an open question (as well as which, if any, associated adjset
entries need to be considered). With this being said, I propose the following alternative interfaces for these functions:
blueprint::mpi::mesh::generate_{points|lines|faces}(conduit::Node& mesh, const std::string& src_adjset_path, const std::string& dst_adjset_path, const std::string& dst_topo_path, conduit::Node& s2dmap, conduit::Node& d2smap)
blueprint::mpi::mesh::generate_{centroids|sides|corners}(conduit::Node& mesh, const std::string& src_adjset_path, const std::string& dst_adjset_path, const std::string& dst_topo_path, const std::string& dst_cset_path, conduit::Node& s2dmap, conduit::Node& d2smap)
These new interfaces come with the following important considerations/caveats:
s2dmap
and d2smap
nodes contain mappings between the topology
associated with the source adjset
and the toplogy
associated with the destination adjset
; these mappings do not map between the adjset
entries themselves.generate_*
functions (i.e. generate_{points|lines|faces}
) are always association: element
(as inherting association: vertex
is always redundant).generate_*
functions (i.e. generate_{centroids|sides|corners}
) are always association: vertex
(as these cannot generate shared elements between topologies).@xjrc I agree this is a better path. Q: If we have a case where adjsets aren't in play (even in mpi land) -- folks can just use the non mpi variants? Or are their still some aspects of the MPI case that would be helpful to provide?
@cyrush: I think the answer will be better illuminated after I write some code. My current feeling is that there will be some useful pieces of independent machinery in the MPI code (e.g. for each domain in a mesh, apply a transform to a specific topology and place the results in a uniform path), but I've not thought very hard about how these pieces might look as dedicated interfaces. We should revisit this after we can look at some semi-complete code.
Sounds good
After some more pondering, I've come to the conclusion that these functions and those being written by @nselliott in #642 will require some interface retooling. This is because, unlike other blueprint::mesh::*::*
interfaces that can be called error-free assuming that the inputs pass a blueprint::mesh::*::verify
check, the new blueprint::mpi::mesh::generate_*
functions have a number of additional baked-in assumptions (e.g. that the given topologies and adjacency sets exist, that the given topology is unstructured, that the topologies match up across domains/ranks, etc.).
This could be helped by the following changes:
verify
, e.g. bool blueprint::mpi::mesh::generate_*(..., Node &info)
and allow for failure.blueprint::mpi::mesh::unsafe::generate_*
.@cyrush, @nselliott: Do you have any thoughts on this?
I think they can check the preconditions and throw a descriptive error if those preconditions aren't met. Yes it's a shift from past, but I think there are other cases where we will hit this as well (given that an empty node is now valid)
resolved in #767
In order to simplify the user burden for calling any of the
blueprint::mesh::topology::unstructured::generate_*
functions on a multi-domain mesh, the Blueprint library should include multi-domain/MPI extensions for these functions, which would handle the non-trivial task of generating newadjsets
entries based on the function invocation and original mesh contents. Here's a rough sketch of the new functions to be introduced:blueprint::mpi::mesh::generate_{points|lines|faces}(conduit::Node& mesh, const std::string& src_topo_path, const std::string& dst_topo_path, const std::string& dst_adjset_path, conduit::Node& s2dmap, conduit::Node& d2smap)
blueprint::mpi::mesh::generate_{sides|corners}(conduit::Node& mesh, const std::string& src_topo_path, const std::string& dst_topo_path, const std::string& dst_cset_path, const std::string& dst_topo_adjset_path, const std::string& dst_cset_adjset_path, conduit::Node& s2dmap, conduit::Node& d2smap)
The sketch prototypes above deviate from their uni-domain counterparts in a few key ways, which are highlighted and explained below:
std::string
Overconduit::Node
: In the uni-domain case, the caller is given more freedom in specifying the location of a derived topology because this topology exists in isolation (or, at least, it is presumed to). In the multi-domain case, these derived topologies need to share a path to signal that they are linked across domains, hence the added constraint of a path specification instead of an arbitrary node.conduit::Node
s will have the mappings embedded by domain identifier (e.g.s2dmap={"domain0": {"values": [...]}, "domain1": {"values": [...]}}
).conduit::Node
objects with per-domain entries for each spec (e.g.src_topo_path={"domain0": "topo0", "domain1", "topo1", ...}
). This interface requires additional tooling and may become confusing for users (eachpath
presents the opportunity for a disjoint per-domain mapping), but the possibility is open if required.These interfaces/stipulations will be fleshed out more as their usage within real applications is further explored/manifested.