Skip to content

Commit

Permalink
Split construction of OM (passing comm,params,ts,is_restart) with setup
Browse files Browse the repository at this point in the history
(passing FM and GM)
  • Loading branch information
tcclevenger committed Oct 17, 2024
1 parent 890d5d7 commit 7222540
Show file tree
Hide file tree
Showing 17 changed files with 220 additions and 188 deletions.
117 changes: 77 additions & 40 deletions components/eamxx/src/control/atmosphere_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,56 +677,42 @@ void AtmosphereDriver::create_fields()
m_atm_logger->info("[EAMxx] create_fields ... done!");
}

void AtmosphereDriver::initialize_output_managers () {
m_atm_logger->info("[EAMxx] initialize_output_managers ...");
void AtmosphereDriver::create_output_managers () {
m_atm_logger->info("[EAMxx] create_output_managers ...");
start_timer("EAMxx::init");
start_timer("EAMxx::initialize_output_managers");
start_timer("EAMxx::create_output_managers");

check_ad_status (s_comm_set | s_params_set | s_grids_created | s_fields_created);
check_ad_status (s_comm_set | s_params_set | s_ts_inited);

auto& io_params = m_atm_params.sublist("Scorpio");

ekat::ParameterList checkpoint_params;
checkpoint_params.set("frequency_units",std::string("never"));
checkpoint_params.set("Frequency",-1);

// IMPORTANT: create model restart OutputManager first! This OM will be in charge
// of creating rpointer.atm, while other OM's will simply append to it.
// If this assumption is not verified, we must always append to rpointer, which
// can make the rpointer file a bit confusing.

// Check for model restart output
ekat::ParameterList checkpoint_params;
checkpoint_params.set("frequency_units",std::string("never"));
checkpoint_params.set("Frequency",-1);
if (io_params.isSublist("model_restart")) {
auto restart_pl = io_params.sublist("model_restart");
restart_pl.set<std::string>("Averaging Type","Instant");
restart_pl.sublist("provenance") = m_atm_params.sublist("provenance");
auto& om = m_output_managers.emplace_back();
if (fvphyshack) {
// Don't save CGLL fields from ICs to the restart file.
std::map<std::string,field_mgr_ptr> fms;
for (auto& it : m_field_mgrs) {
if (it.first == "Physics GLL") continue;
fms[it.first] = it.second;
}
om.set_logger(m_atm_logger);
om.setup(m_atm_comm,restart_pl, fms,m_grids_manager,m_run_t0,m_case_t0,true);
} else {
om.set_logger(m_atm_logger);
om.setup(m_atm_comm,restart_pl,m_field_mgrs,m_grids_manager,m_run_t0,m_case_t0,true);
}
om.set_logger(m_atm_logger);
for (const auto& it : m_atm_process_group->get_restart_extra_data()) {
om.add_global(it.first,it.second);
}
// Create model restart manager
auto params = io_params.sublist("model_restart");
params.set<std::string>("Averaging Type","Instant");
params.sublist("provenance") = m_atm_params.sublist("provenance");
m_output_managers.emplace_back(m_atm_comm,
params,
m_run_t0,
m_case_t0,
/*is_model_restart_output*/ true);

// Store the "Output Control" pl of the model restart as the "Checkpoint Control" for all other output streams
checkpoint_params.set<std::string>("frequency_units",restart_pl.sublist("output_control").get<std::string>("frequency_units"));
checkpoint_params.set("Frequency",restart_pl.sublist("output_control").get<int>("Frequency"));
checkpoint_params.set<std::string>("frequency_units",params.sublist("output_control").get<std::string>("frequency_units"));
checkpoint_params.set("Frequency",params.sublist("output_control").get<int>("Frequency"));
}

// Build one manager per output yaml file
// Create one output manager per output yaml file
using vos_t = std::vector<std::string>;
const auto& output_yaml_files = io_params.get<vos_t>("output_yaml_files",vos_t{});
int om_tally = 0;
for (const auto& fname : output_yaml_files) {
ekat::ParameterList params;
ekat::parse_yaml_file(fname,params);
Expand All @@ -737,15 +723,64 @@ void AtmosphereDriver::initialize_output_managers () {

// Check if the filename prefix for this file has already been set. If not, use the simulation casename.
if (not params.isParameter("filename_prefix")) {
params.set<std::string>("filename_prefix",m_casename+".scream.h"+std::to_string(om_tally));
om_tally++;
params.set<std::string>("filename_prefix",m_casename+".scream.h");
}
params.sublist("provenance") = m_atm_params.sublist("provenance");
// Add a new output manager
m_output_managers.emplace_back();
auto& om = m_output_managers.back();

m_output_managers.emplace_back(m_atm_comm,
params,
m_run_t0,
m_case_t0,
/*is_model_restart_output*/ false);
}

m_ad_status |= s_output_created;

stop_timer("EAMxx::create_output_managers");
stop_timer("EAMxx::init");
m_atm_logger->info("[EAMxx] create_output_managers ... done!");
}

void AtmosphereDriver::initialize_output_managers () {
m_atm_logger->info("[EAMxx] initialize_output_managers ...");
start_timer("EAMxx::init");
start_timer("EAMxx::initialize_output_managers");

check_ad_status (s_output_created | s_grids_created | s_fields_created);

// Early return if no output managers exist
if (m_output_managers.empty()) return;

// Check for model restart output manager and setup if it exists.
// IMPORTANT: the restart output manager must be the first in the list.
if (m_output_managers.front().is_restart()) {
auto& om = m_output_managers.front();
if (fvphyshack) {
// Don't save CGLL fields from ICs to the restart file.
std::map<std::string,field_mgr_ptr> fms;
for (auto& it : m_field_mgrs) {
if (it.first == "Physics GLL") continue;
fms[it.first] = it.second;
}
om.set_logger(m_atm_logger);
om.setup(fms, m_grids_manager);
} else {
om.set_logger(m_atm_logger);
om.setup(m_field_mgrs,m_grids_manager);
}
om.set_logger(m_atm_logger);
om.setup(m_atm_comm,params,m_field_mgrs,m_grids_manager,m_run_t0,m_case_t0,false);
for (const auto& it : m_atm_process_group->get_restart_extra_data()) {
om.add_global(it.first,it.second);
}
}

// Setup output managers
for (auto& om : m_output_managers) {
// We do not need to setup any restart output manager
if (om.is_restart()) continue;

om.set_logger(m_atm_logger);
om.setup(m_field_mgrs,m_grids_manager);
}

m_ad_status |= s_output_inited;
Expand Down Expand Up @@ -1574,6 +1609,8 @@ initialize (const ekat::Comm& atm_comm,

init_time_stamps (run_t0, case_t0);

create_output_managers ();

create_atm_processes ();

create_grids ();
Expand Down
4 changes: 4 additions & 0 deletions components/eamxx/src/control/atmosphere_driver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ class AtmosphereDriver
// Load initial conditions for atm inputs
void initialize_fields ();

// Create output managers
void create_output_managers ();

// Initialie I/O structures for output
void initialize_output_managers ();

Expand Down Expand Up @@ -239,6 +242,7 @@ class AtmosphereDriver
static constexpr int s_fields_inited = 256;
static constexpr int s_procs_inited = 512;
static constexpr int s_ts_inited = 1024;
static constexpr int s_output_created = 2048;

// Lazy version to ensure s_atm_inited & flag is true for every flag,
// even if someone adds new flags later on
Expand Down
4 changes: 2 additions & 2 deletions components/eamxx/src/dynamics/homme/tests/dyn_grid_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ TEST_CASE("dyn_grid_io")
out_params.sublist("output_control").set<std::string>("frequency_units","nsteps");
out_params.set<std::string>("Floating Point Precision","real");

OutputManager output;
output.setup (comm, out_params, fm_dyn, gm, t0, t0, false);
OutputManager output(comm, out_params, t0, false);
output.setup (fm_dyn, gm);
output.run(t0);
output.finalize();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ void scream_create_atm_instance (const MPI_Fint f_comm, const int atm_id,
ad.set_params(scream_params);
ad.init_scorpio(atm_id);
ad.init_time_stamps(run_t0,case_t0);
ad.create_output_managers ();
ad.create_atm_processes ();
ad.create_grids ();
ad.create_fields ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ create_om (const std::string& filename_prefix,
ctrl_pl.set("Frequency",1);
ctrl_pl.set("save_grid_data",false);

auto om = std::make_shared<OutputManager>();
om->setup(comm,params,fm,gm,t0,t0,false);
auto om = std::make_shared<OutputManager>(comm,params,t0,false);
om->setup(fm,gm);
return om;
}

Expand Down
59 changes: 27 additions & 32 deletions components/eamxx/src/share/io/scream_output_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,10 @@

namespace scream
{

OutputManager::
~OutputManager ()
{
finalize();
}

void OutputManager::
setup (const ekat::Comm& io_comm, const ekat::ParameterList& params,
const std::shared_ptr<fm_type>& field_mgr,
const std::shared_ptr<const gm_type>& grids_mgr,
const util::TimeStamp& run_t0,
const util::TimeStamp& case_t0,
const bool is_model_restart_output)
{
using map_t = std::map<std::string,std::shared_ptr<fm_type>>;
map_t fms;
fms[field_mgr->get_grid()->name()] = field_mgr;
setup(io_comm,params,fms,grids_mgr,run_t0,case_t0,is_model_restart_output);
}

void OutputManager::
setup (const ekat::Comm& io_comm, const ekat::ParameterList& params,
const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs,
const std::shared_ptr<const gm_type>& grids_mgr,
const util::TimeStamp& run_t0,
const util::TimeStamp& case_t0,
const bool is_model_restart_output)
OutputManager (const ekat::Comm& io_comm, const ekat::ParameterList& params,
const util::TimeStamp& run_t0, const util::TimeStamp& case_t0,
const bool is_model_restart_output)
{
// Sanity checks
EKAT_REQUIRE_MSG (run_t0.is_valid(),
Expand All @@ -56,13 +32,35 @@ setup (const ekat::Comm& io_comm, const ekat::ParameterList& params,
" case_t0: " + case_t0.to_string() + "\n");

m_io_comm = io_comm;
m_params = params;
m_run_t0 = run_t0;
m_case_t0 = case_t0;
m_is_restarted_run = (case_t0<run_t0);
m_is_model_restart_output = is_model_restart_output;
}

OutputManager::
~OutputManager ()
{
finalize();
}

void OutputManager::
setup (const std::shared_ptr<fm_type>& field_mgr,
const std::shared_ptr<const gm_type>& grids_mgr)
{
using map_t = std::map<std::string,std::shared_ptr<fm_type>>;
map_t fms;
fms[field_mgr->get_grid()->name()] = field_mgr;
setup(fms,grids_mgr);
}

void OutputManager::
setup (const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs,
const std::shared_ptr<const gm_type>& grids_mgr)
{
// Read input parameters and setup internal data
set_params(params,field_mgrs);
set_params(field_mgrs);

// Here, store if PG2 fields will be present in output streams.
// Will be useful if multiple grids are defined (see below).
Expand Down Expand Up @@ -653,13 +651,10 @@ compute_filename (const IOFileSpecs& file_specs,
}

void OutputManager::
set_params (const ekat::ParameterList& params,
const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs)
set_params (const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs)
{
using vos_t = std::vector<std::string>;

m_params = params;

if (m_is_model_restart_output) {
// We build some restart parameters internally
m_avg_type = OutputAvgType::Instant;
Expand Down
47 changes: 16 additions & 31 deletions components/eamxx/src/share/io/scream_output_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,14 @@ class OutputManager
using globals_map_t = std::map<std::string,ekat::any>;

// Constructor(s) & Destructor
OutputManager () = default;
OutputManager (const ekat::Comm& io_comm, const ekat::ParameterList& params,
const util::TimeStamp& run_t0, const util::TimeStamp& case_t0,
const bool is_model_restart_output);
OutputManager (const ekat::Comm& io_comm, const ekat::ParameterList& params,
const util::TimeStamp& run_t0,
const bool is_model_restart_output)
: OutputManager(io_comm, params, run_t0, run_t0, is_model_restart_output) {}

virtual ~OutputManager ();

// Set up the manager, creating all output streams. Inputs:
Expand All @@ -79,34 +86,11 @@ class OutputManager
// - case_t0: the timestamp of the start of the overall simulation (precedes run_r0 for
// a restarted simulation. Restart logic is triggered *only* if case_t0<run_t0.
// - is_model_restart_output: whether this output stream is to write a model restart file
void setup (const ekat::Comm& io_comm, const ekat::ParameterList& params,
const std::shared_ptr<fm_type>& field_mgr,
const std::shared_ptr<const gm_type>& grids_mgr,
const util::TimeStamp& run_t0,
const util::TimeStamp& case_t0,
const bool is_model_restart_output);
void setup (const ekat::Comm& io_comm, const ekat::ParameterList& params,
const std::shared_ptr<fm_type>& field_mgr,
const std::shared_ptr<const gm_type>& grids_mgr,
const util::TimeStamp& run_t0,
const bool is_model_restart_output) {
setup (io_comm,params,field_mgr,grids_mgr,run_t0,run_t0,is_model_restart_output);
}
void setup (const std::shared_ptr<fm_type>& field_mgr,
const std::shared_ptr<const gm_type>& grids_mgr);

void setup (const ekat::Comm& io_comm, const ekat::ParameterList& params,
const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs,
const std::shared_ptr<const gm_type>& grids_mgr,
const util::TimeStamp& run_t0,
const util::TimeStamp& case_t0,
const bool is_model_restart_output);

void setup (const ekat::Comm& io_comm, const ekat::ParameterList& params,
const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs,
const std::shared_ptr<const gm_type>& grids_mgr,
const util::TimeStamp& run_t0,
const bool is_model_restart_output) {
setup (io_comm,params,field_mgrs,grids_mgr,run_t0,run_t0,is_model_restart_output);
}
void setup (const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs,
const std::shared_ptr<const gm_type>& grids_mgr);

void set_logger(const std::shared_ptr<ekat::logger::LoggerBase>& atm_logger) {
m_atm_logger = atm_logger;
Expand All @@ -119,6 +103,8 @@ class OutputManager

long long res_dep_memory_footprint () const;

bool is_restart () const { return m_is_model_restart_output; }

// For debug and testing purposes
const IOControl& output_control () const { return m_output_control; }
const IOFileSpecs& output_file_specs () const { return m_output_file_specs; }
Expand All @@ -129,9 +115,8 @@ class OutputManager

void set_file_header(const IOFileSpecs& file_specs);

// Craft the restart parameter list
void set_params (const ekat::ParameterList& params,
const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs);
// Craft the restart parameter list from the parameters given at construction
void set_params (const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs);

void setup_file ( IOFileSpecs& filespecs,
const IOControl& control);
Expand Down
Loading

0 comments on commit 7222540

Please sign in to comment.