Limit number of threads from Threads.@threads

Is there any way to limit the number of threads used in Threads.@threads loops (for instance, use at most 3 threads)?

I have a nested function where both inner and outer function does multithreading, but due to memory constraints, I can only run a few outer i loops at the same time. For example, say I enable 24 threads, can I run at most 3 i indices in the outer loop and have the remaining threads run the inner?

The pseudo-code looks like the following

function inner(v)
    # memory intensive code that is multithreaded
end

function outer()
    Threads.@threads for i in 1:100
        inner(v) # I only want a few `i` to run here
    end
end
1 Like

Something like this?

function inner()
    # memory intensive code that is multithreaded
end

function outer()
    Threads.@threads for i in 1:3
        for j in i:3:100
            @show i, j
            inner() # I only want a few `i` to run here
        end
    end
end
1 Like

Quite generally, @threads shouldn’t be nested. You might want to switch to using Threads.@spawn instead (which can be nested arbitrarily).

Otherwise, the answer is no, there is no easy way to limit the number of threads used by @threads. Of course, you can always use @threads :static and manually split up and distribute the work among a subset of the threads. But this can become tedious, in particular with nesting, and you should really think about whether this is the right approach.

3 Likes

@threads shouldn’t be nested

I had always thought multithreading in Julia is composable (i.e. you can nest them as much as you want). Is composability restricted to just @spawn?

For now it is, yes. However, @threads will likely get more scheduler options in the future one of which will presumably have @spawn like composability properties (i.e. depth-first scheduling etc.). (Until recently, we only had @threads :static, now we also have @threads :dynamic, more to follow)

1 Like