Подтвердить что ты не робот

Параллельное программирование Julia - Предоставление существующей функции всем работникам

Я столкнулся со следующей проблемой:

У меня есть функция с именем TrainModel, которая работает очень долго в одном потоке. Когда он заканчивает вычисления, он возвращает функцию в качестве выходного аргумента, пусть назовет ее f. Когда я задаю тип этого f, Джулия возвращает:

(общая функция с 1 методом)

(я не уверен, что эта последняя информация полезна для всех, кто это читает)

Теперь на втором этапе мне нужно применить функцию f к очень большому массиву значений. Это шаг, который я хотел бы распараллелить. Запустив Julia с несколькими процессами, например

julia -p 4

в идеале я бы использовал:

pmap(f, my_values)

или, возможно:

aux = @parallel (hcat) for ii=1:100000000
        f(my_values[ii])
      end

К сожалению, это не работает. Юлия жалуется, что работники не знают о функции f, то есть я получаю сообщение:

ОШИБКА: функция f не определена в процессе 2

Как я могу сделать функцию f доступной для всех работников? Очевидно, что "грязным" решением будет выполнение отнимающей много времени функции TrainModel для всех рабочих, например, это возможно:

@everywhere f = TrainModel( ... )

но это будет пустой тратой процессора, когда все, что я хочу, это то, что только результат f доступен всем работникам.

Хотя я искал сообщения с похожими проблемами, до сих пор я не мог найти ответ...

Спасибо заранее! лучше,

Н.

4b9b3361

Ответ 1

Подход к возврату функции кажется элегантным, но, к сожалению, в отличие от JavaScript, Julia не решает все переменные при создании функций. Технически ваша обучающая функция может генерировать исходный код функции с буквальными значениями для всех подготовленных параметров. Затем передайте его каждому рабочему процессу, который может анализировать его в своей среде на вызываемую функцию.

Я предлагаю вернуть структуру данных, которая содержит всю информацию для создания обучаемой функции: веса ANN, векторов поддержки, правил принятия решений... Определите "обученную" функцию для рабочих процессов, чтобы она использовала подготовленные параметры. Возможно, вы захотите иметь возможность сохранять результаты обучения на диске в любом случае, чтобы вы могли легко перепрограммировать свои вычисления.

Ответ 2

Существует решение, основанное на Unix, основанное на пакете PTools.jl(https://github.com/amitmurthy/PTools.jl).

Он полагается на parallelism через forking вместо встроенного механизма Julia. Формованные процессы порождаются с тем же рабочим пространством, что и основной процесс, поэтому все функции и переменные доступны непосредственно работникам.

Это похоже на кластеры Fork в R параллельном пакете, поэтому его можно использовать как функцию mclapply.

Интересующей функцией является pfork (n:: Integer, f:: Function, args...) и одна заметная разница с mclapply в R состоит в том, что функция f должна принимать в качестве первого аргумента индекс рабочего.

Пример:

Pkg.add("PTools")
Pkg.checkout("PTools") #to get the last version, else the package does not build at the time of writing

using PTools
f(workid,x) = x[workid] + 1
pfork(3, f, [1,2,3,4,5]) #Only the three first elements of the array will be computed

3-element Array{Any,1}:  
 2  
 3  
 4  

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