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
Work balance #11216
Conversation
Job Documentation on b185589 wanted to post the following: View the site here This comment will be updated on new commits. |
…ll modifications to WorkBalance documentation closes idaholab#11217 refs idaholab#11209
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.
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) { |
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 inconsistency between your two lambdas. Neither one needs a capture, but the one above includes an ampersand.
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.
The one with the &
needs to capture mean
.
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.
Again: I am not writing this code randomly.
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.
Oh, well then how about &mean?
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.
Good idea
|
||
})); | ||
default: | ||
mooseError("Unknown statistics type1"); |
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.
Typo? Maybe print the stat number.
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!
// Now Node info | ||
auto wb_nl = WBNodeLoop(_fe_problem); | ||
|
||
Threads::parallel_reduce(*mesh.getLocalNodeRange(), wb_nl); |
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.
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?
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 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).
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.
As for doing it threaded: any mesh-sweep we do should be threaded.
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.
Not only that - but I've done the hard work to make it threaded. Why on earth would we remove it now?
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 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" | ||
|
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.
#include <numeric>
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 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...
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.
Because you need it: https://civet.inl.gov/job/174638/
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.
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
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.
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.
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 #included
it to be sure
const auto & name = the_pair.first; | ||
const auto & values = *the_pair.second.current; | ||
|
||
auto & stat_vector = *_stat_vectors[name]; |
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.
Potential accidental insertion... Try to avoid using map [] operators on the RHS - like ever :)
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 can't be - initialize()
above guarantees that it will exist. But I'll change it because I don't feel like fighting over pedantry.
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'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.
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.
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!)
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.
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).
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 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 |
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.
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.
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.
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).
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.
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++) |
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: 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 |
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.
Perhaps an option for either or both is in order:
MooseEnum system_enum("NL AUX ALL", "ALL"); |
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.
Possibly - but I accept pull requests... I don't have time to do all the possibilities.
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.
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.
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.
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.
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.
Also: thanks for pointing to NumDOFs
... I'll make this consistent.
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'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
994b5be
to
717d952
Compare
717d952
to
5bdd0e9
Compare
2821790
to
b185589
Compare
stat_vector.end(), | ||
0, | ||
[&mean](Real running_value, Real current_value) { | ||
return running_value + std::pow(current_value - mean, 2); |
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: Could use one of the fast pow utilities we have (either libMesh's templated one, or Moose's fast one).
Create a new VectorPostprocessor that can help in determining the quality of a partitioning.
closes #11209