Skip to content

Commit 5ee65eb

Browse files
Update debugging docs (#2259)
1 parent 3a28325 commit 5ee65eb

File tree

1 file changed

+51
-9
lines changed

1 file changed

+51
-9
lines changed

docs/src/debugging.md

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,15 @@ function ClimaCore.DebugOnly.post_op_callback(result, args...; kwargs...)
4141
end
4242
end
4343
```
44-
If needed, `post_op_callback` can be specialized or behave differently in
45-
different cases, but here, it only checks if `NaN`s are in the given that.
4644

47-
Note that, due to dispatch, `post_op_callback` will likely need a very general
48-
method signature, and using `post_op_callback
49-
(result::DataLayouts.VIJFH, args...; kwargs...)` above fails (on the CPU),
50-
because `post_op_callback` ends up getting called multiple times with different
51-
datalayouts.
45+
If needed, multiple methods of `post_op_callback` can be defined, but here, we
46+
define a general method that checks if `NaN`s are in the given object.
47+
48+
Note that we need `post_op_callback` to be called for a wide variety of inputs
49+
because it is called by many many different functions with many different
50+
objects. Therefore, we recommend that you define `post_op_callback` with a very
51+
general method signature, like the one above and perhaps use `Infiltrator` to
52+
inspect the arguemtns.
5253

5354
Now, let us put everything together and demonstrate a complete example:
5455

@@ -104,7 +105,9 @@ end
104105

105106
FT = Float64
106107
data = ClimaCore.DataLayouts.VIJFH{FT}(Array{FT}, zeros; Nv=5, Nij=2, Nh=2)
107-
@. data = NaN
108+
x = ClimaCore.DataLayouts.VIJFH{FT}(Array{FT}, zeros; Nv=5, Nij=2, Nh=2)
109+
parent(x)[1] = NaN # emulate incorrect initialization
110+
@. data = x + 1
108111
# Let's see what happened
109112
(;result, args, kwargs, st) = Infiltrator.safehouse;
110113

@@ -115,11 +118,50 @@ ClimaCore.DebugOnly.print_depth_limited_stack_trace(st; maxtypedepth=1)
115118
# Inspecting `args` shows that the `Broadcasted` object used to populate the
116119
# result was:
117120
julia> args[2]
118-
Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{0}}(identity, (NaN,))
121+
Base.Broadcast.Broadcasted{ClimaCore.DataLayouts.VIJFHStyle{5, 2, Array{Float64}}}(+, (ClimaCore.DataLayouts.VIJFH{Float64, 5, 2, Array{Float64, 5}}
122+
[NaN, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 1))
119123

120124
# And there's your problem, NaNs is on the right-hand-side of that assignment.
121125
```
122126

127+
If your broadcasted object is very long, it can be a bit overwhelming to figure
128+
out which part of the expression contains NaNs (if any). To make this process
129+
more manageable, we can use [`StructuredPrinting.jl`]
130+
(https://github.com/charleskawczynski/StructuredPrinting.jl) to highlight which
131+
parts of the broadcasted object contains NaNs:
132+
133+
```julia
134+
using StructuredPrinting
135+
import ClimaCore: DataLayouts
136+
highlight_nans(x::DataLayouts.AbstractData) = any(y->isnan(y), parent(x));
137+
highlight_nans(_) = false;
138+
bc = Infiltrator.safehouse.args[2]; # we know that argument 2 is the broadcasted object
139+
(; result) = Infiltrator.safehouse; # get the result
140+
@structured_print bc Options(; highlight = x->highlight_nans(x))
141+
```
142+
This last line results in:
143+
144+
```julia
145+
julia> @structured_print bc Options(; highlight = x->highlight_nans(x))
146+
bc
147+
bc.style::ClimaCore.DataLayouts.VIJFHStyle{5, 2, Array{Float64}}
148+
bc.f::typeof(+)
149+
bc.args::Tuple{ClimaCore.DataLayouts.VIJFH{Float64, 5, 2, Array{…}}, Int64}
150+
bc.args.1::ClimaCore.DataLayouts.VIJFH{Float64, 5, 2, Array{Float64, 5}} # highlighted in RED
151+
bc.args.2::Int64
152+
bc.axes::NTuple{5, Base.OneTo{Int64}}
153+
bc.axes.1::Base.OneTo{Int64}
154+
bc.axes.1.stop::Int64
155+
bc.axes.2::Base.OneTo{Int64}
156+
bc.axes.2.stop::Int64
157+
bc.axes.3::Base.OneTo{Int64}
158+
bc.axes.3.stop::Int64
159+
bc.axes.4::Base.OneTo{Int64}
160+
bc.axes.4.stop::Int64
161+
bc.axes.5::Base.OneTo{Int64}
162+
bc.axes.5.stop::Int64
163+
```
164+
123165
### Caveats
124166

125167
!!! warn

0 commit comments

Comments
 (0)