# Toggle Threads.@threads with a variable

**URL:** <https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818>\
**Category:** General Usage\
**Created:** [November 20, 2021, 9:24am UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818 "2021-11-20T09:24:39Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![JackStrauss](https://avatars.discourse-cdn.com/v4/letter/j/f14d63/32.png) [@JackStrauss](https://discourse.julialang.org/u/JackStrauss)\
**Post date:** [November 20, 2021, 9:24am UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818/1 "2021-11-20T09:24:39Z")

</div>

Hello

I am sure the elegant answer is in the documentation, but I could not find it.

I use threads but sometimes want to execute same loop without threads. Is there a way to tell Julia not to use Threads.@threads if some variable, like DoThreads==false, without repeating the for loop with and without Threads.@threads

all the best, Jack

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 20, 2021, 11:53am UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818/2 "2021-11-20T11:53:38Z")

</div>

As far as I know, there is not.

I have used and have seen the use of

```julia
    if parallel && nthreads() > 1

```

In more than one package.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [November 20, 2021, 1:53pm UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818/3 "2021-11-20T13:53:26Z")

</div>

I sometime use a clever pattern which has been originally suggested [here](https://discourse.julialang.org/t/assert-alternatives/24775/14):

```julia
module MyModule

using Base.Threads

use_threads() = true

macro maybe_threads(code)
    return esc(:(
        if $(@ __MODULE__ ).use_threads()
            @threads($code)
        else
            $code
        end
    ))
end

function computation()
    @maybe_threads for i in 1:10
        @show i, threadid()
    end
end

end

```

which gives

```julia
julia> MyModule.computation()
(i, threadid()) = (3, 2)
(i, threadid()) = (4, 2)
(i, threadid()) = (1, 1)
(i, threadid()) = (2, 1)
(i, threadid()) = (10, 6)
(i, threadid()) = (7, 4)
(i, threadid()) = (8, 4)
(i, threadid()) = (9, 5)
(i, threadid()) = (5, 3)
(i, threadid()) = (6, 3)

julia> MyModule.use_threads() = false

julia> MyModule.computation()
(i, threadid()) = (1, 1)
(i, threadid()) = (2, 1)
(i, threadid()) = (3, 1)
(i, threadid()) = (4, 1)
(i, threadid()) = (5, 1)
(i, threadid()) = (6, 1)
(i, threadid()) = (7, 1)
(i, threadid()) = (8, 1)
(i, threadid()) = (9, 1)
(i, threadid()) = (10, 1)

julia> MyModule.use_threads() = true

julia> MyModule.computation()
(i, threadid()) = (5, 3)
(i, threadid()) = (9, 5)
(i, threadid()) = (3, 2)
(i, threadid()) = (4, 2)
(i, threadid()) = (10, 6)
(i, threadid()) = (6, 3)
(i, threadid()) = (1, 1)
(i, threadid()) = (2, 1)
(i, threadid()) = (7, 4)
(i, threadid()) = (8, 4)

```

---

<div class="post-metadata">

**Author:** ![Bruno\_Amorim](https://avatars.discourse-cdn.com/v4/letter/b/f6c823/32.png) [@Bruno\_Amorim](https://discourse.julialang.org/u/Bruno_Amorim)\
**Post date:** [November 20, 2021, 3:42pm UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818/4 "2021-11-20T15:42:24Z")

</div>

Another possibility would be to use [FLoops.jl](https://github.com/JuliaFolds/FLoops.jl)  
By doing

```julia
@floop ex for ...

```

The `ex` variable can be used to control the parallel execution. By setting `ex = ThreadedEx()` it uses multithreading, setting it to `ex = SequentialEx()` no threads are used.

---

<div class="post-metadata">

**Author:** ![JackStrauss](https://avatars.discourse-cdn.com/v4/letter/j/f14d63/32.png) [@JackStrauss](https://discourse.julialang.org/u/JackStrauss)\
**Post date:** [November 20, 2021, 5:46pm UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818/5 "2021-11-20T17:46:18Z")

</div>

Fantastic, thanks for all the suggestions. I knew Julia could do it! All look like they will solve my problem, and I will give all a spin. Floops.jl looks very nice! So many excellent Julia packages.

thanks again, Jack.

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [November 20, 2021, 11:34pm UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818/6 "2021-11-20T23:34:00Z")

</div>

For a _runtime_ flag, I recently rolled my own solution at [https://github.com/JuliaQuantumControl/QuantumControlBase.jl/blob/master/src/conditionalthreads.jl](https://github.com/JuliaQuantumControl/QuantumControlBase.jl/blob/master/src/conditionalthreads.jl), as discussed in [Optional macro invocation - #21 by goerz](https://discourse.julialang.org/t/optional-macro-invocation/18588/21)

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [November 21, 2021, 1:02am UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818/7 "2021-11-21T01:02:47Z")

</div>

For non-library uses, “toggling” `Threads.@threads` with a macro that generates two versions is a decent solution.

For library authors, I strongly recommend specifying the _size of the base case_ rather than the number of tasks used. In JuliaFolds packages such as FLoops.jl, it is called the `basesize`. The idea is to determine the “size” of the sub-problem such that computation of it takes roughly at least (say) a few hundred of microseconds. Here, `basesize` is of arbitrary unit. For example, for linear-time computation (e.g., `map`), it can be the number of elements. This way, you’d only spawn roughly `ntasks = size_of_the_whole_problem / basesize` tasks. If the size of the whole problem is not big enough, it’d only consume `ntasks` CPUs. This is a very important property for composable parallel programs since other components in your program may want to use the CPUs. Furthermore, since a program using this strategy will automatically degenerate to a single-thread program when the problem size is small enough (i.e., it is not worth spawning tasks), you don’t need to implement the extra mechanism for toggling the run-time option.

---

<div class="post-metadata">

**Author:** ![JackStrauss](https://avatars.discourse-cdn.com/v4/letter/j/f14d63/32.png) [@JackStrauss](https://discourse.julialang.org/u/JackStrauss)\
**Post date:** [November 21, 2021, 7:55am UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818/8 "2021-11-21T07:55:01Z")

</div>

Thanks goerz,

Your solution worked brilliantly. @floop didn’t work since it complained about local variables and race conditions. I am realising from your answer and tktf’s suggestion, I better learn macro programming. It should be super helpful.

Thanks again everybody, it is due to the excellence of Julia and the friendliness of the community that those of us who are python and R refugees find is so easy to move over.

best, jack

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [November 21, 2021, 10:25pm UTC](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818/9 "2021-11-21T22:25:48Z")

</div>

There’s no need to learn macro meta programming to use Julia. In fact, it is a common pitfall that people write non-composable programs with macros (and `@generated` functions) when more straightforward abstraction with plain functions and types is possible.

`@floop` macro is just a short hand for calling `Folds.reduce`. As mentioned in the “Manual reductions” section of my tutorial [A quick introduction to data parallelism in Julia](https://juliafolds.github.io/data-parallelism/tutorials/quick-introduction/#manual_reductions), you can manually call `Folds.reduce` without using any macros.
