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

Work balance #11216

Merged
merged 8 commits into from Apr 9, 2018
Merged

Work balance #11216

merged 8 commits into from Apr 9, 2018

Conversation

friedmud
Copy link
Contributor

@friedmud friedmud commented Apr 7, 2018

Create a new VectorPostprocessor that can help in determining the quality of a partitioning.

closes #11209

@moosebuild
Copy link
Contributor

moosebuild commented Apr 7, 2018

Job Documentation on b185589 wanted to post the following:

View the site here

This comment will be updated on new commits.

Copy link
Member

@permcody permcody left a comment

Choose a reason for hiding this comment

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

Looks pretty good, just a few minor comments.

}
case 5: // norm2
return std::sqrt(std::accumulate(
stat_vector.begin(), stat_vector.end(), 0, [](Real running_value, Real current_value) {
Copy link
Member

Choose a reason for hiding this comment

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

Minor inconsistency between your two lambdas. Neither one needs a capture, but the one above includes an ampersand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The one with the & needs to capture mean.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again: I am not writing this code randomly.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, well then how about &mean?

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 idea


}));
default:
mooseError("Unknown statistics type1");
Copy link
Member

Choose a reason for hiding this comment

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

Typo? Maybe print the stat number.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks!

// Now Node info
auto wb_nl = WBNodeLoop(_fe_problem);

Threads::parallel_reduce(*mesh.getLocalNodeRange(), wb_nl);
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, on one hand you aren't really after efficiency (you are doing two complete sweeps over the mesh when you could just do them together). On the other hand you went through the trouble of creating two custom threaded loops (when we don't run threads very often). Are you sure this is a better design than just gather both stats at once deriving from an existing looping type?

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 do really wish you would give me the benefit of the doubt. I didn't just "do" this stuff because it makes me happy...

You can't do an element loop and count things on nodes because nodes are shared by elements so you double count. The same goes for doing a node loop and counting elemental things. Yes, you could invent some complicated logic / structure... but it would be a mess or waste memory / efficiency. It's better to do them in two loops.

This is exactly the same reason why we have two different loops for elemental things (like elemental postprocessors) and nodal things (like nodal postprocessors).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As for doing it threaded: any mesh-sweep we do should be threaded.

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 only that - but I've done the hard work to make it threaded. Why on earth would we remove it now?

Copy link
Member

Choose a reason for hiding this comment

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

Just asking the question. I just saw a bunch of new loops and wanted to make sure that this was the right choice here. Sounds like you've thought about it.

#include "ThreadedNodeLoop.h"

#include "libmesh/quadrature.h"

Copy link
Member

Choose a reason for hiding this comment

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

#include <numeric>

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 guess - there are LOTS of things that we use that we never #include... tons in fact.

If I #included everything used in this file it would be ~20 or so header files...

Copy link
Member

Choose a reason for hiding this comment

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

Because you need it: https://civet.inl.gov/job/174638/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's not what caused that failure. The failure was an actual copy-and-paste bug that you missed: https://github.com/idaholab/moose/pull/11216/files#diff-5e0bb82e85bf3311c34cfcf6d004e3e9R13

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, Are you sure? Doing a "grep" shows that we only have three includes of "numeric" in the whole framework. Two of them in vector postprocessors and one in MooseUtils.h. The unity build will work because of the former, but we are definitely pushing the lucky side of things if we are relying on MooseUtils to pull it in through an indirect include.

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 #included it to be sure

const auto & name = the_pair.first;
const auto & values = *the_pair.second.current;

auto & stat_vector = *_stat_vectors[name];
Copy link
Member

Choose a reason for hiding this comment

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

Potential accidental insertion... Try to avoid using map [] operators on the RHS - like ever :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It can't be - initialize() above guarantees that it will exist. But I'll change it because I don't feel like fighting over pedantry.

Copy link
Member

Choose a reason for hiding this comment

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

I've fixed literally dozens of these over the years. Maybe even hundreds. The pedantry is more than worth it. I'm not picking on you, I'm trying to encourage defensive coding. If you want to keep the RHS bracket usage, add a mooseAssert right before it, or at least at the top of the method. Maybe someday we'll refactor and initialize and execute won't appear next to one another in the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair - I will change it. What is your preferred way here again? Do we have it written down somewhere (maybe it should be on the code-standards... maybe we should even look for this in precheck!)

Copy link
Member

Choose a reason for hiding this comment

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

Almost impossible in a pre-check. Using the bracket operator on the RHS with a vector is common and the only way to get values out. Telling the difference between a map and a vector would require full semantic analysis. I usually just go with std::map::find(), Robert likes std::map::count() better. If you want to use the brackets, then just put a mooseAssert somewhere before so we can actually guarantee (at least in debug) that the value is there. Finally there is std::map::at() but we've more or less decided against using that because it can throw (which at least finds the problem, but doesn't give useful information when it causes your simulation to crash, especially in parallel).

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 wonder if it would be possible to write a custom clang plugin that would error if you call std::map::operator[]...

Anyway - I changed it...

csvdiff = 'distributed_work_balance_0000.csv'
min_parallel = 2
max_parallel = 2
mesh_mode = distributed
Copy link
Member

Choose a reason for hiding this comment

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

This shouldn't be necessary for a framework test, but I'll leave that up to you. We do run distributed mesh in parallel. This is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Again: please give me the benefit of the doubt. It's not just random. If you see something that I've done that looks like I did it on purpose (not just copy and paste)... THEN I DID IT ON PURPOSE. Please try to think about why I would have done that instead of just criticizing. I've been working hard on making good code that is tested and documented...

In this case the gold files are particular to the partitioner and the number of processors the test is run on. There isn't one gold file that will work for both replicated and distributed - but I want to make sure that both are tested with this object (it's obviously important that it works with both).

Copy link
Member

Choose a reason for hiding this comment

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

Oh right, good point. In fact there's a possibly it won't be stable on different platforms. I guess we'll see.


auto n_vars = node.n_vars(sys);

for (decltype(n_vars) var = 0; var < n_vars; var++)
Copy link
Member

Choose a reason for hiding this comment

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

Minor: Lots of whitespace (newlines), not really clear why.


// For MOOSE, system 0 is the nonnlinear system - that's what we care about here
// I've left the other code commented out here because I might change my mind in a little while
// and add back the ability to set the system or compute over all
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps an option for either or both is in order:

MooseEnum system_enum("NL AUX ALL", "ALL");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Possibly - but I accept pull requests... I don't have time to do all the possibilities.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I'm just commenting that we previously ran into this before and I read your comment here showing you that we eventually added the option. You don't have to change anything, but you can see that we may want to add options. Again, I'm not saying that you should change it, just getting you to think and be consistent with other pars of the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well - the other problem here is that it might be some other system other than NL or Aux. For instance: I have a few systems in my ray tracing stuff.

I know that I can get the enum to accept more values than what are given... but how exactly do I get an id for those? Do you have to give the real name of the system (like rt0) or do you provide the system number or something?

This is what I wasn't quite sure of so I didn't know how I wanted to proceed.

I'll at least add in NL, AUX and ALL for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also: thanks for pointing to NumDOFs... I'll make this consistent.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure how we get the extra ids. @aeslaughter - has rewritten that system and things have changed quite a bit. NL and Aux will be sufficient for almost anyone

friedmud added a commit to friedmud/moose that referenced this pull request Apr 7, 2018
friedmud added a commit to friedmud/moose that referenced this pull request Apr 7, 2018
stat_vector.end(),
0,
[&mean](Real running_value, Real current_value) {
return running_value + std::pow(current_value - mean, 2);
Copy link
Member

Choose a reason for hiding this comment

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

Minor: Could use one of the fast pow utilities we have (either libMesh's templated one, or Moose's fast one).

@permcody permcody merged commit f1a649d into idaholab:devel Apr 9, 2018
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.

None yet

3 participants