3 votes

Utiliser addprocs() et pmap() à l'intérieur d'une fonction dans Julia

Dans Julia, je veux utiliser addprocs y pmap à l'intérieur d'une fonction qui est définie dans un module. Voici un exemple stupide :

module test

using Distributions

export g, f

function g(a, b)
  a + rand(Normal(0, b))
end

function f(A, b)

  close = false
  if length(procs()) == 1    #  If there are already extra workers,
    addprocs()               #  use them, otherwise, create your own.
    close = true
  end

  W  = pmap(x -> g(x, b), A)

  if close == true
    rmprocs(workers())       #  Remove the workers you created.
  end

  return W

end

end

test.f(randn(5), 1)

Cela renvoie une erreur très longue

WARNING: Module test not defined on process 4
WARNING: Module test not defined on process 3
fatal error on fatal error on WARNING: Module test not defined on process 2
43: : WARNING: Module test not defined on process 5
fatal error on fatal error on 5: 2: ERROR: UndefVarError: test not defined
 in deserialize at serialize.jl:504
 in handle_deserialize at serialize.jl:477
 in deserialize at serialize.jl:696

...

 in message_handler_loop at multi.jl:878
 in process_tcp_streams at multi.jl:867
 in anonymous at task.jl:63
Worker 3 terminated.
Worker 2 terminated.ERROR (unhandled task failure): EOFError: read end of file
WARNING: rmprocs: process 1 not removed

Worker 5 terminated.ERROR (unhandled task failure): EOFError: read end of file

4-element Array{Any,1}:Worker 4 terminated.ERROR (unhandled task failure): EOFError: read end of file

 ERROR (unhandled task failure): EOFError: read end of file
ProcessExitedException()
 ProcessExitedException()
 ProcessExitedException()
 ProcessExitedException()

Ce que j'essaie de faire, c'est d'écrire un paquet contenant des fonctions qui effectuent des opérations qui peuvent être optionnellement parallélisées à la discrétion de l'utilisateur. Ainsi, une fonction comme f pourrait prendre un argument par::Bool qui fait quelque chose comme je l'ai montré ci-dessus si l'utilisateur appelle f avec par = true et boucle sinon. Ainsi, dans la définition de f (et dans la définition du module test ), je veux créer des travailleurs et diffuser le paquet Distributions et la fonction g à eux.

1voto

Michael Ohlrogge Points 6401

Qu'y a-t-il de mal à utiliser @everywhere dans votre fonction ? La fonction suivante, par exemple, fonctionne bien sur mon ordinateur.

function f(A, b)

  close = false
  if length(procs()) == 1    #  If there are already extra workers,
    addprocs()               #  use them, otherwise, create your own.
    @everywhere begin
      using Distributions
      function g(a, b)
        a + rand(Normal(0, b))
      end
    end
    close = true
  end

  W  = pmap(x -> g(x, b), A)

  if close == true
    rmprocs(workers())       #  Remove the workers you created.
  end

  return W

end

f(randn(5), 1)

Remarque : lors de la première exécution, j'ai dû recompiler le fichier Distributions puisqu'il avait été mis à jour depuis la dernière fois que je l'avais utilisé. Quand j'ai d'abord essayé le script ci-dessus juste après la recompilation, cela a échoué. Mais, j'ai ensuite quitté Julia et l'ai rouvert et cela a fonctionné correctement. Peut-être est-ce ce qui a causé votre erreur ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X