10#include <kernel/solver/base.hpp>
18 int cuda_sor_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 template<
int BlockSize_>
21 int cuda_sor_bcsr_apply(
int m,
double* y,
const double* x,
const double* csrVal,
const int* csrColInd,
int ncolors,
double omega,
22 int* colored_row_ptr,
int* rows_per_color,
int* inverse_row_ptr);
23 void cuda_sor_done_symbolic(
int* colored_row_ptr,
int* rows_per_color,
int* inverse_row_ptr);
24 void cuda_sor_init_symbolic(
int m,
int nnz,
const double* csrVal,
const int* csrRowPtr,
const int* csrColInd,
int& ncolors,
25 int*& colored_row_ptr,
int*& rows_per_color,
int*& inverse_row_ptr);
42 template<
typename Matrix_>
46 typedef typename Matrix_::DataType DataType;
47 typedef typename Matrix_::VectorTypeL VectorType;
49 virtual void set_omega(DataType omega) = 0;
51 virtual void init_symbolic() = 0;
53 virtual void done_symbolic() = 0;
55 virtual String name()
const = 0;
57 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def) = 0;
62 template<PreferredBackend backend_,
typename Matrix_,
typename Filter_>
77 template<
typename Filter_,
typename DT_,
typename IT_>
84 typedef IT_ IndexType;
85 typedef Filter_ FilterType;
90 const FilterType& _filter;
114 XABORTM(
"Matrix is not square!");
135 const MatrixType& matrix,
const FilterType& filter) :
142 XABORTM(
"Matrix is not square!");
145 auto omega_p = section->
query(
"omega");
146 if (omega_p.second && !omega_p.first.parse(this->_omega))
147 throw ParseError(section_name +
".omega", omega_p.first,
"a positive float");
169 virtual void init_symbolic()
override
173 virtual void done_symbolic()
override
177 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
override
179 XASSERTM(_matrix.
rows() == vec_cor.size(),
"matrix / vector size mismatch!");
180 XASSERTM(_matrix.
rows() == vec_def.size(),
"matrix / vector size mismatch!");
185 vec_cor.copy(vec_def);
187 _apply_intern(_matrix, vec_cor, vec_def);
189 this->_filter.filter_cor(vec_cor);
192 Statistics::add_time_precon(ts_stop.elapsed(ts_start));
199 void _apply_intern(
const LAFEM::SparseMatrixCSR<DataType, IndexType>& matrix, VectorType& vec_cor,
const VectorType& vec_def)
202 DataType* pout(vec_cor.elements());
203 const DataType* pin(vec_def.elements());
204 const DataType* pval(matrix.val());
205 const IndexType* pcol_ind(matrix.col_ind());
206 const IndexType* prow_ptr(matrix.row_ptr());
207 const IndexType n((IndexType(matrix.rows())));
211 for (IndexType i(0); i < n; ++i)
216 for (col = prow_ptr[i]; pcol_ind[col] < i; ++col)
218 d += pval[col] * pout[pcol_ind[col]];
220 pout[i] = _omega * (pin[i] - d) / pval[col];
225 template<
typename Filter_,
typename DT_,
typename IT_,
int BlockHeight_,
int BlockW
idth_>
227 public SORPrecondBase<typename LAFEM::SparseMatrixBCSR<DT_, IT_, BlockHeight_, BlockWidth_>>
229 static_assert(BlockHeight_ == BlockWidth_,
"only square blocks are supported!");
232 typedef Filter_ FilterType;
239 const FilterType& _filter;
242 void _apply_intern(
const MatrixType& matrix, VectorType& vec_cor,
const VectorType& vec_def)
245 auto* pout(vec_cor.elements());
246 const auto* pin(vec_def.elements());
247 const auto* pval(matrix.
val());
248 const IndexType* pcol_ind(matrix.
col_ind());
249 const IndexType* prow_ptr(matrix.
row_ptr());
250 const IndexType n((IndexType(matrix.
rows())));
256 for (IndexType i(0); i < n; ++i)
259 typename VectorType::ValueType d(0);
262 for (col = prow_ptr[i]; pcol_ind[col] < i; ++col)
264 d += pval[col] * pout[pcol_ind[col]];
267 pout[i] = _omega * inverse * (pin[i] - d);
292 XABORTM(
"Matrix is not square!");
313 const MatrixType& matrix,
const FilterType& filter) :
320 XABORTM(
"Matrix is not square!");
324 auto omega_p = section->
query(
"omega");
327 set_omega(DataType(std::stod(omega_p.first)));
350 virtual void init_symbolic()
override
354 virtual void done_symbolic()
override
358 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
360 XASSERTM(_matrix.
rows() == vec_cor.size(),
"matrix / vector size mismatch!");
361 XASSERTM(_matrix.
rows() == vec_def.size(),
"matrix / vector size mismatch!");
366 vec_cor.copy(vec_def);
368 _apply_intern(_matrix, vec_cor, vec_def);
370 this->_filter.filter_cor(vec_cor);
373 Statistics::add_time_precon(ts_stop.elapsed(ts_start));
374 Statistics::add_flops(_matrix.template used_elements<LAFEM::Perspective::pod>() + 3 * vec_cor.template size<LAFEM::Perspective::pod>());
397 template<
typename Filter_>
398 class SORPrecondWithBackend<
PreferredBackend::
cuda, LAFEM::SparseMatrixCSR<double, unsigned int>, Filter_> :
399 public SORPrecondBase<LAFEM::SparseMatrixCSR<double, unsigned int>>
402 typedef LAFEM::SparseMatrixCSR<double, unsigned int> MatrixType;
403 typedef Filter_ FilterType;
404 typedef typename MatrixType::VectorTypeL VectorType;
405 typedef typename MatrixType::DataType DataType;
408 const MatrixType& _matrix;
409 const FilterType& _filter;
412 int* _colored_row_ptr;
414 int* _rows_per_color;
416 int* _inverse_row_ptr;
434 explicit SORPrecondWithBackend(
const MatrixType& matrix,
const FilterType& filter,
const DataType omega = DataType(1)) :
438 _colored_row_ptr(nullptr),
439 _rows_per_color(nullptr),
440 _inverse_row_ptr(nullptr),
443 if (_matrix.columns() != _matrix.rows())
445 XABORTM(
"Matrix is not square!");
465 explicit SORPrecondWithBackend(
const String& ,
const PropertyMap* section,
466 const MatrixType& matrix,
const FilterType& filter) :
470 _colored_row_ptr(nullptr),
471 _rows_per_color(nullptr),
472 _inverse_row_ptr(nullptr),
475 if (_matrix.columns() != _matrix.rows())
477 XABORTM(
"Matrix is not square!");
481 auto omega_p = section->query(
"omega");
484 set_omega(DataType(std::stod(omega_p.first)));
489 virtual String name()
const override
501 virtual void set_omega(DataType omega)
override
507 virtual void init_symbolic()
override
509 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,
510 _colored_row_ptr, _rows_per_color, _inverse_row_ptr);
513 virtual void done_symbolic()
override
515 Intern::cuda_sor_done_symbolic(_colored_row_ptr, _rows_per_color, _inverse_row_ptr);
518 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
override
520 XASSERTM(_matrix.rows() == vec_cor.size(),
"matrix / vector size mismatch!");
521 XASSERTM(_matrix.rows() == vec_def.size(),
"matrix / vector size mismatch!");
525 int status = Intern::cuda_sor_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);
527 this->_filter.filter_cor(vec_cor);
530 Statistics::add_time_precon(ts_stop.elapsed(ts_start));
537 template<
typename Filter_,
int BlockHeight_,
int BlockW
idth_>
538 class SORPrecondWithBackend<
PreferredBackend::
cuda, LAFEM::SparseMatrixBCSR<double, unsigned int, BlockHeight_, BlockWidth_>, Filter_> :
539 public SORPrecondBase<typename LAFEM::SparseMatrixBCSR<double, unsigned int, BlockHeight_, BlockWidth_>>
541 static_assert(BlockHeight_ == BlockWidth_,
"only square blocks are supported!");
543 typedef LAFEM::SparseMatrixBCSR<double, unsigned int, BlockHeight_, BlockWidth_> MatrixType;
544 typedef Filter_ FilterType;
545 typedef typename MatrixType::VectorTypeL VectorType;
546 typedef typename MatrixType::DataType DataType;
547 typedef typename MatrixType::IndexType IndexType;
550 const MatrixType& _matrix;
551 const FilterType& _filter;
554 int* _colored_row_ptr;
556 int* _rows_per_color;
558 int* _inverse_row_ptr;
576 explicit SORPrecondWithBackend(
const MatrixType& matrix,
const FilterType& filter,
const DataType omega = DataType(1)) :
580 _colored_row_ptr(nullptr),
581 _rows_per_color(nullptr),
582 _inverse_row_ptr(nullptr),
585 if (_matrix.columns() != _matrix.rows())
587 XABORTM(
"Matrix is not square!");
607 explicit SORPrecondWithBackend(
const String& ,
const PropertyMap* section,
608 const MatrixType& matrix,
const FilterType& filter) :
612 _colored_row_ptr(nullptr),
613 _rows_per_color(nullptr),
614 _inverse_row_ptr(nullptr),
617 if (_matrix.columns() != _matrix.rows())
619 XABORTM(
"Matrix is not square!");
623 auto omega_p = section->query(
"omega");
626 set_omega(DataType(std::stod(omega_p.first)));
631 virtual String name()
const override
643 virtual void set_omega(DataType omega)
override
649 virtual void init_symbolic()
override
651 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,
652 _colored_row_ptr, _rows_per_color, _inverse_row_ptr);
655 virtual void done_symbolic()
override
657 Intern::cuda_sor_done_symbolic(_colored_row_ptr, _rows_per_color, _inverse_row_ptr);
660 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
override
662 XASSERTM(_matrix.rows() == vec_cor.size(),
"matrix / vector size mismatch!");
663 XASSERTM(_matrix.rows() == vec_def.size(),
"matrix / vector size mismatch!");
667 int status = Intern::cuda_sor_bcsr_apply<BlockHeight_>((
int)vec_cor.size(), vec_cor.template elements<LAFEM::Perspective::pod>(), vec_def.template elements<LAFEM::Perspective::pod>(),
668 _matrix.template val<LAFEM::Perspective::pod>(), (
const int*)_matrix.col_ind(), _ncolors, _omega, _colored_row_ptr, _rows_per_color, _inverse_row_ptr);
670 this->_filter.filter_cor(vec_cor);
673 Statistics::add_time_precon(ts_stop.elapsed(ts_start));
674 Statistics::add_flops(_matrix.template used_elements<LAFEM::Perspective::pod>() + 3 * vec_cor.template size<LAFEM::Perspective::pod>());
682 template<PreferredBackend backend_,
typename Matrix_,
typename Filter_>
687 template<
typename DT_>
700 virtual Status apply(
typename Matrix_::VectorTypeL&,
const typename Matrix_::VectorTypeL&)
override
702 XABORTM(
"not implemented yet!");
705 virtual String name()
const override
707 XABORTM(
"not implemented yet!");
710 virtual void init_symbolic()
override
712 XABORTM(
"not implemented yet!");
715 virtual void done_symbolic()
override
717 XABORTM(
"not implemented yet!");
720 virtual void set_omega(
typename Matrix_::DataType )
override
722 XABORTM(
"not implemented yet!");
738 template<
typename Matrix_,
typename Filter_>
742 std::shared_ptr<SORPrecondBase<Matrix_>> _impl;
745 typedef Matrix_ MatrixType;
746 typedef Filter_ FilterType;
747 typedef typename MatrixType::VectorTypeL VectorType;
748 typedef typename MatrixType::DataType DataType;
782 _impl = std::make_shared<SORPrecondWithBackend<PreferredBackend::cuda, Matrix_, Filter_>>(matrix, filter, omega);
787 _impl = std::make_shared<SORPrecondWithBackend<PreferredBackend::generic, Matrix_, Filter_>>(matrix, filter, omega);
816 _impl = std::make_shared<SORPrecondWithBackend<PreferredBackend::cuda, Matrix_, Filter_>>(section_name, section, matrix, filter, omega);
821 _impl = std::make_shared<SORPrecondWithBackend<PreferredBackend::generic, Matrix_, Filter_>>(section_name, section, matrix, filter, omega);
835 return _impl->name();
847 _impl->set_omega(omega);
850 virtual Status apply(VectorType& vec_cor,
const VectorType& vec_def)
override
852 return _impl->apply(vec_cor, vec_def);
857 _impl->init_symbolic();
862 _impl->done_symbolic();
884 template<
typename Matrix_,
typename Filter_>
886 const Matrix_& matrix,
const Filter_& filter,
887 const typename Matrix_::DataType omega =
typename Matrix_::DataType(1))
889 return std::make_shared<SORPrecond<Matrix_, Filter_>>(backend, matrix, filter, omega);
913 template<
typename Matrix_,
typename Filter_>
916 const Matrix_& matrix,
const Filter_& filter)
918 return std::make_shared<SORPrecond<Matrix_, Filter_>>(section_name, section, backend, 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.
SOR preconditioner implementation.
virtual void set_omega(DataType omega)
Sets the damping parameter.
virtual void init_symbolic() override
Symbolic initialization method.
SolverBase< VectorType > BaseClass
Our base class.
SORPrecond(PreferredBackend backend, const MatrixType &matrix, const FilterType &filter, DataType omega=DataType(1))
Constructor.
virtual String name() const override
Returns the name of the solver.
SORPrecond(const String §ion_name, const PropertyMap *section, PreferredBackend backend, const MatrixType &matrix, const FilterType &filter, DataType omega=DataType(1))
Constructor using a PropertyMap.
virtual ~SORPrecond()
Empty virtual destructor.
virtual void done_symbolic() override
Symbolic finalization method.
SORPrecondWithBackend(const String §ion_name, const PropertyMap *section, const MatrixType &matrix, const FilterType &filter)
Constructor using a PropertyMap.
virtual void set_omega(DataType omega) override
Sets the damping parameter.
SORPrecondWithBackend(const MatrixType &matrix, const FilterType &filter, const DataType omega=DataType(1))
Constructor.
virtual String name() const override
Returns the name of the solver.
SORPrecondWithBackend(const String &, const PropertyMap *section, const MatrixType &matrix, const FilterType &filter)
Constructor using a PropertyMap.
virtual String name() const override
Returns the name of the solver.
SORPrecondWithBackend(const MatrixType &matrix, const FilterType &filter, const DataType omega=DataType(1))
Constructor.
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.
Status
Solver status return codes enumeration.
@ success
solving successful (convergence criterion fulfilled)
@ aborted
premature abort (solver aborted due to internal errors or preconditioner failure)
std::shared_ptr< SORPrecond< Matrix_, Filter_ > > new_sor_precond(PreferredBackend backend, const Matrix_ &matrix, const Filter_ &filter, const typename Matrix_::DataType omega=typename Matrix_::DataType(1))
Creates a new SORPrecond solver object.
PreferredBackend
The backend that shall be used in all compute heavy calculations.