LoopVectorization.jl
LoopVectorization.jl copied to clipboard
Segmentation fault for `PermutedDimsArray` with `ndims > 8`
I'm seeing segmentation faults for operations with PermutedDimsArray with ndims > 8:
using LoopVectorization
function permutedims_lv(A, p)
Ap = PermutedDimsArray(A, p)
B = similar(Ap)
@turbo B .= Ap
return B
end
function main(ndims, d)
A = randn(ntuple(Returns(d), ndims))
p = tuple(reverse(1:ndims)...)
B1 = @time permutedims_lv(A, p)
B2 = @time permutedims(A, p)
return B1 ≈ B2
end
This runs fine for ndims ≤ 8 and gives a nice speedup over Base.permutedims:
julia> main(8, 10)
0.679227 seconds (13 allocations: 762.940 MiB)
1.345448 seconds (3 allocations: 762.940 MiB, 0.04% gc time)
true
However I see a segmentation fault for ndims > 8:
Segmentation fault output:
julia> main(9, 2)
signal (11): Segmentation fault
in expression starting at REPL[3]:1
setindex! at ./array.jl:903 [inlined]
rank_to_sortperm at /home/mfishman/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:269 [inlined]
_create_mrefs! at /home/mfishman/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:468
create_mrefs! at /home/mfishman/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:423
unknown function (ip: 0x7fa94fd3216f)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
avx_loopset! at /home/mfishman/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:858
unknown function (ip: 0x7fa950d7d7b9)
_turbo_loopset at /home/mfishman/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:929
unknown function (ip: 0x7fa950d7d791)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
#s191#85 at /home/mfishman/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:970 [inlined]
#s191#85 at ./none:0
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
GeneratedFunctionStub at ./boot.jl:580
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
jl_call_staged at /buildworker/worker/package_linux64/build/src/method.c:431
jl_code_for_staged at /buildworker/worker/package_linux64/build/src/method.c:482
get_staged at ./compiler/utilities.jl:111
retrieve_code_info at ./compiler/utilities.jl:123 [inlined]
InferenceState at ./compiler/inferencestate.jl:234
typeinf_edge at ./compiler/typeinfer.jl:814 [inlined]
abstract_call_method at ./compiler/abstractinterpretation.jl:504
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:105
abstract_call_known at ./compiler/abstractinterpretation.jl:1342
abstract_call at ./compiler/abstractinterpretation.jl:1397
abstract_apply at ./compiler/abstractinterpretation.jl:987
abstract_call_known at ./compiler/abstractinterpretation.jl:1249
abstract_call at ./compiler/abstractinterpretation.jl:1397
abstract_call at ./compiler/abstractinterpretation.jl:1382
abstract_eval_statement at ./compiler/abstractinterpretation.jl:1534
typeinf_local at ./compiler/abstractinterpretation.jl:1918
typeinf_nocycle at ./compiler/abstractinterpretation.jl:2014
_typeinf at ./compiler/typeinfer.jl:226
typeinf at ./compiler/typeinfer.jl:209
typeinf_edge at ./compiler/typeinfer.jl:823 [inlined]
abstract_call_method at ./compiler/abstractinterpretation.jl:504
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:105
abstract_call_known at ./compiler/abstractinterpretation.jl:1342
abstract_call at ./compiler/abstractinterpretation.jl:1397
abstract_call at ./compiler/abstractinterpretation.jl:1382
abstract_eval_statement at ./compiler/abstractinterpretation.jl:1534
typeinf_local at ./compiler/abstractinterpretation.jl:1918
typeinf_nocycle at ./compiler/abstractinterpretation.jl:2014
_typeinf at ./compiler/typeinfer.jl:226
typeinf at ./compiler/typeinfer.jl:209
typeinf_ext at ./compiler/typeinfer.jl:909
typeinf_ext_toplevel at ./compiler/typeinfer.jl:942
typeinf_ext_toplevel at ./compiler/typeinfer.jl:938
jfptr_typeinf_ext_toplevel_11534.clone_1 at /home/mfishman/software/julia-1.7.3/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
jl_type_infer at /buildworker/worker/package_linux64/build/src/gf.c:295
jl_generate_fptr at /buildworker/worker/package_linux64/build/src/jitlayers.cpp:338
jl_compile_method_internal at /buildworker/worker/package_linux64/build/src/gf.c:1980
jl_compile_method_internal at /buildworker/worker/package_linux64/build/src/gf.c:2246 [inlined]
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2239 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
permutedims_lv at /home/mfishman/Dropbox (Simons Foundation)/workdir/LoopVectorization.jl/permuteddimsarray_bug.jl:6
unknown function (ip: 0x7fa94fd2f501)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
macro expansion at ./timing.jl:220 [inlined]
main at /home/mfishman/Dropbox (Simons Foundation)/workdir/LoopVectorization.jl/permuteddimsarray_bug.jl:13
unknown function (ip: 0x7fa950d50e7c)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:126
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:215
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:166 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:587
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:731
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:885
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:830
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:830
jl_toplevel_eval_in at /buildworker/worker/package_linux64/build/src/toplevel.c:944
eval at ./boot.jl:373 [inlined]
eval_user_input at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.7/REPL/src/REPL.jl:150
repl_backend_loop at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.7/REPL/src/REPL.jl:246
start_repl_backend at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.7/REPL/src/REPL.jl:231
#run_repl#47 at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.7/REPL/src/REPL.jl:364
run_repl at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.7/REPL/src/REPL.jl:351
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
#936 at ./client.jl:394
jfptr_YY.936_35454.clone_1 at /home/mfishman/software/julia-1.7.3/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
jl_f__call_latest at /buildworker/worker/package_linux64/build/src/builtins.c:757
#invokelatest#2 at ./essentials.jl:716 [inlined]
invokelatest at ./essentials.jl:714 [inlined]
run_main_repl at ./client.jl:379
exec_options at ./client.jl:309
_start at ./client.jl:495
jfptr__start_22567.clone_1 at /home/mfishman/software/julia-1.7.3/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2247 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2429
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1788 [inlined]
true_main at /buildworker/worker/package_linux64/build/src/jlapi.c:559
jl_repl_entrypoint at /buildworker/worker/package_linux64/build/src/jlapi.c:701
main at julia (unknown line)
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x400808)
Allocations: 915749038 (Pool: 915736438; Big: 12600); GC: 89
[1] 90991 segmentation fault (core dumped) julia
Version information:
julia> versioninfo()
Julia Version 1.7.3
Commit 742b9abb4d (2022-05-06 12:58 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Xeon(R) E-2176M CPU @ 2.70GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-12.0.1 (ORCJIT, skylake)
Environment:
JULIA_EDITOR = vim
julia> using Pkg; Pkg.status("LoopVectorization")
Status `~/.julia/environments/v1.7/Project.toml`
[bdcacae8] LoopVectorization v0.12.121
Hmm, are you running with --check-bounds=no?
I tried your example and got
julia> main(9,2)
ERROR: BoundsError: attempt to access 9-element Vector{Bool} at index [1099512283137]
Stacktrace:
[1] getindex
@ ./essentials.jl:13 [inlined]
[2] permute_mref!(ar::LoopVectorization.ArrayReferenceMeta, C::Int64, sp::Vector{Int64})
@ LoopVectorization ~/.julia/dev/LoopVectorization/src/reconstruct_loopset.jl:360
[3] _add_mref!(sptrs::Expr, ls::LoopVectorization.LoopSet, ar::LoopVectorization.ArrayReferenceMeta, T_sym::Symbol, C::Int64, B::Int64, sp::Vector{Int64}, name::Symbol)
@ LoopVectorization ~/.julia/dev/LoopVectorization/src/reconstruct_loopset.jl:316
[4] add_mref!(sptrs::Expr, ls::LoopVectorization.LoopSet, ar::LoopVectorization.ArrayReferenceMeta, #unused#::Type{Ptr{Float64}}, C::Int64, B::Int64, sp::Vector{Int64}, name::Symbol)
@ LoopVectorization ~/.julia/dev/LoopVectorization/src/reconstruct_loopset.jl:294
[5] _create_mrefs!(ls::LoopVectorization.LoopSet, arf::Vector{LoopVectorization.ArrayRefStruct}, as::Vector{Symbol}, os::Vector{Symbol}, nopsv::Vector{Int64}, expanded::Vector{Bool}, P::Core.SimpleVector, C::Vector{Int64}, B::Vector{Int64}, R::Vector{Tuple{NTuple{8, Int64}, Int64}})
@ LoopVectorization ~/.julia/dev/LoopVectorization/src/reconstruct_loopset.jl:470
[6] create_mrefs!(ls::LoopVectorization.LoopSet, arf::Vector{LoopVectorization.ArrayRefStruct}, as::Vector{Symbol}, os::Vector{Symbol}, nopsv::Vector{Int64}, expanded::Vector{Bool}, #unused#::Type{LayoutPointers.GroupedStridedPointers{Tuple{Ptr{Float64}, Ptr{Float64}}, (9, 1), (0, 0), ((9, 8, 7, 6, 5, 4, 3, 2, 1), (1, 2, 3, 4, 5, 6, 7, 8, 9)), ((1, 2, 3, 4, 5, 6, 7, 8, 9), (10, 11, 12, 13, 14, 15, 16, 17, 18)), Tuple{Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Static.StaticInt{8}, Static.StaticInt{8}, Vararg{Int64, 8}}, NTuple{18, Static.StaticInt{0}}}})
@ LoopVectorization ~/.julia/dev/LoopVectorization/src/reconstruct_loopset.jl:423
This looks like roughly the same region as your segfault came from.
That's weird, indeed it seems like bounds checking is being turned off for me. When I start Julia with:
julia --check-bounds=yes
I see:
julia> main(9, 2)
ERROR: BoundsError: attempt to access NTuple{8, Int64} at index [9]
Stacktrace:
[1] getindex
@ ./tuple.jl:29 [inlined]
[2] rank_to_sortperm
@ ~/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:269 [inlined]
[3] _create_mrefs!(ls::LoopVectorization.LoopSet, arf::Vector{LoopVectorization.ArrayRefStruct}, as::Vector{Symbol}, os::Vector{Symbol}, nopsv::Vector{Int64}, expanded::Vector{Bool}, P::Core.SimpleVector, C::Vector{Int64}, B::Vector{Int64}, R::Vector{Tuple{NTuple{8, Int64}, Int64}})
@ LoopVectorization ~/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:468
[4] create_mrefs!(ls::LoopVectorization.LoopSet, arf::Vector{LoopVectorization.ArrayRefStruct}, as::Vector{Symbol}, os::Vector{Symbol}, nopsv::Vector{Int64}, expanded::Vector{Bool}, #unused#::Type{LayoutPointers.GroupedStridedPointers{Tuple{Ptr{Float64}, Ptr{Float64}}, (9, 1), (0, 0), ((9, 8, 7, 6, 5, 4, 3, 2, 1), (1, 2, 3, 4, 5, 6, 7, 8, 9)), ((1, 2, 3, 4, 5, 6, 7, 8, 9), (10, 11, 12, 13, 14, 15, 16, 17, 18)), Tuple{Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Static.StaticInt{8}, Static.StaticInt{8}, Int64, Int64, Int64, Int64, Int64, Int64, Int64, Int64}, NTuple{18, Static.StaticInt{0}}}})
@ LoopVectorization ~/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:423
[5] avx_loopset!(ls::LoopVectorization.LoopSet, instr::Vector{LoopVectorization.Instruction}, ops::Vector{LoopVectorization.OperationStruct}, arf::Vector{LoopVectorization.ArrayRefStruct}, AM::Vector{Any}, LPSYM::Vector{Any}, LB::Core.SimpleVector, vargs::Core.SimpleVector)
@ LoopVectorization ~/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:858
[6] _turbo_loopset(OPSsv::Any, ARFsv::Any, AMsv::Any, LPSYMsv::Any, LBsv::Core.SimpleVector, vargs::Core.SimpleVector, UNROLL::Tuple{Bool, Int8, Int8, Int8, Bool, Int64, Int64, Int64, Int64, Int64, Int64, Int64, UInt64})
@ LoopVectorization ~/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:929
[7] #s191#85
@ ~/.julia/packages/LoopVectorization/jHQO4/src/reconstruct_loopset.jl:970 [inlined]
[8] var"#s191#85"(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, vargs#::Any, ::Any, #unused#::Type, #unused#::Type, #unused#::Type, #unused#::Type, #unused#::Type, #unused#::Any, var#arguments#::Any)
@ LoopVectorization ./none:0
[9] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any})
@ Core ./boot.jl:580
[10] macro expansion
@ ~/.julia/packages/LoopVectorization/jHQO4/src/broadcast.jl:540 [inlined]
[11] vmaterialize!
@ ~/.julia/packages/LoopVectorization/jHQO4/src/broadcast.jl:540 [inlined]
[12] vmaterialize!(dest::Array{Float64, 9}, bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{9}, Nothing, typeof(identity), Tuple{PermutedDimsArray{Float64, 9, (9, 8, 7, 6, 5, 4, 3, 2, 1), (9, 8, 7, 6, 5, 4, 3, 2, 1), Array{Float64, 9}}}}, #unused#::Val{:Main}, #unused#::Val{(true, 0, 0, 0, true, 0, 32, 15, 64, 32768, 262144, 12582912, 0x0000000000000001, 1)})
@ LoopVectorization ~/.julia/packages/LoopVectorization/jHQO4/src/broadcast.jl:664
[13] permutedims_lv(A::Array{Float64, 9}, p::NTuple{9, Int64})
@ Main ~/Dropbox (Simons Foundation)/workdir/LoopVectorization.jl/permuteddimsarray_bug.jl:6
[14] macro expansion
@ ./timing.jl:220 [inlined]
[15] main(ndims::Int64, d::Int64)
@ Main ~/Dropbox (Simons Foundation)/workdir/LoopVectorization.jl/permuteddimsarray_bug.jl:13
[16] top-level scope
@ REPL[3]:1
Before I was just starting Julia with:
julia
so for some reason my bounds checking is being turned off by default? I think I installed the executable using UpdateJulia.jl.
Interesting. Of course, it shouldn't be throwing at all. But throwing is a lot nicer than crashing.