Skip to content

Commit 65da814

Browse files
authored
Merge branch 'whannah/eamxx/update-field_utils' (PR #7702)
Add a check to print_field_hyperslab to aid in debugging an edge case where a postcondition check tries to throw an error but the underlying grid of the current process is incorrectly defined. [BFB]
2 parents d64badf + a5452e0 commit 65da814

File tree

4 files changed

+42
-16
lines changed

4 files changed

+42
-16
lines changed

components/eamxx/src/share/field/field_layout.hpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,12 @@ class FieldLayout {
9292
// The rank is the number of tags associated to this field.
9393
int rank () const { return m_rank; }
9494

95-
int dim_idx (const FieldTag t) const;
95+
// If throw_if_multiple_matches=false, simply return the idx of the
96+
// first match, otherwise throws an exception if 2+ matches are found
97+
int dim_idx (const FieldTag t, bool throw_if_multiple_matches = true) const;
9698

97-
int dim (const std::string& name) const;
98-
int dim (const FieldTag tag) const;
99+
int dim (const std::string& name, bool throw_if_multiple_matches = true) const;
100+
int dim (const FieldTag tag, bool throw_if_multiple_matches = true) const;
99101
int dim (const int idim) const;
100102
const std::vector<int>& dims () const { return m_dims; }
101103
const extents_type& extents () const { return m_extents; }
@@ -157,8 +159,7 @@ class FieldLayout {
157159
void compute_type ();
158160
void set_extents ();
159161
void add_dim (const FieldTag t, const int extent, const std::string& name,
160-
bool prepend_instead_of_append = false);
161-
162+
bool prepend_instead_of_append = false);
162163

163164
int m_rank;
164165
std::vector<FieldTag> m_tags;
@@ -174,22 +175,27 @@ bool operator== (const FieldLayout& fl1, const FieldLayout& fl2);
174175

175176
// ========================== IMPLEMENTATION ======================= //
176177

177-
inline int FieldLayout::dim_idx (const FieldTag t) const {
178-
// Check exactly one tag (no ambiguity)
179-
EKAT_REQUIRE_MSG(ekat::count(m_tags,t)==1,
180-
"Error! FieldTag::dim_idx requires that the tag appears exactly once.\n"
178+
inline int FieldLayout::dim_idx (const FieldTag t, bool throw_if_multiple_matches) const {
179+
EKAT_REQUIRE_MSG( (not throw_if_multiple_matches) or ekat::count(m_tags,t)<=1,
180+
"[FieldTag::dim_idx] Error! Multiple matches found for the requested tag.\n"
181+
" - field tag: " + e2str(t) + "\n"
182+
" - field layout: " + this->to_string() + "\n");
183+
184+
auto it = ekat::find(m_tags,t);
185+
EKAT_REQUIRE_MSG (it!=m_tags.end(),
186+
"[FieldTag::dim_idx] Error! Requested tag not found.\n"
181187
" - field tag: " + e2str(t) + "\n"
182-
" - tag count: " + std::to_string(ekat::count(m_tags,t)) + "\n");
188+
" - field layout: " + this->to_string() + "\n");
183189

184-
return std::distance(m_tags.begin(),ekat::find(m_tags,t));
190+
return std::distance(m_tags.begin(),it);
185191
}
186192

187193
// returns extent
188-
inline int FieldLayout::dim (const FieldTag t) const {
189-
return m_dims[dim_idx(t)];
194+
inline int FieldLayout::dim (const FieldTag t, bool throw_if_multiple_matches) const {
195+
return m_dims[dim_idx(t,throw_if_multiple_matches)];
190196
}
191197

192-
inline int FieldLayout::dim (const std::string& name) const {
198+
inline int FieldLayout::dim (const std::string& name, bool throw_if_multiple_matches) const {
193199
auto it = ekat::find(m_names,name);
194200

195201
// Check if found
@@ -198,7 +204,7 @@ inline int FieldLayout::dim (const std::string& name) const {
198204
" - layout dims: " + ekat::join(m_names,",") + "\n");
199205

200206
// Check only one tag (no ambiguity)
201-
EKAT_REQUIRE_MSG(ekat::count(m_names,name)==1,
207+
EKAT_REQUIRE_MSG( (not throw_if_multiple_matches) or ekat::count(m_names,name)==1,
202208
"Error! Dimension name '" + name + "' appears multiple times.\n"
203209
" - layout dims: " + ekat::join(m_names,",") + "\n");
204210

components/eamxx/src/share/field/field_utils.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,23 @@ void print_field_hyperslab (const Field& f,
313313
{
314314
const auto dt = f.data_type();
315315
const auto rank = f.rank();
316+
const auto& fl = f.get_header().get_identifier().get_layout();
316317

317318
EKAT_REQUIRE_MSG (rank>=static_cast<int>(tags.size()),
318319
"Error! Requested location incompatible with field rank.\n"
319320
" - field name: " + f.name() + "\n"
320321
" - field rank: " + std::to_string(rank) + "\n"
321-
" - requested indices: (" + ekat::join(indices,",") + "\n");
322+
" - requested indices: (" + ekat::join(indices,",") + ")\n");
323+
324+
const int num_indices = indices.size();
325+
for (int i=0; i<num_indices; ++i) {
326+
EKAT_REQUIRE_MSG ( indices[i]>=0 && indices[i]<fl.dim(tags[i],false),
327+
"Error! Requested slice index is out of bound.\n"
328+
" - field name: " + f.name() + "\n"
329+
" - field layout: " + fl.to_string() + "\n"
330+
" - hyperslab tags: (" + ekat::join(tags2str(tags),",") + ")\n"
331+
" - hyperslab indices: (" + ekat::join(indices,",") + ")\n");
332+
}
322333

323334
switch (dt) {
324335
case DataType::IntType:

components/eamxx/src/share/field/tests/field_header_tests.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ TEST_CASE("field_layout", "") {
2929
REQUIRE (fl5.type()==LayoutType::Vector3D);
3030
REQUIRE (fl6.type()==LayoutType::Tensor3D);
3131

32+
REQUIRE (fl3.dim(COL)==1);
33+
REQUIRE_THROWS (fl3.dim(CMP));
34+
REQUIRE (fl3.dim(CMP,false)==3);
35+
3236
REQUIRE (not fl1.is_vector_layout());
3337
REQUIRE ( fl2.is_vector_layout());
3438
REQUIRE (not fl3.is_vector_layout());

components/eamxx/src/share/field/tests/field_utils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,11 @@ TEST_CASE ("print_field_hyperslab") {
773773
}
774774

775775
REQUIRE (out.str()==expected.str());
776+
777+
loc_idxs[0] = nel;
778+
REQUIRE_THROWS(print_field_hyperslab(f,loc_tags,loc_idxs,out));
779+
loc_idxs[0] = -1;
780+
REQUIRE_THROWS(print_field_hyperslab(f,loc_tags,loc_idxs,out));
776781
}
777782
SECTION ("slice_0234") {
778783
std::vector<FieldTag> loc_tags = {EL,GP,GP,LEV};

0 commit comments

Comments
 (0)