# @threads in array comprehension

**URL:** <https://discourse.julialang.org/t/threads-in-array-comprehension/24072>\
**Category:** Julia at Scale\
**Tags:** proposal\
**Created:** [May 10, 2019, 1:09pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072 "2019-05-10T13:09:03Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![samo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samo/32/35398_2.png) [@samo](https://discourse.julialang.org/u/samo)\
**Post date:** [May 10, 2019, 1:09pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/1 "2019-05-10T13:09:03Z")

</div>

This is just a feature suggestion. It would be nice it the @threads macro would work also inside array comprehensions as:

```julia
[i @threads for i=1:4]

```

I.e. that example should produce the same result as:

```julia
julia> [i for i=1:4]
4-element Array{Int64,1}:
 1
 2
 3
 4

```

Yet, currently it is not supported:

```julia
julia> [i @threads for i=1:4]
ERROR: syntax: invalid comprehension syntax

```

Thanks!

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [May 10, 2019, 7:44pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/2 "2019-05-10T19:44:41Z")

</div>

That’s a nice idea. Maybe open an issue on GitHub? [https://github.com/JuliaLang/julia/issues/new](https://github.com/JuliaLang/julia/issues/new)

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [May 10, 2019, 8:06pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/3 "2019-05-10T20:06:19Z")

</div>

Why not `@threads [i for i in 1:4]`?

---

<div class="post-metadata">

**Author:** ![samo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samo/32/35398_2.png) [@samo](https://discourse.julialang.org/u/samo)\
**Post date:** [May 10, 2019, 9:02pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/4 "2019-05-10T21:02:35Z")

</div>

Because to my understanding the @threads macro applies to the for loop it stands before. This doesn’t come out in my example,but  
`[i @threads for i in 1:4 for j in 1:3]`  
would not be the same as:  
`[i for i in 1:4 @threads for j in 1:3]`.  
In the first case, the parallelization would be over `i`, in the second case over `j`.

---

<div class="post-metadata">

**Author:** ![samo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samo/32/35398_2.png) [@samo](https://discourse.julialang.org/u/samo)\
**Post date:** [May 10, 2019, 9:06pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/5 "2019-05-10T21:06:03Z")

</div>

> [@Mason](#):
>
> That’s a nice idea. Maybe open an issue on GitHub? [Sign in to GitHub · GitHub](https://github.com/JuliaLang/julia/issues/new)

Done: [@threads in array comprehension · Issue #32000 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/32000)

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [May 10, 2019, 9:27pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/6 "2019-05-10T21:27:45Z")

</div>

Yes, but wouldn’t it be nice to put the macro in front of a comprehension (or a broadcast) to have it run threaded?

```julia
@threads x = sin.(pi/L.*1:1500000) .+ cos.(3*pi/L.1:1500000)

```

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [May 10, 2019, 9:42pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/7 "2019-05-10T21:42:08Z")

</div>

There’s also a technical reason to prefer `@threads [x for x in xs]` — it can work without any parser changes.

```julia
julia> :([x @threads for x in xs])
ERROR: syntax: invalid comprehension syntax

julia> :(@threads [x for x in xs])
:(#= REPL[2]:1 =# @threads [x for x = xs])

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [May 10, 2019, 10:07pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/8 "2019-05-10T22:07:55Z")

</div>

Some broadcasts can already be multi-threaded:

```julia
julia> using Strided

julia> v = pi/50 .* (1:15_000_000) |> collect;

julia> @time x = sin.(v) .+ cos.(v);
  0.421032 seconds (12 allocations: 114.441 MiB, 13.27% gc time)

julia> @time x = @strided sin.(v) .+ cos.(v);
  0.188288 seconds (28 allocations: 114.442 MiB, 7.12% gc time)

```

It would indeed be nice to have something similar for comprehensions too.

---

<div class="post-metadata">

**Author:** ![samo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samo/32/35398_2.png) [@samo](https://discourse.julialang.org/u/samo)\
**Post date:** [May 11, 2019, 11:05am UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/9 "2019-05-11T11:05:58Z")

</div>

Maybe then @threads could take a keyword argument e.g. something like

```julia
@threads indices=(i, j) [i for i=1:4, j=1:3, k=1:5]

```

As you brought up the topic of broadcast, this could maybe be analogically done like this

```julia
@threads dims=(1,2) B .= sin.(A) .+ cos.(A);

```

assuming A and B are both arrays with 2 or more dimensions.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [May 11, 2019, 11:52am UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/10 "2019-05-11T11:52:38Z")

</div>

I am going to make a broad statement and say  
macros are the wrong tool for the job.  
(the current use of `@threads` included)

`thread_map(f, xs)` is the right tool,  
and we should have that. which would for your example me  
`thread_map(identity, 1:4)`.

Ontop of such functions it is easy to build some macro based DSL,  
if you want.  
Or to build an Array type that automatically dispatches to using multiple threads,  
when using normal `map`  
etc.

---

<div class="post-metadata">

**Author:** ![Jordan\_Cluts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jordan_cluts/32/13753_2.png) [@Jordan\_Cluts](https://discourse.julialang.org/u/Jordan_Cluts)\
**Post date:** [May 11, 2019, 11:55am UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/11 "2019-05-11T11:55:53Z")

</div>

Do you (or anyone else) know why @threads was implemented as a macro instead of as a function?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [May 11, 2019, 3:48pm UTC](https://discourse.julialang.org/t/threads-in-array-comprehension/24072/12 "2019-05-11T15:48:28Z")

</div>

If anyone is interested in such a threaded map, an implementation is available here  
[https://github.com/mohamed82008/KissThreading.jl](https://github.com/mohamed82008/KissThreading.jl)
