Skip to content

Commit 1c14228

Browse files
authored
Merge branch 'eagles-project:mjs271/eamxx/DAG-refactor' (PR #6860)
Finishes PR #3101 originally submitted to the scream repo the atmospheric DAG generator (atmosphere_process_dag.xpp) and atmosphere driver to get things working again
2 parents 596924f + 651927e commit 1c14228

File tree

4 files changed

+249
-76
lines changed

4 files changed

+249
-76
lines changed

components/eamxx/src/control/atmosphere_driver.cpp

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "physics/share/physics_constants.hpp"
66

7+
#include "share/scream_config.hpp"
78
#include "share/atm_process/atmosphere_process_group.hpp"
89
#include "share/atm_process/atmosphere_process_dag.hpp"
910
#include "share/field/field_utils.hpp"
@@ -685,10 +686,29 @@ void AtmosphereDriver::create_fields()
685686
fm->add_to_group(fid.name(),"RESTART");
686687
}
687688

689+
auto& driver_options_pl = m_atm_params.sublist("driver_options");
690+
const int verb_lvl = driver_options_pl.get<int>("atmosphere_dag_verbosity_level",-1);
691+
if (verb_lvl>0) {
692+
// now that we've got fields, generate a DAG with fields and dependencies
693+
// NOTE: at this point, fields provided by initial conditions may (will)
694+
// appear as unmet dependencies
695+
AtmProcDAG dag;
696+
// First, add all atm processes
697+
dag.create_dag(*m_atm_process_group);
698+
// Write a dot file for visualizing the DAG
699+
if (m_atm_comm.am_i_root()) {
700+
std::string filename = "scream_atm_createField_dag";
701+
if (is_scream_standalone()) {
702+
filename += ".np" + std::to_string(m_atm_comm.size());
703+
}
704+
filename += ".dot";
705+
dag.write_dag(filename, verb_lvl);
706+
}
707+
}
708+
688709
m_ad_status |= s_fields_created;
689710

690711
// If the user requested it, we can save a dictionary of the FM fields to file
691-
auto& driver_options_pl = m_atm_params.sublist("driver_options");
692712
if (driver_options_pl.get("save_field_manager_content",false)) {
693713
auto pg = m_grids_manager->get_grid("Physics");
694714
const auto& fm = m_field_mgrs.at(pg->name());
@@ -902,28 +922,6 @@ initialize_fields ()
902922
TraceGasesWorkaround::singleton().run_type = m_run_type;
903923
}
904924

905-
// See if we need to print a DAG. We do this first, cause if any input
906-
// field is missing from the initial condition file, an error will be thrown.
907-
// By printing the DAG first, we give the user the possibility of seeing
908-
// what fields are inputs to the atm time step, so he/she can fix the i.c. file.
909-
// TODO: would be nice to do the IC input first, and mark the fields in the
910-
// DAG node "Begin of atm time step" in red if there's no initialization
911-
// mechanism set for them. That is, allow field XYZ to not be found in
912-
// the IC file, and throw an error when the dag is created.
913-
914-
auto& driver_options_pl = m_atm_params.sublist("driver_options");
915-
const int verb_lvl = driver_options_pl.get<int>("atmosphere_dag_verbosity_level",-1);
916-
if (verb_lvl>0) {
917-
// Check the atm DAG for missing stuff
918-
AtmProcDAG dag;
919-
920-
// First, add all atm processes
921-
dag.create_dag(*m_atm_process_group);
922-
923-
// Write a dot file for visualization
924-
dag.write_dag("scream_atm_dag.dot",std::max(verb_lvl,0));
925-
}
926-
927925
// Initialize fields
928926
if (m_run_type==RunType::Restart) {
929927
restart_model ();
@@ -1101,7 +1099,6 @@ void AtmosphereDriver::set_initial_conditions ()
11011099
// Check which fields need to have an initial condition.
11021100
std::map<std::string,std::vector<std::string>> ic_fields_names;
11031101
std::vector<FieldIdentifier> ic_fields_to_copy;
1104-
std::map<std::string,std::vector<std::string>> fields_inited;
11051102

11061103
// Check which fields should be loaded from the topography file
11071104
std::map<std::string,std::vector<std::string>> topography_file_fields_names;
@@ -1130,7 +1127,7 @@ void AtmosphereDriver::set_initial_conditions ()
11301127
EKAT_ERROR_MSG ("ERROR: invalid assignment for variable " + fname + ", only scalar "
11311128
"double or string, or vector double arguments are allowed");
11321129
}
1133-
fields_inited[grid_name].push_back(fname);
1130+
m_fields_inited[grid_name].push_back(fname);
11341131
} else if (fname == "phis" or fname == "sgh30") {
11351132
// Both phis and sgh30 need to be loaded from the topography file
11361133
auto& this_grid_topo_file_fnames = topography_file_fields_names[grid_name];
@@ -1146,7 +1143,7 @@ void AtmosphereDriver::set_initial_conditions ()
11461143
grid_name == "Point Grid") {
11471144
this_grid_topo_file_fnames.push_back("PHIS_d");
11481145
this_grid_topo_eamxx_fnames.push_back(fname);
1149-
fields_inited[grid_name].push_back(fname);
1146+
m_fields_inited[grid_name].push_back(fname);
11501147
} else {
11511148
EKAT_ERROR_MSG ("Error! Requesting phis on an unknown grid: " + grid_name + ".\n");
11521149
}
@@ -1158,7 +1155,7 @@ void AtmosphereDriver::set_initial_conditions ()
11581155
" topo file only has sgh30 for Physics PG2.\n");
11591156
topography_file_fields_names[grid_name].push_back("SGH30");
11601157
topography_eamxx_fields_names[grid_name].push_back(fname);
1161-
fields_inited[grid_name].push_back(fname);
1158+
m_fields_inited[grid_name].push_back(fname);
11621159
}
11631160
} else if (not (fvphyshack and grid_name == "Physics PG2")) {
11641161
// The IC file is written for the GLL grid, so we only load
@@ -1170,7 +1167,7 @@ void AtmosphereDriver::set_initial_conditions ()
11701167
// If this field is the parent of other subfields, we only read from file the subfields.
11711168
if (not ekat::contains(this_grid_ic_fnames,fname)) {
11721169
this_grid_ic_fnames.push_back(fname);
1173-
fields_inited[grid_name].push_back(fname);
1170+
m_fields_inited[grid_name].push_back(fname);
11741171
}
11751172
} else if (fvphyshack and grid_name == "Physics GLL") {
11761173
// [CGLL ICs in pg2] I tried doing something like this in
@@ -1187,7 +1184,7 @@ void AtmosphereDriver::set_initial_conditions ()
11871184
} else {
11881185
this_grid_ic_fnames.push_back(fname);
11891186
}
1190-
fields_inited[grid_name].push_back(fname);
1187+
m_fields_inited[grid_name].push_back(fname);
11911188
}
11921189
}
11931190
}
@@ -1233,7 +1230,7 @@ void AtmosphereDriver::set_initial_conditions ()
12331230
auto p = f.get_header().get_parent().lock();
12341231
if (p) {
12351232
const auto& pname = p->get_identifier().name();
1236-
if (ekat::contains(fields_inited[grid_name],pname)) {
1233+
if (ekat::contains(m_fields_inited[grid_name],pname)) {
12371234
// The parent is already inited. No need to init this field as well.
12381235
names.erase(it2);
12391236
run_again = true;
@@ -1456,7 +1453,7 @@ void AtmosphereDriver::set_initial_conditions ()
14561453
// Loop through fields and apply perturbation.
14571454
for (size_t f=0; f<perturbed_fields.size(); ++f) {
14581455
const auto fname = perturbed_fields[f];
1459-
EKAT_REQUIRE_MSG(ekat::contains(fields_inited[fm->get_grid()->name()], fname),
1456+
EKAT_REQUIRE_MSG(ekat::contains(m_fields_inited[fm->get_grid()->name()], fname),
14601457
"Error! Attempting to apply perturbation to field not in initial_conditions.\n"
14611458
" - Field: "+fname+"\n"
14621459
" - Grid: "+fm->get_grid()->name()+"\n");
@@ -1655,6 +1652,28 @@ void AtmosphereDriver::initialize_atm_procs ()
16551652
m_atm_logger->info("[EAMxx] initialize_atm_procs ... done!");
16561653

16571654
report_res_dep_memory_footprint ();
1655+
1656+
auto& driver_options_pl = m_atm_params.sublist("driver_options");
1657+
const int verb_lvl = driver_options_pl.get<int>("atmosphere_dag_verbosity_level",-1);
1658+
if (verb_lvl>0) {
1659+
// now that we've got fields, generate a DAG with fields and dependencies
1660+
// NOTE: at this point, fields provided by initial conditions may (will)
1661+
// appear as unmet dependencies
1662+
AtmProcDAG dag;
1663+
// First, add all atm processes
1664+
dag.create_dag(*m_atm_process_group);
1665+
// process the initial conditions to maybe fulfill unmet dependencies
1666+
dag.process_initial_conditions(m_fields_inited);
1667+
// Write a dot file for visualizing the DAG
1668+
if (m_atm_comm.am_i_root()) {
1669+
std::string filename = "scream_atm_initProc_dag";
1670+
if (is_scream_standalone()) {
1671+
filename += ".np" + std::to_string(m_atm_comm.size());
1672+
}
1673+
filename += ".dot";
1674+
dag.write_dag(filename, verb_lvl);
1675+
}
1676+
}
16581677
}
16591678

16601679
void AtmosphereDriver::

components/eamxx/src/control/atmosphere_driver.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ class AtmosphereDriver
264264

265265
// Current simulation casename
266266
std::string m_casename;
267+
// maps grid name to a vector of its initialized fields
268+
std::map<std::string, std::vector<std::string>> m_fields_inited;
267269
};
268270

269271
} // namespace control

0 commit comments

Comments
 (0)