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

Unify Containers and MeshBlockPacks #328

Merged
merged 64 commits into from
Nov 5, 2020
Merged

Conversation

jdolence
Copy link
Collaborator

@jdolence jdolence commented Oct 21, 2020

PR Summary

Here's a stab at what was discussed for generalizing the idea of Containers (now MeshBlockData) to the Mesh level with the MeshData class.

PR Checklist

  • Code passes cpplint
  • New features are documented.
  • Adds a test for any bugs fixed. Adds tests for new features.
  • Code is formatted
  • Changes are summarized in CHANGELOG.md

@pgrete
Copy link
Collaborator

pgrete commented Nov 2, 2020

@pgrete Sorry about the particles stuff. I think the interaction between particles and meshblockpacks is going to be pretty strong (one might want only one swarm per meshblockpack, for example).

Yes, I think so too, which is why I brought this up.
A "blind" (in terms of not know how you work with this downstream) merge and conflict fix from me may have caused additional work on your side.

The whole notion of a swarm_container is probably going away but that's a nontrivial change... do you want me to try my hand at merging develop in to this PR and just seeing whether I can hack the particles implementation to still work for now?

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.
I'll be able to provide feedback on that PR on short notice so that we can get that quickly in here and then merge this into develop.
This will also make it easier to add additional updates here (which I'm currently working on and that are unrelated to the swarm/particles).

docs/interface/containers.md Outdated Show resolved Hide resolved
docs/interface/containers.md Outdated Show resolved Hide resolved
docs/interface/containers.md Outdated Show resolved Hide resolved
docs/interface/containers.md Outdated Show resolved Hide resolved
docs/interface/containers.md Outdated Show resolved Hide resolved
src/interface/data_collection.hpp Show resolved Hide resolved
src/interface/meshblock_data.hpp Outdated Show resolved Hide resolved
src/interface/meshblock_data.hpp Show resolved Hide resolved
src/mesh/mesh.cpp Show resolved Hide resolved
src/mesh/meshblock.hpp Outdated Show resolved Hide resolved
@pgrete pgrete changed the title [WIP] Unify Containers and MeshBlockPacks Unify Containers and MeshBlockPacks Nov 5, 2020
@pgrete
Copy link
Collaborator

pgrete commented Nov 5, 2020

@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 CheckRefinement and FillDerived functions for separate PRs.
My main reason is that those changes are likely more involved than we hoped for, e.g.,

  • CheckRefinement will require either a reduction or an Kokkos::View for the MeshBlockPacks that stored the results for each individual MeshBlock
  • FillDerived handles the PreFill FillDerived and PostFill functions in different ways (in the same function call to support multiple packages) that is not immediate obvious to me any more why we decided on that approach. So I'd like to discuss this in a separate issue first before making changes and then review them in a PR that (hopefully) has less than 70 files touched and 1000+ lines of code changed.

What do you think?

@pgrete pgrete self-requested a review November 5, 2020 16:05
@AndrewGaspar
Copy link
Contributor

FillDerived handles the PreFill FillDerived and PostFill functions in different ways (in the same function call to support multiple packages) that is not immediate obvious to me any more why we decided on that approach.

I actually don't fully appreciate why we need PreFill and PostFill. Is it so packages can have dependencies on the FillDerived of other packages?

@AndrewGaspar
Copy link
Contributor

Actually, it can't be that, because PreFill and PostFIll aren't per-package, as pointed out.

@Yurlungur
Copy link
Collaborator

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.

Copy link
Collaborator

@Yurlungur Yurlungur left a 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);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I like this.

Comment on lines +114 to +117
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);
Copy link
Collaborator

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.

Comment on lines +159 to +179
// 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);
}
Copy link
Collaborator

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.

Copy link
Collaborator

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.

example/calculate_pi/pi_driver.cpp Show resolved Hide resolved
@@ -266,6 +266,7 @@ class BoundaryVariable : public BoundaryCommunication, public BoundaryBuffer {
bool ReceiveBoundaryBuffers() override;
void ReceiveAndSetBoundariesWithWait() override;
void SetBoundaries() override;
auto GetPBdVar() { return &bd_var_; }
Copy link
Collaborator

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
Copy link
Collaborator

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?

Copy link
Collaborator

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);
Copy link
Collaborator

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

Suggested change
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.

Copy link
Collaborator

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.

Comment on lines +114 to +134
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);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

src/interface/meshblock_data.cpp Show resolved Hide resolved
@Yurlungur
Copy link
Collaborator

Tests pass. Pulling the trigger.

@Yurlungur Yurlungur merged commit f47690f into develop Nov 5, 2020
@pgrete pgrete deleted the jdolence/containers_and_packs branch November 6, 2020 20:29
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.

5 participants