-
Notifications
You must be signed in to change notification settings - Fork 140
Mixed-precision parallel linear solver #7048
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
nrseman
wants to merge
13
commits into
OPM:master
Choose a base branch
from
haugenlabs:mixed-istl
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
c22c8cc
mixed: noop mixed-adapter implementation
c1394a6
mixed: dummy mixed-precision adapter
c9524ba
mixed: working adapter with basic mixed spmv
ca51e66
mixed: removing stale code
74365be
mixed: wrap mixed bsr matrix to interface with operator
f31a16a
mixed: unify parallel and sequential
cf5ac4d
mixed: wrap mixed ilu0 preconditioner
973bcef
mixed: add mixed dilu option
3a26ef8
mixed: optimized sequential scalar product
f0b86af
mixed: add destructors and documentation
d2d9947
mixed: renaming aesthetics
55dd13e
mixed: update list of public header files
5c1a77e
mixed: update README file
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| #ifndef OPM_MIXED_MATRIX_HEADER_INCLUDED | ||
| #define OPM_MIXED_MATRIX_HEADER_INCLUDED | ||
|
|
||
|
|
||
| #include <opm/simulators/linalg/mixed/bsr.h> | ||
|
|
||
|
|
||
| //! @brief Wraps c-implementation of mixed-precision matrix | ||
| //! | ||
| //! @tparam Vector the block-vector used by linear operator | ||
| //! @tparam b block size | ||
| template <class Vector, int b> | ||
| class MatrixWrapper | ||
| { | ||
| public: | ||
| virtual void mv(const Vector& x, Vector& y) const; | ||
| virtual void umv(const Vector& x, Vector& y) const; | ||
| virtual void usmv(double alpha, const Vector& x, Vector& y) const; | ||
|
|
||
| //! @brief constructor | ||
| //! | ||
| //! @param nrows number of block rows | ||
| //! @param nnz number of nonzero blocks | ||
| MatrixWrapper(int nrows, int nnz) | ||
| { | ||
| nnz_=nnz; | ||
| M_ = bsr_alloc(); | ||
| bsr_init(M_, nrows, nnz, b); | ||
| } | ||
|
|
||
| //! @brief destructor | ||
| ~MatrixWrapper() {bsr_free(M_);} | ||
|
|
||
| void update(double const *data); | ||
|
|
||
| int *rowptr(){return M_->rowptr;} | ||
| int *colidx(){return M_->colidx;} | ||
|
|
||
| private: | ||
| int nnz_; | ||
| bsr_matrix *M_; | ||
| }; | ||
|
|
||
| template <class Vector, int b> | ||
| void MatrixWrapper<Vector,b>:: | ||
| mv(const Vector& x, Vector& y) const | ||
| { | ||
| // mixed-precision block spmv (y = M.x) | ||
| bsr_vmspmv3(M_, &x[0][0], &y[0][0]); | ||
| } | ||
|
|
||
| template <class Vector, int b> | ||
| void MatrixWrapper<Vector,b>:: | ||
| umv(const Vector& x, Vector& y) const | ||
| { | ||
| // mixed-precision block spmv with update (y += M.x) | ||
| bsr_vmspumv3(M_, &x[0][0], &y[0][0], 1.0); | ||
| } | ||
|
|
||
| template <class Vector, int b> | ||
| void MatrixWrapper<Vector,b>:: | ||
| usmv(double alpha, const Vector& x, Vector& y) const | ||
| { | ||
| // scaled mixed-precision block spmv with update (y += alpha * M.x) | ||
| bsr_vmspumv3(M_, &x[0][0], &y[0][0], alpha); | ||
| } | ||
|
|
||
| template <class Vector, int b> | ||
| void MatrixWrapper<Vector,b>:: | ||
| update(double const *data) | ||
| { | ||
| // transpose each dense block to make them column-major | ||
| int bb=b*b; | ||
| double B[bb]; | ||
| for(int k=0;k<nnz_;k++) | ||
| { | ||
| for(int i=0;i<b;i++) for(int j=0;j<b;j++) B[b*j+i] = data[bb*k + b*i + j]; | ||
| for(int i=0;i<bb;i++) M_->dbl[bb*k + i] = B[i]; | ||
| } | ||
|
|
||
| // downcast to single precision | ||
| bsr_downcast(M_); | ||
| } | ||
|
|
||
| #endif // OPM_MIXED_MATRIX_HEADER_INCLUDED | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| #ifndef OPM_MIXED_PREC_HEADER_INCLUDED | ||
| #define OPM_MIXED_PREC_HEADER_INCLUDED | ||
|
|
||
| #include <opm/simulators/linalg/mixed/prec.h> | ||
|
|
||
| namespace Opm { | ||
|
|
||
| //! @brief Wraps c-implementation of mixed-precision preconditioner | ||
| //! | ||
| //! @tparam Vector the block-vector used by linear operator | ||
| //! @tparam M block-sparse matrix type | ||
| //! @tparam X block-vector input type | ||
| //! @tparam Y block vector output type | ||
| template <class M, class X, class Y> | ||
| class MixedPreconditioner : public Dune::PreconditionerWithUpdate<X, Y> | ||
| { | ||
| public: | ||
|
|
||
| using domain_type = X; | ||
| static constexpr auto block_size = domain_type::block_type::dimension; | ||
|
|
||
| //! @brief constructor | ||
| //! | ||
| //! @param A block-sparse matrix | ||
| //! @param use_dilu toggle between dilu or ilu0 factorization | ||
| MixedPreconditioner(const M& A, bool use_dilu = false) | ||
| { | ||
| // Access double precision matrix data | ||
| int nrows = A.N(); | ||
| int nnz = A.nonzeroes(); | ||
| double_data_ = &A[0][0][0][0]; | ||
| prec_ = prec_alloc(); | ||
|
|
||
| // allocate and initialize mixed-precision matrix | ||
| mixed_matrix_ = bsr_alloc(); | ||
| bsr_init(mixed_matrix_, nrows, nnz, block_size); | ||
|
|
||
| // copy sparsity pattern from double preccision matrix | ||
| int *rows = mixed_matrix_->rowptr; | ||
| int *cols = mixed_matrix_->colidx; | ||
|
|
||
| int irow = 0; | ||
| int icol = 0; | ||
| rows[0] = 0; | ||
| for(auto row=A.begin(); row!=A.end(); row++) | ||
| { | ||
| for(unsigned int i=0; i<row->getsize(); i++) | ||
| { | ||
| cols[icol++] = row->getindexptr()[i]; | ||
| } | ||
| rows[irow+1] = rows[irow]+row->getsize(); | ||
| irow++; | ||
| } | ||
|
|
||
| // allocate and initialize preconditioner | ||
| prec_init(prec_,mixed_matrix_); | ||
|
|
||
| // attribute initialization | ||
| nnz_ = nnz; | ||
| use_dilu_ = use_dilu; | ||
|
|
||
| // perform matrix factorization | ||
| update(); | ||
| }; | ||
|
|
||
| //! @brief destructor | ||
| ~MixedPreconditioner() | ||
| { | ||
| bsr_free(mixed_matrix_); | ||
| prec_free(prec_); | ||
| } | ||
|
|
||
| virtual void update() override; | ||
| virtual bool hasPerfectUpdate() const override {return true;} | ||
| virtual void pre ([[maybe_unused]] X& x, [[maybe_unused]] Y& y) override {}; | ||
| virtual void post ([[maybe_unused]] X& x) override {}; | ||
| virtual void apply ([[maybe_unused]] X& x, [[maybe_unused]] const Y& y) override; | ||
| virtual Dune::SolverCategory::Category category() const override { return Dune::SolverCategory::sequential; }; | ||
|
|
||
| private: | ||
| bool use_dilu_; | ||
| double const *double_data_; | ||
| bsr_matrix *mixed_matrix_; | ||
| prec_t *prec_; | ||
| int nnz_; | ||
| }; | ||
|
|
||
| template <class M, class X, class Y> | ||
| void MixedPreconditioner<M,X,Y>:: | ||
| update () | ||
| { | ||
| // transpose each dense block to make them column-major | ||
| int b = block_size; | ||
| int bb=b*b; | ||
| double B[bb]; | ||
| for(int k=0;k<nnz_;k++) | ||
| { | ||
| for(int i=0;i<b;i++) for(int j=0;j<b;j++) B[b*j+i] = double_data_[bb*k + b*i + j]; | ||
| for(int i=0;i<bb;i++) mixed_matrix_->dbl[bb*k + i] = B[i]; | ||
| } | ||
|
|
||
| use_dilu_ ? prec_dilu_factorize(prec_, mixed_matrix_) : prec_ilu0_factorize(prec_, mixed_matrix_); // choose dilu or ilu0 | ||
| prec_downcast(prec_); | ||
| } | ||
|
|
||
| template <class M, class X, class Y> | ||
| void MixedPreconditioner<M,X,Y>:: | ||
| apply ([[maybe_unused]] X& x, [[maybe_unused]] const Y& y) | ||
| { | ||
| x=y; | ||
| prec_mapply3c(prec_,&x[0][0]); | ||
| } | ||
|
|
||
| } | ||
| #endif // OPM_MIXED_PREC_HEADER_INCLUDED |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add this to a namespace?
Also, from the point of view of the user of this class, it is irrelevant that it wraps the c implementation or not. What is important is that its storage of 3x3 blocks is downcasted to single precision and vectorized. So I would call it something else, like
MixedMatrixWrapperfor example.