Кластер: запуск на нескольких компьютерах

Предпочтительный способ запустить кластер

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

См. julia --help или документацию на сайте.

Возможно программно запускать, настраивать и останавливать воркеры

Исследование этого способа дает приблизительное представление, о том как работает встроенный менеджер кластера.

С компьютера (comp1) можно запустить один или несколько процессов julia, работающих на другом компьютере (comp2). Это можно сделать либо: 1) указав параметры командной строки при запуске главного julia-процесса 2) либо программно - вызывая с главного процесса функции добавления новых процессов.

В любом случае: 1) компьютер comp2 должен быть доступен для выполнения команд с компьютера comp1 по ssh с беспарольным доступом (по ключам). См. документацию по ssh. 2) на обоих компьютерах по должна быть доступна одна и та же версия julia, расположенная по одному и тому же абсолютному пути. При несоблюдении этих условий, при попытке с главного процесса запустить удаленный, будет возвращена ошибка.

Рассмотрим пример программного управления:

На comp1 запускаем REPL: julia Проверим, на каком компьютере запущен этот процесс:

run(`hostname`) # - comp1 - возвращена строка с именем текущего хоста

Проверим количество запущенных процессов (локальных или удаленных):

nprocs() # 1 - возвращено число

Запустим на comp2 новый процесс:

addprocs(["comp2"]) # 2 - возвращен номер в кластере (не путать с номером процесса в системе) запущенного процесса.

nprocs() # 2 - теперь запущено два процесса

Попросим второй процесс выполнить run(hostname) и посмотрим, что он вернет:

remotecall_fetch(2,run,`hostname`) # From worker 2: comp2

Обратите внимание: удаленному процессу (2) мы передаем отдельно имя вызываемой функции (run) и отдельно - параметр для этой функции (объект hostname типа Cmd).

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

Пусть просесс 2 дополнит пути поиска библиотек, чтобы мы могли подключить свой модуль, расположенный по пути /home/my_user_name/path_to_my_libs/src на машине comp2:

remotecall_fetch(2, push!, LOAD_PATH, "/home/my_user_name/path_to_my_libs/src" )

В ответе REPL выведет содержимое массива LOAD_PATH второго процесса.

Подключим какой-нибудь модуль: для этого в главном процессе можно выполнить команду: using , где my_module - имя подключаемого модуля.

using: В главном процессе команда using подключит модуль my_module и импортирует в текущее пространство имен экспортируемые модулем my_module имена.

В воркерах, в нашем случае на просессе 2, работающем на comp2 using только подключает модуль, не выполняя импорта. Таким образом, если в главном процессе вызвать импортированную из my_module функию my_func можно так: my_func(param1,param2), то на процессе 2 это нужно делать так: my_module.my_func(param1,param2), а полностью (с использованием remotecall_fech):

remotecall_fetch(2, my_module.my_func, param1, param2)

Если все сделано правильно - в ответе PERL вы увидите возвращенное с хоста comp2 функцией my_func значение.

Note. Попытка выполнить remotecall_fetch(2, using, my_module) приведет к ошибке, потому что using - не функция.

Набор макросов: @spawn(),@spawnat(),@fetch(),@fetchfrom() и @everywhere() позволяет не разлагать удаленный вызов на имя функции и ее аргументы, а использовать обычный синтаксис вызова функций.

Сейчас наиболее интересен макрос @everywhere(), который позволяет программно выполнить на всех воркерах любое выражение (а не только сделать вызов функции) из главного процесса. Например, можно объявить функцию на всех удаленных процессах:

@everywhere myfunc1(x) = x+x

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

@everywhere begin
  push(LOAD_PATH,"/usr/local/rle/var/share3/TIKETS/juice/J/src")
  using J
end

@fetchfrom выполняет выражение на указанном по номеру воркере и возвращает результат на вызвавшую машину.

Можно передать ему блок кода, внутри которого сделать нужные объявления и вызовы:

@fetchfrom 2 begin myfunc(x) = x+x myfunc(3) end

В отличие от @everywhere, объявленная функция не сохранится в пространстве имен воркера 2.

results matching ""

    No results matching ""