Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a parallel loop in julia?

I have the following Julia code and I would like to parallelize it.

using DistributedArrays

function f(x)
    return x^2;
end
y = DArray[]
@parallel for i in 1:100
    y[i] = f(i)
end
println(y)

The output is DistributedArrays.DArray[]. I would like to have the value of y as follows: y=[1,4,9,16,...,10000]

like image 231
Kira Avatar asked Oct 20 '15 02:10

Kira


People also ask

Does Julia use multiple cores?

Julia's multi-threading provides the ability to schedule Tasks simultaneously on more than one thread or CPU core, sharing memory. This is usually the easiest way to get parallelism on one's PC or on a single large multi-core server. Julia's multi-threading is composable.

Is Julia multithreaded?

The Julia language implements multithreading using task parallelism where tasks communicate in shared memory as described in their article Announcing composable multi-threaded parallelism in Julia. In task parallelism, a task refers to a computational task such as executing a function.

What is parallel computing and how it works?

Parallel computing refers to the process of breaking down larger problems into smaller, independent, often similar parts that can be executed simultaneously by multiple processors communicating via shared memory, the results of which are combined upon completion as part of an overall algorithm.


Video Answer


1 Answers

You can use n-dimensional distributed array comprehensions:

First you need to add some more processes, either local or remote:

julia> addprocs(CPU_CORES - 1);

Then you must use DistributedArrays at every one of the spawned processes:

julia> @everywhere using DistributedArrays

Finally you can use the @DArray macro, like this:

julia> x = @DArray [@show x^2 for x = 1:10];
        From worker 2:  x ^ 2 = 1
        From worker 2:  x ^ 2 = 4
        From worker 4:  x ^ 2 = 64
        From worker 2:  x ^ 2 = 9
        From worker 4:  x ^ 2 = 81
        From worker 4:  x ^ 2 = 100
        From worker 3:  x ^ 2 = 16
        From worker 3:  x ^ 2 = 25
        From worker 3:  x ^ 2 = 36
        From worker 3:  x ^ 2 = 49

You can see it does what you expect:

julia> x
10-element DistributedArrays.DArray{Int64,1,Array{Int64,1}}:
   1
   4
   9
  16
  25
  36
  49
  64
  81
 100

Remember it works with an arbitrary number of dimensions:

julia> y = @DArray [@show i + j for i = 1:3, j = 4:6];
        From worker 4:  i + j = 7
        From worker 4:  i + j = 8
        From worker 4:  i + j = 9
        From worker 2:  i + j = 5
        From worker 2:  i + j = 6
        From worker 2:  i + j = 7
        From worker 3:  i + j = 6
        From worker 3:  i + j = 7
        From worker 3:  i + j = 8

julia> y
3x3 DistributedArrays.DArray{Int64,2,Array{Int64,2}}:
 5  6  7
 6  7  8
 7  8  9

julia>

This is the most julian way to do what you intended IMHO.

We can look at macroexpand output in order to see what's going on:

Note: this output has been slightly edited for readability, T stands for:

DistributedArrays.Tuple{DistributedArrays.Vararg{DistributedArrays.UnitRange{DistributedArrays.Int}}}

julia> macroexpand(:(@DArray [i^2 for i = 1:10]))
  :(
    DistributedArrays.DArray(
      (
        #231#I::T -> begin
          [i ^ 2 for i = (1:10)[#231#I[1]]]
        end
      ),
      DistributedArrays.tuple(DistributedArrays.length(1:10))
    )
  )

Which basically is the same as manually typing:

julia> n = 10; dims = (n,);

julia> DArray(x -> [i^2 for i = (1:n)[x[1]]], dims)
10-element DistributedArrays.DArray{Any,1,Array{Any,1}}:
   1
   4
   9
  16
  25
  36
  49
  64
  81
 100

julia>
like image 53
HarmonicaMuse Avatar answered Sep 19 '22 14:09

HarmonicaMuse