2015-10-20 15 views
8

Ho il seguente codice Julia e vorrei parallelizzarlo.Come scrivere un ciclo parallelo in julia?

using DistributedArrays 

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

L'uscita è DistributedArrays.DArray[]. Mi piacerebbe avere il valore di y come segue: y=[1,4,9,16,...,10000]

+0

Cosa vuoi fare in loop parallelo? Penso che sia una domanda ampia senza una risposta esatta. –

risposta

3

Ciao Kira,

Sono nuovo su Julia, ma di fronte lo stesso problema. Prova questo approccio e verifica se soddisfa le tue esigenze.

function f(x) 
    return x^2; 
end 

[email protected] vcat for i= 1:100 
f(i); 
end; 

println(y) 

saluti, RN

+0

quick aside: perché funziona solo con il prefisso @parallel e non senza? –

+0

Sembra (almeno in Julia v0.6) è necessario definire f ad ogni lavoratore, cioè @everywhere f (x) return x^2; fine –

9

È possibile utilizzare n-dimensionali comprensioni di array distribuiti:

prima cosa è necessario aggiungere un po 'più processi, locale o remoto:

julia> addprocs(CPU_CORES - 1); 

Quindi è necessario utilizzareDistributedArrays in ognuno dei pro generati cessi:

julia> @everywhere using DistributedArrays 

Infine è possibile utilizzare la macro @DArray, in questo modo:

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 

si può vedere che fa quello che ci si aspetta:

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

Ricordate che funziona con un numero arbitrario delle dimensioni:

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> 

Questo è il più julian modo di fare ciò che intendevi IMHO.

Possiamo guardare macroexpand uscita per vedere cosa sta succedendo:

Nota: questa uscita è stato leggermente modificato per migliorare la leggibilità, T significa:

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)) 
    ) 
) 

Che in pratica equivale alla digitazione manuale:

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> 
Problemi correlati