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 parameters to Callback #2127

Closed
glwagner opened this issue Dec 26, 2021 · 4 comments · Fixed by #2162
Closed

Add parameters to Callback #2127

glwagner opened this issue Dec 26, 2021 · 4 comments · Fixed by #2162

Comments

@glwagner
Copy link
Member

Probably related:

I saw the new Simulation API and the new Callback idea. This brought a change: the old way of building a Simulation included a parameters arguments. This parameters was accesible from the progress function. With the new way, we build callbacks and then register them, but there is no way to pass additional parameters to it.

In one of my usages I was hacking a progress function https://github.com/aramirezreyes/RamirezReyes_ShallowWaterInFPlane/blob/c1971c0cb3fc99fbb2dbf3303a8fd60b17a59d5a/scripts/run_oceananigans_example_cpu.jl#L101 to update some arrays on a parameterization. Unfortunately, this depended on the parameters argument. The more generalized idea of the callbacks is very elegant and works nice, but it loses some power from the lack of ability to add additional parameters to the callback function.

Is there a way to recover this ability? (there are other ways of getting it to work but having it in the design would be nice).

Originally posted by @aramirezreyes in #1895 (comment)

@glwagner
Copy link
Member Author

@aramirezreyes one possibility is a parameters feature for Callback; when !isnothing(callback.parameters), the callback function is called with func(simulation, parameters).

@glwagner
Copy link
Member Author

glwagner commented Dec 26, 2021

Before this issue is resolved, one solution is to use callable objects:

struct ParameterizedCallback{P}
    parameters :: P
end

(cb::ParameterizedCallback)(simulation) = # function that depends on both `sim` and `cb.parameters`

cb = ParameterizedCallback(parameters) # builds the callable object, capturing `parameters`

simulation.callbacks[:callback] = Callback(cb, IterationInterval(10))

@aramirezreyes
Copy link
Contributor

aramirezreyes commented Dec 27, 2021

Thanks!
The solution I came up with is using a function with a default argument.

mycallback(simulation, parameters = my_parameters)
simulation.callbacks[:callback] = Callback(mycallback, IterationInterval(10))

I have not checked if the way in which both capture the object would be equivalent.

@glwagner
Copy link
Member Author

A default argument works great too! You can also capture data as a global variable:

julia> a = 3
3

julia> f(x) = x * a
f (generic function with 4 methods)

julia> f(2)
6

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

Successfully merging a pull request may close this issue.

2 participants