Skip to content

Allow for accessing flux Metadata from Metadata::WithFluxes Metadata #1161

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

Merged
merged 16 commits into from
Sep 12, 2024

Conversation

lroberts36
Copy link
Collaborator

@lroberts36 lroberts36 commented Aug 26, 2024

PR Summary

This PR adds a std::shared_ptr<Metadata> flux_metadata member to Metadata that is initialized in the Metadata constructor when the flag Metadata::WithFluxes is set. A new Metadata constructor is added that takes a list of flags for both the original field and the flux field, as well as separate prolongation and restriction operations for the base field and the flux field (but all of the old constructors behavior is unchanged). The easier way to set non-default properties of the flux Metadata is to get access to it through the method Metadata::GetSPtrFluxMetadata() and Set and Unset flags there and register refinement operations, e.g.

Metadata m({Metadata::Face, Metadata::WithFluxes, Metadata::Vector}, {1, 2});
auto pm_flux = m.GetSPtrFluxMetadata(); 
pm_flux.Unset(Metadata::OneCopy); 
pm_flux.RegisterRefinementOps<OpPro, OpRes, OpInternalPro>();  

This PR also adds a flag Metadata::CellMemAligned, which causes a field to have memory allocated with the same size as a cell variable no matter what its topological type is. This is set by default for fluxes associated with cell centered fields (to ensure backwards compatibility). Obviously, having this flag set means that face, edge, and nodal fields will be missing one layer of ghosts on some sides, but having it set can allow for vectorization in some downstream codes.

Finally, (sorry) this PR includes a couple of small changes to sparse pack cache checking and to boundary communication. These are just performance enhancements that got merged into this branch by mistake and it was easier to leave them in than jump through a bunch of git hoops. If people are strongly opposed to including them here, let me know.

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
  • Change is breaking (API, behavior, ...)
    • Change is additionally added to CHANGELOG.md in the breaking section
    • PR is marked as breaking
    • Short summary API changes at the top of the PR (plus optionally with an automated update/fix script)
  • CI has been triggered on Darwin for performance regression tests.
  • Docs build
  • (@lanl.gov employees) Update copyright on changed files

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.

LGTM! Should we have a test?

@lroberts36
Copy link
Collaborator Author

LGTM! Should we have a test?

Let's have a Sam based test first. Once that passes I can add one to the unit tests.

@lroberts36
Copy link
Collaborator Author

@Yurlungur: Maybe this isn't the "right" way to do things. It seems like we will have to add a second flag for many options just so that it can pass through to the fluxes. Maybe we should really be making a Metadata constructor that takes two vectors of metadata flags and uses the second one to internally construct a second Metadata object for the flux field. What do you think?

Also, I added a flag Metadat::CellMemAligned in this PR that allows you to explicitly choose what the allocated size of an array is (so that you can do the Riot vectorization tricks more easily in the FLD solver).

@Yurlungur
Copy link
Collaborator

@Yurlungur: Maybe this isn't the "right" way to do things. It seems like we will have to add a second flag for many options just so that it can pass through to the fluxes. Maybe we should really be making a Metadata constructor that takes two vectors of metadata flags and uses the second one to internally construct a second Metadata object for the flux field. What do you think?

I think this is a nice idea... though I would suggest it be optional.

Also, I added a flag Metadat::CellMemAligned in this PR that allows you to explicitly choose what the allocated size of an array is (so that you can do the Riot vectorization tricks more easily in the FLD solver).

👍

@lroberts36
Copy link
Collaborator Author

@Yurlungur: Maybe this isn't the "right" way to do things. It seems like we will have to add a second flag for many options just so that it can pass through to the fluxes. Maybe we should really be making a Metadata constructor that takes two vectors of metadata flags and uses the second one to internally construct a second Metadata object for the flux field. What do you think?

I think this is a nice idea... though I would suggest it be optional.

It would have to be optional for backward compatibility, but the idea would be to just have a set of default Metadata (which we effectively have now) and allow that to be overridden with by the new constructor.

@lroberts36 lroberts36 changed the title Small: Allow for fluxes that are not Metadata::OneCopy Small: Allow for accessing flux Metadata from Metadata::WithFluxes Metadata Sep 4, 2024
@@ -213,7 +213,7 @@ TaskStatus ReceiveBoundBufs(std::shared_ptr<MeshData<Real>> &md) {
[&all_received](auto pbuf) { all_received = pbuf->TryReceive() && all_received; });

int ibound = 0;
if (Globals::sparse_config.enabled) {
if (Globals::sparse_config.enabled && all_received) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This changes to allocating fields only after all boundary buffers are received. This should have no impact on code behavior, but can have a performance impact in some cases. The change is unrelated to the rest of the PR.

@@ -138,7 +138,7 @@ struct PackDescriptor {
// default constructor needed for certain use cases
PackDescriptor()
: nvar_groups(0), var_group_names({}), var_groups({}), with_fluxes(false),
coarse(false), flat(false), identifier("") {}
coarse(false), flat(false), identifier(""), nvar_tot(0) {}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This just counts the total number of variables included in the pack at the time of PackDescriptor construction so it doesn't have to be redone every time the cache is checked to see if a given pack is stale. Unrelated to the bulk of this PR.

Comment on lines +78 to +79
astat[idx++] =
uid_map.count(uid) > 0 ? (uid_map.at(uid))->GetAllocationStatus() : -1;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Try to limit branching and preallocate the std::vector for SparsePack cache checking. Unrelated to the rest of the PR.

@lroberts36 lroberts36 changed the title Small: Allow for accessing flux Metadata from Metadata::WithFluxes Metadata Allow for accessing flux Metadata from Metadata::WithFluxes Metadata Sep 4, 2024
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.

This all looks good to me.

@lroberts36 lroberts36 merged commit 864f5c8 into develop Sep 12, 2024
53 checks passed
@Yurlungur Yurlungur deleted the lroberts36/add-non-one-copy-fluxes branch June 20, 2025 19:38
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.

3 participants