Вызов 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