Discontinuous Galerkin Library
#include "dg/algorithm.h"
mpi_matrix.h
Go to the documentation of this file.
1#pragma once
2
3#include "mpi_vector.h"
4#include "memory.h"
5#include "timer.h"
6
13namespace dg {
14namespace blas2 {
15//forward declare blas2 symv functions
16template< class MatrixType, class ContainerType1, class ContainerType2>
17void symv( MatrixType&& M,
18 const ContainerType1& x,
19 ContainerType2& y);
20template< class FunctorType, class MatrixType, class ContainerType1, class ContainerType2>
21void stencil( FunctorType f, MatrixType&& M,
22 const ContainerType1& x,
23 ContainerType2& y);
24template< class MatrixType, class ContainerType1, class ContainerType2>
26 MatrixType&& M,
27 const ContainerType1& x,
29 ContainerType2& y);
30}//namespace blas2
31
34
63template<class LocalMatrixInner, class LocalMatrixOuter, class Collective >
65{
69
77 RowColDistMat( const LocalMatrixInner& inside, const LocalMatrixOuter& outside, const Collective& c):
78 m_i(inside), m_o(outside), m_c(c), m_buffer( c.allocate_buffer()) { }
79
92 template< class OtherMatrixInner, class OtherMatrixOuter, class OtherCollective>
94 m_i(src.inner_matrix()), m_o( src.outer_matrix()), m_c(src.collective()), m_buffer( m_c.allocate_buffer()) { }
96 const LocalMatrixInner& inner_matrix() const{return m_i;}
98 LocalMatrixInner& inner_matrix(){return m_i;}
100 const LocalMatrixOuter& outer_matrix() const{return m_o;}
102 LocalMatrixOuter& outer_matrix(){return m_o;}
104 const Collective& collective() const{return m_c;}
105
118 template<class ContainerType1, class ContainerType2>
119 void symv( value_type alpha, const ContainerType1& x, value_type beta, ContainerType2& y) const
120 {
121 //the blas2 functions should make enough static assertions on tpyes
122 if( !m_c.isCommunicating()) //no communication needed
123 {
124 dg::blas2::symv( alpha, m_i, x.data(), beta, y.data());
125 return;
126
127 }
128 int result;
129 MPI_Comm_compare( x.communicator(), y.communicator(), &result);
130 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
131 MPI_Comm_compare( x.communicator(), m_c.communicator(), &result);
132 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
133
134 //1.1 initiate communication
135 MPI_Request rqst[4];
136 const value_type * x_ptr = thrust::raw_pointer_cast(x.data().data());
137 value_type * y_ptr = thrust::raw_pointer_cast(y.data().data());
138 m_c.global_gather_init( x_ptr, m_buffer.data(), rqst);
139 //1.2 compute inner points
140 dg::blas2::symv( alpha, m_i, x.data(), beta, y.data());
141 //2. wait for communication to finish
142 m_c.global_gather_wait( x_ptr, m_buffer.data(), rqst);
143 //3. compute and add outer points
144 const value_type** b_ptr = thrust::raw_pointer_cast(m_buffer.data().data());
145 m_o.symv( SharedVectorTag(), get_execution_policy<ContainerType1>(), alpha, b_ptr, 1., y_ptr);
146 }
147
158 template<class ContainerType1, class ContainerType2>
159 void symv( const ContainerType1& x, ContainerType2& y) const
160 {
161 //the blas2 functions should make enough static assertions on tpyes
162 if( !m_c.isCommunicating()) //no communication needed
163 {
164 dg::blas2::symv( m_i, x.data(), y.data());
165 return;
166
167 }
168 int result;
169 MPI_Comm_compare( x.communicator(), y.communicator(), &result);
170 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
171 MPI_Comm_compare( x.communicator(), m_c.communicator(), &result);
172 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
173
174 //1.1 initiate communication
175 MPI_Request rqst[4];
176 const value_type * x_ptr = thrust::raw_pointer_cast(x.data().data());
177 value_type * y_ptr = thrust::raw_pointer_cast(y.data().data());
178 m_c.global_gather_init( x_ptr, m_buffer.data(), rqst);
179 //1.2 compute inner points
180 dg::blas2::symv( m_i, x.data(), y.data());
181 //2. wait for communication to finish
182 m_c.global_gather_wait( x_ptr, m_buffer.data(), rqst);
183 //3. compute and add outer points
184 const value_type** b_ptr = thrust::raw_pointer_cast(m_buffer.data().data());
185 m_o.symv( SharedVectorTag(), get_execution_policy<ContainerType1>(), 1., b_ptr, 1., y_ptr);
186 }
187
188 private:
189 LocalMatrixInner m_i;
190 LocalMatrixOuter m_o;
191 Collective m_c;
193};
194
195
198{
200 col_dist=1
202
217template<class LocalMatrix, class Collective >
219{
230 MPIDistMat( const LocalMatrix& m, const Collective& c, enum dist_type dist = row_dist):
231 m_m(m), m_c(c), m_buffer( c.allocate_buffer()), m_dist( dist) { }
232
240 template< class OtherMatrix, class OtherCollective>
242 m_m(src.matrix()), m_c(src.collective()), m_buffer( m_c->allocate_buffer()), m_dist(src.get_dist()) { }
248 const LocalMatrix& matrix() const{return m_m;}
254 const Collective& collective() const{return *m_c;}
255
256 enum dist_type get_dist() const {return m_dist;}
257 void set_dist(enum dist_type dist){m_dist=dist;}
258
259 template<class ContainerType1, class ContainerType2>
260 void symv( value_type alpha, const ContainerType1& x, value_type beta, ContainerType2& y) const
261 {
262 //the blas2 functions should make enough static assertions on tpyes
263 if( !m_c->isCommunicating()) //no communication needed
264 {
265 dg::blas2::symv( alpha, m_m, x.data(), beta, y.data());
266 return;
267
268 }
269 int result;
270 MPI_Comm_compare( x.communicator(), y.communicator(), &result);
271 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
272 MPI_Comm_compare( x.communicator(), m_c->communicator(), &result);
273 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
274 if( m_dist == row_dist){
275 const value_type * x_ptr = thrust::raw_pointer_cast(x.data().data());
276 m_c->global_gather( x_ptr, m_buffer.data());
277 dg::blas2::symv( alpha, m_m, m_buffer.data(), beta, y.data());
278 }
279 if( m_dist == col_dist){
280 dg::blas2::symv( alpha, m_m, x.data(), beta, m_buffer.data());
281 value_type * y_ptr = thrust::raw_pointer_cast(y.data().data());
282 m_c->global_scatter_reduce( m_buffer.data(), y_ptr);
283 }
284 }
285 template<class ContainerType1, class ContainerType2>
286 void symv( const ContainerType1& x, ContainerType2& y) const
287 {
288 //the blas2 functions should make enough static assertions on tpyes
289 if( !m_c->isCommunicating()) //no communication needed
290 {
291 dg::blas2::symv( m_m, x.data(), y.data());
292 return;
293
294 }
295 int result;
296 MPI_Comm_compare( x.communicator(), y.communicator(), &result);
297 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
298 MPI_Comm_compare( x.communicator(), m_c->communicator(), &result);
299 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
300 if( m_dist == row_dist){
301 const value_type * x_ptr = thrust::raw_pointer_cast(x.data().data());
302 m_c->global_gather( x_ptr, m_buffer.data());
303 dg::blas2::symv( m_m, m_buffer.data(), y.data());
304 }
305 if( m_dist == col_dist){
306 dg::blas2::symv( m_m, x.data(), m_buffer.data());
307 value_type * y_ptr = thrust::raw_pointer_cast(y.data().data());
308 m_c->global_scatter_reduce( m_buffer.data(), y_ptr);
309 }
310 }
311 template<class Functor, class ContainerType1, class ContainerType2>
312 void stencil( const Functor f, const ContainerType1& x, ContainerType2& y) const
313 {
314 //the blas2 functions should make enough static assertions on tpyes
315 if( !m_c->isCommunicating()) //no communication needed
316 {
317 dg::blas2::stencil( f, m_m, x.data(), y.data());
318 return;
319
320 }
321 int result;
322 MPI_Comm_compare( x.communicator(), y.communicator(), &result);
323 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
324 MPI_Comm_compare( x.communicator(), m_c->communicator(), &result);
325 assert( result == MPI_CONGRUENT || result == MPI_IDENT);
326 if( m_dist == row_dist){
327 const value_type * x_ptr = thrust::raw_pointer_cast(x.data().data());
328 m_c->global_gather( x_ptr, m_buffer.data());
329 dg::blas2::stencil( f, m_m, m_buffer.data(), y.data());
330 }
331 if( m_dist == col_dist){
332 throw Error( Message(_ping_)<<"stencil cannot be used with a column distributed mpi matrix!");
333 }
334 }
335
336 private:
337 LocalMatrix m_m;
340 enum dist_type m_dist;
341};
343
346template<class LI, class LO, class C>
347struct TensorTraits<RowColDistMat<LI,LO, C> >
348{
351};
352
353template<class L, class C>
355{
358};
360
361} //namespace dg
class intended for the use in throw statements
Definition: exceptions.h:83
small class holding a stringstream
Definition: exceptions.h:29
#define _ping_
Definition: exceptions.h:12
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
Definition: blas2.h:287
void stencil(FunctorType f, MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
Definition: blas2.h:423
@ y
y direction
@ x
x direction
dist_type
Type of distribution of MPI distributed matrices.
Definition: mpi_matrix.h:198
@ col_dist
Column distributed.
Definition: mpi_matrix.h:200
@ row_dist
Row distributed.
Definition: mpi_matrix.h:199
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
Definition: tensor_traits.h:38
typename TensorTraits< std::decay_t< Vector > >::execution_policy get_execution_policy
Definition: tensor_traits.h:42
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
T & data() const
Get write access to the data on the heap.
Definition: memory.h:187
Distributed memory matrix class.
Definition: mpi_matrix.h:219
void stencil(const Functor f, const ContainerType1 &x, ContainerType2 &y) const
Definition: mpi_matrix.h:312
MPIDistMat(const MPIDistMat< OtherMatrix, OtherCollective > &src)
Copy Constructor.
Definition: mpi_matrix.h:241
get_value_type< LocalMatrix > value_type
Definition: mpi_matrix.h:220
const LocalMatrix & matrix() const
Access to the local matrix.
Definition: mpi_matrix.h:248
MPIDistMat(const LocalMatrix &m, const Collective &c, enum dist_type dist=row_dist)
Constructor.
Definition: mpi_matrix.h:230
void symv(const ContainerType1 &x, ContainerType2 &y) const
Definition: mpi_matrix.h:286
enum dist_type get_dist() const
Definition: mpi_matrix.h:256
void set_dist(enum dist_type dist)
Definition: mpi_matrix.h:257
void symv(value_type alpha, const ContainerType1 &x, value_type beta, ContainerType2 &y) const
Definition: mpi_matrix.h:260
MPIDistMat()
no memory allocation
Definition: mpi_matrix.h:222
const Collective & collective() const
Access to the communication object.
Definition: mpi_matrix.h:254
indicate one of our mpi matrices
Definition: matrix_categories.h:31
Distributed memory matrix class, asynchronous communication.
Definition: mpi_matrix.h:65
const LocalMatrixInner & inner_matrix() const
Read access to the inner matrix.
Definition: mpi_matrix.h:96
RowColDistMat(const RowColDistMat< OtherMatrixInner, OtherMatrixOuter, OtherCollective > &src)
Copy constructor.
Definition: mpi_matrix.h:93
get_value_type< LocalMatrixInner > value_type
Definition: mpi_matrix.h:66
void symv(value_type alpha, const ContainerType1 &x, value_type beta, ContainerType2 &y) const
Matrix Vector product.
Definition: mpi_matrix.h:119
LocalMatrixOuter & outer_matrix()
Write access to the outer matrix.
Definition: mpi_matrix.h:102
const LocalMatrixOuter & outer_matrix() const
Read access to the outer matrix.
Definition: mpi_matrix.h:100
LocalMatrixInner & inner_matrix()
Write access to the inner matrix.
Definition: mpi_matrix.h:98
RowColDistMat()
no memory allocation
Definition: mpi_matrix.h:68
const Collective & collective() const
Read access to the communication object.
Definition: mpi_matrix.h:104
void symv(const ContainerType1 &x, ContainerType2 &y) const
Matrix Vector product.
Definition: mpi_matrix.h:159
RowColDistMat(const LocalMatrixInner &inside, const LocalMatrixOuter &outside, const Collective &c)
Constructor.
Definition: mpi_matrix.h:77
Indicate a contiguous chunk of shared memory.
Definition: vector_categories.h:41
get_value_type< L > value_type
value type
Definition: mpi_matrix.h:356
get_value_type< LI > value_type
value type
Definition: mpi_matrix.h:349
The vector traits.
Definition: tensor_traits.h:31