Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added return codes to IOStream for better managing missing/skipped streams #184

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 38 additions & 37 deletions components/omega/src/infra/IOStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,17 +240,18 @@ int IOStream::read(
Metadata &ReqMetadata, // [inout] global metadata requested from file
bool ForceRead // [in] optional: read even if not time
) {
int Err = 0; // default return code
int Err = Success; // default return code

// Retrieve stream by name and make sure it exists
auto StreamItr = AllStreams.find(StreamName);
if (StreamItr != AllStreams.end()) {
// Stream found, call the read function
std::shared_ptr<IOStream> ThisStream = StreamItr->second;
Err = ThisStream->readStream(ModelClock, ReqMetadata, ForceRead);
} else { // Stream not found, return error
LOG_ERROR("Unable to read stream {}. Stream not defined", StreamName);
Err = 1;
} else { // Stream not found
// The response to this case must be determined by the calling routine
// since a missing stream might be expected in some cases
Err = Fail;
}

return Err;
Expand All @@ -264,7 +265,7 @@ int IOStream::write(
const Clock *ModelClock, // [in] Model clock needed for time stamps
bool ForceWrite // [in] optional: write even if not time
) {
int Err = 0; // default return code
int Err = Success; // default return code

// Retrieve stream by name and make sure it exists
auto StreamItr = AllStreams.find(StreamName);
Expand All @@ -275,7 +276,7 @@ int IOStream::write(
} else {
// Stream not found, return error
LOG_ERROR("Unable to write stream {}. Stream not defined", StreamName);
Err = 1;
Err = Fail;
}

return Err;
Expand Down Expand Up @@ -303,7 +304,7 @@ int IOStream::writeAll(
}

// check for errors
if (Err1 != 0) {
if (Err1 == Fail) {
++Err;
LOG_ERROR("writeAll error in stream {}", StreamName);
}
Expand Down Expand Up @@ -2314,24 +2315,24 @@ int IOStream::readStream(
Metadata &ReqMetadata, // [inout] global metadata to extract from file
bool ForceRead // [in] optional: read even if not time
) {
int Err = 0; // default return code

int Err; // return code

// First check that this is an input stream
if (Mode != IO::ModeRead) {
LOG_ERROR("IOStream read: cannot read stream defined as output stream");
Err = 1;
return Err;
return Fail;
}

// If it is not time to read, return
if (!ForceRead) {
if (!MyAlarm.isRinging() and !OnStartup)
return Err;
return Skipped;
if (UseStartEnd) { // If time outside interval, return
if (!StartAlarm.isRinging())
return Err;
return Skipped;
if (EndAlarm.isRinging())
return Err;
return Skipped;
}
}

Expand Down Expand Up @@ -2365,7 +2366,7 @@ int IOStream::readStream(
ExistAction);
if (Err != 0) {
LOG_ERROR("Error opening file {} for input", InFileName);
return Err;
return Fail;
}

// Read any requested global metadata
Expand Down Expand Up @@ -2405,12 +2406,12 @@ int IOStream::readStream(
} else {
LOG_ERROR("Metadata read failed: unknown data type for {} in file {}",
MetaName, InFileName);
ErrRead = 2;
ErrRead = Fail;
}

if (ErrRead != 0) {
LOG_ERROR("Error reading metadata {} from file {}", InFileName);
return ErrRead;
return Fail;
}
} // end loop over requested metadata

Expand All @@ -2419,7 +2420,7 @@ int IOStream::readStream(
Err = defineAllDims(InFileID, AllDimIDs);
if (Err != 0) {
LOG_ERROR("Error defining dimensions for file {} ", InFileName);
return Err;
return Fail;
}

// For each field in the contents, define field and read field data
Expand All @@ -2435,7 +2436,7 @@ int IOStream::readStream(
if (Err != 0) {
LOG_ERROR("Error reading field data for Field {} in Stream {}",
FieldName, Name);
return Err;
return Fail;
}

} // End loop over field list
Expand All @@ -2444,13 +2445,13 @@ int IOStream::readStream(
Err = IO::closeFile(InFileID);
if (Err != 0) {
LOG_ERROR("Error closing input file {}", InFileName);
return Err;
return Fail;
}

LOG_INFO("Successfully read stream {} from file {}", Name, InFileName);

// End of routine - return
return Err;
return Success;

} // End read

Expand All @@ -2463,25 +2464,25 @@ int IOStream::writeStream(
bool FinalCall // [in] Optional flag if called from finalize
) {

int Err = 0; // default return code
int Err = Success; // default return code

// First check that this is an output stream
if (Mode != IO::ModeWrite) {
LOG_ERROR("IOStream write: cannot write stream defined as input stream");
Err = 1;
return Err;
return Fail;
}

// If it is not time to write, return
if (!ForceWrite) {
bool StartupShutdown = OnStartup or (OnShutdown and FinalCall);
if (!MyAlarm.isRinging() and !StartupShutdown)
return Err;
return Skipped;
if (UseStartEnd) { // If time outside interval, return
if (!StartAlarm.isRinging())
return Err;
return Skipped;
if (EndAlarm.isRinging())
return Err;
return Skipped;
}
}

Expand Down Expand Up @@ -2520,15 +2521,15 @@ int IOStream::writeStream(
if (Err != 0) {
LOG_ERROR("IOStream::write: error opening file {} for output",
OutFileName);
return Err;
return Fail;
}

// Write Metadata for global metadata (Code and Simulation)
// Always add current simulation time to Simulation metadata
Err = writeFieldMeta(CodeMeta, OutFileID, IO::GlobalID);
if (Err != 0) {
LOG_ERROR("Error writing Code Metadata to file {}", OutFileName);
return Err;
return Fail;
}
std::shared_ptr<Field> SimField = Field::get(SimMeta);
// Add the simulation time - if it was added previously, remove and
Expand All @@ -2538,20 +2539,20 @@ int IOStream::writeStream(
Err = SimField->addMetadata("SimulationTime", SimTimeStr);
if (Err != 0) {
LOG_ERROR("Error adding current sim time to output {}", OutFileName);
return Err;
return Fail;
}
Err = writeFieldMeta(SimMeta, OutFileID, IO::GlobalID);
if (Err != 0) {
LOG_ERROR("Error writing Simulation Metadata to file {}", OutFileName);
return Err;
return Fail;
}

// Assign dimension IDs for all defined dimensions
std::map<std::string, int> AllDimIDs;
Err = defineAllDims(OutFileID, AllDimIDs);
if (Err != 0) {
LOG_ERROR("Error defined dimensions for file {}", OutFileName);
return Err;
return Fail;
}

// Define each field and write field metadata
Expand All @@ -2574,7 +2575,7 @@ int IOStream::writeStream(
if (Err != 0) {
LOG_ERROR("Error retrieving dimension names for Field {}",
FieldName);
return Err;
return Fail;
}
}
// If this is a time-dependent field, we insert the unlimited time
Expand All @@ -2599,7 +2600,7 @@ int IOStream::writeStream(
FieldID);
if (Err != 0) {
LOG_ERROR("Error defining field {} in stream {}", FieldName, Name);
return Err;
return Fail;
}
FieldIDs[FieldName] = FieldID;

Expand All @@ -2608,15 +2609,15 @@ int IOStream::writeStream(
if (Err != 0) {
LOG_ERROR("Error writing field metadata for field {} in stream {}",
FieldName, Name);
return Err;
return Fail;
}
}

// End define mode
Err = IO::endDefinePhase(OutFileID);
if (Err != 0) {
LOG_ERROR("Error ending define phase for stream {}", Name);
return Err;
return Fail;
}

// Now write data arrays for all fields in contents
Expand All @@ -2632,15 +2633,15 @@ int IOStream::writeStream(
if (Err != 0) {
LOG_ERROR("Error writing field data for Field {} in Stream {}",
FieldName, Name);
return Err;
return Fail;
}
}

// Close output file
Err = IO::closeFile(OutFileID);
if (Err != 0) {
LOG_ERROR("Error closing output file {}", OutFileName);
return Err;
return Fail;
}

// If using pointer files for this stream, write the filename to the pointer
Expand All @@ -2654,7 +2655,7 @@ int IOStream::writeStream(
LOG_INFO("Successfully wrote stream {} to file {}", Name, OutFileName);

// End of routine - return
return Err;
return Success;

} // end writeStream

Expand Down
7 changes: 7 additions & 0 deletions components/omega/src/infra/IOStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ class IOStream {
);

public:
//---------------------------------------------------------------------------
/// Return codes - these will be removed once Error Handler is completed

static constexpr int Success{0}; ///< Successful read/write completion
static constexpr int Skipped{1}; ///< Normal early return (eg if not time)
static constexpr int Fail{2}; ///< Fail

//---------------------------------------------------------------------------
/// Default empty constructor
IOStream();
Expand Down
19 changes: 10 additions & 9 deletions components/omega/src/ocn/OceanInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,22 +174,23 @@ int initOmegaModules(MPI_Comm Comm) {
std::string SimTimeStr = " "; // create SimulationTime metadata
std::shared_ptr<Field> SimField = Field::get(SimMeta);
SimField->addMetadata("SimulationTime", SimTimeStr);
int Err1 = IOStream::Success;
int Err2 = IOStream::Success;

// read from initial state if this is starting a new simulation
Metadata ReqMeta; // no requested metadata for initial state
Err = IOStream::read("InitialState", ModelClock, ReqMeta);
if (Err != 0) {
LOG_CRITICAL("Error reading the initial state file");
return Err;
}
Err1 = IOStream::read("InitialState", ModelClock, ReqMeta);

// read restart if starting from restart
SimTimeStr = " ";
ReqMeta["SimulationTime"] = SimTimeStr;
Err = IOStream::read("RestartRead", ModelClock, ReqMeta);
if (Err != 0) {
LOG_CRITICAL("Error reading the restart file");
return Err;
Err2 = IOStream::read("RestartRead", ModelClock, ReqMeta);

// One of the above two streams must be successful to initialize the
// state and other fields used in the model
if (Err1 != IOStream::Success and Err2 != IOStream::Success) {
LOG_CRITICAL("Error initializing ocean variables from input streams");
return Err1 + Err2;
}

// If reading from restart, reset the current time to the input time
Expand Down
4 changes: 2 additions & 2 deletions components/omega/test/infra/IOStreamTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ int main(int argc, char **argv) {
// Read restart file for initial temperature and salinity data
Metadata ReqMetadata; // leave empty for now - no required metadata
Err1 = IOStream::read("InitialState", ModelClock, ReqMetadata);
TestEval("Read restart file", Err1, ErrRef, Err);
TestEval("Read restart file", Err1, IOStream::Success, Err);

// Overwrite salinity array with values associated with global cell
// ID to test proper indexing of IO
Expand Down Expand Up @@ -230,7 +230,7 @@ int main(int argc, char **argv) {
std::this_thread::sleep_for(std::chrono::seconds(5));
bool ForceRead = true;
Err1 = IOStream::read("RestartRead", ModelClock, ReqMetadata, ForceRead);
TestEval("Restart force read", Err1, ErrRef, Err);
TestEval("Restart force read", Err1, IOStream::Success, Err);

Err1 = 0;
auto DataReducer = Kokkos::Sum<I4>(Err1);
Expand Down
2 changes: 1 addition & 1 deletion components/omega/test/ocn/StateTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ int initStateTest() {
// Read the state variables from the initial state stream
Metadata ReqMeta; // no global metadata needed for init state read
Err = IOStream::read("InitialState", ModelClock, ReqMeta);
if (!StreamsValid) {
if (Err != IOStream::Success) {
LOG_CRITICAL("ocnInit: Error reading initial state from stream");
return Err;
}
Expand Down
Loading