Skip to content
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

Clean up system vector and matrix initialization #1378

Merged
merged 2 commits into from
Jul 10, 2017

Conversation

YaqiWang
Copy link
Contributor

@YaqiWang YaqiWang commented Jul 6, 2017

This also enables the construction of vectors and matrices outside of the systems. Close #1376.

@YaqiWang
Copy link
Contributor Author

YaqiWang commented Jul 6, 2017

I will not touch the part in @roystgnr 's #1377.

@roystgnr
Copy link
Member

roystgnr commented Jul 6, 2017

Eliminating TransientSystem::init_data once it's unused was a nice touch. We can apply that on top of my refactoring.

@jwpeterson
Copy link
Member

jwpeterson commented Jul 6, 2017

@YaqiWang please accept my invitation to join the libmesh "Associates" team so your PRs will be tested automatically. Otherwise, every time you push I need to activate them all by hand...

@YaqiWang
Copy link
Contributor Author

YaqiWang commented Jul 6, 2017

@jwpeterson Thanks for the invitation. I have accepted.

@YaqiWang YaqiWang force-pushed the system_cleanup_1376 branch 2 times, most recently from 4a868b8 to 91b9039 Compare July 6, 2017 18:28
@jwpeterson
Copy link
Member

jwpeterson commented Jul 6, 2017

Hm... sounds like you guys were not expecting this to conflict with #1377, but it does.

@YaqiWang
Copy link
Contributor Author

YaqiWang commented Jul 6, 2017

yes, i am resolving it.

@@ -113,6 +107,11 @@ void ImplicitSystem::init_matrices ()
if (matrix->initialized())
return;

// Clear any existing matrices
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure if I should move this code inside here. Let me try move it back. I will need to run MOOSE test to make sure. BTW, how do I run libmesh test locally?

Copy link
Member

Choose a reason for hiding this comment

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

how do I run libmesh test locally?

make check in the top level of the build directory will run all the libmesh unit tests and examples. You can also run make check within a single example directory to test it alone.

@YaqiWang
Copy link
Contributor Author

YaqiWang commented Jul 6, 2017

I saw a Memory leak detected! in one of the examples, possibly due to system matrix management. So do not merge it.

@YaqiWang
Copy link
Contributor Author

YaqiWang commented Jul 6, 2017

I think this is good to go. Thanks.

Copy link
Member

@jwpeterson jwpeterson left a comment

Choose a reason for hiding this comment

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

One additional nitpick: can you please fix your commit message formatting so that it follows these guidelines.

/**
* Initializes the matrices associated with this system.
*/
virtual void init_matrices ();
Copy link
Member

Choose a reason for hiding this comment

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

Maybe I didn't fully understand the new design that was discussed. Did init_matrices() need to become public?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought I would need this to be public. But after working on moose after this, turns out I only need to do

  // do not assemble system matrix for JFNK solve
  if (solverParams()._type == Moose::ST_JFNK)
    _nl->system().set_basic_system_only();
  _nl->nonlinearSolver()->jacobian = NULL;

in MOOSE FEProblemBase::init. So this does not have to be public to me. However, it may be desired in general.

Copy link
Member

Choose a reason for hiding this comment

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

I never desire to make things public without very compelling reasons....

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, will make it back.

// Add the system RHS.
// (We must do this before initializing the System data,
// then we lose the opportunity to add vectors).
// Restore us to a "basic" state
this->add_system_rhs ();
Copy link
Member

Choose a reason for hiding this comment

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

Were we calling add_system_rhs() in ExplicitSystem::clear() before? If not, I find it confusing for a clear() function to be adding vectors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Me too, but this appears necessary for restoring. It also follows @roystgnr 's coding in TransientSystem::clear.


_matrices[mat_name]->clear();
delete _matrices[mat_name];
_matrices[mat_name] = libmesh_nullptr;
Copy link
Member

Choose a reason for hiding this comment

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

This leaves a NULL entry in the _matrices container that will cause ImplicitSystem::have_matrix() to return confusing values.

Copy link
Member

Choose a reason for hiding this comment

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

It also does 3 map lookups (via operator[]) which is unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch. I forgot to erase the entry in _matrices.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know that is not ideal, I basically copied some codes in remove_vector... Want me change that as well?

Copy link
Member

Choose a reason for hiding this comment

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

Want me change that as well?

No, not for this PR. I'll fix it some other time...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, because it is in system.C, I fixed it here already. It belongs to cleanup.

@YaqiWang YaqiWang force-pushed the system_cleanup_1376 branch 3 times, most recently from 015729a to 68ae6c1 Compare July 6, 2017 21:19
delete pos->second;

_matrices.erase(mat_name);
}
Copy link
Member

Choose a reason for hiding this comment

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

But this still does 3 lookups: 1 for have_matrix(), one for find() and one for erase(key). Also I don't think it's necessary to call clear() followed by delete because all the SparseMatrix destructors call clear(). So, the following should work:

matrices_iterator pos = _matrices.find (mat_name);
if (pos==end) return;
delete pos->second;
_matrices.erase(pos);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, will update.


//Return if the matrix does not exist
if (pos == _matrices.end())
return
Copy link
Member

Choose a reason for hiding this comment

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

No semi-colon here! I'm not sure how this even compiles?!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, strange.

The vectors and matrices are managed in the same way throughout the systems.
Because adding system matrix in implicit system is moved to the constructor,
users can choose to delay the matrix construction by calling set_basic_system_only().
A new interface function, remove_matrix(), is added in ImplicitSystem.
@moosebuild
Copy link

Job Test debug on 99cc7ab : invalidated by @jwpeterson

Two of the usual debug mode timeout suspects

@jwpeterson
Copy link
Member

This looks OK to me, but @roystgnr should probably also sign off on the changes.

@@ -45,6 +46,8 @@ ExplicitSystem::~ExplicitSystem ()
{
// clear data
this->clear();

remove_vector("RHS Vector");
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this here? The additional vectors are all about to be destroyed by System::~System anyways.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure, because System::~System calls this->clear(), which is ExplicitSystem::clear(), right? If so, rhs vector is not cleared.

Copy link
Member

Choose a reason for hiding this comment

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

Although, to be fair, that's not obvious. System::~System() calls this->clear(), and C++ rules say that that means System::clear(), not ExplicitSystem::clear(), which in this case is exactly what we want and won't leave a re-added RHS vector, but which is such obscure behavior that CERT recommends never doing it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see. Thanks. We then can completely remove the ExplicitSystem destructor, right?

@@ -55,6 +57,8 @@ ImplicitSystem::~ImplicitSystem ()
{
// Clear data
this->clear();

remove_matrix("System Matrix");
Copy link
Member

Choose a reason for hiding this comment

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

This, on the other hand, looks like the ideal workaround for what otherwise would have been a memory leak introduced by the improved ImplicitSystem::clear() behavior.

@@ -713,15 +713,16 @@ NumericVector<Number> & System::add_vector (const std::string & vec_name,

void System::remove_vector (const std::string & vec_name)
{
vectors_iterator pos = _vectors.find(vec_name);

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the optimization

@roystgnr
Copy link
Member

Verify that that remove_vector() call is redundant, and take it out (a separate commit, no need to rebase, since this isn't a breakage-inducing bug), and this should be good to merge.

@roystgnr
Copy link
Member

And if you want to be super nice you could add a comment to System::~System explaining what's going on so that it doesn't confuse anyone else in the future.

@roystgnr
Copy link
Member

Or you could even just change this->clear() to an explicit System::clear() there, if you feel that's clearer.

(no, I couldn't resist the pun)

@YaqiWang
Copy link
Contributor Author

@roystgnr added one commit to address your comment.

@roystgnr
Copy link
Member

This looks good to me, once tests are done.

@roystgnr roystgnr merged commit be6af92 into libMesh:master Jul 10, 2017
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.

4 participants