Discontinuous Galerkin Library
#include "dg/algorithm.h"
blas2.h
Go to the documentation of this file.
1#pragma once
2
7#include "backend/blas2_dispatch_scalar.h"
8#include "backend/blas2_dispatch_shared.h"
9#include "backend/blas2_cusp.h"
10#include "backend/blas2_sparseblockmat.h"
11#include "backend/blas2_selfmade.h"
12#include "backend/blas2_densematrix.h"
13#ifdef MPI_VERSION
14#include "backend/blas2_dispatch_mpi.h"
15#endif //MPI_VERSION
16#include "backend/blas2_dispatch_vector.h"
17
18
23namespace dg{
29namespace blas2{
32
34namespace detail{
35
36template< class ContainerType1, class MatrixType, class ContainerType2>
37inline std::vector<int64_t> doDot_superacc( const ContainerType1& x, const MatrixType& m, const ContainerType2& y)
38{
39 static_assert( all_true<
40 dg::is_vector<ContainerType1>::value,
41 dg::is_vector<MatrixType>::value,
42 dg::is_vector<ContainerType2>::value>::value,
43 "The container types must have a vector data layout (AnyVector)!");
44 //check ContainerTypes: must be either scalar or same base category
45 using vector_type = find_if_t<dg::is_not_scalar, ContainerType1, ContainerType1, ContainerType2>;
46 using vector_category = get_tensor_category<vector_type>;
47 static_assert( all_true<
48 dg::is_scalar_or_same_base_category<ContainerType1, vector_category>::value,
49 dg::is_scalar_or_same_base_category<ContainerType2, vector_category>::value
50 >::value,
51 "All container types must be either Scalar or have compatible Vector categories (AnyVector or Same base class)!");
52 return doDot_superacc( x, m, y, get_tensor_category<MatrixType>(), vector_category());
53}
54
55}//namespace detail
57
84template< class ContainerType1, class MatrixType, class ContainerType2>
85inline get_value_type<MatrixType> dot( const ContainerType1& x, const MatrixType& m, const ContainerType2& y)
86{
87 std::vector<int64_t> acc = dg::blas2::detail::doDot_superacc( x,m,y);
88 return exblas::cpu::Round(acc.data());
89}
90
105template< class MatrixType, class ContainerType>
106inline get_value_type<MatrixType> dot( const MatrixType& m, const ContainerType& x)
107{
108 return dg::blas2::dot( x, m, x);
109}
111namespace detail{
112//resolve tags in two stages: first the matrix and then the container type
113template< class MatrixType, class ContainerType1, class ContainerType2>
114inline void doSymv( get_value_type<ContainerType1> alpha,
115 MatrixType&& M,
116 const ContainerType1& x,
118 ContainerType2& y,
120{
121 dg::blas1::pointwiseDot( alpha, std::forward<MatrixType>(M), x, beta, y);
122}
123template< class MatrixType, class ContainerType1, class ContainerType2>
124inline void doSymv( MatrixType&& M,
125 const ContainerType1& x,
126 ContainerType2& y,
127 AnyScalarTag)
128{
129 dg::blas1::pointwiseDot( std::forward<MatrixType>(M), x, y);
130}
131
132template< class MatrixType, class ContainerType1, class ContainerType2>
133inline void doSymv( get_value_type<ContainerType1> alpha,
134 MatrixType&& M,
135 const ContainerType1& x,
136 get_value_type<ContainerType1> beta,
137 ContainerType2& y,
138 AnyMatrixTag)
139{
140 static_assert( std::is_same<get_execution_policy<ContainerType1>,
141 get_execution_policy<ContainerType2>>::value,
142 "Vector types must have same execution policy");
143 static_assert( std::is_same<get_value_type<ContainerType1>,
144 get_value_type<MatrixType>>::value &&
145 std::is_same<get_value_type<ContainerType2>,
146 get_value_type<MatrixType>>::value,
147 "Vector and Matrix types must have same value type");
148 static_assert( std::is_same<get_tensor_category<ContainerType1>,
149 get_tensor_category<ContainerType2>>::value,
150 "Vector types must have same data layout");
151 dg::blas2::detail::doSymv( alpha, std::forward<MatrixType>(M), x, beta, y,
152 get_tensor_category<MatrixType>(),
153 get_tensor_category<ContainerType1>());
154}
155template< class MatrixType, class ContainerType1, class ContainerType2>
156inline void doSymv( MatrixType&& M,
157 const ContainerType1& x,
158 ContainerType2& y,
159 AnyMatrixTag)
160{
161 static_assert( std::is_same<get_execution_policy<ContainerType1>,
162 get_execution_policy<ContainerType2>>::value,
163 "Vector types must have same execution policy");
164 static_assert( std::is_same<get_value_type<ContainerType1>,
165 get_value_type<MatrixType>>::value &&
166 std::is_same<get_value_type<ContainerType2>,
167 get_value_type<MatrixType>>::value,
168 "Vector and Matrix types must have same value type");
169 static_assert( std::is_same<get_tensor_category<ContainerType1>,
170 get_tensor_category<ContainerType2>>::value,
171 "Vector types must have same data layout");
172 dg::blas2::detail::doSymv( std::forward<MatrixType>(M), x, y,
173 get_tensor_category<MatrixType>(),
174 get_tensor_category<ContainerType1>());
175}
176template< class FunctorType, class MatrixType, class ContainerType1, class ContainerType2>
177inline void doStencil(
178 FunctorType f,
179 MatrixType&& M,
180 const ContainerType1& x,
181 ContainerType2& y,
182 AnyMatrixTag)
183{
184 static_assert( std::is_same<get_execution_policy<ContainerType1>,
185 get_execution_policy<ContainerType2>>::value,
186 "Vector types must have same execution policy");
187 static_assert( std::is_same<get_value_type<ContainerType1>,
188 get_value_type<MatrixType>>::value &&
189 std::is_same<get_value_type<ContainerType2>,
190 get_value_type<MatrixType>>::value,
191 "Vector and Matrix types must have same value type");
192 static_assert( std::is_same<get_tensor_category<ContainerType1>,
193 get_tensor_category<ContainerType2>>::value,
194 "Vector types must have same data layout");
195 dg::blas2::detail::doStencil( f, std::forward<MatrixType>(M), x, y,
196 get_tensor_category<MatrixType>(),
197 get_tensor_category<ContainerType1>());
198}
199
200template< class MatrixType, class ContainerType1, class ContainerType2>
201inline void doSymv( get_value_type<ContainerType1> alpha,
202 MatrixType&& M,
203 const ContainerType1& x,
204 get_value_type<ContainerType1> beta,
205 ContainerType2& y,
206 NotATensorTag)
207{
208 // if a compiler error message brings you here then you need to overload
209 // the parenthesis operator for your class
210 // void operator()( value_type alpha, const ContainerType1& x, value_type beta, ContainerType2& y)
211 M(alpha,x,beta,y);
212}
213template< class MatrixType, class ContainerType1, class ContainerType2>
214inline void doSymv( MatrixType&& M,
215 const ContainerType1& x,
216 ContainerType2& y,
217 NotATensorTag)
218{
219 // if a compiler error message brings you here then you need to overload
220 // the parenthesis operator for your class
221 // void operator()( const ContainerType1& x, ContainerType2& y)
222 M(x,y);
223}
224
225}//namespace detail
227
249template< class MatrixType, class ContainerType1, class ContainerType2>
251 MatrixType&& M,
252 const ContainerType1& x,
254 ContainerType2& y)
255{
256 if(alpha == (get_value_type<ContainerType1>)0) {
257 dg::blas1::scal( y, beta);
258 return;
259 }
260 dg::blas2::detail::doSymv( alpha, std::forward<MatrixType>(M), x, beta, y, get_tensor_category<MatrixType>());
261}
262
263
264
286template< class MatrixType, class ContainerType1, class ContainerType2>
287inline void symv( MatrixType&& M,
288 const ContainerType1& x,
289 ContainerType2& y)
290{
291 dg::blas2::detail::doSymv( std::forward<MatrixType>(M), x, y, get_tensor_category<MatrixType>());
292}
298template< class MatrixType, class ContainerType1, class ContainerType2>
300 MatrixType&& M,
301 const ContainerType1& x,
303 ContainerType2& y)
304{
305 dg::blas2::symv( alpha, std::forward<MatrixType>(M), x, beta, y);
306}
307
313template< class MatrixType, class ContainerType1, class ContainerType2>
314inline void gemv( MatrixType&& M,
315 const ContainerType1& x,
316 ContainerType2& y)
317{
318 dg::blas2::symv( std::forward<MatrixType>(M), x, y);
319}
320
377template< class Stencil, class ContainerType, class ...ContainerTypes>
378inline void parallel_for( Stencil f, unsigned N, ContainerType&& x, ContainerTypes&&... xs)
379{
380 // Is the assumption that results are automatically ready on return still true?
381 // Do we have to introduce barriers around this function?
382 static_assert( all_true<
383 dg::is_vector<ContainerType>::value,
384 dg::is_vector<ContainerTypes>::value...>::value,
385 "All container types must have a vector data layout (AnyVector)!");
386 using vector_type = find_if_t<dg::is_not_scalar, ContainerType, ContainerType, ContainerTypes...>;
387 using tensor_category = get_tensor_category<vector_type>;
388 static_assert( all_true<
389 dg::is_scalar_or_same_base_category<ContainerType, tensor_category>::value,
390 dg::is_scalar_or_same_base_category<ContainerTypes, tensor_category>::value...
391 >::value,
392 "All container types must be either Scalar or have compatible Vector categories (AnyVector or Same base class)!");
393 //using basic_tag_type = std::conditional_t< all_true< is_scalar<ContainerType>::value, is_scalar<ContainerTypes>::value... >::value, AnyScalarTag , AnyVectorTag >;
394 dg::blas2::detail::doParallelFor(tensor_category(), f, N, std::forward<ContainerType>(x), std::forward<ContainerTypes>(xs)...);
395}
422template< class FunctorType, class MatrixType, class ContainerType1, class ContainerType2>
423inline void stencil(
424 FunctorType f,
425 MatrixType&& M,
426 const ContainerType1& x,
427 ContainerType2& y)
428{
429 dg::blas2::detail::doStencil( f, std::forward<MatrixType>(M), x, y, get_tensor_category<MatrixType>());
430}
442template<class MatrixType, class AnotherMatrixType>
443inline void transfer( const MatrixType& x, AnotherMatrixType& y)
444{
445 dg::blas2::detail::doTransfer( x,y,
448}
450
451} //namespace blas2
460template< class MatrixType, class ContainerType1, class ContainerType2>
462 MatrixType&& M,
463 const ContainerType1& x,
465 ContainerType2& y)
466{
467 dg::blas2::symv( alpha, std::forward<MatrixType>(M), x, beta, y);
468}
469
478template< class MatrixType, class ContainerType1, class ContainerType2>
479inline void apply( MatrixType&& M,
480 const ContainerType1& x,
481 ContainerType2& y)
482{
483 dg::blas2::symv( std::forward<MatrixType>(M), x, y);
484}
485} //namespace dg
void apply(get_value_type< ContainerType1 > alpha, MatrixType &&M, const ContainerType1 &x, get_value_type< ContainerType1 > beta, ContainerType2 &y)
; (alias for dg::blas2::symv)
Definition: blas2.h:461
void scal(ContainerType &x, get_value_type< ContainerType > alpha)
Definition: blas1.h:185
void pointwiseDot(get_value_type< ContainerType > alpha, const ContainerType1 &x1, const ContainerType2 &x2, get_value_type< ContainerType > beta, ContainerType &y)
Definition: blas1.h:336
void gemv(get_value_type< ContainerType1 > alpha, MatrixType &&M, const ContainerType1 &x, get_value_type< ContainerType1 > beta, ContainerType2 &y)
; (alias for symv)
Definition: blas2.h:299
void parallel_for(Stencil f, unsigned N, ContainerType &&x, ContainerTypes &&... xs)
; Customizable and generic for loop
Definition: blas2.h:378
void transfer(const MatrixType &x, AnotherMatrixType &y)
; Generic way to copy and/or convert a Matrix type to a different Matrix type
Definition: blas2.h:443
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
get_value_type< MatrixType > dot(const ContainerType1 &x, const MatrixType &m, const ContainerType2 &y)
; Binary reproducible general dot product
Definition: blas2.h:85
@ y
y direction
@ x
x direction
typename TensorTraits< std::decay_t< Vector > >::tensor_category get_tensor_category
Definition: tensor_traits.h:40
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
Definition: tensor_traits.h:38
static double Round(int64_t *accumulator)
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
Scalar Tag base class, indicates the basic Scalar Tensor concept.
Definition: scalar_categories.h:11