Part of the issue is as stevengj stated above:
One facility from StaticArrays to make size information available at compile time rather than run time is to wrap a standard array as a SizedArray
. The size of the array then becomes part of the type. Thus we can know the size at compile time.
julia> using StaticArrays
julia> A = zeros(Int, 1024, 512);
julia> SA = SizedArray{Tuple{1024, 512}}(A);
julia> typeof(A)
Matrix{Int64} (alias for Array{Int64, 2})
julia> typeof(SA)
SizedMatrix{1024, 512, Int64, 2, Matrix{Int64}} (alias for SizedArray{Tuple{1024, 512}, Int64, 2, 2, Array{Int64, 2}})
julia> @code_warntype Size(A)
MethodInstance for Size(::Matrix{Int64})
from Size(a::T) where T<:AbstractArray in StaticArrays at ~/.julia/packages/StaticArrays/68nRv/src/traits.jl:88
Static Parameters
T = Matrix{Int64}
Arguments
#self#::Type{Size}
a::Matrix{Int64}
Body::Size{(StaticArrays.Dynamic(), StaticArrays.Dynamic())}
1 ─ %1 = StaticArrays.Size($(Expr(:static_parameter, 1)))::Core.Const(Size(StaticArrays.Dynamic(), StaticArrays.Dynamic()))
└── return %1
julia> @code_warntype Size(SA)
MethodInstance for Size(::SizedMatrix{1024, 512, Int64, 2, Matrix{Int64}})
from Size(a::T) where T<:AbstractArray in StaticArrays at ~/.julia/packages/StaticArrays/68nRv/src/traits.jl:88
Static Parameters
T = SizedMatrix{1024, 512, Int64, 2, Matrix{Int64}}
Arguments
#self#::Type{Size}
a::SizedMatrix{1024, 512, Int64, 2, Matrix{Int64}}
Body::Size{(1024, 512)}
1 ─ %1 = StaticArrays.Size($(Expr(:static_parameter, 1)))::Core.Const(Size(1024, 512))
└── return %1
Above we see that we know the size statically at compile time from the line that states Body::Size{(1024, 512)}
.
Actually for your case, we need to know the strides at compile time. For the SizedArray
I created above we actually do know this at compile time because we know the parent is just an Array
. However, Base.strides
fails us here. Fortunately we have ArrayInterface.strides
:
julia> using ArrayInterface
julia> ArrayInterface.strides(A)
(static(1), 1024)
julia> ArrayInterface.strides(SA)
(static(1), static(1024))
Applied to your specific problem using your example above, we can now see
julia> sa = SizedArray{Tuple{sz...}}(a);
julia> ArrayInterface.strides(sa)
(static(1), static(123), static(123), static(15990))
We need more machinery to take advantage of this information though. I believe StrideArrays.jl likely helps here, but the documentation is a bit too sparse for me to be sure. Perhaps @Elrod would have more insight here.