Discontinuous Galerkin Library
#include "dg/algorithm.h"
Loading...
Searching...
No Matches
mpi_projection.h
Go to the documentation of this file.
1#pragma once
2
4#include "dg/backend/index.h"
7#include "mpi_grid.h"
8#include "projection.h"
9
14namespace dg
15{
16
49template<class ConversionPolicy, class real_type>
51 const dg::IHMatrix_t<real_type>& global_cols, const ConversionPolicy& col_policy)
52{
53 // Our approach here is:
54 // 1. Convert to coo format
55 // 2. mark rows in global_cols that are communicating
56 // we need to grab the entire row to ensure reproducibility (which is guaranteed by order of computations)
57 // 3. Convert inner rows to local and move outer rows to vectors (invalidating them in inner)
58 // 4. Use global columns vector to construct MPIGather
59 // 5. Use buffer index to construct local CooMat
60 int size;
61 MPI_Comm_size( col_policy.communicator(), &size);
62 if( size == 1)
63 {
64 return { global_cols,
67 thrust::host_vector<int>{} };
68 }
69 int rank;
70 MPI_Comm_rank( col_policy.communicator(), &rank);
71
72 const dg::IHMatrix_t<real_type>& A = global_cols;
73 std::vector<int> global_row( A.num_rows(), 0);
74 thrust::host_vector<int> pids(A.num_nnz()), lIdx(A.num_nnz());
75 // 1st pass determine local rows
76 for(int i = 0; i < (int)A.num_rows(); i++)
77 for (int jj = A.row_offsets()[i]; jj < A.row_offsets()[i+1]; jj++)
78 {
79 assert( col_policy.global2localIdx( A.column_indices()[jj], lIdx[jj], pids[jj]));
80 if( pids[jj] != rank)
81 {
82 global_row[i] = 1;
83 }
84 }
85
86 // 2nd pass: distribute entries
87 thrust::host_vector<std::array<int,2>> outer_col;
88 thrust::host_vector<int> inner_row, inner_col, outer_row;
89 thrust::host_vector<real_type> inner_val, outer_val;
90 thrust::host_vector<int> row_scatter;
91 inner_row.push_back(0);
92 outer_row.push_back(0);
93 for(int i = 0; i < (int)A.num_rows(); i++)
94 {
95 for (int jj = A.row_offsets()[i]; jj < A.row_offsets()[i+1]; jj++)
96 {
97 if( global_row[i] == 1)
98 {
99 outer_col.push_back( {pids[jj],lIdx[jj]});
100 outer_val.push_back( A.values()[jj]);
101 }
102 else
103 {
104 inner_col.push_back( lIdx[jj]);
105 inner_val.push_back( A.values()[jj]);
106 }
107 }
108 if( global_row[i] == 1)
109 {
110 row_scatter.push_back(i);
111 int old_end = outer_row.back();
112 outer_row.push_back( old_end + A.row_offsets()[i+1] - A.row_offsets()[i]);
113 inner_row.push_back( inner_row[i]);
114 }
115 else
116 {
117 inner_row.push_back( inner_row[i] + A.row_offsets()[i+1] - A.row_offsets()[i]);
118 }
119 }
120 // 3. Now make MPI Gather object
122 col_policy.local_size(), inner_row, inner_col, inner_val);
123
124 thrust::host_vector<int> lColIdx;
125 auto gather_map = dg::gIdx2unique_idx( outer_col, lColIdx);
127 col_policy.communicator());
128
130 mpi_gather.buffer_size(), outer_row, lColIdx, outer_val);
131
132 return { inner, outer, mpi_gather, row_scatter};
133}
134
135
173template<class ConversionPolicy, class real_type>
175 dg::IHMatrix_t<real_type>& global, const ConversionPolicy& row_policy)
176{
177 int size;
178 MPI_Comm_size( row_policy.communicator(), &size);
179 if( size == 1)
180 {
181 return global; // no conversion necessary
182 }
183 // 0. Convert to coo matrix
184 thrust::host_vector<int> global_row_indices = dg::detail::csr2coo( global.row_offsets());
185
186 // 1. For all rows determine pid to which it belongs
187 thrust::host_vector<int> pids = dg::gIdx2gIdx( global_row_indices, row_policy);
188 std::map<int, thrust::host_vector<int>> rows, cols;
189 std::map<int, thrust::host_vector<real_type>> vals;
190 for( unsigned u=0; u<global_row_indices.size(); u++)
191 {
192 rows[pids[u]].push_back( global_row_indices[u]);
193 cols[pids[u]].push_back( global.column_indices()[u]);
194 vals[pids[u]].push_back( global.values()[u]);
195 }
196 // 2. Now send those rows to where they belong
197 auto row_buf = dg::mpi_permute( rows, row_policy.communicator());
198 auto col_buf = dg::mpi_permute( cols, row_policy.communicator());
199 auto val_buf = dg::mpi_permute( vals, row_policy.communicator());
200
202 // indices come in any order ( so we need to sort)
203 B.setFromCoo( row_policy.local_size(), global.num_cols(),
204 dg::detail::flatten_map( row_buf),
205 dg::detail::flatten_map(col_buf),
206 dg::detail::flatten_map(val_buf), true);
207 return B;
208 // 4. Reduce on identical rows/cols
209 // .... Maybe later
210}
211
244template<class ConversionPolicy, class real_type>
245void convertLocal2GlobalCols( dg::IHMatrix_t<real_type>& local, const ConversionPolicy& policy)
246{
247 // 1. For all columns determine pid to which it belongs
248 int rank=0;
249 MPI_Comm_rank( policy.communicator(), &rank);
250 thrust::host_vector<int>& local_cols = local.column_indices();
251 local.num_cols() = policy.size();
252
253 for(unsigned i=0; i<local.column_indices().size(); i++)
254 assert( policy.local2globalIdx(local_cols[i], rank, local_cols[i]) );
255 //local.set( local.num_rows(), policy.size(), local.row_offsets(), local_cols, local.values());
256}
257
258namespace create
259{
260
262//
265template<class MPITopology, typename = std::enable_if_t<dg::is_vector_v<
266 typename MPITopology::host_vector, MPIVectorTag>>>
268 g_new, const MPITopology& g_old, std::string method = "dg")
269{
271 g_new.local(), g_old.global(), method);
272 return make_mpi_matrix( mat, g_old);
273}
274// This is now dg::create::prolongation
276//template<class real_type>
277//dg::MIHMatrix_t<real_type> interpolation( const aRealMPITopology3d<real_type>&
278// g_new, const aRealMPITopology2d<real_type>& g_old,std::string method = "dg")
279//{
280// dg::IHMatrix_t<real_type> mat = dg::create::interpolation(
281// g_new.local(), g_old.global(), method);
282// return make_mpi_matrix( mat, g_old);
283//}
284
286template<class MPITopology, typename = std::enable_if_t<dg::is_vector_v<
287 typename MPITopology::host_vector, MPIVectorTag>>>
289 g_new, const MPITopology& g_old, std::string method = "dg")
290{
292 g_new.global(), g_old.local(), method);
293 convertLocal2GlobalCols( mat, g_old);
294 auto mat_loc = convertGlobal2LocalRows( mat, g_new);
295 return make_mpi_matrix( mat_loc, g_old);
296}
297
299template<class RecursiveHostVector, class real_type, size_t Nd>
301 const RecursiveHostVector& x,
303 std::array<dg::bc, Nd> bcx,
304 std::string method = "dg")
305{
307 bcx, method);
308 return make_mpi_matrix( mat, g);
309}
310
323template<class host_vector, class real_type>
325 const host_vector& x,
327 dg::bc bcx = dg::NEU,
328 std::string method = "dg")
329{
331 bcx, method);
332 return make_mpi_matrix( mat, g);
333}
346template<class host_vector, class real_type>
348 const host_vector& x,
349 const host_vector& y,
351 dg::bc bcx = dg::NEU, dg::bc bcy = dg::NEU,
352 std::string method = "dg")
353{
355 bcx, bcy, method);
356 return make_mpi_matrix( mat, g);
357}
358
371template<class host_vector, class real_type>
373 const host_vector& x,
374 const host_vector& y,
375 const host_vector& z,
377 dg::bc bcx = dg::NEU, dg::bc bcy = dg::NEU, dg::bc bcz = dg::PER,
378 std::string method = "dg")
379{
381 g.global(), bcx, bcy, bcz, method);
382 return make_mpi_matrix( mat, g);
383}
384
385
386
388
389}//namespace create
390}//namespace dg
bc
Switch between boundary conditions.
Definition enums.h:15
@ z
z direction
@ PER
periodic boundaries
Definition enums.h:16
@ NEU
Neumann on both boundaries.
Definition enums.h:20
@ y
y direction
@ x
x direction
constexpr bool is_vector_v
Utility typedef.
Definition predicate.h:75
dg::MIHMatrix_t< typename MPITopology::value_type > projection(const MPITopology &g_new, const MPITopology &g_old, std::string method="dg")
Create a projection between two grids.
Definition mpi_projection.h:288
dg::SparseMatrix< int, real_type, thrust::host_vector > interpolation(const RecursiveHostVector &x, const aRealTopology< real_type, Nd > &g, std::array< dg::bc, Nd > bcx, std::string method="dg")
Create interpolation matrix of a list of points in given grid.
Definition interpolation.h:445
void mpi_gather(const thrust::host_vector< std::array< int, 2 > > &gather_map, const ContainerType &gatherFrom, ContainerType &result, MPI_Comm comm)
Un-optimized distributed gather operation.
Definition mpi_permutation.h:148
std::map< int, MessageType > mpi_permute(const std::map< int, MessageType > &messages, MPI_Comm comm)
Exchange messages between processes in a communicator.
Definition mpi_permutation.h:90
void convertLocal2GlobalCols(dg::IHMatrix_t< real_type > &local, const ConversionPolicy &policy)
Convert a matrix with local column indices to a matrix with global column indices.
Definition mpi_projection.h:245
dg::IHMatrix_t< real_type > convertGlobal2LocalRows(const dg::IHMatrix_t< real_type > &global, const ConversionPolicy &row_policy)
Convert a (column-distributed) matrix with global row and column indices to a row distributed matrix.
Definition mpi_projection.h:174
dg::MIHMatrix_t< real_type > make_mpi_matrix(const dg::IHMatrix_t< real_type > &global_cols, const ConversionPolicy &col_policy)
Convert a (row-distributed) matrix with local row and global column indices to a row distributed MPI ...
Definition mpi_projection.h:50
dg::bc bcy
dg::bc bcx
MPI Grid objects.
MPI matrix classes.
I csr2coo(const I &csr)
Definition sparsematrix.h:45
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
Creation of projection matrices.
Distributed memory matrix class, asynchronous communication.
Definition mpi_matrix.h:395
Optimized MPI Gather operation.
Definition mpi_gather.h:673
A distributed vector contains a data container and a MPI communicator.
Definition vector_categories.h:52
The simplest implementation of aRealMPITopology3d.
Definition mpi_grid.h:804
A CSR formatted sparse matrix.
Definition sparsematrix.h:102
size_t & num_cols()
Set number of columns in matrix (empties performance cache)
Definition sparsematrix.h:282
const Vector< Index > & row_offsets() const
Read row_offsets vector.
Definition sparsematrix.h:298
void setFromCoo(size_t num_rows, size_t num_cols, const Vector< Index > &row_indices, const Vector< Index > &column_indices, const Vector< Value > &values, bool sort=false)
Set csr values from coo formatted sparse matrix.
Definition sparsematrix.h:177
size_t & num_rows()
Set number of rows in matrix (empties performance cache)
Definition sparsematrix.h:280
size_t num_nnz() const
Number of nonzero elements in matrix.
Definition sparsematrix.h:291
const Vector< Index > & column_indices() const
Read column indices vector.
Definition sparsematrix.h:302
const Vector< Value > & values() const
Read values vector.
Definition sparsematrix.h:306
An abstract base class for MPI distributed Nd-dimensional dG grids.
Definition mpi_grid.h:95
const RealGrid< real_type, Nd > & global() const
The global grid as a shared memory grid.
Definition mpi_grid.h:288
Useful typedefs of commonly used types.