Вызов numpy на параллельных процессорах в ноутбуке IJulia

Я хочу запустить простой код в блокноте IJulia, который использует библиотеку python numpy. Я называю NumPy с PyCall:

используя PyCall

@pyimport numpy as np

Это отлично работает. Затем я хочу разделить это на несколько процессоров. Я добавляю процессоры:

addprocs (4)

Затем я запускаю N/proc итерации для функции f, где proc - это количество процессоров. Я равномерно распределил нагрузку между четырьмя процессорами на моем компьютере:

n=round(Int,N/proc);

proc_sum = @parallel (+) for i=1:proc

        f(n)

end

return proc_sum / proc

Без NumPy это работает нормально. Однако, когда я пытаюсь разделить код с NumPy на разные процессоры, я получаю сообщение об ошибке

ОШИБКА (необработанный сбой задачи): на работнике 3:

UndefVarError: np не определено

Есть ли способ заставить работать на других процессорах неряшливо? Обратите внимание, что у меня есть Julia 0.5.2, и у меня есть Canopy. Я знаю, что ранее сообщалось о проблемах с PyCall и Canopy, но я бы предпочел оставить Canopy на своей машине.

2 ответа

Решение

Чтобы еще больше расширить сказанное, все, что вам нужно, должно быть загружено во все процессы. Например:

addprocs(4) @everywhere using PyCall @everywhere @pyimport numpy as np

То, что вы написали с ошибкой, потому что все процессы пытались использовать @pyimport но только основной процесс PyCall загружен. Если вам требуется много пакетов для выполнения вычислений, возможно, проще будет выполнить всю загрузку в одном скрипте, т.е. load_modules.jl а потом просто беги

addprocs(4) @everywhere include("load_modules.jl")

РЕДАКТИРОВАТЬ: Кажется, что using не очень крепко с @everywhere (исправлено на Julia 0.6, см. здесь). Что, кажется, работает лучше:

addprocs(4) import PyCall @everywhere using PyCall @everywhere @pyimport numpy as np

Я расширяю комментарий Линдона, чтобы дать более полный ответ.

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

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

Так:

addprocs(4); # create 4 extra processes (i.e. workers); this is in addition
             # to the main process that handles the REPL

@everywhere import Pycall
@everywhere PyCall.@pyimport numpy as np # load module on _all_ 5 active processes
Другие вопросы по тегам