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

AbstractSchedules for scheduling output and diagnostics #1070

Merged
merged 25 commits into from
Oct 19, 2020

Conversation

glwagner
Copy link
Member

@glwagner glwagner commented Oct 16, 2020

This PR provides a substantial rewrite to the user API for "scheduling" output and diagnostics.

Previously, output was scheduled by specifying one of two keyword arguments when constructing the AbstractOutputWriter: time_interval, and iteration_interval. An example from the documentation is

simulation.output_writers[:field_writer] =
    NetCDFOutputWriter(model, fields, filename="output_fields.nc", time_interval=60)

# output
NetCDFOutputWriter (time_interval=60): output_fields.nc
├── dimensions: zC(16), zF(17), xC(16), yF(16), xF(16), yC(16), time(0)
└── 2 outputs: ["T", "u"]

Time-averaging was specified by providing one or two additional keyword arguments: time_average_interval and (optionally) time_average_stride.

This PR eliminates these keyword arguments in favor of a single argument schedule. In general, the schedule is an object which returns true (when output should be written, or a diagnostic calculated) and false (otherwise).

This PR implements four AbstractSchedules, and more are possible:

  • TimeInterval: periodic schedule that reoccurs on a interval of model time.
  • IterationInterval: periodic schedule that reoccurs on an iteration of model iterations
  • WallClockInterval periodic schedule that reoccurs on an interval of "wall time", as kept by the clock on your wall
  • AveragedTimeInterval: periodic schedule that reoccurs on an interval of model time, and specifies time-averaging of output over a window (and a default window equal to interval is now provided for friendliness)

The old syntax thus becomes

simulation.output_writers[:field_writer] =
    NetCDFOutputWriter(model, fields, filepath="fields.nc", schedule=TimeInterval(60))

and averaging is specified (with a time window of 20 seconds) by writing

simulation.output_writers[:field_writer] =
    NetCDFOutputWriter(model, fields, filepath="fields.nc", schedule=AveragedTimeInterval(60, window=20))

This PR starts updating the examples and docs, though we still need to

  • finish updating verification scripts
  • finish updating docs

Since we now have a fairly convincing test about the accuracy of WindowedTimeAverage, I think we should also

  • add documentation for WindowedTimeAverage

which is apropos to this PR since it changes the syntax through which averaging is specified.

Eventually, we should use the "scheduling" concept for both callafter function in run!(simulation) and the TimeStepWizard (separately), which will get rid of the iteration_interval argument in run!(simulation).

PS: should we use WindowAveragedTimeInterval rather than AveragedTimeInterval? I wasn't sure if the added verbosity added clarity here (the important part is the "Averaging") but I'm open to considering it.

Resolves #1019
Resolves #853
Resolves #845

@ali-ramadhan
Copy link
Member

ali-ramadhan commented Oct 17, 2020

PS: should we use WindowAveragedTimeInterval rather than AveragedTimeInterval? I wasn't sure if the added verbosity added clarity here (the important part is the "Averaging") but I'm open to considering it.

I think AveragedTimeInterval is fine since window is a keyword argument. I guess by not setting a window AveragedTimeInterval suggests that no windowing will occur and the time average is accumulated every iteration?

Copy link
Member

@ali-ramadhan ali-ramadhan left a comment

Choose a reason for hiding this comment

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

This is awesome! Much cleaner interface with tons of uses.

For now I guess you can only have one schedule per output writer. I think this is fine: if users want to specify multiple schedules they can create multiple output writers (or just define a custom schedule(model). I.e. we shouldn't worry about this.

Thanks for updating the documentation on output writing, it was quite out of date and it's not the most enjoyable work. Also nice work on refactoring the NetCDFOutputWriter through multiple disptach!

Super pedantic but Oceananigans.Util now defines minutes and hours so we can use e.g. TimeInterval(2minutes) instead of TimeInterval(2minute) but maybe this is bad as it could signal a proliferation of exported names .

Comment on lines 46 to 48
```@docs
NetCDFOutputWriter
```
Copy link
Member

Choose a reason for hiding this comment

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

💯

docs/src/model_setup/output_writers.md Outdated Show resolved Hide resolved
@glwagner
Copy link
Member Author

I guess by not setting a window AveragedTimeInterval suggests that no windowing will occur and the time average is accumulated every iteration?

Right, that's default! I think it makes sense.

@glwagner
Copy link
Member Author

we can use e.g. TimeInterval(2minutes)

Is this for examples and docs? It does obviously read better; I'm not sure about the downside of name proliferation. Maybe we can stew on it and update in a future PR?

@ali-ramadhan
Copy link
Member

Just updated a few remaining jldoctests so tests should pass soon.

@ali-ramadhan
Copy link
Member

ali-ramadhan commented Oct 17, 2020

Is this for examples and docs? It does obviously read better; I'm not sure about the downside of name proliferation. Maybe we can stew on it and update in a future PR?

I was thinking both, i.e. encourage their use to improve script readability. Yeah we can just update things as we go along.

I guess the downside is that new users may not immediately notice that these common words, e.g. minutes, are actually being exported by Oceananigans.Utils. Perhaps if they were exported by a submodule like Oceananigans.Units that would be clearer. Also, newcomers to Julia may not realize that you can write things like or 3hours but this should not stop us from using this nice language feature.

@glwagner
Copy link
Member Author

Perhaps if they were exported by a submodule like Oceananigans.Units that would be clearer.

very much agree.

@glwagner
Copy link
Member Author

For now I guess you can only have one schedule per output writer. I think this is fine: if users want to specify multiple schedules they can create multiple output writers (or just define a custom schedule(model). I.e. we shouldn't worry about this.

Yeah, I think eventually or if we get lots of requests it might make sense to add some kind of MixedSchedule / MultiSchedule / JointSchedule / CombinedSchedule feature that combines multiple schedules (either with && or ||). Which should be trivial I think. We probably want to design a schedule that activates output based on a criteria diagnosed from the model state (and then either stays activated, or is continuously re-evaluated). Futuristic stuff I think!

@ali-ramadhan ali-ramadhan mentioned this pull request Oct 17, 2020
@codecov
Copy link

codecov bot commented Oct 19, 2020

Codecov Report

Merging #1070 into master will decrease coverage by 0.42%.
The diff coverage is 64.17%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1070      +/-   ##
==========================================
- Coverage   57.70%   57.28%   -0.43%     
==========================================
  Files         158      164       +6     
  Lines        3807     4139     +332     
==========================================
+ Hits         2197     2371     +174     
- Misses       1610     1768     +158     
Impacted Files Coverage Δ
src/Diagnostics/Diagnostics.jl 100.00% <ø> (ø)
src/OutputWriters/OutputWriters.jl 66.66% <ø> (ø)
src/OutputWriters/field_slicer.jl 69.69% <0.00%> (-6.97%) ⬇️
src/OutputWriters/output_writer_utils.jl 51.92% <0.00%> (-5.53%) ⬇️
src/Utils/Utils.jl 40.00% <ø> (ø)
src/Utils/output_writer_diagnostic_utils.jl 83.33% <ø> (+1.19%) ⬆️
src/OutputWriters/jld2_output_writer.jl 84.31% <33.33%> (-6.26%) ⬇️
src/Utils/schedules.jl 45.45% <45.45%> (ø)
src/OutputWriters/checkpointer.jl 85.29% <66.66%> (-0.22%) ⬇️
src/OutputWriters/netcdf_output_writer.jl 82.65% <72.22%> (-10.38%) ⬇️
... and 27 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c5f47e0...ecb956f. Read the comment docs.

@glwagner glwagner merged commit 27265b8 into master Oct 19, 2020
@glwagner glwagner deleted the glw/flexible-output-criteria branch October 19, 2020 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants