Skip to content

Replace matrix with Matrix in various cyclic inversions#900

Merged
d7919 merged 21 commits intonextfrom
remove_matrix_cyclic
Mar 2, 2018
Merged

Replace matrix with Matrix in various cyclic inversions#900
d7919 merged 21 commits intonextfrom
remove_matrix_cyclic

Conversation

@d7919
Copy link
Member

@d7919 d7919 commented Feb 23, 2018

Helps enable bounds checking for these various inversion classes built on cyclic_reduction.hxx.

Typically we use new to 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 using new and 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.

@d7919 d7919 mentioned this pull request Feb 24, 2018
/// Solve a single triadiagonal system
///
void solve(T rhs[], T x[]) {
void solve(Matrix<T> &rhs, Matrix<T> &x) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should note there's a similar argument for setcoefs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

/// Solve a set of tridiagonal systems
///
void solve(int nrhs, T **rhs, T **x) {
void solve(int nrhs, Matrix<T> &rhs, Matrix<T> &x) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now removed.

Can get this information from the passed objects.
@d7919 d7919 mentioned this pull request Feb 24, 2018
Copy link
Member

@ZedThree ZedThree left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some petty things, some minor things, a couple of larger questions:

  1. 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?

  2. This is somewhat orthogonal to this PR, but we appear to always new a CyclicReduce<>. I'm not sure there's any need for this, can we replace with a plain value?


/// Set the entries in the matrix to be inverted
///
/// @param[in] nsys The number of independent matrices to be solved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doxygen comment is now out of date

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

void setPeriodic(bool p=true) {periodic=p;}

/// Set up a single equation to invert
void setCoefs(T a[], T b[], T c[]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be deprecated instead of removed? Or is the signature compatible with Matrix<T>?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

// void solve(Matrix<T> &rhs, Matrix<T> &x) {
// // Solving single system
// solve(1, &rhs, &x);
// }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out code should be removed instead

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I'd not staged this, oops.

// }

/// Solve a set of tridiagonal systems
///
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace issue

ic[0] *= -alpha;
ic[1] = c[4*i + 1] - alpha*ic[2];
ic[2] = c[4*i + 2];
ifc(j, 4+0) *= -alpha;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whitespace changes have made the preceding comment not very useful. Should we either preserve the whitespace, or delete/modify the comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll revert the whitespace.

}

/// Free all memory arrays allocated by allocMemory()
void freeMemory() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed at all now? Can it be deprecated/removed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Routine is private so removing uses in framework sufficient to remove
entirely without breaking compatibility
@d7919 d7919 dismissed ZedThree’s stale review February 26, 2018 17:15

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),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use std::begin here, similar to how ifp gets passed below? Or is that not possible due to the subscripting?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@d7919 d7919 merged commit 30c83fb into next Mar 2, 2018
@d7919 d7919 deleted the remove_matrix_cyclic branch March 2, 2018 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants