Discontinuous Galerkin Library
#include "dg/algorithm.h"
mpi_projection.h
Go to the documentation of this file.
1#pragma once
2
6#include "mpi_grid.h"
7#include "projection.h"
8
13namespace dg
14{
16namespace detail{
17//given global indices -> make a sorted unique indices vector + a gather map into the unique vector:
18//@param buffer_idx -> (gather map/ new column indices) same size as global_idx ( can alias global_idx, index into unique_global_idx
19//@param unique_global_idx -> (list of unique global indices to be used in a Collective Communication object)
20static void global2bufferIdx(
21 const cusp::array1d<int, cusp::host_memory>& global_idx,
22 cusp::array1d<int, cusp::host_memory>& buffer_idx,
23 thrust::host_vector<int>& locally_unique_global_idx)
24{
25 thrust::host_vector<int> index(global_idx.begin(), global_idx.end()), m_global_idx(index);
26 thrust::sequence( index.begin(), index.end());
27 //1. sort input global indices
28 thrust::stable_sort_by_key( m_global_idx.begin(), m_global_idx.end(), index.begin());//this changes both global_idx and index
29 //2. now reduce on multiple indices
30 thrust::host_vector<int> ones( index.size(), 1);
31 thrust::host_vector<int> unique_global( index.size()), howmany( index.size());
32 typedef typename thrust::host_vector<int>::iterator iterator;
33 thrust::pair<iterator, iterator> new_end;
34 new_end = thrust::reduce_by_key( m_global_idx.begin(), m_global_idx.end(), ones.begin(), unique_global.begin(), howmany.begin());
35 //3. copy unique indices
36 locally_unique_global_idx.assign( unique_global.begin(), new_end.first);
37 //4. manually make gather map into locally_unique_global_idx
38 thrust::host_vector<int> gather_map;
39 for( int i=0; i<(int)locally_unique_global_idx.size(); i++)
40 for( int j=0; j<howmany[i]; j++)
41 gather_map.push_back(i);
42 assert( gather_map.size() == global_idx.size());
43 //5. buffer idx is the new index
44 buffer_idx.resize( global_idx.size());
45 thrust::scatter( gather_map.begin(), gather_map.end(), index.begin(), buffer_idx.begin());
46}
47}//namespace detail
49
74template<class ConversionPolicy, class real_type>
75dg::MIHMatrix_t<real_type> convert( const dg::IHMatrix_t<real_type>& global, const ConversionPolicy& policy)
76{
77 dg::iHVec unique_global_idx;
78 cusp::array1d<int, cusp::host_memory> buffer_idx;
79 dg::detail::global2bufferIdx( global.column_indices, buffer_idx, unique_global_idx);
80 dg::GeneralComm<dg::iHVec, thrust::host_vector<real_type>> comm( unique_global_idx, policy);
81 if( !comm.isCommunicating() )
82 {
83 cusp::array1d<int, cusp::host_memory> local_idx(global.column_indices), pids(local_idx);
84 bool success = true;
85 for(unsigned i=0; i<local_idx.size(); i++)
86 success = policy.global2localIdx(global.column_indices[i], local_idx[i], pids[i]);
87 assert( success);
88 dg::IHMatrix_t<real_type> local( global.num_rows, policy.local_size(), global.values.size());
89 // It is more memory efficient to leave the global communicator empty
91 local.row_offsets=global.row_offsets;
92 local.column_indices=local_idx;
93 local.values=global.values;
94 return dg::MIHMatrix_t<real_type>( local, comm, dg::row_dist);
95 }
96 dg::IHMatrix_t<real_type> local( global.num_rows, comm.buffer_size(), global.values.size());
97 local.row_offsets=global.row_offsets;
98 local.column_indices=buffer_idx;
99 local.values=global.values;
100 dg::MIHMatrix_t<real_type> matrix( local, comm, dg::row_dist);
101 return matrix;
102}
103
135template<class ConversionPolicy, class real_type>
137{
138 // 0. Convert rows to coo rows
139 cusp::array1d<int, cusp::host_memory> rows( global.column_indices.size()), local_rows(rows);
140 for( unsigned i=0; i<global.num_rows; i++)
141 for( int k = global.row_offsets[i]; k < global.row_offsets[i+1]; k++)
142 rows[k] = i;
143 // 1. For all rows determine pid to which it belongs
144 thrust::host_vector<int> pids(rows.size());
145 bool success = true;
146 for(unsigned i=0; i<rows.size(); i++)
147 if( !policy.global2localIdx(rows[i], local_rows[i], pids[i]) ) success = false;
148 assert( success);
149 // 2. Construct BijectiveComm with it
150 dg::BijectiveComm<dg::iHVec, thrust::host_vector<real_type>> comm( pids, policy.communicator());
151 // 3. Gather all rows/cols/vals triplets local to matrix
152 auto rowsV = dg::construct<thrust::host_vector<real_type> >( local_rows);
153 auto colsV = dg::construct<thrust::host_vector<real_type> >( global.column_indices);
154 auto row_buffer = comm.global_gather( &rowsV[0]);
155 auto col_buffer = comm.global_gather( &colsV[0]);
156 auto val_buffer = comm.global_gather( &global.values[0]);
157 int local_num_rows = dg::blas1::reduce( row_buffer, (real_type)0, thrust::maximum<real_type>())+1;
158 cusp::coo_matrix<int, real_type, cusp::host_memory> A( local_num_rows, global.num_cols, row_buffer.size());
159 A.row_indices = dg::construct<cusp::array1d<int, cusp::host_memory>>( row_buffer);
160 A.column_indices = dg::construct<cusp::array1d<int, cusp::host_memory>>( col_buffer);
161 A.values = val_buffer;
162 A.sort_by_row_and_column();
164 // 4. Reduce on identical rows/cols
165 // .... Maybe later
166}
167
195template<class ConversionPolicy, class real_type>
196void convertLocal2GlobalCols( dg::IHMatrix_t<real_type>& local, const ConversionPolicy& policy)
197{
198 // 1. For all rows determine pid to which it belongs
199 int rank=0;
200 MPI_Comm_rank( policy.communicator(), &rank);
201
202 bool success = true;
203 for(unsigned i=0; i<local.column_indices.size(); i++)
204 if( !policy.local2globalIdx(local.column_indices[i], rank, local.column_indices[i]) ) success = false;
205 assert( success);
206 local.num_cols = policy.size();
207}
208
209namespace create
210{
211
213//
215
217template<class real_type>
219 g_new, const aRealMPITopology2d<real_type>& g_old,std::string method = "dg")
220{
222 g_new.local(), g_old.global(), method);
223 return convert( mat, g_old);
224}
226template<class real_type>
228 g_new, const aRealMPITopology3d<real_type>& g_old,std::string method = "dg")
229{
231 g_new.local(), g_old.global(), method);
232 return convert( mat, g_old);
233}
235template<class real_type>
237 g_new, const aRealMPITopology2d<real_type>& g_old,std::string method = "dg")
238{
240 g_new.local(), g_old.global(), method);
241 return convert( mat, g_old);
242}
243
244
246template<class real_type>
248 g_new, const aRealMPITopology2d<real_type>& g_old, std::string method = "dg")
249{
251 g_new.global(), g_old.local(), method);
252 convertLocal2GlobalCols( mat, g_old);
253 auto mat_loc = convertGlobal2LocalRows( mat, g_new);
254 return convert( mat_loc, g_old);
255}
257template<class real_type>
259 g_new, const aRealMPITopology3d<real_type>& g_old, std::string method = "dg")
260{
262 g_new.global(), g_old.local(), method);
263 convertLocal2GlobalCols( mat, g_old);
264 auto mat_loc = convertGlobal2LocalRows( mat, g_new);
265 return convert( mat_loc, g_old);
266}
267
273template<class real_type>
275 const thrust::host_vector<real_type>& x,
276 const thrust::host_vector<real_type>& y,
278 dg::bc bcx = dg::NEU, dg::bc bcy = dg::NEU,
279 std::string method = "dg")
280{
282 bcx, bcy, method);
283 return convert( mat, g);
284}
285
291template<class real_type>
293 const thrust::host_vector<real_type>& x,
294 const thrust::host_vector<real_type>& y,
295 const thrust::host_vector<real_type>& z,
297 dg::bc bcx = dg::NEU, dg::bc bcy = dg::NEU, dg::bc bcz = dg::PER,
298 std::string method = "linear")
299{
301 g.global(), bcx, bcy, bcz, method);
302 return convert( mat, g);
303}
304
305
306
308
309}//namespace create
310}//namespace dg
OutputType reduce(const ContainerType &x, OutputType zero, BinaryOp binary_op, UnaryOp unary_op=UnaryOp())
Custom (transform) reduction
Definition: blas1.h:139
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
cusp::coo_matrix< int, real_type, cusp::host_memory > interpolation(const thrust::host_vector< real_type > &x, const RealGrid1d< real_type > &g, dg::bc bcx=dg::NEU, std::string method="dg")
Create interpolation matrix.
Definition: interpolation.h:254
dg::MIHMatrix_t< real_type > projection(const aRealMPITopology2d< real_type > &g_new, const aRealMPITopology2d< real_type > &g_old, std::string method="dg")
Create a projection between two grids.
Definition: mpi_projection.h:247
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:196
dg::MIHMatrix_t< real_type > convert(const dg::IHMatrix_t< real_type > &global, const ConversionPolicy &policy)
Convert a (row-distributed) matrix with local row and global column indices to a row distributed MPI ...
Definition: mpi_projection.h:75
dg::IHMatrix_t< real_type > convertGlobal2LocalRows(const dg::IHMatrix_t< real_type > &global, const ConversionPolicy &policy)
Convert a (column-distributed) matrix with global row and column indices to a row distributed matrix.
Definition: mpi_projection.h:136
@ row_dist
Row distributed.
Definition: mpi_matrix.h:199
cusp::csr_matrix< int, real_type, cusp::host_memory > IHMatrix_t
Definition: typedefs.h:37
thrust::host_vector< int > iHVec
integer Host Vector
Definition: typedefs.h:20
MPI Grid objects.
MPI matrix classes.
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
Creation of projection matrices.
Perform bijective gather and its transpose (scatter) operation across processes on distributed vector...
Definition: mpi_collective.h:208
Perform general gather and its transpose (scatter) operation across processes on distributed vectors ...
Definition: mpi_collective.h:504
Distributed memory matrix class.
Definition: mpi_matrix.h:219
void global_gather(const value_type *values, LocalContainer &buffer) const
. Globally (across processes) gather data into a buffer
Definition: mpi_communicator.h:124
unsigned buffer_size() const
The local size of the buffer vector w = local map size.
Definition: mpi_communicator.h:178
bool isCommunicating() const
True if the gather/scatter operation involves actual MPI communication.
Definition: mpi_communicator.h:211
2D MPI abstract grid class
Definition: mpi_grid.h:45
const RealGrid2d< real_type > & local() const
Return a non-MPI grid local for the calling process.
Definition: mpi_grid.h:252
const RealGrid2d< real_type > & global() const
Return the global non-MPI grid.
Definition: mpi_grid.h:262
3D MPI Grid class
Definition: mpi_grid.h:329
const RealGrid3d< real_type > & global() const
Return the global non-MPI grid.
Definition: mpi_grid.h:562
const RealGrid3d< real_type > & local() const
Return a non-MPI grid local for the calling process.
Definition: mpi_grid.h:560
Useful typedefs of commonly used types.