# Assignment not effective in \`@spawn\` in function

**URL:** <https://discourse.julialang.org/t/assignment-not-effective-in-spawn-in-function/52382>\
**Category:** General Usage\
**Tags:** multithreading\
**Created:** [December 25, 2020, 8:26pm UTC](https://discourse.julialang.org/t/assignment-not-effective-in-spawn-in-function/52382 "2020-12-25T20:26:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [December 25, 2020, 8:26pm UTC](https://discourse.julialang.org/t/assignment-not-effective-in-spawn-in-function/52382/1 "2020-12-25T20:26:06Z")

</div>

Define a simple function copying the contents of one array to another:

```julia
function copy_array!(array_t::AbstractArray, array_s::AbstractArray)
    array_t .= array_s

    return nothing
end

```

The following function performs the above function with and without `@spawn` and compares the results:

```julia
using Base.Threads: @spawn
using LinearAlgebra: norm

function test_spawned_copy()
    N = 1000
    A = rand(N);
    B = zeros(N);
    C = zeros(N);

    copy_array!(B, A)
    @spawn copy_array!(C, A)

    println("‖A‖ = $(norm(A))\n‖B‖ = $(norm(B))\n‖C‖ = $(norm(C))")
end

```

Executing the above function, we realize that `copy_array!` is not effective with `@spawn`:

```julia
julia> test_spawned_copy()
‖A‖ = 18.176417571506622
‖B‖ = 18.176417571506622
‖C‖ = 0.0 # assignment in array C didn't occur

```

However, if the contents of the above test function are executed in REPL, `copy_array!` produces the same results with and without `@spawn`:

```julia
julia> N = 1000;

julia> A = rand(N);

julia> B = zeros(N);

julia> C = zeros(N);

julia> copy_array!(B, A);

julia> @spawn copy_array!(C, A);

julia> println("‖A‖ = $(norm(A))\n‖B‖ = $(norm(B))\n‖C‖ = $(norm(C))");
‖A‖ = 18.054455128272014
‖B‖ = 18.054455128272014
‖C‖ = 18.054455128272014 # assignment in array C did occur

```

Is this an expected result? Here is the Julia version:

```julia
julia> VERSION
v"1.5.4-pre.0"

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [December 25, 2020, 9:30pm UTC](https://discourse.julialang.org/t/assignment-not-effective-in-spawn-in-function/52382/2 "2020-12-25T21:30:45Z")

</div>

It seems that the @spawn macro from Distribution is used (sometimes).  
If you do in a fresh REPL:

```julia
function copy_array!(array_t::AbstractArray, array_s::AbstractArray)
    array_t .= array_s
    return nothing
end

function test_spawned_copy()
    n = 10
    c = zeros(n);
	d = zeros(n);
    @spawn copy_array!(c, rand(n))
	Threads.@spawn copy_array!(d, rand(n))
	(c,d)
end

(c,d)=test_spawned_copy()

```

you get:

```julia
([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.5282095840733001, 0.5556105622927612, 0.20150965328960568, 0.31812680241750946, 0.46483288319514715, 0.013753794057519642, 0.6303004740215832, 0.22042140183053638, 0.9973105034241585, 0.346232614933345])

```

If you start again a new REPL and start with:

```julia
using Base.Threads: @spawn

```

you get:

```julia
([0.35270524970982176, 0.7986731832036376, 0.4356428356231954, 0.4497905410479941, 0.3878368060348809, 0.11946402924101096, 0.6408044427105426, 0.6883479688491787, 0.7404863070919507, 0.31914232478228866], [0.004167961824976141, 0.5848904661256766, 0.5722504383047835, 0.9284901252145417, 0.677612496185245, 0.715904376389237, 0.9944319571686495, 0.005437923152379565, 0.1644076654195401, 0.17196103627138593])

```

Again, a fresh REPL:

```julia
function copy_array!(array_t::AbstractArray, array_s::AbstractArray)
    array_t .= array_s
    return nothing
end
n = 10
c = zeros(n);
@which( @spawn copy_array!(c, rand(n)) )

```

gives

```julia
julia> @which( @spawn copy_array!(c, rand(n)) )
@spawn( __source__ ::LineNumberNode, __module__ ::Module, expr) in Distributed at C:\Users\oheil\AppData\Local\Programs\Julia 1.5.3\share\julia\stdlib\v1.5\Distributed\src\macros.jl:46

```

That `Distributed.@spawn` doesn’t work is understandable, as different processes are used where data is copied into the new process.  
So, the solution is, always make sure, that `Threads.@spawn` is used.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [December 25, 2020, 9:32pm UTC](https://discourse.julialang.org/t/assignment-not-effective-in-spawn-in-function/52382/3 "2020-12-25T21:32:00Z")

</div>

Of course the REPL must be started with Threads and/or Processes:  
`julia.exe -t auto -p auto`

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [December 25, 2020, 9:35pm UTC](https://discourse.julialang.org/t/assignment-not-effective-in-spawn-in-function/52382/4 "2020-12-25T21:35:57Z")

</div>

Isn’t this a race condition? You are not waiting for the task to finish.

---

<div class="post-metadata">

**Author:** ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)\
**Post date:** [December 26, 2020, 1:25am UTC](https://discourse.julialang.org/t/assignment-not-effective-in-spawn-in-function/52382/5 "2020-12-26T01:25:11Z")

</div>

Thanks, @kristoffer.carlsson! For other people, the solution is to modify `test_spawned_copy` using `wait` as follows:

```julia
function test_spawned_copy()
    N = 1000
    A = rand(N);
    B = zeros(N);
    C = zeros(N);

    copy_array!(B, A)
    t = @spawn copy_array!(C, A)
    wait(t)

    println("‖A‖ = $(norm(A))\n‖B‖ = $(norm(B))\n‖C‖ = $(norm(C))")
end

```
