-
Notifications
You must be signed in to change notification settings - Fork 37
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
Unify Containers and MeshBlockPacks #328
Conversation
…rete/meshblock-pack-in-one
Yes, I think so too, which is why I brought this up.
It'd be great if you could work on the integration of develop in here. In terms of easier review (e.g., to see how the particle/swarm infrastructure is affected) it'd be great if you could work on a separate branch, i.e., derive from this one, merge develop into the new one, and then open a PR to merge the new one against this one. |
Co-authored-by: Andrew Gaspar <[email protected]>
Merge develop (especially particles) into meshblockpack work
@jdolence @jdolence @AndrewGaspar after having stared at this for some more time I now suggest to make a final review of the changes that were introduced to address the comments and leave the update of the
What do you think? |
I actually don't fully appreciate why we need |
Actually, it can't be that, because PreFill and PostFIll aren't per-package, as pointed out. |
I can take another pass through if you like. But from my point of view, let's get this in and fix incremental things still missing later. |
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 happy with this. As soon as the long regression tests pass, I'll pull the trigger.
// MeshBlockData of the previous stage of blocks in partition i | ||
auto &mc0 = pmesh->mesh_data.GetOrAdd(stage_name[stage - 1], i); | ||
// MeshBlockData of the current stage of blocks in partition i | ||
auto &mc1 = pmesh->mesh_data.GetOrAdd(stage_name[stage], i); |
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 like this.
auto &mbase = pmesh->mesh_data.GetOrAdd("base", i); | ||
auto &mc0 = pmesh->mesh_data.GetOrAdd(stage_name[stage - 1], i); | ||
auto &mc1 = pmesh->mesh_data.GetOrAdd(stage_name[stage], i); | ||
auto &mdudt = pmesh->mesh_data.GetOrAdd("dUdt", i); |
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.
much improved compared to the more manual method before.
// estimate next time step | ||
if (stage == integrator->nstages) { | ||
auto new_dt = tl.AddTask( | ||
fill_derived, | ||
[](MeshBlock *pmb) { | ||
pmb->pmr->CheckRefinementCondition(); | ||
[](std::shared_ptr<MeshBlockData<Real>> &rc) { | ||
auto pmb = rc->GetBlockPointer(); | ||
pmb->SetBlockTimestep(parthenon::Update::EstimateTimestep(rc)); | ||
return TaskStatus::complete; | ||
}, | ||
pmb); | ||
sc1); | ||
|
||
// Update refinement | ||
if (pmesh->adaptive) { | ||
auto tag_refine = tl.AddTask( | ||
fill_derived, | ||
[](std::shared_ptr<MeshBlock> pmb) { | ||
pmb->pmr->CheckRefinementCondition(); | ||
return TaskStatus::complete; | ||
}, | ||
pmb); | ||
} |
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.
In a future MR, we should try to make these work over the whole MeshBlockPack
as there is probably some advantage to doing so.
I think that's a topic for a future MR, however.
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.
Yes, that's another item on the list of things to be addressed in a separate MR (sooner than later) as it'll make reviewing easier.
@@ -266,6 +266,7 @@ class BoundaryVariable : public BoundaryCommunication, public BoundaryBuffer { | |||
bool ReceiveBoundaryBuffers() override; | |||
void ReceiveAndSetBoundariesWithWait() override; | |||
void SetBoundaries() override; | |||
auto GetPBdVar() { return &bd_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.
👍
const std::string label = mbd_label + "_part-" + std::to_string(partition_id); | ||
auto it = containers_.find(label); | ||
if (it == containers_.end()) { | ||
// TODO(someone) add caching of partitions to Mesh at some point |
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.
Do we know if this is a performance bottleneck? Partitioning should be very fast, as it just moves some shared pointers around. Also if packs and MeshData<Real>>
are already cached, then will the partition caching ever be relevant?
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 far as I've looked at the profiling data (without looking at this part specifically) this is now likely less of an issue.
I only added the comment as in the first iteration in this PR without the GetOrAdd
function, the partitioning would happen in every (sub)cycle just to extract the right (cached) container.
With the current automated caching in place this should be negligible compared to other piece that are triggered when the caches are invalid (such as after load balancing).
return it->second; | ||
} | ||
|
||
std::shared_ptr<T> &GetOrAdd(const std::string &mbd_label, const int &partition_id); |
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 feel like GetOrAdd
could be unified with Get/Add
a bit better. For example, perhaps there could be a version with signature
std::shared_ptr<T> &GetOrAdd(const std::string &mbd_label, const std::string &base);
to replace separate Get
and Add
calls elsewhere in the code.
Also perhaps the signature for the one with an int partition id should have a default for the case of only 1 partition. e.g.,
std::shared_ptr<T> &GetOrAdd(const std::string &mbd_label, const int &partition_id); | |
std::shared_ptr<T> &GetOrAdd(const std::string &mbd_label, const int partition_id = 0); |
This can all be saved for another time (or never) though.
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 main reason why I didn't go a more "unified" version as the GetOrAdd
is specific to the DataCollection<MeshData>
and not implemented for the DataCollection<MeshBlockData>
(both implementation would be distinct whereas the high level GetOrAdd
work in their templated form.
template <typename... Args> | ||
auto PackVariables(Args &&... args) { | ||
auto pack_function = [&](std::shared_ptr<MeshBlockData<T>> meshblock_data) { | ||
return meshblock_data->PackVariables(std::forward<Args>(args)...); | ||
}; | ||
std::vector<std::string> key; | ||
auto vpack = block_data_[0]->PackVariables(std::forward<Args>(args)..., key); | ||
return pack_on_mesh_impl::PackOnMesh<VariablePack<T>>(key, varPackMap_, block_data_, | ||
pack_function); | ||
} | ||
|
||
template <typename... Args> | ||
auto PackVariablesAndFluxes(Args &&... args) { | ||
auto pack_function = [&](std::shared_ptr<MeshBlockData<T>> meshblock_data) { | ||
return meshblock_data->PackVariablesAndFluxes(std::forward<Args>(args)...); | ||
}; | ||
vpack_types::StringPair key; | ||
auto vpack = block_data_[0]->PackVariablesAndFluxes(std::forward<Args>(args)..., key); | ||
return pack_on_mesh_impl::PackOnMesh<VariableFluxPack<T>>(key, varFluxPackMap_, | ||
block_data_, pack_function); | ||
} |
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.
👍
Tests pass. Pulling the trigger. |
PR Summary
Here's a stab at what was discussed for generalizing the idea of
Container
s (nowMeshBlockData
) to theMesh
level with theMeshData
class.PR Checklist