# Parallel Computing For Loop With Dictionaries

**URL:** https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402
**Category:** General Usage
**Created:** [April 1, 2021, 10:57pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402 "2021-04-01T22:57:07Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 1, 2021, 10:57pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/1 "2021-04-01T22:57:07Z")

</div>

What’s the best way to implement parallel computing here? I’m new to it and Julia. I have eight physical cores.

The **process** function returns two dictionaries.

```julia
@time begin
param = "reaction" # reaction, mesh, diffusion
r_start = 0
r_end = 0.5
r_length = 10
parameter_range = range(r_start, r_end, length=r_length)
u_steps, speed_steps = process(param, parameter_range, ncores)
data = reduce(vcat, values(speed_steps))

```

Inside **process** , there is a **for** loop that iterates over **parameter\_range**. This is where I can employ parallel computing as the order does not matter. At the end of each iteration, I add two results to two separate dictionaries.

```julia
function process(param, parameter_range, ncores)
  a = 0
  b = 20
  T = 10
  t_steps = 10^4
  global solutions = Dict()
  global speed = Dict()
  for key in parameter_range
    key = round(key, digits = 5)
    if param == "reaction"
      M = 512
      D = 1
      alpha = key
    end
    if param == "mesh"
      alpha = -0.5
      D = 1
      M = key
    end
    if param == "diffusion"
      alpha = 0.10
      M = 512
      D = key
    end

    k = T / t_steps
    h = (b - a) / M
    mu = k / h^2
    boundary = "HN"

    x = [h * i for i = 0:M]
    t = [k * i for i = 0:t_steps]

    # initial condition
    u0 = initial_condition(x)

    # crank matrices
    local B_inv, P = crank(M, mu, D, boundary)
    # time step
    local time_steps = calc_new_step(B_inv, P, u0, D, k, t_steps, M, alpha)
    p_title = string("reduced nagumo:", " ", "M = ", M, " ", "alpha = ", alpha, " ",
    "k = ", k, " ", "diff = ", D)
    Plots.contourf(x, t, time_steps, fill=true, c=:vik, title=p_title, xlabel="x", ylabel="t", dpi=300)

    # saves the current plot:
    global output_name = string(p_title, ".png")
    global subfolder = joinpath(pwd(), string(param))
    if ispath(subfolder) == 0
      mkdir(subfolder)
    end
    output_loc = joinpath(subfolder, output_name)
    savefig(output_loc)
    complete = DataFrame(Transpose(time_steps),:auto)
    solutions[key] = complete
    speed_key = calc_speed(complete, h, k, M, alpha, D, param, key)
    speed[key] = speed_key
  end
  return solutions, speed
end

```

---

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 2, 2021, 2:46am UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/2 "2021-04-02T02:46:18Z")

</div>

The following doesn’t work.

```julia
using Base.Threads

@threads for key in parameter_range

```

I get the following error.

> GKS: GKS: Specified workstation is open in routine OPEN\_WS  
> GKS: GKS not in proper state. GKS must be either in the state WSOP or WSAC in routine ACTIVATE\_WSGKS:  
> Specified workstation is open in routine OPEN\_WS  
> Specified workstation is open in routine OPEN\_WS  
> GKS: GKS not in proper state. GKS must be either in the state WSOP or WSAC in routine ACTIVATE\_WS  
> GKS: GKS not in proper state. GKS must be either in the state WSOP or WSAC in routine ACTIVATE\_WS  
> GKS: GKS not in proper state. GKS must be either in the state WSOP or WSAC in routine ACTIVATE\_WS
> 
> signal (11): Segmentation fault  
> in expression starting at /home/wesley/repos/pde/juliatest\_parallel.jl:148
> 
> signal (11): Segmentation fault  
> in expression starting at /home/wesley/repos/pde/juliatest\_parallel.jl:148
> 
> signal (11): Segmentation fault  
> in expression starting at /home/wesley/repos/pde/juliatest\_parallel.jl:148  
> set\_clip\_path at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/./svgplugin.so (unknown line)  
> set\_clip\_path at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/./svgplugin.so (unknown line)  
> gks\_svgplugin at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/./svgplugin.so (unknown line)  
> gks\_svgplugin at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/./svgplugin.so (unknown line)  
> unknown function (ip: 0x7fb141d6a99e)  
> gks\_select\_xform at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> gks\_open\_ws at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> set\_clip\_path at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/./svgplugin.so (unknown line)  
> gks\_svgplugin at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/./svgplugin.so (unknown line)  
> initgks at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> initgks at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> gr\_setcharheight at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> gr\_setcharheight at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> setcharheight at /home/wesley/.julia/packages/GR/9Vi4m/src/GR.jl:1470  
> setcharheight at /home/wesley/.julia/packages/GR/9Vi4m/src/GR.jl:1470  
> unknown function (ip: 0x7fb14a927373)  
> unknown function (ip: 0x7fb14a927373)  
> jl\_apply\_generic at /opt/julia-1.6.0/bin/…/lib/julia/libjulia-internal.so.1 (unknown line)  
> #gr\_set\_font#351 at /home/wesley/.julia/packages/Plots/z5Msu/src/backends/gr.jl:390  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> jl\_apply\_generic at /buildworker/worke#gr\_set\_font#351 at /home/wesley/.julia/packages/Plots/z5Msu/src/backends/gr.jl:390  
> unknown function (ip: 0x7fb14a926db1)  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlin\_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> gr\_set\_font at /home/wesley/.julia/packages/Plots/z5Msu/src/backends/gr.jl:389  
> gr\_set\_font at /home/wesley/.julia/packages/Plots/z5Msu/src/backends/gr.jl:389  
> \_update\_min\_padding! at /home/wesley/.julia/packages/Plots/z5Msu/src/backends/gr.jl:735  
> \_update\_min\_padding! at /home/wesley/.julia/packages/Plots/z5Msu/src/backends/gr.jl:735  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> iterate at ./generator.jl:47 [inlined]  
> iterate at ./generator.jl:47 [inlined]  
> \_collect at ./array.jl:691  
> \_collect at ./array.jl:691  
> collect\_similar at ./array.jl:606 [inlined]  
> map at ./abstractarray.jl:2294 [inlined]  
> \_update\_min\_padding! at /home/wesley/.julia/packages/Plots/z5Msu/src/layouts.jl:282  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> prepare\_output at /home/wesley/.julia/packages/Plots/z5Msu/src/plot.jl:189  
> collect\_similar at ./array.jl:606 [inlined]  
> map at ./abstractarray.jl:2294 [inlined]  
> \_update\_min\_padding! at /home/wesley/.julia/packages/Plots/z5Msu/src/layouts.jl:282  
> show at /home/wesley/.julia/packages/Plots/z5Msu/src/output.jl:214 [inlined]  
> png at /home/wesley/.julia/packages/Plots/z5Msu/src/output.jl:7  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> d]  
> prepare\_output at /home/wesley/.julia/packages/Plots/z5Msu/src/plot.jl:189  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> savefig at /home/wesley/.julia/packages/Plots/z5Msu/src/output.jl:124  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> savefig at /home/wesley/.julia/packages/Plots/z5Msu/src/output.jl:129  
> macro expansion at /home/wesley/repos/pde/juliatest\_parallel.jl:140 [inlined]  
> #13#threadsfor\_fun at ./threadingconstructs.jl:81  
> show at /home/wesley/.julia/packages/Plots/z5Msu/src/output.jl:214 [inlined]  
> gks\_ddlk.isra.0 at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> png at /home/wesley/.julia/packages/Plots/z5Msu/src/output.jl:7  
> gks\_open\_ws at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> savefig at /home/wesley/.julia/packages/Plots/z5Msu/src/output.jl:124  
> #13#threadsfor\_fun at ./threadingconstructs.jl:48  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> savefig at /home/wesley/.julia/packages/Plots/z5Msu/src/output.jl:129  
> macro expansion at /home/wesley/repos/pde/juliatest\_parallel.jl:140 [inlined]  
> #13#threadsfor\_fun at ./threadingconstructs.jl:81  
> #13#threadsfor\_fun at ./threadingconstructs.jl:48  
> unknown function (ip: 0x7fb16692333c)  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> unknown function (ip: 0x7fb16692333c)  
> initgks at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> gr\_setcharheight at /home/wesley/.julia/packages/GR/9Vi4m/src/…/deps/gr/lib/libGR.so (unknown line)  
> \_jl\_invoke at /buildworker/worker/package\_linux64/build/src/gf.c:2237 [inlined]  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.c:2419  
> jl\_apply\_generic at /buildworker/worker/package\_linux64/build/src/gf.cunknown function (ip: 0x7fb14a927373)  
> unknown function (ip: 0x7fb14a927373)  
> /package\_linux64/build/src/gf.c:2419  
> ed]  
> start\_task at /buildworker/worker/package\_linux64/build/src/task.c:839  
> unknown function (ip: (nil))  
> Allocations: 62183429 (Pool: 61684794; Big: 498635); GC: 52

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [April 2, 2021, 3:10am UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/3 "2021-04-02T03:10:49Z")

</div>

I would recommend a thorough read of the [performance tips](https://docs.julialang.org/en/v1/manual/performance-tips/) to make sure your code is efficient on a single process before you try to make it parallel. Your code has a few issues (global untyped dictionaries are an immediate red flag) that, when fixed, might be able to deliver more than the ~8x speedup you’d get from parallelism.

Separately, the error you’re seeing is from the GR plotting library, which is an external C library and may not cooperate well with Julia’s multithreading. You might be better off with [`pmap`](https://docs.julialang.org/en/v1/stdlib/Distributed/#Distributed.pmap).

---

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 2, 2021, 3:29am UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/4 "2021-04-02T03:29:00Z")

</div>

Thanks for the tip. I was wondering if typing would make much of a difference because the elements are matrices. I saw **pmap** mentioned in a few places but didn’t look it up.

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [April 2, 2021, 3:41am UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/5 "2021-04-02T03:41:13Z")

</div>

Typing is one part of the problem, but the bigger issue is `global` - it makes it hard for the compiler to ensure that whatever variable it’s working on hasn’t been touched or modified by some other part of the program, which prevents most optimizations.

---

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 2, 2021, 3:53am UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/6 "2021-04-02T03:53:13Z")

</div>

I initially declared the Dicts as local, but the code wouldn’t run until I declared it global. However, I just declared it as local and it ran just fine.

I misspoke (typed) earlier. The **solutions** and **speed** dictionaries have float keys and DataFrame elements. This seems to work, but I must be doing something wrong because I’m not seeing any performance gains.

```julia

solutions = Dict{Float64, DataFrame}()

```

---

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 2, 2021, 3:51pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/7 "2021-04-02T15:51:54Z")

</div>

Here’s my attempt at pmap.

```julia
param = "reaction" # reaction, mesh, diffusion
r_start = 0
r_end = 0.5
r_length = 10
parameter_range = range(r_start, r_end, length=r_length)
u_steps, speed_steps = pmap(process, param, parameter_range)
data = reduce(vcat, values(speed_steps))

```

```julia
@everywhere begin
function process(param, parameter_range)
  a = 0
  b = 20
  T = 10
  t_steps = 10^4
  local solutions = Dict{Float64, DataFrame}()
  local speed = Dict{Float64, DataFrame}()
  for key in parameter_range
    key = round(key, digits = 5)
    if param == "reaction"
      M = 512
      D = 1
      alpha = key
    end
    if param == "mesh"
      alpha = -0.5
      D = 1
      M = key
    end
    if param == "diffusion"
      alpha = 0.10
      M = 512
      D = key
    end

    k = T / t_steps
    h = (b - a) / M
    mu = k / h^2
    boundary = "HN"

    x = [h * i for i = 0:M]
    t = [k * i for i = 0:t_steps]

    # initial condition
    u0 = initial_condition(x)

    # crank matrices
    local B_inv, P = crank(M, mu, D, boundary)
    # time step
    local time_steps = calc_new_step(B_inv, P, u0, D, k, t_steps, M, alpha)
    p_title = string("reduced nagumo:", " ", "M = ", M, " ", "alpha = ", alpha, " ",
    "k = ", k, " ", "diff = ", D)
    Plots.contourf(x, t, time_steps, fill=true, c=:vik, title=p_title, xlabel="x", ylabel="t", dpi=300)

    # saves the current plot:
    global output_name = string(p_title, ".png")
    global subfolder = joinpath(pwd(), string(param))
    if ispath(subfolder) == 0
      mkdir(subfolder)
    end
    output_loc = joinpath(subfolder, output_name)
    savefig(output_loc)
    complete = DataFrame(Transpose(time_steps),:auto)
    solutions[key] = complete
    speed_key = calc_speed(complete, h, k, M, alpha, D, param, key)
    speed[key] = speed_key
  end
  return solutions, speed
end
end

```

I get the error message

> LoadError: UndefVarError: M not defined
> 
> in expression starting at /home/wesley/repos/pde/juliatest\_parallel.jl:150
> 
> (::Base.var"#837#839")(x::Task) at asyncmap.jl:177
> 
> foreach(f::Base.var"#837#839", itr::Vector{Any}) at abstractarray.jl:2141
> 
> maptwice(wrapped\_f::Function, chnl::Channel{Any}, worker\_tasks::Vector{Any}, c::Base.Iterators.Zip{Tuple{String, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}}) at asyncmap.jl:177
> 
> wrap\_n\_exec\_twice at asyncmap.jl:153 [inlined]
> 
> #async\_usemap#822 at asyncmap.jl:103 [inlined]
> 
> async\_usemap at asyncmap.jl:85 [inlined]
> 
> #asyncmap#821 at asyncmap.jl:81 [inlined]
> 
> asyncmap at asyncmap.jl:81 [inlined]
> 
> pmap(f::Function, p::WorkerPool, c::Base.Iterators.Zip{Tuple{String, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}}; distributed::Bool, batch\_size::Int64, on\_error::Nothing, retry\_delays::Vector{Any}, retry\_check::Nothing) at pmap.jl:126
> 
> pmap(f::Function, p::WorkerPool, c::Base.Iterators.Zip{Tuple{String, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}}) at pmap.jl:101
> 
> pmap(f::Function, c::Base.Iterators.Zip{Tuple{String, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}}}; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}) at pmap.jl:156
> 
> pmap at pmap.jl:156 [inlined]
> 
> pmap(f::Function, c1::String, c::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}) at pmap.jl:157
> 
> pmap(f::Function, c1::String, c::StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}}) at pmap.jl:157
> 
> macro expansion at juliatest\_parallel.jl:156 [inlined]
> 
> top-level scope at timing.jl:210
> 
> eval at boot.jl:360 [inlined]
> 
> include\_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String) at loading.jl:1094

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [April 2, 2021, 4:11pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/8 "2021-04-02T16:11:26Z")

</div>

Before doing `pmap`, make sure your function works with `map`. You’ll probably need to rearrange your code a bit - `map` essentially takes the place of a for loop, and you should use it to replace the `for key in parameter_range` loop.

---

<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: [April 2, 2021, 8:28pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/9 "2021-04-02T20:28:10Z")

</div>

I agree with stillyslalom. For parallelizing this kind of computation, making sequential `map` work is the best first step. You can then use various APIs for parallelizing this, as I noted in [A quick introduction to data parallelism in Julia](https://juliafolds.github.io/data-parallelism/tutorials/quick-introduction/)

Regarding the actual question in the OP, since the keys (`parameter_range`) are unique, there’s no point in using dictionaries as output. You can just use `Dict(zip(parameter_range, the_result))` to get the dictionary.

Having said that, you can use Folds.jl to directly obtain the dictionary (which can be beneficial when `hash`ing is the bottleneck and there are some overlaps in the keys):

```julia
julia> Folds.dict(x => x^2 for x in 1:3)
Dict{Int64, Int64} with 3 entries:
  2 => 4
  3 => 9
  1 => 1

```

Creating two dictionaries is a bit more involved but possible:

```julia
julia> using Transducers, BangBang, MicroCollections

julia> Folds.mapreduce(ProductRF(merge!!, merge!!), 1:3; init=(EmptyDict(), EmptyDict())) do x
           (SingletonDict(x => x^2), SingletonDict(x => x^2))
       end
(Dict(2 => 4, 3 => 9, 1 => 1), Dict(2 => 4, 3 => 9, 1 => 1))

```

---

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 3, 2021, 1:53am UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/10 "2021-04-03T01:53:15Z")

</div>

Thanks for the replies.

I tried **map** and it says that M is not defined. M is defined in a conditional in the **process** function. Is there some incompatibility this way with map?

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [April 3, 2021, 2:22am UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/11 "2021-04-03T02:22:43Z")

</div>

These issues are hard to diagnose unless you can provide code and a stacktrace. As a guess, are you still passing `param` to `map`? If so, you need to instead wrap those parameters in a closure. Here’s what’s probably happening (using `println` as a dummy function):

```julia
julia> map(println, "reaction", 1:10)
r1
e2
a3
c4
t5
i6
o7
n8

```

Since `String` is an iterable type in Julia, `param` is getting mapped as a series of characters, so it never satisfies any of your conditionals (and thus `M`, `D`, and `alpha` are never defined). The solution might look something like this.

```julia
function process(param, param_range)
    a = 0
    b = 20
    T = 10
    #... other setup stuff
    
    map(param_range) do key
        if param == "reaction"
            M = 512
            D = 1
            alpha = key
        elseif param == "mesh"
            alpha = -0.5
            D = 1
            M = key
        elseif param == "diffusion"
            alpha = 0.10
            M = 512
            D = key
        else
            @error "Invalid parameter $param"
        end

        #... other computations

        solutions[key] = complete
        speed[key] = complete
        return nothing
    end

    return solutions, speed
end

```

This is not very Julian - it should be reworked to avoid potential type instabilities in the definition of `M`, `D`, and `alpha` - but it should be enough to get you off the ground.

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [April 3, 2021, 2:53am UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/12 "2021-04-03T02:53:00Z")

</div>

A better approach:

```julia
using Printf

function process(; M = 512, D = 1, α = 0.10)
    a = 0
    b = 20
    T = 10
    #... other setup stuff
    
    map(Iterators.product(M, D, α)) do (M, D, α)
        keystr = @sprintf("M = %0.5g, α = %0.5g, D = %0.5g", M, α, D)

        #... computations

        solutions[keystr] = complete
        speed[keystr] = complete
        return nothing
    end

    return solutions, speed
end

```

By setting the parameters as keyword arguments and using `Iterators.product`, you can call the function like this:

```julia
julia> process(; M = 2 .^ (5:10))
M = 32, α = 0.1, D = 1
M = 64, α = 0.1, D = 1
M = 128, α = 0.1, D = 1
M = 256, α = 0.1, D = 1
M = 512, α = 0.1, D = 1
M = 1024, α = 0.1, D = 1

```

…or this

```julia
julia> process(; α = [-0.5, 0.1], D = [1.0, 1.2])
M = 512, α = -0.5, D = 1
M = 512, α = -0.5, D = 1.2
M = 512, α = 0.1, D = 1
M = 512, α = 0.1, D = 1.2

```

---

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 3, 2021, 5:07pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/13 "2021-04-03T17:07:30Z")

</div>

Thanks. I got **map** to work and then I just changed it to **pmap**. What’s the best way to round the elements in **parameter\_range**?

```julia
r_start = 0
r_end = 0.50
r_length = 100
parameter_range = range(r_start, r_end, length=r_length)
u_steps, speed_steps = process(; alpha = parameter_range, D = [1.0], M = [1024])

```

```julia
function process(; M = 512, D = 1, alpha = 0.10)
  a = 0
  b = 20
  T = 10
  t_steps = 10^4
  local solutions = Dict{String, DataFrame}()
  local speed = Dict{String, DataFrame}()
  #key = round(alpha, digits = 5)
  pmap(Iterators.product(M, D, alpha)) do (M, D, alpha)
        keystr = @sprintf("M = %0.5g, α = %0.5g, D = %0.5g", M, alpha, D)

```

---

<div class="post-metadata">

### Author: ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)
#### Post date: [April 3, 2021, 5:23pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/14 "2021-04-03T17:23:05Z")

</div>

Have you read the documentation of `pmap`? `pmap` won’t do you any good unless you use `Distributed` to `addprocs` first. Have you already done this step?

There are two parallel paradigms: Shared memory parallelism and embarrassingly/distributed parallelism.

The `@threads` and the associated `Threads` library use shared memory parallelism. Here you have to account for data races, deadlocks, and utilizing thread pools properly. This sort of parallelism is nicely suited for when you want to split your `for` loop over multiple threads as the “work” of each iteration is not that much.

For distributed parallelism, the `addprocs` function launches `n` independent Julia processes (think of this as you running `julia` n times in the terminal). Then `pmap` executes a function on all of these independent julia processes with the results collected at the end. The problem here is that you have to make sure all the variables, libraries, and functions are available on the remote processes as well, which is why you get the `M` is not defined on worker n errors.

In general you’d want to use `pmap` when the function being executed is “costly”, atleast most costly than the overhead of setting up the remote processes data communication. (Infact, if I recall correctly, the data is passed using `ssh` between the independent workers). What do your `computations` look like? If they are quick, then threading will probably be the best option here.

If you post your full code, we may be able to help you better (and possibly just speed your sequential code).

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [April 3, 2021, 7:06pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/15 "2021-04-03T19:06:48Z")

</div>

`round` has a number of keyword options to tweak according to your needs, but I can’t say what options will be suitable for your use case. You may want to set up rounding for `M`, `D`, and `alpha` individually, to account for the different characteristics (known only to you) of each parameter space.

---

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 3, 2021, 7:34pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/16 "2021-04-03T19:34:59Z")

</div>

This should be accessible. The sequential version is juliatest. I added @everywhere and **addprocs** to the parallel version, but I get the error below

[https://bitbucket.org/Forbeswa/computing/src/master/](https://bitbucket.org/Forbeswa/computing/src/master/)

> LoadError: On worker 2:  
> LoadError: UndefVarError: @sprintf not defined  
> Stacktrace:  
> [1] top-level scope  
> @ :0  
> [2] eval  
> @ ./boot.jl:360  
> [3] #103  
> @ /buildworker/worker/package\_linux64/build/usr/share/julia/stdlib/v1.6/Distributed/src/process\_messages.jl:274  
> [4] run\_work\_thunk  
> @ /buildworker/worker/package\_linux64/build/usr/share/julia/stdlib/v1.6/Distributed/src/process\_messages.jl:63  
> [5] run\_work\_thunk  
> @ /buildworker/worker/package\_linux64/build/usr/share/julia/stdlib/v1.6/Distributed/src/process\_messages.jl:72  
> [6] #96  
> @ ./task.jl:406  
> in expression starting at /home/wesley/repos/computing/juliatest\_parallel.jl:124  
> …and 7 more exceptions.  
> in expression starting at /home/wesley/repos/computing/juliatest\_parallel.jl:114  
> sync\_end(c::Channel{Any}) at task.jl:364  
> macro expansion at task.jl:383 [inlined]  
> remotecall\_eval(m::Module, procs::Vector{Int64}, ex::Expr) at macros.jl:223  
> top-level scope at macros.jl:207  
> eval at boot.jl:360 [inlined]  
> include\_string(mapexpr::typeof(identity), mod::Module, code::String, filename::String) at loading.jl:1094

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [April 3, 2021, 7:58pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/17 "2021-04-03T19:58:38Z")

</div>

`@sprintf` is from the Printf standard library - it’s an easy way to combine strings & variables rounded to a specified precision. I included it in the top of my earlier answer:

> [@stillyslalom](#):
>
> A better approach:
> 
> ```julia
> using Printf
> 
> function process(; M = 512, D = 1, α = 0.10)
> 
> ```

---

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 3, 2021, 8:20pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/18 "2021-04-03T20:20:21Z")

</div>

Yeah. It worked until I added @everywhere and addprocs().

```julia
@everywhere function process(; M = 512, D = 1, alpha = 0.10)
  a = 0
  b = 20
  T = 10
  t_steps = 10^4
  local solutions = Dict{String, DataFrame}()
  local speed = Dict{String, DataFrame}()
  #key = round(alpha, digits = 5)
  addprocs(8)
  pmap(Iterators.product(M, D, alpha)) do (M, D, alpha)
        keystr = @sprintf("M = %0.5g, α = %0.5g, D = %0.5g", M, alpha, D)

```

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [April 3, 2021, 8:28pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/19 "2021-04-03T20:28:48Z")

</div>

`@everywhere using Printf`?

---

<div class="post-metadata">

### Author: ![waforbes](https://avatars.discourse-cdn.com/v4/letter/w/6bbea6/32.png) [@waforbes](https://discourse.julialang.org/u/waforbes)
#### Post date: [April 3, 2021, 8:40pm UTC](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402/20 "2021-04-03T20:40:36Z")

</div>

I thought that I had to use @everywhere in conjunction with pmap.

[Next page](https://discourse.julialang.org/t/parallel-computing-for-loop-with-dictionaries/58402.md?page=2)
