Replace matrix with Matrix in various cyclic inversions#900
Conversation
Instead of matrix (pointer to pointer). This is the first step in allowing the cyclic solvers to replace all static/class level memory.
One remains unchanged (see #895 for why)
in cyclic_reduction.hxx
This ensures bounds checking when compiled with appropriate CHECK
Could now move all storage from class level to method scope
Also replaces new with Array in laplacexz cyclic
include/cyclic_reduction.hxx
Outdated
| /// Solve a single triadiagonal system | ||
| /// | ||
| void solve(T rhs[], T x[]) { | ||
| void solve(Matrix<T> &rhs, Matrix<T> &x) { |
There was a problem hiding this comment.
I think this should be Array, rather than Matrix. This function solves a single system (Ax=b), so x and rhs here should be Arrays. On line 128 the address of rhs and x were used, to convert T* to T** . Is there a way to convert an Array to a single-column (or single-row) Matrix?
There was a problem hiding this comment.
There's not currently a way to convert an Array to a Matrix, but it should be easy enough to add a constructor to Matrix that does this. In general there isn't a unique way to do this, but we could always make the choice that either the matrix is 1xN or Nx1.
I've been thinking about the possibility of making Matrix::operator[] return an Array slice of the data (either by creating a new Array and copying in values, or making Matrix::data actually be a vector of Array). WIth this I think it would make sense to get a 1xN shape Matrix when constructing from an Array of size N.
This interface to solve isn't actually used anywhere at the moment (at least not in any of the framework or the tests) so we could remove it and revisit if/when this is needed/the Matrix<-->Array conversion is sorted?
There was a problem hiding this comment.
I should note there's a similar argument for setcoefs.
There was a problem hiding this comment.
I've added interfaces to setCoefs and solve that take Array instead of Matrix. These then copy into a Matrix and pass to the main routine before copying back into the Array (where needed).
include/cyclic_reduction.hxx
Outdated
| /// Solve a set of tridiagonal systems | ||
| /// | ||
| void solve(int nrhs, T **rhs, T **x) { | ||
| void solve(int nrhs, Matrix<T> &rhs, Matrix<T> &x) { |
There was a problem hiding this comment.
Can the nrhs argument be removed? This should be the number of columns in rhs? I guess it is bounds checked anyway, but shouldn't be needed.
Can get this information from the passed objects.
ZedThree
left a comment
There was a problem hiding this comment.
Some petty things, some minor things, a couple of larger questions:
-
This changes the signatures of a few functions. Is this going to break backwards-compatibility? Or more precisely, will people need to update physics models? If so, can we just deprecate the old signatures instead of removing them?
-
This is somewhat orthogonal to this PR, but we appear to always
newaCyclicReduce<>. I'm not sure there's any need for this, can we replace with a plain value?
include/cyclic_reduction.hxx
Outdated
|
|
||
| /// Set the entries in the matrix to be inverted | ||
| /// | ||
| /// @param[in] nsys The number of independent matrices to be solved |
There was a problem hiding this comment.
Doxygen comment is now out of date
| void setPeriodic(bool p=true) {periodic=p;} | ||
|
|
||
| /// Set up a single equation to invert | ||
| void setCoefs(T a[], T b[], T c[]) { |
There was a problem hiding this comment.
Should this be deprecated instead of removed? Or is the signature compatible with Matrix<T>?
There was a problem hiding this comment.
Yes I guess this should be deprecated -- I've replaced all uses in the repository but I suppose someone could be using it in their private model. My main issue was how to then construct a Matrix from this to pass through to the actual routine.
The same for the solve interfaces I guess.
include/cyclic_reduction.hxx
Outdated
| // void solve(Matrix<T> &rhs, Matrix<T> &x) { | ||
| // // Solving single system | ||
| // solve(1, &rhs, &x); | ||
| // } |
There was a problem hiding this comment.
Commented-out code should be removed instead
There was a problem hiding this comment.
I thought I'd not staged this, oops.
| // } | ||
|
|
||
| /// Solve a set of tridiagonal systems | ||
| /// |
There was a problem hiding this comment.
Could the doxygen comment be expanded here?
| ic[2] *= -beta; | ||
| ifc(j, 1) = co(j, 4*i + 1) - beta * ifc(j, 0); | ||
| ifc(j, 0) = co(j, 4*i); | ||
| ifc(j, 2) *= -beta; |
include/cyclic_reduction.hxx
Outdated
| ic[0] *= -alpha; | ||
| ic[1] = c[4*i + 1] - alpha*ic[2]; | ||
| ic[2] = c[4*i + 2]; | ||
| ifc(j, 4+0) *= -alpha; |
| c[k][y+y0] = bcoef + 0.5*Im*kwave*ccoef +0.5*ecoef; | ||
| rhsk[k][y+y0] = rhs[y+y0][k]; // Transpose | ||
| a(k, y + y0) = bcoef - 0.5 * Im * kwave * ccoef - 0.5 * ecoef; |
There was a problem hiding this comment.
The whitespace changes have made the preceding comment not very useful. Should we either preserve the whitespace, or delete/modify the comment?
There was a problem hiding this comment.
I'll revert the whitespace.
include/cyclic_reduction.hxx
Outdated
| } | ||
|
|
||
| /// Free all memory arrays allocated by allocMemory() | ||
| void freeMemory() { |
There was a problem hiding this comment.
Is this needed at all now? Can it be deprecated/removed?
There was a problem hiding this comment.
It currently also resets the problem size. I don't think we really need this as it should be cheap enough to fully tear down and rebuild a new instance should we need to. May be worth deprecating?
There was a problem hiding this comment.
I've marked as deprecated, but this is private so I think we should probably be free to just remove it if we decide that we don't need to reset the problem size or if we want to do this a different way.
Restore whitespace in parderiv/cyclic to keep alignment with terms
May be helpful in the situation where the is only one system to solve at a time. Adds a few ASSERTs in places to further guard.
May be helpful in the situation where the is only one system to solve at a time. Adds a few ASSERTs in places to further guard.
…/BOUT-dev into remove_matrix_cyclic
Routine is private so removing uses in framework sufficient to remove entirely without breaking compatibility
All comments addressed except the 2nd larger question which may be outside the scope of this PR
| output << "Expecting receive from " << p << " of size " << len << endl; | ||
| #endif | ||
| MPI_Irecv(recvbuffer[p], | ||
| MPI_Irecv(&recvbuffer(p, 0), |
There was a problem hiding this comment.
Can we use std::begin here, similar to how ifp gets passed below? Or is that not possible due to the subscripting?
There was a problem hiding this comment.
Yes, I think the indexing prevents this from working with std::begin, as recvbuffer(p,0) refers to a single value I'm not sure what begin would do here.
There was a problem hiding this comment.
Most of the places I take the address or use std::begin with all the changes related to arrays, matrices and tensors are places I would like to change the interface of the functions to take the bounds-checked class rather than reverting to passing pointers. I've not made such changes yet as it would touch a lot of signatures and there are a couple of things that we might want to change in the design of Matrix and similar which might change the best route forward.
Helps enable bounds checking for these various inversion classes built on
cyclic_reduction.hxx.Typically we use
newto create a new cyclic_reduction instance. Now all of the allocation is associated with Matrix or Array so should be fast. We may be able to avoid usingnewand instead just create the solver at the scope in which it is needed. Similar could be done with the storage arrays used in these solvers which are typically currently created in the constructor.