Юлия параллельная функция внутри модуля - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть функция внутри модуля, в которой я хочу динамически изменять количество процессов (addproc).После того, как я раскручиваю эти новые процессы, я хотел бы добавить функцию, которая будет выполняться для каждого из рабочих.Однако у меня возникают трудности с определением этой функции с помощью @everywhere внутри модуля.Я хочу породить эти новые процессы только в функции do_work.Я не хочу порождать новые процессы перед импортом / использованием модуля (это было бы идеальной работой для многопоточности, но моя функция выполняет много операций ввода-вывода, и в настоящее время я получаю segfault в Julia 1.0).

Вот простой рабочий пример моей проблемы.Есть ли способ определить foo на рабочих процессах (в идеале без вызова @everywhere include("somefile_with_foo.jl"))

module Example

using Distributed

function do_work()
    total_procs = nprocs()
    # Make sure we have as many works are cores
    if total_procs < Sys.CPU_THREADS
        addprocs(Sys.CPU_THREADS - total_procs); 
    end

    @everywhere function foo(x::Integer)
        println(x)
    end

    remotecall(foo, 2, 2)

    while nprocs() > total_procs
        rmprocs(procs()[end])
    end
end
end

1 Ответ

0 голосов
/ 17 ноября 2018

Вы не можете использовать @everywhere внутри функции, потому что функция имеет собственную область именования, и эта область не существует в удаленных процессах.

Один вариант (и в большинстве случаев это рекомендуемый подход)чтобы загрузить module на всех рабочих:

@everywhere using Example

И теперь вы можете использовать его функции на удаленных рабочих.

Однако, если вы действительно хотите иметь возможность определять и запускать удаленныефункции, которые вы могли бы использовать метапрограммирование для отправки кода в удаленный процесс.Рассмотрим мою сессию Джулии ниже:

julia> using Distributed

julia> addprocs(1)
1-element Array{Int64,1}:
 2

julia> function do_work(w)
    f_foo = quote 
        function foo(x::Int64)
           println("hello ",x," from ",myid())
        end
    end
    Main.eval(f_foo)
    @fetchfrom w Main.eval(f_foo)
    @fetchfrom w foo(9999)
end
do_work (generic function with 1 method)

julia> do_work(2)
      From worker 2:    hello 9999 from 2
...