28 std::vector<int> remain_dims;
34inline std::map<MPI_Comm, MPICartInfo> mpi_cart_registry;
36inline void mpi_cart_registry_display( std::ostream& out = std::cout)
38 out <<
"MPI Cart registry\n";
39 for (
auto pair : detail::mpi_cart_registry)
41 auto& re = pair.second.remain_dims;
42 out <<
"Comm "<<pair.first<<
" Root "<<pair.second.root<<
" Remains size "<<re.size();
44 for(
unsigned i=0; i<re.size(); i++)
50inline void mpi_cart_registry_clear( )
52 mpi_cart_registry.clear();
55inline void mpi_cart_register_cart( MPI_Comm comm)
58 auto it = detail::mpi_cart_registry.find( comm);
59 if( it == detail::mpi_cart_registry.end())
62 dg::mpi_cartdim_get( comm, &ndims);
63 std::vector<int> remain_dims( ndims,
true);
64 detail::MPICartInfo info{ comm, remain_dims};
65 detail::mpi_cart_registry[comm] = info;
80inline void register_mpi_cart_sub( MPI_Comm comm,
const int remain_dims[], MPI_Comm newcomm)
83 detail::mpi_cart_register_cart( comm);
84 detail::MPICartInfo info = detail::mpi_cart_registry.at(comm);
85 unsigned ndims = info.remain_dims.size();
86 for(
unsigned u=0; u<ndims; u++)
87 info.remain_dims[u] = remain_dims[u];
88 detail::mpi_cart_registry[newcomm] = info;
116inline MPI_Comm
mpi_cart_sub( MPI_Comm comm, std::vector<int> remain_dims,
bool
120 dg::mpi_cartdim_get( comm, &ndims);
121 assert( (
unsigned) ndims == remain_dims.size());
123 detail::mpi_cart_register_cart( comm);
124 detail::MPICartInfo info = detail::mpi_cart_registry.at(comm);
128 for(
unsigned u=0; u<info.remain_dims.size(); u++)
129 if( info.remain_dims[u])
131 info.remain_dims[u] = remain_dims[counter];
134 assert( counter == (
int)remain_dims.size());
137 for (
auto it = detail::mpi_cart_registry.begin(); it !=
138 detail::mpi_cart_registry.end(); ++it)
144 if( it->second.root == info.root && it->second.remain_dims ==
153 if( err != MPI_SUCCESS)
155 "Cannot create Cartesian sub comm from given communicator");
156 register_mpi_cart_sub( comm, &remain_dims[0], newcomm);
189 return MPI_COMM_NULL;
190 if( comms.size() == 1)
193 std::vector<detail::MPICartInfo> infos(comms.size());
195 for(
unsigned u=0; u<comms.size(); u++)
198 infos [u] = detail::mpi_cart_registry.at(comms[u]);
199 }
catch( std::exception& e)
201 std::cerr <<
"Did not find "<<comms[u]<<
" in Registry!\n";
202 detail::mpi_cart_registry_display();
207 MPI_Comm root = infos[0].root;
208 for(
unsigned u=0; u<comms.size(); u++)
209 if( infos[u].root != root)
211 "In mpi_cart_kron all comms must have same root comm "
212 <<root<<
" Offending comm number "<<u<<
" with root "
214 auto root_info = detail::mpi_cart_registry.at(root);
215 size_t ndims = root_info.remain_dims.size();
216 std::vector<int> remain_dims( ndims,
false) ;
217 unsigned current_free_k=0;
218 for(
unsigned u=0; u<comms.size(); u++)
220 for(
unsigned k=0; k<ndims; k++)
221 if( infos[u].remain_dims[k])
225 "Cannot form kronecker product with given communicators as remaining dims must be orthogonal ");
226 if( k < current_free_k)
228 "Cannot form kronecker product with communicators in reverse order compared to original ");
229 remain_dims[k] = infos[u].remain_dims[k];
230 current_free_k = k+1;
240template<
class Vector>
243 return mpi_cart_kron( std::vector<MPI_Comm>(comms.begin(), comms.end()));
260 dg::mpi_cartdim_get( comm, &ndims);
262 std::vector<MPI_Comm> comms(ndims);
263 for(
int u=0; u<ndims; u++)
265 std::vector<int> remain_dims(ndims, 0);
285 std::array<MPI_Comm, Nd> arr;
286 std::copy_n(
split.begin(), Nd, arr.begin());
class intended for the use in throw statements
Definition exceptions.h:83
small class holding a stringstream
Definition exceptions.h:29
Error classes or the dg library.
#define _ping_
Definition exceptions.h:12
std::array< MPI_Comm, Nd > mpi_cart_split_as(MPI_Comm comm)
Same as mpi_cart_split but different return type.
Definition mpi_kron.h:282
std::vector< MPI_Comm > mpi_cart_split(MPI_Comm comm)
Split a Cartesian communicator along each dimensions.
Definition mpi_kron.h:256
MPI_Comm mpi_cart_sub(MPI_Comm comm, std::vector< int > remain_dims, bool duplicate=false)
Call and register a call to MPI_Cart_sub with the dg library.
Definition mpi_kron.h:116
MPI_Comm mpi_cart_kron(std::vector< MPI_Comm > comms)
Form a (transposed) Kronecker product among Cartesian communicators.
Definition mpi_kron.h:184
void split(SharedContainer &in, std::vector< View< SharedContainer > > &out, const aRealTopology3d< real_type > &grid)
Split a vector into planes along the last dimension (fast version)
Definition split_and_join.h:32
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...