Skip to content

Commit c1d446a

Browse files
committed
Merge branch 'bartgol/eamxx/field-utils' into next (PR #7857)
This design pattern uses a type-agnostic wrapper for scalars, so that we don't need to expose the templated method implementation to the customers. [non-BFB] For runs using the IC perturb feature
2 parents 7e476dc + 890b0b3 commit c1d446a

File tree

72 files changed

+2903
-2776
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2903
-2776
lines changed

components/eamxx/src/control/atmosphere_driver.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,13 +1408,11 @@ void AtmosphereDriver::set_initial_conditions ()
14081408
seed = ic_pl.get<int>("perturbation_random_seed", 0);
14091409
}
14101410
m_atm_logger->info(" For IC perturbation, random seed: "+std::to_string(seed));
1411-
std::mt19937_64 engine(seed);
14121411

14131412
// Get perturbation limit. Defines a range [1-perturbation_limit, 1+perturbation_limit]
14141413
// for which the perturbation value will be randomly generated from. Create a uniform
14151414
// distribution for this range.
14161415
const auto perturbation_limit = ic_pl.get<Real>("perturbation_limit", 0.001);
1417-
std::uniform_real_distribution<Real> pdf(1-perturbation_limit, 1+perturbation_limit);
14181416

14191417
// Define a level mask using reference pressure and the perturbation_minimum_pressure parameter.
14201418
// This mask dictates which levels we apply a perturbation.
@@ -1423,13 +1421,21 @@ void AtmosphereDriver::set_initial_conditions ()
14231421
const auto hybm_h = gll_grid->get_geometry_data("hybm").get_view<const Real*, Host>();
14241422
constexpr auto ps0 = physics::Constants<Real>::P0;
14251423
const auto min_pressure = ic_pl.get<Real>("perturbation_minimum_pressure", 1050.0);
1426-
auto pressure_mask = [&] (const int ilev) {
1424+
1425+
const auto& pmask_lt = gll_grid->get_vertical_layout(true);
1426+
const auto nondim = ekat::units::Units::nondimensional();
1427+
FieldIdentifier pmask_fid("lev_mask",pmask_lt,nondim,gll_grid->name(),DataType::IntType);
1428+
Field pressure_mask(pmask_fid,true);
1429+
auto pmask_h = pressure_mask.get_view<int*,Host>();
1430+
for (int ilev=0; ilev<pmask_lt.dim(0); ++ilev) {
14271431
const auto pref = (hyam_h(ilev)*ps0 + hybm_h(ilev)*ps0)/100; // Reference pressure ps0 is in Pa, convert to millibar
1428-
return pref > min_pressure;
1429-
};
1432+
pmask_h(ilev) = static_cast<int>(pref > min_pressure);
1433+
}
1434+
pressure_mask.sync_to_dev();
14301435

14311436
// Loop through fields and apply perturbation.
14321437
const std::string gll_grid_name = gll_grid->name();
1438+
auto dofs_gids = gll_grid->get_dofs_gids();
14331439
for (size_t f=0; f<perturbed_fields.size(); ++f) {
14341440
const auto fname = perturbed_fields[f];
14351441
EKAT_REQUIRE_MSG(ekat::contains(m_fields_inited[gll_grid_name], fname),
@@ -1438,7 +1444,7 @@ void AtmosphereDriver::set_initial_conditions ()
14381444
" - Grid: "+gll_grid_name+"\n");
14391445

14401446
auto field = m_field_mgr->get_field(fname, gll_grid_name);
1441-
perturb(field, engine, pdf, seed, pressure_mask, gll_grid->get_dofs_gids());
1447+
perturb(field, perturbation_limit, seed, pressure_mask, dofs_gids);
14421448
}
14431449

14441450
m_atm_logger->info(" [EAMxx] Adding random perturbation to ICs ... done!");

components/eamxx/src/dynamics/homme/tests/dyn_grid_io.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,13 @@ TEST_CASE("dyn_grid_io")
116116
std::vector<std::string> fnames = {"field_1", "field_2", "field_3"};
117117

118118
// Randomize dyn fields, then remap to ctrl fields
119-
std::uniform_real_distribution<Real> pdf(0.01,100.0);
120-
auto engine = setup_random_test(&comm);
119+
auto seed = get_random_test_seed(&comm);
121120
auto dyn2ctrl = gm->create_remapper(dyn_grid,phys_grid);
122121
for (const auto& fn : fnames) {
123122
auto fd = fm->get_field(fn,dyn_grid->name());
124123
auto fc = fm_ctrl->get_field(fn,phys_grid->name());
125124
dyn2ctrl->register_field(fd,fc);
126-
randomize(fd,engine,pdf);
125+
randomize_uniform(fd,seed++);
127126

128127
// Init phys field to something obviously wrong
129128
auto fp = fm->get_field(fn,phys_grid->name());

components/eamxx/src/physics/cosp/eamxx_cosp.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "share/property_checks/field_within_interval_check.hpp"
77
#include "share/field/field_utils.hpp"
88

9+
#include <ekat_team_policy_utils.hpp>
910
#include <ekat_assert.hpp>
1011
#include <ekat_units.hpp>
1112

components/eamxx/src/physics/iop_forcing/eamxx_iop_forcing_process_interface.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,17 +461,17 @@ void IOPForcing::run_impl (const double dt)
461461
view_1d<Pack> qv_mean, t_mean;
462462
view_2d<Pack> horiz_winds_mean;
463463
if (iop_nudge_tq){
464-
horiz_contraction<Real>(m_helper_fields.at("qv_mean"), get_field_out("qv"),
465-
m_helper_fields.at("horiz_mean_weights"), &m_comm);
464+
horiz_contraction(m_helper_fields.at("qv_mean"), get_field_out("qv"),
465+
m_helper_fields.at("horiz_mean_weights"), true, &m_comm);
466466
qv_mean = m_helper_fields.at("qv_mean").get_view<Pack*>();
467467

468-
horiz_contraction<Real>(m_helper_fields.at("t_mean"), get_field_out("T_mid"),
469-
m_helper_fields.at("horiz_mean_weights"), &m_comm);
468+
horiz_contraction(m_helper_fields.at("t_mean"), get_field_out("T_mid"),
469+
m_helper_fields.at("horiz_mean_weights"), true, &m_comm);
470470
t_mean = m_helper_fields.at("t_mean").get_view<Pack*>();
471471
}
472472
if (iop_nudge_uv){
473-
horiz_contraction<Real>(m_helper_fields.at("horiz_winds_mean"), get_field_out("horiz_winds"),
474-
m_helper_fields.at("horiz_mean_weights"), &m_comm);
473+
horiz_contraction(m_helper_fields.at("horiz_winds_mean"), get_field_out("horiz_winds"),
474+
m_helper_fields.at("horiz_mean_weights"), true, &m_comm);
475475
horiz_winds_mean = m_helper_fields.at("horiz_winds_mean").get_view<Pack**>();
476476
}
477477

components/eamxx/src/share/algorithm/tests/data_interpolation_tests.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,8 @@ void run_tests (const std::shared_ptr<const AbstractGrid>& grid,
215215
// Compute the rel error
216216
diff[i].update(fields[i],1,1);
217217
diff[i].update(expected[i],-1,1);
218-
diff[i].scale(1.0 / frobenius_norm<Real>(expected[i]));
219-
if (frobenius_norm<Real>(diff[i])>=tol) {
220-
print_field_hyperslab(expected[i]);
221-
print_field_hyperslab(fields[i]);
222-
}
223-
REQUIRE (frobenius_norm<Real>(diff[i])<tol);
218+
diff[i].scale(1.0 / frobenius_norm(expected[i]).as<Real>());
219+
REQUIRE (frobenius_norm(diff[i]).as<Real>()<tol);
224220
}
225221
}
226222
}

components/eamxx/src/share/algorithm/tests/time_interpolation_tests.cpp

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ bool views_are_approx_equal(const Field& f0, const Field& f1, const Real tol)
242242
// simply.
243243
auto ft = f0.clone();
244244
ft.update(f1,1.0,-1.0);
245-
auto d_min = field_min<Real>(ft);
246-
auto d_max = field_max<Real>(ft);
245+
auto d_min = field_min(ft).as<Real>();
246+
auto d_max = field_max(ft).as<Real>();
247247
if (std::abs(d_min) > tol or std::abs(d_max) > tol) {
248248
printf("The two copies of (%16s) are NOT approx equal within a tolerance of %e.\n The min and max errors are %e and %e respectively.\n",f0.name().c_str(),tol,d_min,d_max);
249249
return false;
@@ -315,21 +315,13 @@ std::shared_ptr<const GridsManager> get_gm (const ekat::Comm& comm, const int nc
315315
}
316316
/*-----------------------------------------------------------------------------------------------*/
317317
/* Create a fields manager for the test */
318-
std::shared_ptr<FieldManager> get_fm (const std::shared_ptr<const AbstractGrid>& grid, const util::TimeStamp& t0, const int seed)
318+
std::shared_ptr<FieldManager>
319+
get_fm (const std::shared_ptr<const AbstractGrid>& grid, const util::TimeStamp& t0, int seed)
319320
{
320321
using FL = FieldLayout;
321322
using FID = FieldIdentifier;
322323
using namespace ShortFieldTagsNames;
323324

324-
// Random number generation stuff
325-
// NOTES
326-
// - Use integers, so we can check answers without risk of
327-
// non bfb diffs due to different order of sums.
328-
// - Uniform_int_distribution returns an int, and the randomize
329-
// util checks that return type matches the Field data type.
330-
// So wrap the int pdf in a lambda, that does the cast.
331-
std::mt19937_64 engine(seed);
332-
333325
const int nlcols = grid->get_num_local_dofs();
334326
const int nlevs = grid->get_num_vertical_levels();
335327

@@ -343,13 +335,16 @@ std::shared_ptr<FieldManager> get_fm (const std::shared_ptr<const AbstractGrid>&
343335
auto fm = std::make_shared<FieldManager>(grid,RepoState::Closed);
344336

345337
const auto units = ekat::units::Units::nondimensional();
338+
std::vector<Real> values;
339+
for (int i=1; i<=100; ++i)
340+
values.push_back(static_cast<Real>(i));
346341
for (const auto& fl : layouts) {
347342
int gl_size = fl.size();
348343
grid->get_comm().all_reduce(&gl_size,1,MPI_SUM);
349344
FID fid("f_"+std::to_string(gl_size),fl,units,grid->name());
350345
Field f(fid);
351346
f.allocate_view();
352-
randomize (f,engine,my_pdf);
347+
randomize_discrete (f,seed++,values);
353348
f.get_header().get_tracking().update_time_stamp(t0);
354349
fm->add_field(f);
355350
}
@@ -364,7 +359,7 @@ std::vector<std::string> create_test_data_files(
364359
const ekat::Comm& comm,
365360
const std::shared_ptr<const GridsManager>& gm,
366361
const util::TimeStamp& t0,
367-
const int seed)
362+
const int seed)
368363
{
369364
// We initialize a local field manager to use for output
370365
auto fm = get_fm(gm->get_grid("point_grid"), t0, seed);

components/eamxx/src/share/data_managers/tests/field_mgr_tests.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,10 @@ TEST_CASE("tracers_group", "") {
257257
REQUIRE ((0<=sub_idx_c1 and sub_idx_c1<=1));
258258

259259
// Now fill tracer field with random values
260-
auto engine = setup_random_test(&comm);
261-
using RPDF = std::uniform_real_distribution<Real>;
262-
RPDF pdf(0.0,1.0);
260+
int seed = get_random_test_seed(&comm);
263261

264-
randomize(T1,engine,pdf);
265-
randomize(T2,engine,pdf);
262+
randomize_uniform(T1,seed++);
263+
randomize_uniform(T2,seed++);
266264

267265
// Check that the same values are in all individual tracers
268266
T1.sync_to_host();
@@ -300,7 +298,7 @@ TEST_CASE("tracers_group", "") {
300298
// Check that changing sub tracers change tracers group and individual tracers
301299
T1.deep_copy(0.0);
302300
auto& sub_T1 = subtracers.m_monolithic_field;
303-
randomize(*sub_T1,engine,pdf);
301+
randomize_uniform(*sub_T1,seed++);
304302
sub_T1->sync_to_host();
305303
auto sub_T1_h = sub_T1->get_strided_view<Real***,Host>();
306304

components/eamxx/src/share/diagnostics/horiz_avg.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void HorizAvgDiag::initialize_impl(const RunType /*run_type*/) {
5151
m_diagnostic_output.allocate_view();
5252

5353
// scale the area field
54-
auto total_area = field_sum<Real>(m_scaled_area, &m_comm);
54+
auto total_area = field_sum(m_scaled_area, &m_comm).as<Real>();
5555
m_scaled_area.scale(sp(1.0) / total_area);
5656

5757
if (f.get_header().has_extra_data("mask_data")) {
@@ -65,11 +65,7 @@ void HorizAvgDiag::compute_diagnostic_impl() {
6565
const auto &f = get_fields_in().front();
6666
const auto &d = m_diagnostic_output;
6767
// Call the horiz_contraction impl that will take care of everything
68-
if (f.get_header().has_extra_data("mask_data")) {
69-
horiz_contraction<Real>(d, f, m_scaled_area, &m_comm, m_dummy_field);
70-
} else {
71-
horiz_contraction<Real>(d, f, m_scaled_area, &m_comm);
72-
}
68+
horiz_contraction(d, f, m_scaled_area, true, &m_comm, m_dummy_field);
7369
}
7470

7571
} // namespace scream

components/eamxx/src/share/diagnostics/tests/aerocom_cld_test.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,8 @@ TEST_CASE("aerocom_cld") {
104104
ni.allocate_view();
105105
ni.get_header().get_tracking().update_time_stamp(t0);
106106

107-
// Construct random number generator stuff
108-
using RPDF = std::uniform_real_distribution<Real>;
109-
RPDF pdf(0, 0.05);
110-
auto engine = scream::setup_random_test();
107+
// Random number generator seed
108+
int seed = get_random_test_seed();
111109

112110
// Construct the Diagnostics
113111
std::map<std::string, std::shared_ptr<AtmosphereDiagnostic>> diags;
@@ -125,17 +123,17 @@ TEST_CASE("aerocom_cld") {
125123
constexpr int ntests = 3;
126124
for(int itest = 0; itest < ntests; ++itest) {
127125
// Randomize everything to add ensure resiliency
128-
randomize(tm, engine, pdf);
129-
randomize(pd, engine, pdf);
130-
randomize(pm, engine, pdf);
131-
randomize(qv, engine, pdf);
132-
randomize(qc, engine, pdf);
133-
randomize(qi, engine, pdf);
134-
randomize(ec, engine, pdf);
135-
randomize(ei, engine, pdf);
136-
randomize(cd, engine, pdf);
137-
randomize(nc, engine, pdf);
138-
randomize(ni, engine, pdf);
126+
randomize_uniform(tm, seed++, 0, 0.05);
127+
randomize_uniform(pd, seed++, 0, 0.05);
128+
randomize_uniform(pm, seed++, 0, 0.05);
129+
randomize_uniform(qv, seed++, 0, 0.05);
130+
randomize_uniform(qc, seed++, 0, 0.05);
131+
randomize_uniform(qi, seed++, 0, 0.05);
132+
randomize_uniform(ec, seed++, 0, 0.05);
133+
randomize_uniform(ei, seed++, 0, 0.05);
134+
randomize_uniform(cd, seed++, 0, 0.05);
135+
randomize_uniform(nc, seed++, 0, 0.05);
136+
randomize_uniform(ni, seed++, 0, 0.05);
139137

140138
// Create and set up the diagnostic
141139
params.set<std::string>("aero_com_cld_kind", "Top");

components/eamxx/src/share/diagnostics/tests/aodvis_test.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,8 @@ TEST_CASE("aodvis") {
6666
sunlit.allocate_view();
6767
sunlit.get_header().get_tracking().update_time_stamp(t0);
6868

69-
// Construct random number generator stuff
70-
using RPDF = std::uniform_real_distribution<Real>;
71-
RPDF pdf(0, 0.005);
72-
auto engine = scream::setup_random_test();
69+
// Random number generator seed
70+
int seed = get_random_test_seed(&comm);
7371

7472
// Construct the Diagnostics
7573
std::map<std::string, std::shared_ptr<AtmosphereDiagnostic>> diags;
@@ -79,10 +77,10 @@ TEST_CASE("aodvis") {
7977
constexpr int ntests = 5;
8078
for(int itest = 0; itest < ntests; ++itest) {
8179
// Randomize tau
82-
randomize(tau, engine, pdf);
80+
randomize_uniform(tau, seed++, 0, 0.005);
8381

8482
// Randomize sunlit
85-
randomize(sunlit, engine, pdf);
83+
randomize_uniform(sunlit, seed++, 0, 0.005);
8684

8785
// Create and set up the diagnostic
8886
ekat::ParameterList params;

0 commit comments

Comments
 (0)