Open MasonProtter opened 1 year ago
StrideArrays.jl pirates broadcasting + StrideArrays, using LoopVectorization.
The specific problem here is the adjoint unit range + loop vectorization's broadcast handling.
julia> using LoopVectorization
julia> B = rand(10,10); v = 1:10;
julia> @turbo B .= v .* v'
ERROR: conversion to pointer not defined for UnitRange{Int64}
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] unsafe_convert(::Type{Ptr{Int64}}, a::UnitRange{Int64})
@ Base ./pointer.jl:67
[3] unsafe_convert(::Type{Ptr{Int64}}, A::Adjoint{Int64, UnitRange{Int64}})
@ LinearAlgebra ~/Documents/languages/juliamaster/usr/share/julia/stdlib/v1.10/LinearAlgebra/src/adjtrans.jl:356
[4] pointer(x::Adjoint{Int64, UnitRange{Int64}})
@ Base ./abstractarray.jl:1232
[5] unsafe_convert(::Type{Ptr{Int64}}, A::LowDimArray{(false, true), Int64, 2, Adjoint{Int64, UnitRange{Int64}}})
@ LoopVectorization ~/.julia/dev/LoopVectorization/src/broadcast.jl:63
[6] pointer(x::LowDimArray{(false, true), Int64, 2, Adjoint{Int64, UnitRange{Int64}}})
@ Base ./abstractarray.jl:1232
[7] memory_reference(::ArrayInterface.CPUPointer, A::LowDimArray{(false, true), Int64, 2, Adjoint{Int64, UnitRange{Int64}}})
@ LayoutPointers ~/.julia/dev/LayoutPointers/src/stridedpointers.jl:21 [inlined]
[8] memory_reference(A::LowDimArray{(false, true), Int64, 2, Adjoint{Int64, UnitRange{Int64}}})
@ LayoutPointers ~/.julia/dev/LayoutPointers/src/stridedpointers.jl:18 [inlined]
[9] memory_reference(fb::LoopVectorization.ForBroadcast{Int64, 2, LowDimArray{(false, true), Int64, 2, Adjoint{Int64, UnitRange{Int64}}}})
@ LoopVectorization ~/.julia/dev/LoopVectorization/src/broadcast.jl:197 [inlined]
[10] stridedpointer_preserve(A::LoopVectorization.ForBroadcast{Int64, 2, LowDimArray{(false, true), Int64, 2, Adjoint{Int64, UnitRange{…}}}})
while without the adjoint, it works
julia> b = rand(10);
julia> @turbo b .= v .* v
10-element Vector{Float64}:
1.0
4.0
9.0
16.0
25.0
36.0
49.0
64.0
81.0
100.0
Note from the stack trace it has been converted into a "low-dim-array":
[10] stridedpointer_preserve(A::LoopVectorization.ForBroadcast{Int64, 2, LowDimArray{(false, true), Int64, 2, Adjoint{Int64, UnitRange{…}}}})
@ LayoutPointers ~/.julia/dev/LayoutPointers/src/stridedpointers.jl:100 [inlined]
Although we also get that for UnitRange
s:
julia> LoopVectorization.stridedpointer_preserve(v')
ERROR: "Memory access for Adjoint{Int64, UnitRange{Int64}} not implemented yet."
Stacktrace:
[1] memory_reference(::ArrayInterface.CPUIndex, A::Adjoint{Int64, UnitRange{Int64}})
@ LayoutPointers ~/.julia/dev/LayoutPointers/src/stridedpointers.jl:62 [inlined]
[2] memory_reference(A::Adjoint{Int64, UnitRange{Int64}})
@ LayoutPointers ~/.julia/dev/LayoutPointers/src/stridedpointers.jl:18 [inlined]
[3] stridedpointer_preserve(A::Adjoint{Int64, UnitRange{Int64}})
@ LayoutPointers ~/.julia/dev/LayoutPointers/src/stridedpointers.jl:100
[4] top-level scope
@ REPL[18]:1
Probably a few routes you could take to fixing this. Two ideas:
FastRange
type (i.e. what stridedpointer(1:10)
returns, and overloads to produce it here.add_broadcast
function: https://github.com/JuliaSIMD/LoopVectorization.jl/blob/5a4d58f66aef373371d6e0f45ecef60589952ac7/src/broadcast.jl#L480-L508
This works fine with StrideArraysCore.jl, but not with StrideArrays.jl