-
Notifications
You must be signed in to change notification settings - Fork 707
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
ScaLAPACKMatrix: add functions to perform addition, multiplication and row/column scaling #5869
Conversation
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.
LGTM, thanks for improvements 👍 few minor comments. Just wanted to raise the discussion on naming, so don't rush in re-naming anything.
p.s. also add a changelog for the new functionality
include/deal.II/lac/scalapack.h
Outdated
* | ||
* The matrices <tt>A</tt> and <tt>B</tt> must have the same process grid | ||
* | ||
* Following alignment conditions have to be fulfilled: MB_A = NB_B and NB_A = MB_B |
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.
in class description we have
...into
$MB$ by$NB$ blocks...
not sure how it renders, but probably you should do
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.
full stop
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.
I will change it at the one point in the class description, if that is fine with you.
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.
i would actually prefer the opposite, i think it will render better as latex formula. Otherwise you have it as a text MB_A
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.
p.s. that's also how we do it all other places inside ScaLAPACK, including the most recent PR with some docu changes #5875
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.
Right ...
include/deal.II/lac/scalapack.h
Outdated
/** | ||
* Transposing assignment: <i>A = B<sup>T</sup></i> | ||
* | ||
* The matrices <tt>A</tt> and <tt>B</tt> must have the same process grid |
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.
full stop
include/deal.II/lac/scalapack.h
Outdated
* | ||
* else <i>op(B) = B</i> | ||
* | ||
* The matrices <tt>A</tt> and <tt>B</tt> must have the same process grid |
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.
full stop
include/deal.II/lac/scalapack.h
Outdated
* | false | MB_A = MB_B <br> NB_A = NB_B | | ||
* | true | MB_A = NB_B <br> NB_A = MB_B | | ||
*/ | ||
void add(const ScaLAPACKMatrix<NumberType> &B, |
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.
now i see what you wanted to implement, elsewhere (for vector classes) we call this:
sadd (const Number s, const Number a, const VectorSpaceVector< Number > & V)
since other matrix classes don't support this operation, i would rather stick with
sadd (const .. s, const ... a,const ... B, const bool transpose_B = false)
@dealii/dealii any opinions on naming of this matrix operation?
include/deal.II/lac/scalapack.h
Outdated
* | ||
* The matrices <tt>A</tt>, <tt>B</tt> and <tt>C</tt> must have the same process grid. | ||
*/ | ||
void mult(ScaLAPACKMatrix<NumberType> &C, |
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.
@dealii/dealii this is kind of smult
(scale matrix and add multiplication). For consistency with vectors, i would probably move two numbers in front i.e. (const NumberType s, const NumberType a, const Matrix....)
.
But then it would be inconsistent with FullMatrix
void mmult (FullMatrix< number2 > &C, const FullMatrix< number2 > &B, const bool adding=false) const;
hm...
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.
We used to have similar functions in some of the vector classes (e.g here), so I would say that the factors and matrices should be ordered according to the operation along with the input matrices, even if that means that we lose the default values. Does a default value of 0 for b
make sense anyway? This then just becomes an assignment operation.
source/lac/scalapack.cc
Outdated
Assert(this->row_block_size==B.column_block_size,ExcDimensionMismatch(this->column_block_size,B.row_block_size)); | ||
Assert(B.row_block_size==C.column_block_size,ExcDimensionMismatch(B.column_block_size,C.column_block_size)); | ||
} | ||
Threads::Mutex::ScopedLock lock (mutex); |
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.
we need mutex only when mutable
member variables like work
array are being used. I think you don't need it here.
source/lac/scalapack.cc
Outdated
if (this->grid->mpi_process_is_active) | ||
{ | ||
for (int i=0; i<n_local_rows; ++i) | ||
{ |
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.
don't need these brackets
source/lac/scalapack.cc
Outdated
{ | ||
for (int i=0; i<n_local_rows; ++i) | ||
{ | ||
for (int j=0; j<n_local_columns; ++j) |
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.
you should probably loop over columns first, take value and multiply all row elements.
source/lac/scalapack.cc
Outdated
const int glob_i = global_row(i); | ||
for (int j=0; j<n_local_columns; ++j) | ||
{ | ||
local_el(i,j) *= factors[glob_i]; |
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.
just do const NumberType & s = factors[global_row(i)];
source/lac/scalapack.cc
Outdated
{ | ||
const int glob_i = global_row(i); | ||
for (int j=0; j<n_local_columns; ++j) | ||
{ |
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.
and remove these brackets
/run-tests |
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.
LGTM
@dealii/dealii can someone please have a look at the documentation here and the chosen names/arguments for member functions? |
include/deal.II/lac/scalapack.h
Outdated
* | ||
* The matrices <tt>A</tt> and <tt>B</tt> must have the same process grid. | ||
* | ||
* Following alignment conditions have to be fulfilled: $MB_A$ = $NB_B$ and $NB_A$ = $MB_B$ |
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.
Say "The following ...". I had to think about whether "following" is a verb or adjective. Same in a few places below.
Also end the sentence with a period.
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.
You beat me to it! I was also going to make the suggestion that the style of all of the documentation be made more consistent with that of the rest of the class. The conditions can also be put in a @note
.
include/deal.II/lac/scalapack.h
Outdated
/** | ||
* Matrix-addition: | ||
* | ||
* <i>A = a A + b op(B)</i> |
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.
remove the empty line so that this reads back to back
think about whether you could do the same in the following lines
include/deal.II/lac/scalapack.h
Outdated
* | ||
* Copies of @p factors have to available on all processes of the underlying MPI communicator | ||
*/ | ||
void scale_columns(std::vector<NumberType> &factors); |
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.
make the argument const
include/deal.II/lac/scalapack.h
Outdated
* | ||
* Copies of @p factors have to available on all processes of the underlying MPI communicator | ||
*/ | ||
void scale_rows(std::vector<NumberType> &factors); |
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.
same here
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.
btw, we should probably use Vector<NumberType>
instead here. It won't make much of a difference at the end of the day, but is probably more consistent representation of a diagonal matrix used here as pre/post multiplication.
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.
Why is Vector<NumberType>
more consistent than std::vector<NumberType>
?
We do not use Vector<NumberType>
in ScaLAPACKMatrix
unlike std::vector<NumberType>
, which is used at three places.
We could provide two public interfaces and use one private function (working with pointers) internally.
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.
we may seek just a few eigenvalues or all eigenvalues of a matrix. In other places (like Arpack for sparse large matrices) we also use std::vector<>
which is problably ok.
Here, however, this vector has to have as many elements as matrix rows/columns. So in case of a square matrix, this is simply a diagonal matrix represented by a vector. With other matrix classes AFAIK we never use std::vector<>
to represent a diagonal, i.e. https://www.dealii.org/developer/doxygen/deal.II/classSparseMatrix.html#a07ba942c5b7466b3895fed3104fbcc26
// https://www.ibm.com/support/knowledgecenter/SSNR5K_4.2.0/com.ibm.cluster.pessl.v4r2.pssl100.doc/am6gr_lgemm.htm | ||
if (!transpose_A && !transpose_B) | ||
{ | ||
Assert(this->n_columns==B.n_rows,ExcDimensionMismatch(this->n_columns,B.n_rows)); |
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.
thanks for adding all of these asserts!
@BenBrands I'll take a look through the documentation tomorrow! |
Ok, so @bangerth happened post an initial few comment just commented, but I'll stand by my initial commitment and will give it a proper look tomorrow. |
include/deal.II/lac/scalapack.h
Outdated
* | ||
* The matrices <tt>A</tt> and <tt>B</tt> must have the same process grid. | ||
* | ||
* Following alignment conditions have to be fulfilled: $MB_A$ = $NB_B$ and $NB_A$ = $MB_B$ |
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.
I think that for all of the functions that you're documented, the style could be made a bit more similar to that of the existing document. So here, for example, you could consider writing it as follows:
Copy the transpose of the contents of the distributed matrix @p B into this one.
This transpose assignment operation modifies the calling matrix @p A such
that $A = B^{T}$.
@note The matrices @p A and @p B must have the same process grid.
The following alignment conditions also have to be fulfilled:
$MB_A = NB_B$ and $NB_A = MB_B$.
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.
Note also that
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.
I discussed with @davydden the documentation of ScaLAPACKMatrix
and we agree that it has to be reworked to make it uniform. I will do that in a different PR based on the style used for the doc in this PR.
include/deal.II/lac/scalapack.h
Outdated
/** | ||
* Transposing assignment: <i>A = B<sup>T</sup></i> | ||
* | ||
* The matrices <tt>A</tt> and <tt>B</tt> must have the same process grid. |
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.
Why have you used HTML as opposed to LaTeX formatting (both here and below)?
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.
You should use @p
to format the parameters of a function, i.e. @p A
and @p B
, when inline with other text.
Same applies below.
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.
I am also in favour of LaTeX, but we have a mixture of the two, apparently #5897
include/deal.II/lac/scalapack.h
Outdated
* | ||
* if(transpose_B) <i>op(B) = B<sup>T</sup></i> | ||
* | ||
* else <i>op(B) = B</i> |
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.
I'd prefer for this to be expressed in words rather than as pseudo-code. i.e.
If the @p transpose_B is set then the transpose of @p B is used.
That is to say that the operation $op(B)$ corresponds to $B^{T}$.
If this flag is set to false, then $op(B)$ applies @p B with its default ordering.
This also applies below.
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.
I would favor the pseudo-code as it is short and precise.
But I can adapt it if wanted.
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.
I suppose that the pseudo-code is consistent with LapackFullMatrix
and elements of the Vector
class. Although I'm not a huge fan of it, I'm not going to push the issue since there's precedent for it.
include/deal.II/lac/scalapack.h
Outdated
* | ||
* The matrices <tt>A</tt>, <tt>B</tt> and <tt>C</tt> must have the same process grid. | ||
*/ | ||
void mult(ScaLAPACKMatrix<NumberType> &C, |
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.
We used to have similar functions in some of the vector classes (e.g here), so I would say that the factors and matrices should be ordered according to the operation along with the input matrices, even if that means that we lose the default values. Does a default value of 0 for b
make sense anyway? This then just becomes an assignment operation.
include/deal.II/lac/scalapack.h
Outdated
/** | ||
* Matrix-matrix-multiplication. | ||
* | ||
* The optional parameter <tt>adding</tt> determines, whether the result is |
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.
no comma
include/deal.II/lac/scalapack.h
Outdated
* | ||
* else <i>C = A<sup>T</sup>*B</i> | ||
* | ||
* Assumes that <tt>A</tt> and <tt>B</tt> have compatible sizes and that |
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.
It is assumed that...
include/deal.II/lac/scalapack.h
Outdated
@@ -389,6 +546,24 @@ class ScaLAPACKMatrix : protected TransposeTable<NumberType> | |||
*/ | |||
NumberType &local_el(const unsigned int loc_row, const unsigned int loc_column); | |||
|
|||
/** | |||
* Scale the columns of the distributed matrix by scalars in array @p factors. |
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.
by the scalars provided in the array
include/deal.II/lac/scalapack.h
Outdated
* | ||
* The array @p factors must have as many entries as the matrix columns. | ||
* | ||
* Copies of @p factors have to available on all processes of the underlying MPI communicator |
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.
have to be; fullstop at end of sentence.
include/deal.II/lac/scalapack.h
Outdated
* | ||
* The array @p factors must have as many entries as the matrix rows. | ||
* | ||
* Copies of @p factors have to available on all processes of the underlying MPI communicator |
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.
have to be; fullstop at end of sentence.
include/deal.II/lac/scalapack.h
Outdated
void scale_columns(std::vector<NumberType> &factors); | ||
|
||
/** | ||
* Scale the rows of the distributed matrix by scalars in array @p factors. |
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.
by the scalars provided in the array
Thanks for taking the time to add this functionality @BenBrands! Since @davydden checked the implementation already, lets clean up the documentation a little bit and then I think that this is good to go! |
Thank you all for your comments. |
The functions |
@BenBrands Thanks again for the contribution. I've created an issue for the proposed documentation enhancements. |
@davydden @BenBrands Lets discuss the changes made to |
* | ||
* | transpose_B | Block Sizes | Operation | | ||
* | :---------: | :--------------------------: | :-------------------------------------------: | | ||
* | false | $MB_A=MB_B$ <br> $NB_A=NB_B$ | $\mathbf{A} = a \mathbf{A} + b \mathbf{B}$ | |
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.
in another PR #5899 (comment) @kronbichler raised the point whether we shall use bold symbols (\mathbf
) for matrices and vectors.
Personally, I don't mind sticking with plain LaTeX A
, B
, c
for linear algebra, probably with \cdots
to denote multiplication. Downside is that we won't distinguish between scalars and vectors in this notation.
@dealii/dealii thoughts?
template <typename Number> | ||
inline | ||
ArrayView<const Number> | ||
make_array_view (const ArrayView<Number> &array_view) |
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.
@masterleinad I think that you added some of the other make_array_view
functions previously. Are you happy with these two additions (they help instantiation of some functions)?
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.
Sure. In the end, I prefer to have external make_array_functions
instead of modifying the class ArrayView
itself. If this helps with compatibility, I am totally fine with it.
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.
Great, thanks for the confirmation!
Ok, so I think that this is ready to merge but since I've contributed directly to this PR it would be more appropriate for someone else to make the final call. |
tests/scalapack/scalapack_13.cc
Outdated
|
||
const std::vector<unsigned int> sizes = {{400,500}}; | ||
|
||
// test A = alpha A + beta B |
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 please split this test into 2 (each does different operation), previous into 4 (one operation in each test) and the next one into two (rows/cols). If/when something goes south, it's much easier to debug a small tests as opposed to a huge one which covers all the cases .
source/lac/scalapack.cc
Outdated
void ScaLAPACKMatrix<NumberType>::scale_columns(const InputVector &factors) | ||
{ | ||
internal::scale_columns(*this, make_array_view(factors), | ||
this->grid->mpi_process_is_active); |
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.
minor nitpick, i think it's easier to read as
if (this->grid->mpi_process_is_active)
internal::scale_columns(...);
that is, when you move that if
outside of internal function which actually does the job.
No description provided.