How to make use of Threads optional in a Julia function

Viewed 113

I have a function that optionally uses threads for its main loop, doing so when an argument usingthreads is true. At the moment, the code looks like this:

function dosomething(usingthreads::Bool)
    n = 1000
    if usingthreads
        Threads.@threads for i = 1:n
            #20 lines of code here
        end
    else
        for i = 1:n
            #same 20 lines of code repeated here
        end
    end
end

Less nasty than the above would be to put the "20 lines" in a separate function. Is there another way?

2 Answers

You could use a macro that changes its behavior depending on the result of Threads.nthreads():

macro maybe_threaded(ex)
    if Threads.nthreads() == 1
        return esc(ex)
    else
        return esc(:(Threads.@threads $ex))
    end
end

Without threading, this macro will be a no-op:

julia> @macroexpand @maybe_threaded for i in 1:5
           print(i)
       end
:(for i = 1:5
      #= REPL[2]:2 =#
      print(i)
  end)

But when threading is enabled and e.g. JULIA_NUM_THREADS=4 it will expand to the threaded version:

julia>  @maybe_threaded for i in 1:5
           print(i)
       end
41325

Edit: Upon rereading the question, I realize this doesn't really answer it but it might be useful anyway.

You can use ThreadsX as suggested in this discourse link.

The answer from the thread (all credit to oxinabox):

using ThreadsX

function foo(multi_thread=true)
    _foreach = multi_thread ? ThreadsX.foreach : Base.foreach
    _foreach(1:10) do ii
        @show ii
    end
end
Related