# How to handle code availability in a parallel-computing-enabled package

**URL:** https://discourse.julialang.org/t/how-to-handle-code-availability-in-a-parallel-computing-enabled-package/8080
**Category:** General Usage
**Tags:** question
**Created:** [December 31, 2017, 3:17am UTC](https://discourse.julialang.org/t/how-to-handle-code-availability-in-a-parallel-computing-enabled-package/8080 "2017-12-31T03:17:34Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)
#### Post date: [December 31, 2017, 3:17am UTC](https://discourse.julialang.org/t/how-to-handle-code-availability-in-a-parallel-computing-enabled-package/8080/1 "2017-12-31T03:17:34Z")

</div>

I am becoming increasingly confused about code availability in parallel computing. Basically, I want to write a package that will distribute tasks automatically on all processes and I don’t know how to understand code availability.

This is official documentation:

```julia
julia> function rand2(dims...)
           return 2*rand(dims...)
       end

julia> rand2(2,2)
2×2 Array{Float64,2}:
 0.153756 0.368514
 1.15119 0.918912

julia> fetch(@spawn rand2(2,2))
ERROR: RemoteException(2, CapturedException(UndefVarError(Symbol("#rand2"))
[...]

```

It shows `rand2` has to be made available on all processes.

However, this is working:

```julia
# mytest.jl
push!(LOAD_PATH, "C:/Users/wangc/Downloads") # This is my path

using Para

println(mypara())

```

```julia
# Para.jl
module Para

export mypara

function rand2(dims...)
    return 2*rand(dims...)
end

function mypara()
	return fetch(@spawn rand2(2, 2))
end

end

```

Executing `julia -p 3 mytest.jl` gives precisely what I want although I never made `rand2` available on other processes.

I have two questions:

1. How to understand the behavior above?
2. More generally, how to take care of code availability inside a package that performs parallel computing?

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [December 31, 2017, 6:27am UTC](https://discourse.julialang.org/t/how-to-handle-code-availability-in-a-parallel-computing-enabled-package/8080/2 "2017-12-31T06:27:16Z")

</div>

From the rest of the subsection in docs [https://docs.julialang.org/en/stable/manual/parallel-computing:](https://docs.julialang.org/en/stable/manual/parallel-computing:)

Starting Julia with julia -p 2, you can use this to verify the following:

- `include("DummyModule.jl")` loads the file on just a single process (whichever one executes the statement).
- `using DummyModule` causes the module to be loaded on all processes; however, the module is brought into scope only on the one executing the statement.

An example of loading a module but not bringing it to scope on other processes (`julia -p 3`):

```julia
julia> using StaticArrays

julia> fetch(@spawnat 1 SVector((1,2,3)))
3-element SVector{3,Int64}:
 1
 2
 3

julia> fetch(@spawnat 2 SVector((1,2,3)))
ERROR: On worker 2:
UndefVarError: SVector not defined
#3 at .\distributed\macros.jl:25
#103 at .\distributed\process_messages.jl:264 [inlined]
run_work_thunk at .\distributed\process_messages.jl:56
run_work_thunk at .\distributed\process_messages.jl:65 [inlined]
#96 at .\event.jl:73
Stacktrace:
 [1] #remotecall_fetch#141(::Array{Any,1}, ::Function, ::Function, ::Base.Distributed.Worker, ::Base.Distributed.RRID, ::Vararg{Any,N} where N) at .\distributed\remotecall.jl:354
 [2] remotecall_fetch(::Function, ::Base.Distributed.Worker, ::Base.Distributed.RRID, ::Vararg{Any,N} where N) at .\distributed\remotecall.jl:346
 [3] #remotecall_fetch#144(::Array{Any,1}, ::Function, ::Function, ::Int64, ::Base.Distributed.RRID, ::Vararg{Any,N} where N) at .\distributed\remotecall.jl:367
 [4] call_on_owner(::Function, ::Future) at .\distributed\remotecall.jl:440
 [5] fetch(::Future) at .\distributed\remotecall.jl:460

julia> fetch(@spawnat 2 StaticArrays.SVector((1,2,3)))
3-element SVector{3,Int64}:
 1
 2
 3

```

Notice if you start `julia` without additional processes, `@spawn` will still work but it will spawn to itself. An example with `julia` (single process):

```julia
julia> using StaticArrays

julia> fetch(@spawn SVector((1,2,3)))
3-element SVector{3,Int64}:
 1
 2
 3

```

But this is not what’s happening in your example because you started with additional processes, so `@spawn` will only spawn to a proc of id \> 1. In the above code, `mypara` is run by proc 1. But when spawning `rand2`, it spawns to proc 2 for example. So the only way this could just work, which it does, is if `rand2` was actually called as `Para.rand2` which makes it identifiable to proc 2. This means that Julia replaces any “internal” (non-exported) `identifier` by `Module.identifier`. This is verifiable from the following code:

```julia
julia> module Dummy
           f() = 2
           g() = f()
           export g
       end
Dummy

julia> using Dummy

julia> @code_lowered g()
CodeInfo(:(begin
        nothing
        return (Dummy.f)()
    end))

```

---

<div class="post-metadata">

### Author: ![Chong\_Wang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chong_wang/32/20307_2.png) [@Chong\_Wang](https://discourse.julialang.org/u/Chong_Wang)
#### Post date: [December 31, 2017, 6:57am UTC](https://discourse.julialang.org/t/how-to-handle-code-availability-in-a-parallel-computing-enabled-package/8080/3 "2017-12-31T06:57:33Z")

</div>

1. It seems it also works even if `rand2` is exported.
2. Is this behavior guaranteed such that I can count on it in my program? Or it is just how julia is implemented such that it may change due to change of implimentation in future versions?

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [December 31, 2017, 7:01am UTC](https://discourse.julialang.org/t/how-to-handle-code-availability-in-a-parallel-computing-enabled-package/8080/4 "2017-12-31T07:01:43Z")

</div>

> [@Chong\_Wang](#):
>
> It seems it also works even if rand2 is exported.

Yes it works, my bad. It seems I mis-defined the word “internal”, it is not equivalent to non-exported. It seems all functions called indirectly are lowered to their `Module.func` form:

```julia
julia> module Dummy
           f() = 2
           g() = f()
           export f, g
       end
Dummy

julia> using Dummy

julia> @code_lowered g()
CodeInfo(:(begin
        nothing
        return (Dummy.f)()
    end))

```

I think “indirectly called” is more correct than “internal”. The case is different with exported functions called indirectly from global functions as shown below:

```julia
julia> h() = g()
h (generic function with 1 method)

julia> @code_lowered h()
CodeInfo(:(begin
        nothing
        return (Main.g)()
    end))

```

I am not sure what is the best way to describe this behavior, but there you have it.

> [@Chong\_Wang](#):
>
> Is this behavior guaranteed such that I can count on it in my program? Or it is just how julia is implemented such that it may change due to change of implimentation in future versions?

I am in no position to guarantee anything. But if something like this changes, it may break some code, so it may have to wait until 2.0.
