Type instability with SubArray on custom Array type


I have a program that requires me to use my own array type. However, my own array definition seems to cause a type instability problem, leaving lots of performance on the table (potentially 2~3x improvements).

The issue can be reduced to the minimal working example below:

My program defines two custom array types DenseArrayAccessor and DenseArray. The former is essentially a wrapper on a Julia vector and the latter wraps on top of the DenseArrayAccessor. In my actual program, DenseArray contains other fields and supports other operations but those are unnecessary details for this question.

The train function is what I am trying to optimize. @code_warntype shows many warnings when H and W are DenseArrays but those warnings are gone when I use DenseArrayAccessor. Could someone please help me understand what caused this instability?

struct DenseArray{T, N, V} <: AbstractArray{T, N}
    DenseArray{T, N}(accessor::V) where {V <: AbstractArray} where {T, N} = new{T, N, V}(accessor)
    DenseArray{T, N}() where {T, N} = new{T, N, Vector{Float64}}(Nullable{Vector{Float64}}()) # Just put some concrete array type

The problem was accessor::Nullable{AbstractArray}. Knowing T, and N is not enough to say what is inside the nullable so code using it will not be inferable. Solution is to specialize on the concrete type V that will be inside the nullable.


I see. Thank you very much!