LoopVectorization.jl icon indicating copy to clipboard operation
LoopVectorization.jl copied to clipboard

Error caused by `Static.StaticInt` not being an `Integer`

Open ranocha opened this issue 3 years ago • 5 comments

I get the following error (on Julia v1.7.2):

julia> using Pkg; Pkg.activate(temp=true); Pkg.add("LoopVectorization")
...
  [bdcacae8] + LoopVectorization v0.12.119
...
  [aedffcd0] + Static v0.7.4
...

julia> function foo_plain!(dst, src)
           for i in (firstindex(dst, 2) + 1):(lastindex(dst, 2) - 1)
               dst[1, i] = src[1, i]
           end
           dst
       end
foo_plain! (generic function with 1 method)

julia> src = ones(6, 6); dst = zero(src)
6×6 Matrix{Float64}:
 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  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

julia> foo_plain!(dst, src)
6×6 Matrix{Float64}:
 0.0  1.0  1.0  1.0  1.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.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

julia> using LoopVectorization

julia> function foo_turbo!(dst, src)
           @turbo for i in (firstindex(dst, 2) + 1):(lastindex(dst, 2) - 1)
               dst[1, i] = src[1, i]
           end
           dst
       end
foo_turbo! (generic function with 1 method)

julia> foo_turbo!(dst, src)
ERROR: TypeError: in typeassert, expected Integer, got a value of type Static.StaticInt{2}
Stacktrace:
 [1] axes
   @ ./abstractarray.jl:74 [inlined]
 [2] firstindex
   @ ./abstractarray.jl:396 [inlined]
 [3] foo_turbo!(dst::Matrix{Float64}, src::Matrix{Float64})
   @ Main ./REPL[9]:2
 [4] top-level scope
   @ REPL[10]:1

How would you recommend to solve this?

ranocha avatar Jun 30 '22 04:06 ranocha

@turbo made integers static, which now seems like a bad choice given StaticInt is no longer an integer.

chriselrod avatar Jun 30 '22 04:06 chriselrod

Two non-mutually exclusive options:

  1. Add a ArrayInterface.firstindex and ArrayInterface.lastindex function that accepts StaticInt and have LoopVectorization import it and substitute calls, like it does for axes.
  2. Use a whitelist in makestatic! https://github.com/JuliaSIMD/LoopVectorization.jl/blob/a7f9e1bf91e14fba2c7f65a7c8fbd7e5eeb6f619/src/modeling/graphs.jl#L930 that only statics in recognized functions. This should maybe keep recursing, e.g. to get the 2 in foo(bar(axes(a,2))), but it probably wouldn't help. The point is to try and pass static information to LoopVectorization itself (e.g. for i in axes(A,2), if A is a MArray, you really want LoopVectorization to know its size! Because the current version of LoopVectorization isn't integrated with the compiler, it has to get the size from the type system, hence it has to substitute Base.axes(A, ::Int) with ArrayInterface.axes(A, ::StaticInt); a huge amount of effort currently going on will be unnecessary once LoopModels is ready), and odds are that'd be lost in foo and bar anyway.

chriselrod avatar Jun 30 '22 04:06 chriselrod

For my use case right now, I just used a workaround by calling firstindex(dst, 2) etc. outside of the expression @turbo sees (since I expect this code to be called for large common arrays, not something where static arrays would be used).

What was the reason for not making StaticInt an Integer anymore? This seems to be the basic root of the problem here.

ranocha avatar Jul 01 '22 14:07 ranocha

What was the reason for not making StaticInt an Integer anymore? This seems to be the basic root of the problem here.

Invalidations / improve loading time. https://github.com/SciML/Static.jl/pull/64 It causes a lot of issues, unfortunately.

chriselrod avatar Jul 01 '22 14:07 chriselrod

Thanks for the link!

ranocha avatar Jul 01 '22 15:07 ranocha