48 #ifndef LIB_MPI_MULTIDOMAIN_H_
49 #define LIB_MPI_MULTIDOMAIN_H_
54 #include "../uniface.h"
61 template<
class CONFIG>
62 inline std::vector<std::unique_ptr<uniface<CONFIG>>>
create_uniface( std::string domain, std::vector<std::string> interfaces, MPI_Comm world = MPI_COMM_WORLD )
65 int global_size, global_rank;
66 MPI_Comm_size( world, &global_size );
67 MPI_Comm_rank( world, &global_rank );
69 std::map<int, std::string> map;
71 std::vector<int> my_hashes;
72 for(
auto &i : interfaces ) {
73 auto h = std::hash<std::string>()( i );
74 my_hashes.push_back( h );
79 if( !CONFIG::QUIET ) {
80 for(
auto &
e : map ) {
81 std::cout <<
"MUI [lib_mpi_multidomain]: Rank: " << global_rank <<
", \"" << domain
82 <<
"\" registered interface \"" <<
e.second
83 <<
"\" as " << std::hex <<
e.first << std::dec << std::endl;
87 if( global_rank == 0 ) {
88 for(
auto &
e : map ) {
89 std::cout <<
"MUI [lib_mpi_multidomain]: \"" << domain
90 <<
"\" registered interface \"" <<
e.second
91 <<
"\" as " << std::hex <<
e.first << std::dec << std::endl;
99 std::set<int> unique_ifs;
100 if( global_rank == 0 ) {
101 std::vector<int> nifs =
gather(
static_cast<int>(interfaces.size()), world );
102 std::vector<int> displs( global_size + 1, 0 );
103 std::partial_sum( nifs.begin(), nifs.end(), displs.begin() + 1 );
105 std::vector<int> all_hashes( displs.back() );
106 MPI_Gatherv( my_hashes.data(), my_hashes.size(), MPI_INT, all_hashes.data(), nifs.data(), displs.data(), MPI_INT, 0, world );
108 for(
auto &i : all_hashes ) unique_ifs.insert( i );
109 n_unique = unique_ifs.size();
110 std::cout <<
"MUI Info [lib_mpi_multidomain]: " << n_unique <<
" distinct interface(s) found" << std::endl;
112 gather(
static_cast<int>(interfaces.size()), world );
113 MPI_Gatherv( my_hashes.data(), my_hashes.size(), MPI_INT, NULL, NULL, NULL, MPI_INT, 0, world );
116 MPI_Barrier( world );
117 MPI_Bcast( &n_unique, 1, MPI_INT, 0, world );
118 std::vector<int> uniq_hashes( n_unique );
119 if( global_rank == 0 ) uniq_hashes.assign( unique_ifs.begin(), unique_ifs.end() );
120 MPI_Bcast( uniq_hashes.data(), n_unique, MPI_INT, 0, world );
122 std::vector<uniface<CONFIG>*> unifaces;
123 for(
auto &i : uniq_hashes ) {
125 if( map.find( i ) != map.end() ) {
126 MPI_Comm_split( world, 1, global_rank, &comm_ifs );
128 MPI_Comm_rank( comm_ifs, &comm_rank );
129 if( comm_rank == 0 ) {
130 std::cout <<
"MUI [lib_mpi_multidomain]: Setting up interface " << map[i] <<
" [" << std::hex << i
131 << std::dec <<
"] (rank ids are local to each interface)" << std::endl;
133 std::string full_uri(
"mpi://" );
134 full_uri = full_uri + domain +
"/" + map[i];
137 MPI_Comm_split( world, 0, global_rank, &comm_ifs );
140 MPI_Barrier( world );
144 std::vector<std::unique_ptr<uniface<CONFIG>>> unifaces_sorted;
146 for (
const auto &orig_inter : interfaces) {
147 for (
auto &uni : unifaces) {
148 if( uni->uri_path().compare(orig_inter) == 0 ) {
155 return unifaces_sorted;
159 template<
typename IteratorT>
161 typename std::decay<decltype(**begin)>::type::time_type t) {
162 for(
auto it = begin; it != end; ++it) {
168 for(
auto it = begin; it != end; ++it) {
Definition: comm_mpi_smart.h:62
Class definition of base MPI communicator.
MPI data types used internally by MUI.
Base class to contain and manipulate a unique URI (Uniform Resource Identifier).
std::vector< T > gather(T t, MPI_Comm comm)
Definition: lib_mpi_helper.h:68
void sync_all(IteratorT begin, IteratorT end, typename std::decay< decltype(**begin)>::type::time_type t)
Definition: lib_mpi_multidomain.h:160
std::vector< std::unique_ptr< uniface< CONFIG > > > create_uniface(std::string domain, std::vector< std::string > interfaces, MPI_Comm world=MPI_COMM_WORLD)
Definition: lib_mpi_multidomain.h:62