Problema de subprocesos múltiples en Julia

Aug 18 2020

Estoy intentando paralelizar algunos bits de un código, pero no entiendo por qué las siguientes funciones main1 () y main2 () dan resultados diferentes usando el multihilo de Julia:

a = rand(4,4);b = rand(4,4);c = rand(4,4);d = rand(4,4)

function main1(a,b,c,d)
    L = zeros(2,2,16)
    FF = zeros(2,2,16)
    FT = zeros(2,2,16)
    F = Array{Float32}(undef,2,2)
    # L = Array{Array{Float32, 1}, 4}

    for i = 1:4
        for j = 1:4
            ic = i + j*(i-1)
            F[1,1] = a[i,j]
            F[1,2] = b[i,j]
            F[2,1] = c[i,j]
            F[2,2] = d[i,j]
            L[:,:,ic] .= F * F'
            FF[:,:,ic] .= F
            FT[:,:,ic] .= F'
        end
    end
    return L,FF,FT
end

function main2(a,b,c,d)

    L  = zeros(2,2,16)
    FF = zeros(2,2,16)
    FT = zeros(2,2,16)
    F  = Array{Float32}(undef,2,2)
    # L = Array{Array{Float32, 1}, 4}

    Threads.@threads for i = 1:4
        Threads.@threads for j = 1:4
            ic = i + j*(i-1)
            F[1,1] = a[i,j]
            F[1,2] = b[i,j]
            F[2,1] = c[i,j]
            F[2,2] = d[i,j]
            L[:,:,ic] .= F * F'
            FF[:,:,ic] .= F
            FT[:,:,ic] .= F'
        end
    end
    return L,FF,FT
end

¿Cómo podría corregirse correctamente la paralelización de main1 ()?

Respuestas

1 PrzemyslawSzufel Aug 18 2020 at 23:44

No puede anidar @threadsbucles, por lo que normalmente debería hacer:

Threads.@threads for u in vec(CartesianIndices((4,4)))
    i,j = u.I
    # your code goes here
end

Sin embargo, en su código obtiene el mismo icvalor para diferentes pares de valores de (i,j). En el main1sobreescribiendo las mismas partes L, FF, FTmuchas veces, lo cual es un error evidente. El subproceso múltiple cambiará el orden en que se sobrescriben los datos, por lo que producirá resultados diferentes. En conclusión, primero corríjalo main1y luego paralelícelo.