Skip to content

Commit cb432e8

Browse files
authored
Merge Pull Request #3052 from E3SM-Project/scream/bartgol/eamxx/flush-output-with-rhist
Automatically Merged using E3SM Pull Request AutoTester PR Title: A couple of fixes and an addition for IO PR Author: bartgol PR LABELS: enhancement, I/O, AT: AUTOMERGE, bugfix
2 parents 41a944c + c06876c commit cb432e8

File tree

3 files changed

+39
-28
lines changed

3 files changed

+39
-28
lines changed

components/eamxx/src/share/io/scream_io_file_specs.hpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@ namespace scream
1414
{
1515

1616
// How the file capacity is specified
17+
// NOTE: Keep Yearly=0, Monthly=1, Daily=2, so you can use them
18+
// to access a TimeStamp date at the correct index in StorageSpecs methods
1719
enum StorageType {
18-
NumSnaps, // Fixed number of snaps per file
19-
Monthly, // Each file contains output for one month
20-
Yearly // Each file contains output for one year
20+
Yearly = 0, // Each file contains output for one year
21+
Monthly = 1, // Each file contains output for one month
22+
Daily = 2, // Each file contains output for one day
23+
NumSnaps // Fixed number of snaps per file
2124
};
2225

2326
inline std::string e2str (const StorageType st) {
2427
switch (st) {
2528
case NumSnaps: return "num_snapshots";
2629
case Yearly: return "one_year";
2730
case Monthly: return "one_month";
31+
case Daily: return "one_day";
2832
default: return "unknown";
2933
}
3034
}
@@ -33,21 +37,20 @@ struct StorageSpecs {
3337

3438
StorageType type = NumSnaps;
3539

36-
// Current index ***in terms of this->type***
37-
// If type==NumSnaps, curr_idx=num_snapshots_in_file,
38-
// otherwise it is the month/year index stored in this file
40+
// Current index for type!=NumSnaps. It stores the year/month/day
41+
// index associated with this file
3942
int curr_idx = -1;
4043

4144
// A snapshot fits if
4245
// - type=NumSnaps: the number of stored snaps is less than the max allowed per file.
43-
// - otherwise: the snapshot month/year index match the one currently stored in the file
46+
// - otherwise: the snapshot year/month/day index match the one currently stored in the file
4447
// or the file has no snapshot stored yet
4548
bool snapshot_fits (const util::TimeStamp& t) const {
46-
const auto& idx = type==Monthly ? t.get_month() : t.get_year();
4749
switch (type) {
48-
case Yearly:
49-
case Monthly:
50-
return curr_idx==-1 or curr_idx==idx;
50+
case Yearly: [[fallthrough]];
51+
case Monthly: [[fallthrough]];
52+
case Daily:
53+
return curr_idx==-1 or curr_idx==t.get_date()[static_cast<int>(type)];
5154
case NumSnaps:
5255
return num_snapshots_in_file<max_snapshots_in_file;
5356
default:
@@ -56,10 +59,15 @@ struct StorageSpecs {
5659
}
5760

5861
void update_storage (const util::TimeStamp& t) {
62+
// We always update the snap counter (regardless of storage type),
63+
// so that FileSpecs can correctly detect if it needs flushing
5964
switch (type) {
60-
case Yearly: curr_idx = t.get_year(); break;
61-
case Monthly: curr_idx = t.get_month(); break;
62-
case NumSnaps: ++num_snapshots_in_file; break;
65+
case Yearly: [[fallthrough]];
66+
case Monthly: [[fallthrough]];
67+
case Daily:
68+
curr_idx = t.get_date()[static_cast<int>(type)]; [[fallthrough]];
69+
case NumSnaps:
70+
++num_snapshots_in_file; break;
6371
default:
6472
EKAT_ERROR_MSG ("Error! Unrecognized/unsupported file storage type.\n");
6573
}

components/eamxx/src/share/io/scream_output_manager.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,7 @@ setup (const std::map<std::string,std::shared_ptr<fm_type>>& field_mgrs,
228228
const auto& last_output_filename = get_attribute<std::string>(rhist_file,"GLOBAL","last_output_filename");
229229
m_resume_output_file = last_output_filename!="" and not restart_pl.get("force_new_file",false);
230230
if (m_resume_output_file) {
231-
int num_snaps = scorpio::get_attribute<int>(rhist_file,"GLOBAL","last_output_file_num_snaps");
232-
m_output_file_specs.storage.num_snapshots_in_file = num_snaps;
231+
m_output_file_specs.storage.num_snapshots_in_file = scorpio::get_attribute<int>(rhist_file,"GLOBAL","last_output_file_num_snaps");
233232

234233
if (m_output_file_specs.storage.snapshot_fits(m_output_control.next_write_ts)) {
235234
// The setup_file call will not register any new variable (the file is in Append mode,
@@ -500,10 +499,7 @@ void OutputManager::run(const util::TimeStamp& timestamp)
500499
write_timestamp (filespecs.filename,"last_write",m_output_control.last_write_ts,true);
501500
scorpio::set_attribute (filespecs.filename,"GLOBAL","last_output_filename",m_output_file_specs.filename);
502501
scorpio::set_attribute (filespecs.filename,"GLOBAL","num_snapshots_since_last_write",m_output_control.nsamples_since_last_write);
503-
504-
int nsnaps = m_output_file_specs.is_open
505-
? scorpio::get_dimlen(m_output_file_specs.filename,"time") : 0;
506-
scorpio::set_attribute (filespecs.filename,"GLOBAL","last_output_file_num_snaps",nsnaps);
502+
scorpio::set_attribute (filespecs.filename,"GLOBAL","last_output_file_num_snaps",m_output_file_specs.storage.num_snapshots_in_file);
507503
}
508504
// Write these in both output and rhist file. The former, b/c we need these info when we postprocess
509505
// output, and the latter b/c we want to make sure these params don't change across restarts
@@ -563,6 +559,11 @@ void OutputManager::run(const util::TimeStamp& timestamp)
563559
}
564560
if (is_checkpoint_step) {
565561
write_global_data(m_checkpoint_control,m_checkpoint_file_specs);
562+
563+
// Always flush output during checkpoints (assuming we opened it already)
564+
if (m_output_file_specs.is_open) {
565+
scorpio::flush_file (m_output_file_specs.filename);
566+
}
566567
}
567568
stop_timer(timer_root+"::update_snapshot_tally");
568569
if (is_output_step && m_time_bnds.size()>0) {
@@ -636,16 +637,16 @@ compute_filename (const IOFileSpecs& file_specs,
636637
auto ts = (m_avg_type==OutputAvgType::Instant || file_specs.ftype==FileType::HistoryRestart)
637638
? timestamp : control.last_write_ts;
638639

640+
int ts_string_len = 0;
639641
switch (file_specs.storage.type) {
640-
case NumSnaps:
641-
filename += "." + ts.to_string(); break;
642-
case Yearly:
643-
filename += "." + std::to_string(ts.get_year()); break;
644-
case Monthly:
645-
filename += "." + std::to_string(ts.get_year()) + "-" + std::to_string(ts.get_month()); break;
642+
case Yearly: ts_string_len = 4; break; // YYYY
643+
case Monthly: ts_string_len = 7; break; // YYYY-MM
644+
case Daily: ts_string_len = 10; break; // YYYY-MM-DD
645+
case NumSnaps: ts_string_len = 16; break; // YYYY-MM-DD-XXXXX
646646
default:
647647
EKAT_ERROR_MSG ("Error! Unrecognized/unsupported file storage type.\n");
648648
}
649+
filename += "." + ts.to_string().substr(0,ts_string_len);
649650

650651
return filename + ".nc";
651652
}
@@ -701,6 +702,8 @@ setup_internals (const std::map<std::string,std::shared_ptr<fm_type>>& field_mgr
701702
storage.type = Yearly;
702703
} else if (storage_type=="one_month") {
703704
storage.type = Monthly;
705+
} else if (storage_type=="one_day") {
706+
storage.type = Daily;
704707
} else {
705708
EKAT_ERROR_MSG ("Error! Unrecognized/unsupported file storage type.\n");
706709
}

components/eamxx/src/share/io/tests/io_monthly.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,11 @@ void read (const int seed, const ekat::Comm& comm)
178178
// Get filename from timestamp
179179
std::string casename = "io_monthly";
180180
auto get_filename = [&](const util::TimeStamp& t) {
181+
auto t_str = t.to_string().substr(0,7);
181182
std::string fname = casename
182183
+ ".INSTANT.nsteps_x1"
183184
+ ".np" + std::to_string(comm.size())
184-
+ "." + std::to_string(t.get_year())
185-
+ "-" + std::to_string(t.get_month())
185+
+ "." + t_str
186186
+ ".nc";
187187
return fname;
188188
};

0 commit comments

Comments
 (0)