Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Threads are disabled if an error occurs #32970

Closed
ranocha opened this issue Aug 20, 2019 · 2 comments · Fixed by #33034
Closed

Threads are disabled if an error occurs #32970

ranocha opened this issue Aug 20, 2019 · 2 comments · Fixed by #33034
Labels
bug Indicates an unexpected problem or unintended behavior multithreading Base.Threads and related functionality
Milestone

Comments

@ranocha
Copy link
Member

ranocha commented Aug 20, 2019

When an error is thrown in a threaded loop, only one thread is used in threaded loops thereafter.

julia> function f!(a)
           Threads.@threads for i in eachindex(a)
               a[i] = Threads.threadid()
           end
           a
       end
f! (generic function with 1 method)

julia> function g!(a)
           Threads.@threads for i in eachindex(a)
               sleep(Threads.threadid())
               a[i] = log(-Threads.threadid())
           end
           a
       end
g! (generic function with 1 method)

julia> a = zeros(Threads.nthreads())
6-element Array{Float64,1}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

julia> f!(a)
6-element Array{Float64,1}:
 1.0
 2.0
 3.0
 4.0
 5.0
 6.0

julia> g!(a)
ERROR: TaskFailedException:
DomainError with -1.0:
log will only return a complex result if called with a complex argument. Try log(Complex(x)).
Stacktrace:
 [1] throw_complex_domainerror(::Symbol, ::Float64) at ./math.jl:32
 [2] log(::Float64) at ./special/log.jl:285
 [3] macro expansion at ./special/log.jl:395 [inlined]
 [4] (::var"##19#threadsfor_fun#4"{Array{Float64,1},Base.OneTo{Int64}})(::Bool) at ./threadingconstructs.jl:64
 [5] (::var"##19#threadsfor_fun#4"{Array{Float64,1},Base.OneTo{Int64}})() at ./threadingconstructs.jl:31
Stacktrace:
 [1] wait(::Task) at ./task.jl:251
 [2] macro expansion at ./threadingconstructs.jl:75 [inlined]
 [3] g!(::Array{Float64,1}) at ./REPL[2]:2
 [4] top-level scope at REPL[5]:1

julia> a
6-element Array{Float64,1}:
 1.0
 2.0
 3.0
 4.0
 5.0
 6.0

julia> f!(a)
6-element Array{Float64,1}:
 1.0
 1.0
 1.0
 1.0
 1.0
 1.0

julia> Threads.nthreads()
6

This is on Julia v1.3.0-rc1.0. Julia v1.2.0-rc2.0 behaves similar (only a slightly different error message). I'm using the generic Linux x86_64 binaries.

As mentioned by @c42f in https://discourse.julialang.org/t/threads-are-disabled-if-an-error-occurs/27738, this is a bug.

@c42f
Copy link
Member

c42f commented Aug 20, 2019

Thanks for the bug report!

This seems to occur because the C code jl_threading_run can throw, but the julia code doesn’t expect it to and omits to reset the global(!) variable Threads.in_threaded_loop.

See also discussion about dynamic scheduling at #21017 and #32207. I guess we'd want @threads to do dynamic scheduling by default in the new system.

@c42f c42f added bug Indicates an unexpected problem or unintended behavior multithreading Base.Threads and related functionality labels Aug 21, 2019
@c42f c42f added this to the 1.3 milestone Aug 21, 2019
@JeffBezanson
Copy link
Member

This is fixed by #32477

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior multithreading Base.Threads and related functionality
Projects
None yet
3 participants