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

Provide more flexible ways to add subset MeshBlockData objects to DataCollections #921

Merged
merged 36 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
fd6d565
add the ability to get a list of vars given constraints
jdolence Aug 11, 2023
163d263
Merge branch 'develop' into jdolence/meshblockdata_add
jdolence Aug 11, 2023
033baec
expose a mesh-level interface that uses resolved_packages
jdolence Aug 11, 2023
ae64275
add package metadata to all fields, sparse fields, and swarms
jdolence Aug 11, 2023
e85c7f9
refactor Copy and make accessible from DataCollection Add functions
jdolence Aug 11, 2023
7d14eb8
formatting
jdolence Aug 11, 2023
ade63bf
newline for the linter
jdolence Aug 11, 2023
eeaf23d
remove dead code
jdolence Aug 11, 2023
3c72945
sneak in templated versions of the AddField/SparsePool/Swarm/SwarmVal…
jdolence Aug 11, 2023
fa1ce4f
template SparsePool constructor on variable type
jdolence Aug 12, 2023
c127627
that didnt work. try this.
jdolence Aug 12, 2023
c58d82e
change name
jdolence Aug 12, 2023
305089b
DataCollection Add functions should returns references
jdolence Aug 12, 2023
56abe2a
formatting
jdolence Aug 13, 2023
3800f48
fix some things to make adding to the mesh_data collection directly work
jdolence Aug 14, 2023
2c828fd
Add MakePackDescriptor for uids
lroberts36 Aug 14, 2023
7dff9e4
fix style
jdolence Aug 14, 2023
097d0bb
compute uid intersections of variables in different MeshBlockData cla…
jdolence Aug 14, 2023
19bc17b
add a MeshData intersection function
jdolence Aug 14, 2023
61e345a
a little hack to avoid calling a member of StateDescriptor from the h…
jdolence Aug 14, 2023
346e864
get rid of the hack
jdolence Aug 14, 2023
53e9f06
expose Uid_t in the driver/prelude namespace
jdolence Aug 14, 2023
85e0d67
treat shallow copies differently for sparse allocation
jdolence Aug 15, 2023
0d286a3
only allocate/deallocate sparse if it exists in the MeshBlockData object
jdolence Aug 15, 2023
c153a90
formatting and style
jdolence Aug 15, 2023
811e08e
add default descriptors/sparse packs for weird usage downstream
jdolence Aug 15, 2023
1da52bb
Update src/interface/state_descriptor.cpp
jdolence Aug 15, 2023
4e51cc1
Update src/interface/state_descriptor.cpp
jdolence Aug 15, 2023
134f1d1
fix bug and address comments
jdolence Aug 16, 2023
4cdd379
move from Copy to Initialize
jdolence Aug 16, 2023
7ea5de2
change name of package metadata flag
jdolence Aug 16, 2023
0480519
update changelog
jdolence Aug 16, 2023
0657d93
update docs
jdolence Aug 16, 2023
fe1a6af
update all the copyrights
jdolence Aug 16, 2023
42e678e
gah! formatting!
jdolence Aug 16, 2023
6807b61
add a comment as requested
jdolence Aug 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/amr_criteria/amr_criteria.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
#include <string>

#include "defs.hpp"
#include "interface/meshblock_data.hpp"
#include "mesh/domain.hpp"

namespace parthenon {

class ParameterInput;
template <class>
class MeshBlockData;

struct AMRBounds {
AMRBounds(const IndexRange &ib, const IndexRange &jb, const IndexRange &kb)
Expand Down
57 changes: 34 additions & 23 deletions src/interface/data_collection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,54 @@
namespace parthenon {

template <typename T>
std::shared_ptr<T> DataCollection<T>::Add(const std::string &name,
const std::shared_ptr<T> &src,
const std::vector<std::string> &flags) {
std::shared_ptr<T> &
DataCollection<T>::Add(const std::string &name, const std::shared_ptr<T> &src,
const std::vector<std::string> &field_names, const bool shallow) {
auto it = containers_.find(name);
if (it != containers_.end()) {
if (!(it->second)->Contains(flags)) {
PARTHENON_THROW(name + "already exists in collection but does not contain flags");
if (!(it->second)->Contains(field_names)) {
lroberts36 marked this conversation as resolved.
Show resolved Hide resolved
PARTHENON_THROW(name +
"already exists in collection but does not contain field names");
}
return it->second;
}

auto c = std::make_shared<T>();
c->Copy(src, flags);
c->Copy(src.get(), field_names, shallow);

containers_[name] = c;
return containers_[name];
}
Set(name, c);

template <typename T>
std::shared_ptr<T> DataCollection<T>::Add(const std::string &name,
const std::shared_ptr<T> &src) {
// error check for duplicate names
auto it = containers_.find(name);
if (it != containers_.end()) {
// check to make sure they are the same
if (!(*src == *(it->second))) {
PARTHENON_THROW("Error attempting to add a Container to a Collection");
if constexpr (std::is_same<T, MeshData<Real>>::value) {
for (int b = 0; b < pmy_mesh_->block_list.size(); b++) {
auto &mbd = pmy_mesh_->block_list[b]->meshblock_data;
mbd.Set(name, c->GetBlockData(b));
}
return it->second;
}

auto c = std::make_shared<T>();
c->Copy(src);

containers_[name] = c;
return containers_[name];
}
template <typename T>
std::shared_ptr<T> &DataCollection<T>::Add(const std::string &name,
const std::shared_ptr<T> &src,
const std::vector<std::string> &field_names) {
return Add(name, src, field_names, false);
}
Yurlungur marked this conversation as resolved.
Show resolved Hide resolved
template <typename T>
std::shared_ptr<T> &
DataCollection<T>::AddShallow(const std::string &name, const std::shared_ptr<T> &src,
const std::vector<std::string> &field_names) {
return Add(name, src, field_names, true);
}
Yurlungur marked this conversation as resolved.
Show resolved Hide resolved
template <typename T>
std::shared_ptr<T> &DataCollection<T>::Add(const std::string &name,
const std::shared_ptr<T> &src) {
return Add(name, src, {}, false);
}
Yurlungur marked this conversation as resolved.
Show resolved Hide resolved
template <typename T>
std::shared_ptr<T> &DataCollection<T>::AddShallow(const std::string &name,
const std::shared_ptr<T> &src) {
return Add(name, src, {}, true);
}

template <>
std::shared_ptr<MeshData<Real>> &
Expand Down
15 changes: 11 additions & 4 deletions src/interface/data_collection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,15 @@ class DataCollection {

void SetMeshPointer(Mesh *pmesh) { pmy_mesh_ = pmesh; }

std::shared_ptr<T> Add(const std::string &label, const std::shared_ptr<T> &src,
const std::vector<std::string> &flags);
std::shared_ptr<T> Add(const std::string &label, const std::shared_ptr<T> &src);
std::shared_ptr<T> Add(const std::string &label) {
std::shared_ptr<T> &Add(const std::string &label, const std::shared_ptr<T> &src,
const std::vector<std::string> &flags, const bool shallow);
std::shared_ptr<T> &Add(const std::string &label, const std::shared_ptr<T> &src,
const std::vector<std::string> &flags);
std::shared_ptr<T> &AddShallow(const std::string &label, const std::shared_ptr<T> &src,
const std::vector<std::string> &flags);
std::shared_ptr<T> &Add(const std::string &label, const std::shared_ptr<T> &src);
std::shared_ptr<T> &AddShallow(const std::string &label, const std::shared_ptr<T> &src);
std::shared_ptr<T> &Add(const std::string &label) {
// error check for duplicate names
auto it = containers_.find(label);
if (it != containers_.end()) {
Expand All @@ -64,6 +69,8 @@ class DataCollection {
return it->second;
}

void Set(const std::string &name, std::shared_ptr<T> &d) { containers_[name] = d; }

std::shared_ptr<T> &GetOrAdd(const std::string &mbd_label, const int &partition_id);

void PurgeNonBase() {
Expand Down
20 changes: 20 additions & 0 deletions src/interface/make_pack_descriptor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@
#include "interface/metadata.hpp"
#include "interface/sparse_pack.hpp"
#include "interface/state_descriptor.hpp"
#include "interface/variable.hpp"
#include "mesh/mesh.hpp"

namespace parthenon {

inline auto MakeDefaultPackDescriptor() { return typename SparsePack<>::Descriptor(); }

inline auto MakePackDescriptor(StateDescriptor *psd, const std::vector<std::string> &vars,
const std::vector<bool> &use_regex,
const std::vector<MetadataFlag> &flags = {},
Expand Down Expand Up @@ -116,6 +119,23 @@ inline auto MakePackDescriptor(
return MakePackDescriptor(psd, vars, use_regex, flags, options);
}

inline auto MakePackDescriptor(StateDescriptor *psd, const std::vector<Uid_t> &var_ids,
const std::vector<MetadataFlag> &flags = {},
const std::set<PDOpt> &options = {}) {
auto selector = [&](int vidx, const VarID &id, const Metadata &md) {
if (flags.size() > 0) {
for (const auto &flag : flags) {
if (!md.IsSet(flag)) return false;
}
}
if (Variable<Real>::GetUniqueID(id.label()) == var_ids[vidx]) return true;
return false;
};

impl::PackDescriptor base_desc(psd, var_ids, selector, options);
return typename SparsePack<>::Descriptor(base_desc);
}

} // namespace parthenon

#endif // INTERFACE_MAKE_PACK_DESCRIPTOR_HPP_
15 changes: 12 additions & 3 deletions src/interface/mesh_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "utils/communication_buffer.hpp"
#include "utils/error_checking.hpp"
#include "utils/object_pool.hpp"
#include "utils/unique_id.hpp"
#include "utils/utils.hpp"

namespace parthenon {
Expand Down Expand Up @@ -236,14 +237,15 @@ class MeshData {
}

template <typename... Args>
void Copy(const std::shared_ptr<MeshData<T>> src, Args &&...args) {
if (src.get() == nullptr) {
void Copy(const MeshData<T> *src, Args &&...args) {
if (src == nullptr) {
PARTHENON_THROW("src points at null");
}
const int nblocks = src->NumBlocks();
block_data_.resize(nblocks);
for (int i = 0; i < nblocks; i++) {
block_data_[i]->Copy(src->GetBlockData(i), std::forward<Args>(args)...);
block_data_[i] = std::make_shared<MeshBlockData<T>>();
block_data_[i]->Copy(src->GetBlockData(i).get(), std::forward<Args>(args)...);
}
}

Expand Down Expand Up @@ -435,6 +437,13 @@ class MeshData {
BvarsCache_t bvars_cache_;
};

template <typename T, typename... Args>
std::vector<Uid_t> UidIntersection(MeshData<T> *md1, MeshData<T> *md2, Args &&...args) {
auto u1 = md1->GetBlockData(0)->GetVariableUIDs(std::forward<Args>(args)...);
auto u2 = md2->GetBlockData(0)->GetVariableUIDs(std::forward<Args>(args)...);
return UidIntersection(u1, u2);
}

} // namespace parthenon

#endif // INTERFACE_MESH_DATA_HPP_
72 changes: 11 additions & 61 deletions src/interface/meshblock_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,39 +73,31 @@ void MeshBlockData<T>::AddField(const std::string &base_name, const Metadata &me
}
}

// TODO(JMM): Add CopyFrom that takes unique IDs
// TODO(JMM): Move to unique IDs at some point
template <typename T>
void MeshBlockData<T>::CopyFrom(const MeshBlockData<T> &src, bool shallow_copy,
const std::vector<std::string> &names,
const std::vector<MetadataFlag> &flags,
const std::vector<int> &sparse_ids) {
void MeshBlockData<T>::Copy(const MeshBlockData<T> *src,
const std::vector<std::string> &names,
const bool shallow_copy) {
assert(src != nullptr);
SetBlockPointer(src);
resolved_packages_ = src.resolved_packages_;
std::unordered_set<int> sparse_ids_set(sparse_ids.begin(), sparse_ids.end());

auto add_var = [=, &flags, &sparse_ids](auto var) {
if (!flags.empty() && !var->metadata().AnyFlagsSet(flags)) {
return;
}

if (!sparse_ids.empty() && var->IsSparse() &&
(sparse_ids_set.count(var->GetSparseID()) == 0)) {
return;
}
resolved_packages_ = src->resolved_packages_;
is_shallow_ = shallow_copy;

auto add_var = [=](auto var) {
if (shallow_copy || var->IsSet(Metadata::OneCopy)) {
Add(var);
} else {
Add(var->AllocateCopy(pmy_block));
}
};

// special case when the list of names is empty, copy everything
if (names.empty()) {
for (auto v : src.GetVariableVector()) {
for (auto v : src->GetVariableVector()) {
add_var(v);
}
} else {
auto var_map = src.GetVariableMap();
auto var_map = src->GetVariableMap();

for (const auto &name : names) {
bool found = false;
Expand All @@ -114,54 +106,12 @@ void MeshBlockData<T>::CopyFrom(const MeshBlockData<T> &src, bool shallow_copy,
found = true;
add_var(v->second);
}

if (!found && (resolved_packages_ != nullptr)) {
// check if this is a sparse base name, if so we get its pool of sparse_ids,
// otherwise we get an empty pool
const auto &sparse_pool = resolved_packages_->GetSparsePool(name);

// add all sparse ids of the pool
for (const auto iter : sparse_pool.pool()) {
// this variable must exist, if it doesn't something is very wrong
const auto &v = varMap_.at(MakeVarLabel(name, iter.first));
add_var(v);
found = true;
}
lroberts36 marked this conversation as resolved.
Show resolved Hide resolved
}

PARTHENON_REQUIRE_THROWS(found, "MeshBlockData::CopyFrom: Variable '" + name +
"' not found");
}
}
}

// Constructor for getting sub-containers
// the variables returned are all shallow copies of the src container.
// Optionally extract only some of the sparse ids of src variable.
template <typename T>
MeshBlockData<T>::MeshBlockData(const MeshBlockData<T> &src,
const std::vector<std::string> &names,
const std::vector<int> &sparse_ids) {
CopyFrom(src, true, names, {}, sparse_ids);
}

// TODO(JMM): Add constructor that takes unique IDs
template <typename T>
MeshBlockData<T>::MeshBlockData(const MeshBlockData<T> &src,
const std::vector<MetadataFlag> &flags,
const std::vector<int> &sparse_ids) {
CopyFrom(src, true, {}, flags, sparse_ids);
}

// provides a container that has a single sparse slice
template <typename T>
std::shared_ptr<MeshBlockData<T>>
MeshBlockData<T>::SparseSlice(const std::vector<int> &sparse_ids) const {
auto c = std::make_shared<MeshBlockData<T>>();
c->CopyFrom(*this, true, {}, {}, sparse_ids);
return c;
}
Comment on lines -138 to -163
Copy link
Collaborator

Choose a reason for hiding this comment

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

No constructor overloads, always use copy now? That's cleaner from a self-describing interface point of view I think


/// Queries related to variable packs
/// This is a helper function that queries the cache for the given pack.
/// The strings are the keys and the lists are the values.
Expand Down
Loading