使用 @view 导致Julia崩溃

各位好,我在运行如下代码时,每次都会导致Julia崩溃

using LinearAlgebra
using SpecialFunctions
using BenchmarkTools

function main(θ::Array{Float64,1}, ε::Array{Float64,1}, t::Array{Float64,1}, h::Float64)
    α = θ[1]
    b = θ[2]
    σ = zeros(size(ε))
    ω = cumprod(vcat(1, (1 .- (α.+1)./(1:length(ε)-1))))
    
    for i = 1:length(t)
        w_t = @view ω[1:i]
        σ = σ .- σ[1]
        y_t = @view σ[i:-1:1]
        σ[i] = h^(-α)*dot(w_t, y_t)
    end
    σ = @. b*(σ + ε*t^(-α) / gamma(1-α))
    return σ
end

α = 0.3
h = 0.0001
t = collect(0:h:2)
θ = [α, 5.0]
ε = 1.0 .* ones(size(t))

@btime main(θ, ε, t, h)`

并得到如下的错误信息


signal (11): Segmentation fault: 11

in expression starting at /Users/abc/julia/frac_visco_1d_test1.jl:58

dot_compute at /Applications/Julia-1.5.app/Contents/Resources/julia/lib/julia/libopenblas64_.0.3.9.dylib (unknown line)

dot_thread_function at /Applications/Julia-1.5.app/Contents/Resources/julia/lib/julia/libopenblas64_.0.3.9.dylib (unknown line)

legacy_exec at /Applications/Julia-1.5.app/Contents/Resources/julia/lib/julia/libopenblas64_.0.3.9.dylib (unknown line)

exec_blas at /Applications/Julia-1.5.app/Contents/Resources/julia/lib/julia/libopenblas64_.0.3.9.dylib (unknown line)

blas_level1_thread_with_return_value at /Applications/Julia-1.5.app/Contents/Resources/julia/lib/julia/libopenblas64_.0.3.9.dylib (unknown line)

ddot_k_SANDYBRIDGE at /Applications/Julia-1.5.app/Contents/Resources/julia/lib/julia/libopenblas64_.0.3.9.dylib (unknown line)

dot at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/LinearAlgebra/src/blas.jl:320

dot at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/LinearAlgebra/src/blas.jl:369

dot at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/LinearAlgebra/src/matmul.jl:9 [inlined]

computesigma! at /Users/abc/julia/frac_visco_1d_test1.jl:37

main at /Users/abc/julia/frac_visco_1d_test1.jl:46

unknown function (ip: 0x125750ea2)

jl_apply at /Users/julia/buildbot/worker/package_macos64/build/src/./julia.h:1690 [inlined]

do_call at /Users/julia/buildbot/worker/package_macos64/build/src/interpreter.c:117

eval_body at /Users/julia/buildbot/worker/package_macos64/build/src/interpreter.c:428

eval_body at /Users/julia/buildbot/worker/package_macos64/build/src/interpreter.c:492

jl_interpret_toplevel_thunk at /Users/julia/buildbot/worker/package_macos64/build/src/interpreter.c:660

jl_toplevel_eval_flex at /Users/julia/buildbot/worker/package_macos64/build/src/toplevel.c:840

jl_parse_eval_all at /Users/julia/buildbot/worker/package_macos64/build/src/ast.c:913

include_string at ./loading.jl:1088

include_string at ./loading.jl:1096 [inlined]

#216 at /Users/abc/.julia/packages/Atom/ZeFbA/src/eval.jl:174

withpath at /Users/abc/.julia/packages/CodeTools/VsjEq/src/utils.jl:30

unknown function (ip: 0x112e4d6b8)

withpath at /Users/abc/.julia/packages/Atom/ZeFbA/src/eval.jl:9

#215 at /Users/abc/.julia/packages/Atom/ZeFbA/src/eval.jl:171

unknown function (ip: 0x112e4ccac)

with_logstate at ./logging.jl:408

with_logger at ./logging.jl:514 [inlined]

#214 at /Users/abc/.julia/packages/Atom/ZeFbA/src/eval.jl:170 [inlined]

hideprompt at /Users/abc/.julia/packages/Atom/ZeFbA/src/repl.jl:127

macro expansion at /Users/abc/.julia/packages/Media/ItEPc/src/dynamic.jl:24 [inlined]

evalall at /Users/abc/.julia/packages/Atom/ZeFbA/src/eval.jl:160

jl_apply at /Users/julia/buildbot/worker/package_macos64/build/src/./julia.h:1690 [inlined]

do_apply at /Users/julia/buildbot/worker/package_macos64/build/src/builtins.c:655

jl_f__apply at /Users/julia/buildbot/worker/package_macos64/build/src/builtins.c:669 [inlined]

jl_f__apply_latest at /Users/julia/buildbot/worker/package_macos64/build/src/builtins.c:705

#invokelatest#1 at ./essentials.jl:710

jl_apply at /Users/julia/buildbot/worker/package_macos64/build/src/./julia.h:1690 [inlined]

do_apply at /Users/julia/buildbot/worker/package_macos64/build/src/builtins.c:655

invokelatest at ./essentials.jl:709

jl_apply at /Users/julia/buildbot/worker/package_macos64/build/src/./julia.h:1690 [inlined]

do_apply at /Users/julia/buildbot/worker/package_macos64/build/src/builtins.c:655

macro expansion at /Users/abc/.julia/packages/Atom/ZeFbA/src/eval.jl:41 [inlined]

#184 at ./task.jl:356

unknown function (ip: 0x112d7e47c)

jl_apply at /Users/julia/buildbot/worker/package_macos64/build/src/./julia.h:1690 [inlined]

start_task at /Users/julia/buildbot/worker/package_macos64/build/src/task.c:707

Allocations: 73450598 (Pool: 73377110; Big: 73488); GC: 2220

在删除了@view之后,代码可以正常运行。个人觉得是因为使用@view之后内存分配出现了问题。请问大家这个问题怎么解决?谢谢。

我这边能正常运行:

julia> versioninfo()
Julia Version 1.5.1
Commit 697e782ab8 (2020-08-25 20:08 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin19.5.0)
  CPU: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
  JULIA_NUM_THREADS = 8
  JULIA_PKG_SERVER = https://mirrors.bfsu.edu.cn/julia

julia> @btime main(θ, ε, t, h);
  1.385 s (159536 allocations: 2.99 GiB)

很奇怪,我在 Windows 10 和 macOS 下(不同PC)都试了几次,每次Julia都会崩溃。

我这边也会段错误……

发生段错误的行在这里

之前的说法有问题,错误在dot函数里,具体原因不太清楚,可能是bug,如果用@view,试下
dot(x,y)=sum(x.*y),不考虑并行的话,大约多花15%的时间。

这一行

改为@. σ = σ - σ[1]
我不太清楚这段代码含义,你在赋值过程中是否需要生成新的σ变量吗,如果不需要就改为下面这个。我测试了下在8G内存的电脑上,i大约在1000多就会崩溃,128G内存能够到18000多;h如果取大些,程序就可能顺利运行。可能是由于运行时申请的虚拟内存没有完全回收(?)导致的。

这段代码我写的有点问题,应该写作

y_t = @view σ[i:-1:1] .- σ[1]

每个σ[i] 都是由是由σ[1:i-1]计算所得,所以每次循环都会对 σ 进行赋值。你对于这种情况下的优化有什么建议吗?

那么请问有什么办法可以完全回收虚拟内存吗?

除了段错误的问题外,在dot函数中使用view反向索引可能导致计算结果不正确。

julia> using LinearAlgebra

julia> a = ones(3)
3-element Array{Float64,1}:
 1.0
 1.0
 1.0

julia> b = @view a[3:-1:1]
3-element view(::Array{Float64,1}, 3:-1:1) with eltype Float64:
 1.0
 1.0
 1.0

julia> a⋅a
3.0

julia> a⋅b
1.0

这个基本可以确定是bug了,所以你的σ[i:-1:1]不要使用view。
具体可以看:

1 个赞