# Make \` Array{T}(undef, ...) \` fill with a value for debugging?

**URL:** <https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471>\
**Category:** General Usage\
**Tags:** question, debugging\
**Created:** [April 30, 2020, 9:30am UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471 "2020-04-30T09:30:44Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [April 30, 2020, 9:30am UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/1 "2020-04-30T09:30:44Z")

</div>

Is there a way to force array allocation to fill with a specific value, eg `NaN`? I often find myself debugging bugs that don’t appear when the array happens to be filled with zeros, so this would make these bugs reproducible.

I was thinking just overloading the `Array` constructors might work, but perhaps there’s already an established way to do this?

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [April 30, 2020, 10:18am UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/2 "2020-04-30T10:18:48Z")

</div>

Why not just use `fill(NaN, ...)`?

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [April 30, 2020, 10:19am UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/3 "2020-04-30T10:19:25Z")

</div>

Because I’m debugging code that calls `Array`, possibly in other packages.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [April 30, 2020, 10:21am UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/4 "2020-04-30T10:21:40Z")

</div>

Ah, now I see your problem. You could perhaps write a pass with IRTools.jl

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [April 30, 2020, 10:48am UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/5 "2020-04-30T10:48:27Z")

</div>

That looks too complicated for me to figure out on my own…

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [April 30, 2020, 10:58am UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/6 "2020-04-30T10:58:29Z")

</div>

```julia
struct DebugUndef x end
const undef = DebugUndef(NaN)

Base.Array(u::DebugUndef, args...) = fill!(Array(Base.undef, args...), u.x)
Base.Array{T}(u::DebugUndef, args...) where T = fill!(Array{T}(Base.undef, args...), u.x)
Base.Array{T,N}(u::DebugUndef, args...) where {T,N} = fill!(Array{T,N}(Base.undef, args...), u.x)

```

```julia
julia> Array{Float64, 2}(undef, 2, 3)
2×3 Array{Float64,2}:
 NaN NaN NaN
 NaN NaN NaN

julia> Vector{Float64}(undef, 4)
4-element Array{Float64,1}:
 NaN
 NaN
 NaN
 NaN

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [April 30, 2020, 11:22am UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/7 "2020-04-30T11:22:45Z")

</div>

That is still locally scoped though so it won’t work in e.g.

> [@dlfivefifty](#):
>
> Because I’m debugging code that calls `Array` , possibly in other packages.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [April 30, 2020, 12:10pm UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/8 "2020-04-30T12:10:47Z")

</div>

You could try this solution with IRTools:

```julia
using IRTools: @dynamo, IR, recurse!, xcall
using IRTools.Inner: Variable, Statement

_nan(T::Type{<:AbstractFloat}) = T(NaN)
_nan(T) = T(false)

@dynamo function debug_array(a...)
    ir = IR(a...)
    ir === nothing && return
    for (_, st) in ir
        if Meta.isexpr(st.expr, :call)
            x = st.expr.args[1]
            if x isa Variable && haskey(ir, x)
                func = ir[x].expr
                if Meta.isexpr(func, :call) &&
                    func.args[1] === GlobalRef(Core, :apply_type) &&
                    func.args[2] isa GlobalRef && func.args[2].name === :Array

                    T = func.args[3]
                    ir[x] = Statement(Expr(:call, GlobalRef(@ __MODULE__ , :_nan), T))
                    st.expr.args[1] = GlobalRef(Base, :fill)
                    st.expr.args[2] = x
                end
            end
        end
    end
    for (x, st) in ir
        if Meta.isexpr(st.expr, :call) &&
            st.expr.args[1] !== GlobalRef(Base, :fill)
            ir[x] = xcall(debug_array, st.expr.args...)
        end
    end
    return ir
end

```

You can then call it like this:

```julia
julia> debug_array() do
           a = Array{Float32}(undef, 1, 2, 3)
           print(a[1, 2, 1])
       end
NaN

```

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [April 30, 2020, 12:30pm UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/9 "2020-04-30T12:30:26Z")

</div>

How do I make `Array{T,N}` constructors also work, e.g.:

```julia
julia> debug_array() do
       Matrix{Float64}(undef,10,10)
       end
10×10 Array{Float64,2}:
 2.31914e-314 2.27727e-314 2.27195e-314 … 2.27201e-314 0.0
 2.27194e-314 2.27727e-314 2.272e-314 2.27201e-314 0.0
 2.272e-314 2.27727e-314 2.27727e-314 2.27735e-314 0.0
 2.27194e-314 2.27727e-314 2.27727e-314 2.27195e-314 0.0
 2.27727e-314 2.31914e-314 2.272e-314 2.27735e-314 0.0
 2.31914e-314 2.27195e-314 2.272e-314 … 2.27735e-314 2.28897e-314
 2.272e-314 2.27195e-314 2.272e-314 2.27195e-314 2.28897e-314
 2.272e-314 2.27195e-314 2.272e-314 2.27735e-314 0.0
 2.27194e-314 2.27195e-314 2.27727e-314 0.0 0.0
 2.27726e-314 2.27195e-314 2.272e-314 0.0 0.0

```

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [April 30, 2020, 12:36pm UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/10 "2020-04-30T12:36:38Z")

</div>

Perhaps not the nicest solution, but this should do the trick:

```julia
using IRTools: @dynamo, IR, recurse!, xcall
using IRTools.Inner: Variable, Statement

_nan(T::Type{<:AbstractFloat}) = T(NaN)
_nan(T) = T(false)

@dynamo function debug_array(a...)
    ir = IR(a...)
    ir === nothing && return
    for (_, st) in ir
        if Meta.isexpr(st.expr, :call)
            x = st.expr.args[1]
            if x isa Variable && haskey(ir, x)
                func = ir[x].expr
                if Meta.isexpr(func, :call) &&
                    func.args[1] === GlobalRef(Core, :apply_type) &&
                    func.args[2] isa GlobalRef && func.args[2].name in (:Array, :Vector, :Matrix)

                    T = func.args[3]
                    ir[x] = Statement(Expr(:call, GlobalRef(@ __MODULE__ , :_nan), T))
                    st.expr.args[1] = GlobalRef(Base, :fill)
                    st.expr.args[2] = x
                end
            end
        end
    end
    for (x, st) in ir
        if Meta.isexpr(st.expr, :call) &&
            st.expr.args[1] !== GlobalRef(Base, :fill)
            ir[x] = xcall(debug_array, st.expr.args...)
        end
    end
    return ir
end

```

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [April 30, 2020, 12:47pm UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/11 "2020-04-30T12:47:47Z")

</div>

Cool! Seems to work pretty well even with other packages:

```julia
julia> debug_array() do
       BlockBandedMatrix{Float64}(undef, 1:3,1:3, (1,1))
       end
3×3-blocked 6×6 BlockSkylineMatrix{Float64,Array{Float64,1},BlockBandedMatrices.BlockSkylineSizes{Tuple{BlockArrays.BlockedUnitRange{Array{Int64,1}},BlockArrays.BlockedUnitRange{Array{Int64,1}}},Fill{Int64,1,Tuple{Base.OneTo{Int64}}},Fill{Int64,1,Tuple{Base.OneTo{Int64}}},BandedMatrix{Int64,Array{Int64,2},Base.OneTo{Int64}},Array{Int64,1}}}:
 NaN │ NaN NaN │ ⋅ ⋅ ⋅ 
 ───────┼────────────┼─────────────────────
 NaN │ NaN NaN │ NaN NaN NaN  
 NaN │ NaN NaN │ NaN NaN NaN  
 ───────┼────────────┼─────────────────────
    ⋅ │ NaN NaN │ NaN NaN NaN  
    ⋅ │ NaN NaN │ NaN NaN NaN  
    ⋅ │ NaN NaN │ NaN NaN NaN  

```

Note that not every case is caught:

```julia
julia> debug_array() do
       BandedMatrix{Float64}(undef, (3,3), (1,1))
       end
3×3 BandedMatrix{Float64,Array{Float64,2},Base.OneTo{Int64}}:
 0.0 0.0 ⋅ 
 0.0 5.0e-324 5.0e-324
  ⋅ 0.0 0.0

```

Though that’s due to an arguably bad design in BandedMatrices.jl:

```julia
BandedMatrix{T, C}(::UndefInitializer, (n,m)::NTuple{2,Integer}, (a,b)::NTuple{2,Integer}) where {T<:BlasFloat, C<:AbstractMatrix{T}} =
    _BandedMatrix(C(undef,max(0,b+a+1),m), n, a, b)

```

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [April 30, 2020, 12:55pm UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/12 "2020-04-30T12:55:17Z")

</div>

OK, I feel really dumb. This can be written much more concisely like this:

```julia
using IRTools: @dynamo, IR, recurse!, xcall
using IRTools.Inner: Variable, Statement

_nan(T::Type{<:AbstractFloat}) = T(NaN)
_nan(T) = T(false)

debug_array(::Type{<:Array{T}}, ::UndefInitializer, dims...) where T = fill(_nan(T), dims...)

@dynamo function debug_array(a...)
    ir = IR(a...)
    ir === nothing && return
    recurse!(ir)
    return ir
end

```

It even works in the `BandedMatrix` case

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [April 30, 2020, 1:24pm UTC](https://discourse.julialang.org/t/make-array-t-undef-fill-with-a-value-for-debugging/38471/13 "2020-04-30T13:24:39Z")

</div>

> [@simeonschaub](#):
>
> using IRTools: @dynamo, IR, recurse!, xcall using IRTools.Inner: Variable, Statement \_nan(T::Type{\<:AbstractFloat}) = T(NaN) \_nan(T) = T(false) debug\_array(::Type{\<:Array{T}}, ::UndefInitializer, dims…) where T = fill(\_nan(T), dims…) @dynamo function debug\_array(a…) ir = IR(a…) ir === nothing && return recurse!(ir) return ir end

Beautiful!

```julia
julia> debug_array() do
       BandedMatrix{Float64}(undef, (3,3), (1,1))
       end
3×3 BandedMatrix{Float64,Array{Float64,2},Base.OneTo{Int64}}:
 NaN NaN ⋅ 
 NaN NaN NaN
    ⋅ NaN NaN

julia> debug_array() do
       similar(randn(3), 3)
       end
3-element Array{Float64,1}:
 NaN
 NaN
 NaN

```
