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

Add mostRecentAccessTime attribute to streams #4752

Conversation

trhille
Copy link
Contributor

@trhille trhille commented Jan 24, 2022

Add a new attribute to streams called 'mostRecentAccessTime', which is useful when multiple time-levels are needed at once from an input file.

For input, this corresponds to the time for which input was last read. For output, this corresponds to the time for which output was last written. Note that for output, there is an option to specify an output time that is not the current time; the value used here for mostRecentAccessTime uses the time actually sent to the file.

The actualWhen argument to the MPAS_stream_mgr_read() routine is replaced with an optional argument saveActualWhen. The actualWhen argument was ambiguous when MPAS_stream_mgr_read was called in a way such that multiple streams were read; the actualWhen value returned came from the final stream read and could possibly be wrong for the other streams that were read.

Now, instead of being able to have the actualTime returned as an argument, there is the option to have the actual time saved to the new attribute. It can then be retrieved from the stream cursor as needed.

The saveActualWhen argument is optional because some streams do not contain xtime and trying to obtain ‘actual when’ in those cases will cause the reading of the stream to fail. Therefore, it is important to be able to not seek this information in these cases. If the saveActualWhen argument is not provided to MPAS_stream_mgr_read(), its value defaults to false.

This also changes the land ice core to stop using actualWhen and replace it with saveActualWhen. Neither the ocean nor seaice cores use actualWhen so no other changes are necessary.

[BFB]

This commit adds a mostRecentAccessTime attribute to all streams.  For
input, this corresponds to the time for which input was last
read.  For output, this corresponds to the time for which output was
last written.  Note that for output, there is an option to specify an
output time that is not the current time; the value used here for
mostRecentAccessTime uses the time actually sent to the file.

This attribute is initialized to '9999-12-31_23:59:59' and will contain
that value prior to the first access.
This commit modified the previous commit by removing the actualWhen
argument to the MPAS_stream_mgr_read() routine and replacing it with an
optional argument saveActualWhen.  The actualWhen argument was ambiguous
when MPAS_stream_mgr_read was called in a way such that multiple streams
were read - the actualWhen value returned came from the final stream
read and could possibly be wrong for the other streams that were read.
Given the previous commit added the mostRecentAccessTime attribute to
the MPAS_stream_list_type type, the actualTime argument was somewhat
redundant anyway.

Now, instead of being able to have the actualTime returned as an
argument, there is the option to have the actual time saved to the new
attribute.  It can then be retrieved from the stream cursor as needed.

The saveActualWhen argument is optional because some streams do not
contain xtime and trying to obtain ‘actual when’ in those cases will
cause the reading of the stream to fail.  Therefore, it is important to
be able to not seek this information if possible.  If the saveActualWhen
argument is not provided to MPAS_stream_mgr_read(), its value defaults
to false.

This commit also changes the land ice core to stop using actualWhen and
replace it with saveActualWhen.  Neither the ocean nor seaice cores use
actualWhen so no other changes are necessary.
@matthewhoffman
Copy link
Contributor

@mgduda , you may be interested in this small MPAS Framework PR.

@xylar xylar assigned jonbob and unassigned mark-petersen, xylar and akturner Jan 24, 2022
@xylar
Copy link
Contributor

xylar commented Jan 24, 2022

@trhille, could you put the full commit messages (possibly lightly edited) as the description of this PR? I think all that info is necessary to understand what's going on here.

What kind of testing would you suggest to make sure this works as expected? I can certainly run some COMPASS and standard E3SM test cases.

@trhille
Copy link
Contributor Author

trhille commented Jan 25, 2022

@trhille, could you put the full commit messages (possibly lightly edited) as the description of this PR? I think all that info is necessary to understand what's going on here.

Thanks @xylar, I've added this to the PR description.

What kind of testing would you suggest to make sure this works as expected? I can certainly run some COMPASS and standard E3SM test cases.

I think what we need is to write out xtime from the two most recent time levels to a log file, but I recognize that this is sort of a non-standard test requiring some extra code that wouldn't be part of the PR. @matthewhoffman, do you have other ideas for testing?

@matthewhoffman
Copy link
Contributor

Thanks, @trhille . For testing, can you report in a comment the testing you have done in your PR to confirm the new functionality works as expected? (and reference your PR in our repo as an example of usage)

Because the ocean and sea ice cores do not use the functionality being modified, no specific testing needs to be done by them, but a standard set of COMPASS tests to confirm no harm was done is still appropriate. I think that would be sufficient.

@mgduda
Copy link
Contributor

mgduda commented Jan 25, 2022

Thanks for tagging me, @matthewhoffman . Some of our code in MPAS-Atmosphere does make use of the actualWhen argument, which is removed in this PR. I'm not yet sure whether we'll make these changes in the MPAS-Model repository, so my opinion shouldn't carry much weight. But in cases where we don't explicitly iterate over streams with stream_cursor in user code, how would we retrieve mostRecentAccessTime in those cases? For example: https://github.com/MPAS-Dev/MPAS-Model/blob/v7.1/src/core_atmosphere/mpas_atm_core.F#L643-L644 .

@xylar
Copy link
Contributor

xylar commented Jan 25, 2022

@mgduda, from my reading of the changes in this PR and @matthewhoffman's description in a meeting we were in earlier today, it seems like actualWhen gives the most recent xtime read from the last of the streams in the stream manager. It seems like this could be a pretty odd behavior in any situation where you are reading multiple streams that may have different xtime intervals in them. So it doesn't seem like the code as written is super safe in the sense of giving a user a reliable value for actualWhen when reading multiple streams.

@mgduda
Copy link
Contributor

mgduda commented Jan 25, 2022

@xylar Do you mean reading multiple streams with a single call to mpas_stream_mgr_read, or reading multiple streams, each with its own call to mpas_stream_mgr_read? In my experience, the actualWhen value is absolutely reliable in the latter case, and I don't see how to recover this existing functionality under the changes in this PR.

@xylar
Copy link
Contributor

xylar commented Jan 25, 2022

@mgduda, I'm not well versed enough in the I/O framework to address your question. My sense it that @matthewhoffman was referring to the former case. I would guess for the latter case, you would want, indeed, need to "iterate" over the one stream with a stream_cursor to get the attribute you want, which might lead to clumsier code than you'd like.

My understanding is that MPAS-Ocean and MPAS-Seaice don't use this functionality, so I'll leave further discussion up to the MALI and MPAS-Atmosphere folks.

@trhille
Copy link
Contributor Author

trhille commented Jan 25, 2022

Thanks, @trhille . For testing, can you report in a comment the testing you have done in your PR to confirm the new functionality works as expected? (and reference your PR in our repo as an example of usage)

I tested this for MALI on https://github.com/trhille/E3SM/tree/0d1f47742a394d3fb24fc6c9c72f837d86419562. I wrote out xtime of the two most recent input times here: https://github.com/trhille/E3SM/blob/0d1f47742a394d3fb24fc6c9c72f837d86419562/components/mpas-albany-landice/src/mode_forward/mpas_li_calving.F#L1809-L1829

The input stream interval is one year (updated in July) in this case. This gave the expected behavior in log.landice.0000.out:

   Completed timestep.  New time is: 2094-07-01_00:00:00
 Starting timestep number 5
   Setting time step (days) to: 92.6880439814815
 Calculating N assuming perfect ocean connection.
   * Forced a read of input stream 'ismip-gis' from time: 2094-07-01_00:00:00
   * Forced a read of input stream 'ismip-gis' from time: 2093-07-01_00:00:00
 deltatForcing = 31536000.0000000
...
   Completed timestep.  New time is: 2095-04-04_01:23:06
 Starting timestep number 8
   Setting time step (days) to: 87.9422916666667
 Calculating N assuming perfect ocean connection.
   * Forced a read of input stream 'ismip-gis' from time: 2094-07-01_00:00:00
   * Forced a read of input stream 'ismip-gis' from time: 2093-07-01_00:00:00
 deltatForcing = 31536000.0000000
...
 Starting timestep number 9
   Setting time step (days) to: 92.2976620370370
 Calculating N assuming perfect ocean connection.
   * Forced a read of input stream 'ismip-gis' from time: 2095-07-01_00:00:00
   * Forced a read of input stream 'ismip-gis' from time: 2094-07-01_00:00:00
 deltatForcing = 31536000.0000000
 

MALI usage example: MALI-Dev#18

@matthewhoffman
Copy link
Contributor

@mgduda , you are absolutely right that with this change, you would no longer have the option to get the time that was read as an argument and instead would have to access the stream cursor to get the new attribute. I could certainly leave the existing functionality in place for backwards compatibility, but it would fail to address the issue that actualWhen is ambiguous if multiple streams were read. In my mind, that potential ambiguity is more dangerous than the loss of convenience associated with the change, but I'm definitely open to other implementations that would preserve backwards compatibility if you have any. One compromise could be to leave the old behavior in place, and leave it to the developer to know when actualWhen is safe to use (or add a warning or error if it isn't).

On a related note, the way I implemented it, one has to explicitly set the saveActualWhen argument to force the time to be saved to the stream manager. It may be more sensible to just have it always occur.

Copy link
Contributor

@xylar xylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm reviewing these changes mostly from a do-no-harm perspective. Since this is not a functionality that we currently use in MPAS-Ocean, nor that we have a short-term need for, I have not tried to understand all the nuances.

I tested the compass ocean pr test suite on Anvil with Intel and Intel-MPI. All tests passed and matched bit-for-bit with a baseline created from a recent E3SM/master (3523b2b).

@matthewhoffman
Copy link
Contributor

MPAS framework team discussed this PR today and decided that this functionality is unlikely to be used by ocean and sea ice, and maintaining identical framework to NCAR/MPAS-Atmosphere is not a requirement at this point, so we will proceed with the version implemented here, pending approval by remaining reviewers. Any of the modifications discussed above could be implemented in the future if needs arise.

@matthewhoffman
Copy link
Contributor

matthewhoffman commented Feb 1, 2022

After talking with @trhille , we decided it would be a cleaner implementation to have the new attribute always saved and remove the saveActualWhen argument. I will work on a fix for that today. So reviewers will want to wait until that is complete before looking further at this.

Copy link
Contributor

@mark-petersen mark-petersen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This passes the nightly regression suite with both intel and gnu on grizzly. I'm happy for this to be merged.

@mark-petersen
Copy link
Contributor

Just saw the previous comment by @matthewhoffman. I can review again after PR is updated.

Having saving of the actualWhen time being optional could lead to
confusion if one accesses the new mostRecentAccessTime attribute
elsewhere.

This commit makes it so the actualWhen time is always saved for
all streams that are read.  Hence the saveActualWhen argument is
deleted.
@matthewhoffman
Copy link
Contributor

@trhille , I've pushed a new commit that makes it so the mostRecentAccess time is always recorded. Can you retest this branch for your application, and if you confirm it works properly, tag the reviewers to then proceed with their final testing/review?

Some streams do not have the xtime variable.  In those cases, attempting
to access xtime leads to an error.  This commit uses a dummy value for
actualWhen if xtime is not present in an input file.
… xtime"

This reverts commit c7817c6.

The attempt to parse i/o error codes was not reliable because tests
always returned MPAS_IO_ERR_PIO instead of more specific, useful error
codes.  Thus it was not possible to differentiate between xtime being
missing from a file and any other i/o error that should be treated as a
real error.
This reverts commit 1baed5e.

This revert goes with the revert in the previous commit.  See commit
message there for details.
Updated comments explain why the saveActualWhen argument is needed and
why it is not possible to just always save the actualWhen time.
@matthewhoffman
Copy link
Contributor

Update: after testing commits to make the actualWhen time always saved, we found that this change was unacceptable because it was not possible to reliably parse existing i/o error messages to identify if xtime was present or not. (The dreaded generic MPAS_IO_ERR_PIO code was returned instead of more specific, useful error codes.) Rather than further modify the i/o framework to deal with that, we decided we would just revert to the version from yesterday that requires the calling routing to request saveActualWhen for calls in which that information is desired. I left the failed attempt in the commit history (now reverted) for posterity. I also updated the subroutine description to explain why saveActualWhen is an optional argument that by default is false.

The code should now be identical to the version that Xylar and Mark tested earlier this week, but Trevor will retest his use case to be sure, and then it's probably best practice to have at least one of Xylar or Mark retest as well.

Before this commit, a default value of '0000-01-01_00:00:00' was being
saved to the new mostRecentAccessTime attribute on calls to mpas_stream_mgr_read()
where a stream wasn't actually read because its alarm wasn't ringing.

This commit initializes actualWhen_local to a non-time value in order to
only set mostRecentAccessTime if actualWhen_local is successfully
updated to a time by read_stream().
@matthewhoffman
Copy link
Contributor

@xylar , @mark-petersen , @akturner , I have pushed one new commit to this PR that @trhille found during his final testing. Trevor has successfully tested this final version now, so the PR is ready for final review and then merge.

@mark-petersen mark-petersen self-requested a review February 3, 2022 15:29
Copy link
Contributor

@mark-petersen mark-petersen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recompiled with the head with gnu, and this passes the MPAS-O nightly regression suite again. Thanks.

@xylar
Copy link
Contributor

xylar commented Feb 3, 2022

Thanks @mark-petersen. I don't feel the need to retest, so my approval stands.

@matthewhoffman
Copy link
Contributor

Thanks, Mark & Xylar. @akturner , do you still want to review this before we proceed?

jonbob added a commit that referenced this pull request Feb 7, 2022
…-streams' into next (PR #4752)

Add mostRecentAccessTime attribute to streams

Add a new attribute to streams called 'mostRecentAccessTime', which is
useful when multiple time-levels are needed at once from an input file.

The actualWhen argument to the MPAS_stream_mgr_read() routine is
replaced with an optional argument saveActualWhen. The actualWhen
argument was ambiguous when MPAS_stream_mgr_read was called in a way
such that multiple streams were read; the actualWhen value returned came
from the final stream read and could possibly be wrong for the other
streams that were read.

This also changes the land ice core to stop using actualWhen and replace
it with saveActualWhen. Neither the ocean nor seaice cores use
actualWhen so no other changes are necessary.

[BFB]
@jonbob
Copy link
Contributor

jonbob commented Feb 8, 2022

Passes SMS.T62_oQU120_ais20.MPAS_LISIO_TEST.chrysalis_intel, merged to next

@jonbob jonbob merged commit 447d2ba into E3SM-Project:master Feb 8, 2022
@jonbob
Copy link
Contributor

jonbob commented Feb 8, 2022

merged to master. @trhille please feel free to delete the branch from your fork

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants