10#include <kernel/solver/base.hpp>
18 int cuda_ssor_forward_apply(
int m,
double * y,
const double * x,
const double * csrVal,
const int * csrColInd,
int ncolors,
double omega,
19 int * colored_row_ptr,
int * rows_per_color,
int * inverse_row_ptr);
20 int cuda_ssor_backward_apply(
int m,
double * y,
const double * x,
const double * csrVal,
const int * csrColInd,
int ncolors,
double omega,
21 int * colored_row_ptr,
int * rows_per_color,
int * inverse_row_ptr);
22 template <
int BlockSize_>
23 int cuda_ssor_forward_bcsr_apply(
int m,
double * y,
const double * x,
const double * csrVal,
const int * csrColInd,
int ncolors,
double omega,
24 int * colored_row_ptr,
int * rows_per_color,
int * inverse_row_ptr);
25 template <
int BlockSize_>
26 int cuda_ssor_backward_bcsr_apply(
int m,
double * y,
const double * x,
const double * csrVal,
const int * csrColInd,
int ncolors,
double omega,
27 int * colored_row_ptr,
int * rows_per_color,
int * inverse_row_ptr);
28 void cuda_sor_done_symbolic(
int * colored_row_ptr,
int * rows_per_color,
int * inverse_row_ptr);
29 void cuda_sor_init_symbolic(
int m,
int nnz,
const double * csrVal,
const int * csrRowPtr,
const int * csrColInd,
int & ncolors,
30 int* & colored_row_ptr,
int* & rows_per_color,
int* & inverse_row_ptr);
47 template<
typename Matrix_>
51 typedef typename Matrix_::DataType DataType;
52 typedef typename Matrix_::VectorTypeL VectorType;
54 virtual void set_omega(DataType omega) = 0;
56 virtual void init_symbolic() = 0;
58 virtual void done_symbolic() = 0;
60 virtual String name()
const = 0;
62 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def) = 0;
67 template<PreferredBackend backend_,
typename Matrix_,
typename Filter_>
83 template<
typename Filter_,
typename DT_,
typename IT_>
90 typedef IT_ IndexType;
91 typedef Filter_ FilterType;
96 const FilterType& _filter;
120 XABORTM(
"Matrix is not square!");
125 const MatrixType& matrix,
const FilterType& filter) :
132 XABORTM(
"Matrix is not square!");
135 auto omega_p = section->
query(
"omega");
136 if(omega_p.second && !omega_p.first.parse(this->_omega))
137 throw ParseError(section_name +
".omega", omega_p.first,
"a positive float");
159 virtual void init_symbolic()
override
163 virtual void done_symbolic()
override
167 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
override
169 XASSERTM(_matrix.
rows() == vec_cor.size(),
"matrix / vector size mismatch!");
170 XASSERTM(_matrix.
rows() == vec_def.size(),
"matrix / vector size mismatch!");
175 vec_cor.copy(vec_def);
177 _apply_intern(_matrix, vec_cor, vec_def);
179 vec_cor.scale(vec_cor, _omega * (DataType(2.0) - _omega));
181 this->_filter.filter_cor(vec_cor);
184 Statistics::add_time_precon(ts_stop.elapsed(ts_start));
191 void _apply_intern(
const LAFEM::SparseMatrixCSR<DataType, IndexType>& matrix, VectorType& vec_cor,
const VectorType& vec_def)
194 DataType * pout(vec_cor.elements());
195 const DataType * pin(vec_def.elements());
196 const DataType * pval(matrix.val());
197 const IndexType * pcol_ind(matrix.col_ind());
198 const IndexType * prow_ptr(matrix.row_ptr());
199 const IndexType n((IndexType(matrix.rows())));
203 for (
Index i(0); i < n; ++i)
208 for (col = prow_ptr[i]; pcol_ind[col] < i; ++col)
210 d += pval[col] * pout[pcol_ind[col]];
212 pout[i] = (pin[i] - _omega * d) / pval[col];
217 for (
Index i(n); i > 0;)
223 for (col = prow_ptr[i+1] - IndexType(1); pcol_ind[col] > i; --col)
225 d += pval[col] * pout[pcol_ind[col]];
227 pout[i] -= _omega * d / pval[col];
232 template<
typename Filter_,
typename DT_,
typename IT_,
int BlockHeight_,
int BlockW
idth_>
234 public SSORPrecondBase<typename LAFEM::SparseMatrixBCSR<DT_, IT_, BlockHeight_, BlockWidth_>>
236 static_assert(BlockHeight_ == BlockWidth_,
"only square blocks are supported!");
239 typedef Filter_ FilterType;
246 const FilterType& _filter;
249 void _apply_intern(
const MatrixType & matrix, VectorType& vec_cor,
const VectorType& vec_def)
252 auto* pout(vec_cor.elements());
253 const auto* pin(vec_def.elements());
254 const auto* pval(matrix.
val());
255 const IndexType * pcol_ind(matrix.
col_ind());
256 const IndexType * prow_ptr(matrix.
row_ptr());
257 const IndexType n((IndexType(matrix.
rows())));
262 for (
Index i(0); i < n; ++i)
265 typename VectorType::ValueType d(0);
267 for (col = prow_ptr[i]; pcol_ind[col] < i; ++col)
269 d += pval[col] * pout[pcol_ind[col]];
273 pout[i] = inverse * (pin[i] - _omega * d);
278 for (
Index i(n); i > 0;)
282 typename VectorType::ValueType d(0);
284 for (col = prow_ptr[i+1] - IndexType(1); pcol_ind[col] > i; --col)
286 d += pval[col] * pout[pcol_ind[col]];
290 pout[i] = pout[i] - (_omega * inverse * d);
315 XABORTM(
"Matrix is not square!");
320 const MatrixType& matrix,
const FilterType& filter) :
327 XABORTM(
"Matrix is not square!");
331 auto omega_p = section->
query(
"omega");
334 set_omega(DataType(std::stod(omega_p.first)));
357 virtual void init_symbolic()
override
361 virtual void done_symbolic()
override
365 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
override
367 XASSERTM(_matrix.
rows() == vec_cor.size(),
"matrix / vector size mismatch!");
368 XASSERTM(_matrix.
rows() == vec_def.size(),
"matrix / vector size mismatch!");
373 vec_cor.copy(vec_def);
375 _apply_intern(_matrix, vec_cor, vec_def);
377 this->_filter.filter_cor(vec_cor);
380 Statistics::add_time_precon(ts_stop.elapsed(ts_start));
381 Statistics::add_flops(_matrix.template used_elements<LAFEM::Perspective::pod>() * 2 + 6 * vec_cor.template size<LAFEM::Perspective::pod>());
404 template<
typename Filter_>
405 class SSORPrecondWithBackend<
PreferredBackend::
cuda, LAFEM::SparseMatrixCSR<double, unsigned int>, Filter_> :
406 public SSORPrecondBase<LAFEM::SparseMatrixCSR<double, unsigned int>>
409 typedef LAFEM::SparseMatrixCSR<double, unsigned int> MatrixType;
410 typedef Filter_ FilterType;
411 typedef typename MatrixType::VectorTypeL VectorType;
412 typedef typename MatrixType::DataType DataType;
415 const MatrixType& _matrix;
416 const FilterType& _filter;
419 int * _colored_row_ptr;
421 int * _rows_per_color;
423 int * _inverse_row_ptr;
441 explicit SSORPrecondWithBackend(
const MatrixType& matrix,
const FilterType& filter,
const DataType omega = DataType(1)) :
445 _colored_row_ptr(nullptr),
446 _rows_per_color(nullptr),
447 _inverse_row_ptr(nullptr),
450 if (_matrix.columns() != _matrix.rows())
452 XABORTM(
"Matrix is not square!");
456 explicit SSORPrecondWithBackend(
const String& ,
const PropertyMap* section,
457 const MatrixType& matrix,
const FilterType& filter) :
461 _colored_row_ptr(nullptr),
462 _rows_per_color(nullptr),
463 _inverse_row_ptr(nullptr),
466 if (_matrix.columns() != _matrix.rows())
468 XABORTM(
"Matrix is not square!");
472 auto omega_p = section->query(
"omega");
475 set_omega(DataType(std::stod(omega_p.first)));
480 virtual String name()
const override
492 virtual void set_omega(DataType omega)
override
498 virtual void init_symbolic()
override
500 Intern::cuda_sor_init_symbolic((
int)_matrix.rows(), (
int)_matrix.used_elements(), _matrix.val(), (
const int*)_matrix.row_ptr(), (
const int*)_matrix.col_ind(), _ncolors,
501 _colored_row_ptr, _rows_per_color, _inverse_row_ptr);
504 virtual void done_symbolic()
override
506 Intern::cuda_sor_done_symbolic(_colored_row_ptr, _rows_per_color, _inverse_row_ptr);
509 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
override
511 XASSERTM(_matrix.rows() == vec_cor.size(),
"matrix / vector size mismatch!");
512 XASSERTM(_matrix.rows() == vec_def.size(),
"matrix / vector size mismatch!");
516 int status = Intern::cuda_ssor_forward_apply((
int)vec_cor.size(), vec_cor.elements(), vec_def.elements(), (
const double*)_matrix.val(), (
const int*)_matrix.col_ind(), _ncolors, _omega, _colored_row_ptr, _rows_per_color, _inverse_row_ptr);
517 status |= Intern::cuda_ssor_backward_apply((
int)vec_cor.size(), vec_cor.elements(), vec_def.elements(), (
const double*)_matrix.val(), (
const int*)_matrix.col_ind(), _ncolors, _omega, _colored_row_ptr, _rows_per_color, _inverse_row_ptr);
519 vec_cor.scale(vec_cor, _omega * (2.0 - _omega));
521 this->_filter.filter_cor(vec_cor);
524 Statistics::add_time_precon(ts_stop.elapsed(ts_start));
531 template<
typename Filter_,
int BlockHeight_,
int BlockW
idth_>
532 class SSORPrecondWithBackend<
PreferredBackend::
cuda, LAFEM::SparseMatrixBCSR<double, unsigned int, BlockHeight_, BlockWidth_>, Filter_> :
533 public SSORPrecondBase<typename LAFEM::SparseMatrixBCSR<double, unsigned int, BlockHeight_, BlockWidth_>>
535 static_assert(BlockHeight_ == BlockWidth_,
"only square blocks are supported!");
537 typedef LAFEM::SparseMatrixBCSR<double, unsigned int, BlockHeight_, BlockWidth_> MatrixType;
538 typedef Filter_ FilterType;
539 typedef typename MatrixType::VectorTypeL VectorType;
540 typedef typename MatrixType::DataType DataType;
543 const MatrixType& _matrix;
544 const FilterType& _filter;
547 int * _colored_row_ptr;
549 int * _rows_per_color;
551 int * _inverse_row_ptr;
569 explicit SSORPrecondWithBackend(
const MatrixType& matrix,
const FilterType& filter,
const DataType omega = DataType(1)) :
573 _colored_row_ptr(nullptr),
574 _rows_per_color(nullptr),
575 _inverse_row_ptr(nullptr),
578 if (_matrix.columns() != _matrix.rows())
580 XABORTM(
"Matrix is not square!");
584 explicit SSORPrecondWithBackend(
const String& ,
const PropertyMap* section,
585 const MatrixType& matrix,
const FilterType& filter) :
589 _colored_row_ptr(nullptr),
590 _rows_per_color(nullptr),
591 _inverse_row_ptr(nullptr),
594 if (_matrix.columns() != _matrix.rows())
596 XABORTM(
"Matrix is not square!");
600 auto omega_p = section->query(
"omega");
603 set_omega(DataType(std::stod(omega_p.first)));
608 virtual String name()
const override
620 virtual void set_omega(DataType omega)
override
626 virtual void init_symbolic()
override
628 Intern::cuda_sor_init_symbolic((
int)_matrix.rows(), (
int)_matrix.used_elements(), _matrix.template val<LAFEM::Perspective::pod>(), (
const int*)_matrix.row_ptr(), (
const int*)_matrix.col_ind(), _ncolors,
629 _colored_row_ptr, _rows_per_color, _inverse_row_ptr);
632 virtual void done_symbolic()
override
634 Intern::cuda_sor_done_symbolic(_colored_row_ptr, _rows_per_color, _inverse_row_ptr);
637 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
override
639 XASSERTM(_matrix.rows() == vec_cor.size(),
"matrix / vector size mismatch!");
640 XASSERTM(_matrix.rows() == vec_def.size(),
"matrix / vector size mismatch!");
644 int status = Intern::cuda_ssor_forward_bcsr_apply<BlockHeight_>((
int)vec_cor.size(), vec_cor.
template elements<LAFEM::Perspective::pod>(), vec_def.template elements<LAFEM::Perspective::pod>(), _matrix.template val<LAFEM::Perspective::pod>(), (
const int*)_matrix.col_ind(), _ncolors, _omega, _colored_row_ptr, _rows_per_color, _inverse_row_ptr);
645 status |= Intern::cuda_ssor_backward_bcsr_apply<BlockHeight_>((
int)vec_cor.size(), vec_cor.template elements<LAFEM::Perspective::pod>(), vec_def.template elements<LAFEM::Perspective::pod>(), _matrix.template val<LAFEM::Perspective::pod>(), (
const int*)_matrix.col_ind(), _ncolors, _omega, _colored_row_ptr, _rows_per_color, _inverse_row_ptr);
647 vec_cor.scale(vec_cor, _omega * (2.0 - _omega));
649 this->_filter.filter_cor(vec_cor);
652 Statistics::add_time_precon(ts_stop.elapsed(ts_start));
653 Statistics::add_flops(_matrix.template used_elements<LAFEM::Perspective::pod>() *2 + 6 * vec_cor.template size<LAFEM::Perspective::pod>());
661 template<PreferredBackend backend_,
typename Matrix_,
typename Filter_>
666 template<
typename DT_>
679 virtual Status apply(
typename Matrix_::VectorTypeL &,
const typename Matrix_::VectorTypeL &)
override
681 XABORTM(
"not implemented yet!");
684 virtual String name()
const override
686 XABORTM(
"not implemented yet!");
689 virtual void init_symbolic()
override
691 XABORTM(
"not implemented yet!");
694 virtual void done_symbolic()
override
696 XABORTM(
"not implemented yet!");
699 virtual void set_omega(
typename Matrix_::DataType )
override
701 XABORTM(
"not implemented yet!");
717 template<
typename Matrix_,
typename Filter_>
721 std::shared_ptr<SSORPrecondBase<Matrix_>> _impl;
724 typedef Matrix_ MatrixType;
725 typedef Filter_ FilterType;
726 typedef typename MatrixType::VectorTypeL VectorType;
727 typedef typename MatrixType::DataType DataType;
754 _impl = std::make_shared<SSORPrecondWithBackend<PreferredBackend::cuda, Matrix_, Filter_>>(matrix, filter, omega);
759 _impl = std::make_shared<SSORPrecondWithBackend<PreferredBackend::generic, Matrix_, Filter_>>(matrix, filter, omega);
788 _impl = std::make_shared<SSORPrecondWithBackend<PreferredBackend::cuda, Matrix_, Filter_>>(section_name, section, matrix, filter, omega);
793 _impl = std::make_shared<SSORPrecondWithBackend<PreferredBackend::generic, Matrix_, Filter_>>(section_name, section, matrix, filter, omega);
807 return _impl->name();
819 _impl->set_omega(omega);
822 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
override
824 return _impl->apply(vec_cor, vec_def);
829 _impl->init_symbolic();
834 _impl->done_symbolic();
856 template<
typename Matrix_,
typename Filter_>
858 const PreferredBackend backend,
const Matrix_& matrix,
const Filter_& filter,
859 const typename Matrix_::DataType omega =
typename Matrix_::DataType(1))
861 return std::make_shared<SSORPrecond<Matrix_, Filter_>>
862 (backend, matrix, filter, omega);
886 template<
typename Matrix_,
typename Filter_>
889 const Matrix_& matrix,
const Filter_& filter)
891 return std::make_shared<SSORPrecond<Matrix_, Filter_>>
892 (backend, section_name, section, matrix, filter);
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
CSR based blocked sparse matrix.
Intern::BCSRVectorHelper< DT_, IT_, BlockHeight_ >::VectorType VectorTypeL
Compatible L-vector type.
IT_ IndexType
Our indextype.
Index rows() const
Retrieve matrix row count.
IT_ * col_ind()
Retrieve column indices array.
IT_ * row_ptr()
Retrieve row start index array.
Index columns() const
Retrieve matrix column count.
DT_ DataType
Our datatype.
auto val() const -> const typename Intern::BCSRPerspectiveHelper< DT_, BlockHeight_, BlockWidth_, perspective_ >::Type *
Retrieve non zero element array.
Index rows() const
Retrieve matrix row count.
Index columns() const
Retrieve matrix column count.
Index used_elements() const
Retrieve non zero element count.
Class for parser related errors.
A class organizing a tree of key-value pairs.
std::pair< String, bool > query(String key_path) const
Queries a value by its key path.
Inheritances inside sor_precond.hpp.
SSOR preconditioner implementation.
virtual void done_symbolic() override
Symbolic finalization method.
SSORPrecond(const PreferredBackend backend, const MatrixType &matrix, const FilterType &filter, DataType omega=DataType(1))
Constructor.
SSORPrecond(const PreferredBackend backend, const String §ion_name, const PropertyMap *section, const MatrixType &matrix, const FilterType &filter, DataType omega=DataType(1))
Constructor using a PropertyMap.
virtual ~SSORPrecond()
Empty virtual destructor.
virtual void init_symbolic() override
Symbolic initialization method.
virtual void set_omega(DataType omega)
Sets the damping parameter.
virtual String name() const override
Returns the name of the solver.
SolverBase< VectorType > BaseClass
Our base class.
SSORPrecondWithBackend(const MatrixType &matrix, const FilterType &filter, const DataType omega=DataType(1))
Constructor.
virtual String name() const override
Returns the name of the solver.
virtual void set_omega(DataType omega) override
Sets the damping parameter.
SSORPrecondWithBackend(const MatrixType &matrix, const FilterType &filter, const DataType omega=DataType(1))
Constructor.
virtual String name() const override
Returns the name of the solver.
virtual void set_omega(DataType omega) override
Sets the damping parameter.
Dummy class for not implemented specializations.
Polymorphic solver interface.
static void add_flops(Index flops)
Add an amount of flops to the global flop counter.
String class implementation.
Tiny Matrix class template.
CUDA_HOST_DEVICE Matrix & set_inverse(const Matrix< T_, m_, n_, sma_, sna_ > &a)
Sets this matrix to the inverse of another matrix.
std::shared_ptr< SSORPrecond< Matrix_, Filter_ > > new_ssor_precond(const PreferredBackend backend, const Matrix_ &matrix, const Filter_ &filter, const typename Matrix_::DataType omega=typename Matrix_::DataType(1))
Creates a new SSORPrecond solver object.
Status
Solver status return codes enumeration.
@ success
solving successful (convergence criterion fulfilled)
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
PreferredBackend
The backend that shall be used in all compute heavy calculations.
std::uint64_t Index
Index data type.