-
Notifications
You must be signed in to change notification settings - Fork 377
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 FM over all grids #6981
base: master
Are you sure you want to change the base?
Unify FM over all grids #6981
Conversation
Also - remove devivation type - simplify group logic to ensure subfields over grids have same index
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.
A few comments highlight the important pieces since this is such a large PR. So many of the changes come from every instance of the FM has to be used differently (passing grid names instead of only one grid being stored).
// we register a corresponding version of the field on the "target" FM. | ||
|
||
// Helper lambda to reduce code duplication | ||
auto process_imported_groups = [&](const std::set<GroupRequest>& group_requests) { |
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 moved this logic to FieldManager::pre_process_groups()
.
Field::clone(const std::string& name) const { | ||
return clone(name, get_header().get_identifier().get_grid_name()); | ||
} | ||
|
||
Field | ||
Field::clone(const std::string& name) const { | ||
Field::clone(const std::string& name, const std::string& grid_name) const { | ||
// Create new field | ||
const auto& my_fid = get_header().get_identifier(); | ||
FieldIdentifier fid(name,my_fid.get_layout(),my_fid.get_units(), | ||
my_fid.get_grid_name(),my_fid.data_type()); | ||
grid_name,my_fid.data_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 needed to add a grid argument to Field::clone()
because, in many cases, we are cloning a grid (giving it a new name), constructing a FM(new_grid)
, but using a field whose ID gives a grid name from the old grid, and the new FM was complaining that the grid was not in the internal grids manager.
@@ -185,7 +190,7 @@ Field Field::subfield(const std::string& sf_name, | |||
"Error! Input field must be allocated in order to subview it.\n"); | |||
|
|||
auto sf_layout = lt.clone(); | |||
sf_layout.reset_dim(idim, index_end - index_beg); | |||
sf_layout.reset_dim(idim, index_end+1 - index_beg); |
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.
Kokkos::subview(..., beg, end, ...)
has inclusive bounds, but we were treating the subview bound as [bed, end)
.
@@ -88,7 +88,7 @@ FieldAllocProp FieldAllocProp::subview(const int idim, | |||
EKAT_REQUIRE_MSG(index_beg < index_end, | |||
"Error! Slice indices are invalid (non-increasing).\n"); | |||
EKAT_REQUIRE_MSG( | |||
index_beg >= 0 && index_end < m_layout.dim(idim), | |||
index_beg >= 0 && index_end <= m_layout.dim(idim), |
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.
Same as comment above about Kokkos bounds
@@ -117,6 +117,7 @@ class FieldLayout { | |||
// calls get_vector_component_idx() | |||
int get_vector_dim () const; | |||
FieldTag get_vector_tag () const; | |||
std::vector<std::string> get_dim_names() const; |
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.
Needed by the new equivalent_layout()
function.
info.m_subview_idx [*it] = std::distance(cluster_ordered_fields.begin(),it); | ||
} | ||
info.m_bundled = true; | ||
} | ||
} | ||
} | ||
|
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.
Now indices info is independent of grid, guaranteeing each grid agrees.
return it==m_fields.end() ? nullptr : it->second; | ||
FieldManager::get_field_ptr (const std::string& name, const std::string& grid_name) const { | ||
auto it = m_fields.at(grid_name).find(name); | ||
return it==m_fields.at(grid_name).end() ? nullptr : it->second; | ||
} | ||
|
||
void FieldManager::pre_process_group_requests () { |
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.
Important function for gathering which grids should register which group fields
// the parent field. So at registration time, simply keep track of the subfields, | ||
// and create them at registration_ends() time, after all other fields. | ||
std::map<std::string,FieldRequest> m_subfield_requests; | ||
|
||
// The map group_name -> FieldGroupInfo | ||
group_info_map m_field_groups; |
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.
Doesn't change, group info is the same for all grids.
@@ -115,6 +115,53 @@ AbstractGrid::get_3d_tensor_layout (const bool midpoints, const std::vector<int> | |||
return get_3d_tensor_layout(midpoints,cmp_dims,names); | |||
} | |||
|
|||
FieldLayout | |||
AbstractGrid::equivalent_layout (const FieldLayout& template_layout) const |
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 is how we get the layout for tracer on a new grid.
std::set<std::string> GridsManager:: | ||
get_grid_names () const { | ||
std::set<std::string> names; | ||
if (m_grids.size()==0) { | ||
return names; | ||
} | ||
for (const auto& g : m_grids) { | ||
names.emplace(g.second->name()); | ||
} | ||
return names; | ||
} |
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 ended up using this function a lot, but I don't know that I love it. It doesn't take into account aliases. I could instead always loop over the grid manager's grid map and query the names from there.
Quite a few fails in the CI, odd some didn't trigger on my workstation (rrtmgp standalone for instance)... Leaving Draft for now. |
Store a single
FieldManager
for all fields over all grids.This solves the issue in #6789 where having a group as a subset of another, and allocated on different grids, was causing subview indices mismatch between grids.
Also