Skip to content

Commit

Permalink
Acquire ownership of data returned by compute!
Browse files Browse the repository at this point in the history
Prior to this version, `ClimaDiagnostics` would directly store use the
output returned by `compute!` functions the first time they are called.
This leads to problems when the output is a reference to an existing
object since multiple diagnostics would modify the same object. Now,
`ClimaDiagnostics` makes a copy of the return object so that it is no
longer necessary to do so in the `compute!` function.
  • Loading branch information
Sbozzolo committed Oct 8, 2024
1 parent 57d2261 commit 48488e1
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 6 deletions.
9 changes: 9 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
main
-------

## Bug fixes

Prior to this version, `ClimaDiagnostics` would directly store use the output
returned by `compute!` functions the first time they are called. This leads to
problems when the output is a reference to an existing object since multiple
diagnostics would modify the same object. Now, `ClimaDiagnostics` makes a copy
of the return object so that it is no longer necessary to do so in the
`compute!` function.

v0.2.8
-------

Expand Down
2 changes: 1 addition & 1 deletion docs/src/developer_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ add_diagnostic_variable!(
units = "kg m^-3",
compute! = (out, state, cache, time) -> begin
if isnothing(out)
return copy(state.c.ρ)
return state.c.ρ
else
out .= state.c.ρ
end
Expand Down
2 changes: 1 addition & 1 deletion docs/src/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import ClimaDiagnostics: DiagnosticVariable

function compute_ta!(out, state, cache, time)
if isnothing(out)
return copy(state.ta)
return state.ta
else
out .= state.ta
end
Expand Down
5 changes: 3 additions & 2 deletions src/clima_diagnostics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ function DiagnosticsHandler(scheduled_diagnostics, Y, p, t; dt = nothing)
isa_time_reduction = !isnothing(diag.reduction_time_func)

# The first time we call compute! we use its return value. All the subsequent times
# (in the callbacks), we will write the result in place
push!(storage, variable.compute!(nothing, Y, p, t))
# (in the callbacks), we will write the result in place. We call copy to acquire ownership
# of the data in case compute! returned a reference.
push!(storage, copy(variable.compute!(nothing, Y, p, t)))
push!(counters, 1)

# If it is not a reduction, call the output writer as well
Expand Down
2 changes: 1 addition & 1 deletion test/integration_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function setup_integrator(output_dir; context, more_compute_diagnostics = 0)

function compute_my_var!(out, u, p, t)
if isnothing(out)
return copy(u.my_var)
return u.my_var
else
out .= u.my_var
return nothing
Expand Down
2 changes: 1 addition & 1 deletion test/writers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ end

function compute!(out, u, p, t)
if isnothing(out)
return copy(u.field)
return u.field
else
out .= u.field
end
Expand Down

0 comments on commit 48488e1

Please sign in to comment.