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

@Turbo failing

Open ParadaCarleton opened this issue 4 years ago • 11 comments

For some reason, @turbo throws a warning here at this specific line in my code. (Note that this was failing before I made a PR that set avx=false to silence the warning for users.) I have no idea what's going on. I haven't been able to build a MWE because from what I can see the line is so simple that I feel like it should definitely be running; it's probably to do with some weird edge case that I can't isolate without knowing the internals of @tullio.

ParadaCarleton avatar Aug 30 '21 06:08 ParadaCarleton

I'm surprised that fails, it's so simple. But maybe something is tripping over the type of to_sum? Can you post the error message, or the warning?

mcabbott avatar Aug 31 '21 06:08 mcabbott

I'm surprised that fails, it's so simple. But maybe something is tripping over the type of to_sum? Can you post the error message, or the warning?

Bizarrely, it's disappeared now. I have no idea what changed and fixed this, but I can't reproduce it anymore.

ParadaCarleton avatar Sep 01 '21 02:09 ParadaCarleton

I'm surprised that fails, it's so simple. But maybe something is tripping over the type of to_sum? Can you post the error message, or the warning?

Oh weird, it's popping up again. Maybe I just missed it? Here's the warning:

┌ Warning: #= /home/lime/.julia/packages/Tullio/qPZkO/src/macro.jl:1094 =#:
│ `LoopVectorization.check_args` on your inputs failed; running fallback `@inbounds @fastmath` loop instead.
│ Use `warn_check_args=false`, e.g. `@turbo warn_check_args=false ...`, to disable this warning.
└ @ ParetoSmooth ~/.julia/packages/LoopVectorization/atM0u/src/condense_loopset.jl:822

ParadaCarleton avatar Sep 01 '21 19:09 ParadaCarleton

The warning will only print once by default. You can make it appear more often via @turbo warn_check_args=5, which will let it print 5 times (accepts any value that can be converted to an Int).

chriselrod avatar Sep 01 '21 20:09 chriselrod

Ideally Tullio's own check should not send LV things it can't handle. But perhaps it can be made smarter. What are the types of the arrays here?

mcabbott avatar Sep 01 '21 20:09 mcabbott

What are the types of the arrays here?

I should probably have LV's warnings print those.

chriselrod avatar Sep 01 '21 20:09 chriselrod

Ideally Tullio's own check should not send LV things it can't handle. But perhaps it can be made smarter. What are the types of the arrays here?

The arrays are just normal Base arrays of Float64s, with an AxisKeys.jl KeyedArray wrapper around them.

ParadaCarleton avatar Sep 01 '21 20:09 ParadaCarleton

with an AxisKeys.jl KeyedArray wrapper around them.

Okay, that's why.

julia> using LoopVectorization, AxisKeys

julia> A = KeyedArray(rand(2,10), ([:a, :b], 10:10:100))
2-dimensional KeyedArray(...) with keys:
↓   2-element Vector{Symbol}
→   10-element StepRange{Int64,...}
And data, 2×10 Matrix{Float64}:
        (10)          (20)         (30)         (40)          (50)         (60)          (70)         (80)         (90)         (100)
  (:a)     0.498766      0.363857     0.313591     0.303895      0.453926     0.0574657     0.443101     0.179118     0.39422       0.946817
  (:b)     0.0080239     0.544323     0.983931     0.0620305     0.589515     0.903863      0.114999     0.816759     0.377231      0.306352

julia> LoopVectorization.check_args(A)
false

For an array type to be supported, it must implement the ArrayInterface.jl stride array interface (or ArrayInterface can define the appropriate methods itself).

If LoopVectorization.check_args(A) == true and LoopVectorization.stridedpointer(A) returns a sensible result, then it should work. Currently the former returns false and the latter throws an error.

chriselrod avatar Sep 01 '21 21:09 chriselrod

with an AxisKeys.jl KeyedArray wrapper around them.

Okay, that's why.

julia> using LoopVectorization, AxisKeys

julia> A = KeyedArray(rand(2,10), ([:a, :b], 10:10:100))
2-dimensional KeyedArray(...) with keys:
↓   2-element Vector{Symbol}
→   10-element StepRange{Int64,...}
And data, 2×10 Matrix{Float64}:
        (10)          (20)         (30)         (40)          (50)         (60)          (70)         (80)         (90)         (100)
  (:a)     0.498766      0.363857     0.313591     0.303895      0.453926     0.0574657     0.443101     0.179118     0.39422       0.946817
  (:b)     0.0080239     0.544323     0.983931     0.0620305     0.589515     0.903863      0.114999     0.816759     0.377231      0.306352

julia> LoopVectorization.check_args(A)
false

Oh, hmm, that's surprising. It looks like it doesn't work with DimensionalData either. @rafaqz

ParadaCarleton avatar Sep 01 '21 21:09 ParadaCarleton

@chriselrod what ArrayInterface.jl methods do we have to implement for this to work?

rafaqz avatar Sep 01 '21 21:09 rafaqz

If it's just a simple wrapper, then all that is needed is

ArrayInterface.parent_type(::Type{<:YourArrayWrapper}) = ...

For example:

julia> using AxisKeys, ArrayInterface, LoopVectorization

julia> A = KeyedArray(rand(2,10), ([:a, :b], 10:10:100))
2-dimensional KeyedArray(...) with keys:
↓   2-element Vector{Symbol}
→   10-element StepRange{Int64,...}
And data, 2×10 Matrix{Float64}:
        (10)          (20)         (30)         (40)         (50)         (60)         (70)          (80)         (90)         (100)
  (:a)     0.0677124     0.755331     0.558675     0.213256     0.719723     0.195234     0.0587435     0.866621     0.42191       0.156516
  (:b)     0.761694      0.135312     0.386402     0.54806      0.994232     0.730863     0.128959      0.898721     0.971936      0.971892

julia> ArrayInterface.parent_type(::Type{<:KeyedArray{T,N,A}}) where {T,N,A} = A

julia> LoopVectorization.check_args(A)
true

julia> stridedpointer(A)
LayoutPointers.StridedPointer{Float64, 2, 1, 0, (1, 2), Tuple{Static.StaticInt{8}, Int64}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}}}(Ptr{Float64} @0x00007f1f3a82f5a0, ArrayInterface.StrideIndex{2, (1, 2), 1, Tuple{Static.StaticInt{8}, Int64}, Tuple{Static.StaticInt{1}, Static.StaticInt{1}}}((static(8), 16), (static(1), static(1))))

julia> stridedpointer(A) === stridedpointer(parent(A))
true

chriselrod avatar Sep 01 '21 21:09 chriselrod