Основные сведения
Параллельная программа - это программа, копии которой, запущенные на кластере одновременно, могут взаимодействовать друг с другом в процессе счета.
Программа пользователя должна быть оформлена как функция (не скрипт) и находиться в начале запускаемого файла, т.е. предшествовать возможным другим вспомогательным функциям. Имя файла должно совпадать с именем первой (основной) функции в файле. Одноименная с файлом функция, не являющаяся первой, никогда не будет выполнена, так как независимо от имени всегда выполняется первая функция файла. Файл должен иметь расширение "m
" (Пример параллельной программы).
Для выполнения программы пользователя всегда вызывается программа MatLab.
При запуске программы пользователя на кластере в программе MatLab создаётся объект Job
(работа
) с описанием параллельной работы, которое включает определение объекта Task
(задача
), непосредственно связанного с заданной программой. Можно сказать, что копия работающей программы представлена в системе MatLab объектом Task
.
Каждый объект Job
получает идентификатор (ID
) в системе MatLab, равный порядковому номеру. Нумерация начинается с 1.
Соответствующее имя работы вида Job1
, выдаваемое при запуске, хранится в переменной окружения MDCE_JOB_LOCATION и может быть использовано в программе, а сам объект доступен пользователю во время сеанса MatLab.
Аналогично пользователь имеет доступ и к объектам Task
(задача
), которые также нумеруются с 1. Идентификатор или номер задачи (1,2,...
) - это номер соответствующего параллельного процесса (lab
) и его можно узнать с помощью функции labindex
, а общее число запущенных копий с помощью функции numlabs
.
Имена работы (Job1
), задач (Task1, Task2
,…) используются в процессе вычислений для формирования имен файлов и каталогов, связанных с заданной программой. Так, каталог вида Job1
содержит наборы файлов с информацией по задачам. Имена этих файлов начинаются соответственно с Task1, Task2
, … Например, файлы вывода имеют вид Task1.out.mat, Task2.out.mat
, … и содержат, в частности, выходные параметры функции пользователя (массив ячеек argsout
).
Программа пользователя, оформленная в виде объекта Job
, поступает в распоряжение системы запуска, которая ставит её в очередь на счет с присвоением своего уникального идентификатора.
Система запуска создает каталог вида my_function.1
, например для файла my_function.m
. В этом каталоге пользователю может быть интересен, в частности, файл errors
(см. Возможные ошибки). Заметим, что пользователь должен сам удалять ненужные каталоги вида имя_функции.номер
(номера растут, начиная с 1).
Если ресурсов кластера достаточно, то на каждом участвующем в вычислении процессоре (ядре для многоядерных процессоров) начинает выполняться копия программы-функции пользователя при условии наличия достаточного числа лицензий (в настоящее время система запуска не контролирует число лицензий, доступность лицензий определяется в начале счета).
Пользователь может контролировать прохождение своей программы через систему запуска как в окне системы Matlab, например, с помощью Job Monitor (см. п. Доступ к объекту Job ), так и из командной строки с помощью команд системы запуска (запросить информацию об очереди, удалить стоящую в очереди или уже выполняющуюся программу).
Действия пользователя
Войти на кластер (с помощью PuTTY или MobaXterm) и запустить программу-функцию из командной строки или в окне системы Matlab, указав необходимое для счета число параллельных процессов и максимальное время выполнения в минутах.
В ответ пользователь должен получить сообщение вида:
Job output will be written to: /home/u1303/Job1.mpiexec.out
где Job1
- имя сформированной работы, 1
- идентификатор работы
(/home/u1303
- домашний (личный) каталог пользователя).
Замечание. Для локализации результатов вычислений рекомендуется осуществлять запуск программы (даже в случае запуска встроенных функций Matlab ) из рабочего каталога, специально созданного для данной программы в домашнем каталоге.
Запуск параллельной программы из командной строки
Команда запуска mlrun
имеет вид
mlrun -np <number_of_procs> -maxtime <mins> <func> ['<args>']
где<number_of_procs>
- число параллельных процессов (копий программы)<mins>
- максимальное время счета в минутах<func>
- имя файла с одноименной функцией (например, my_function
)<args>
- аргументы функции (не обязательный параметр) берутся в одиночные кавычки и представляются в виде
k,{arg1,...,argn}
где k
- число выходных аргументов функции, а в фигурных скобках список ее входных аргументов. При отсутствии аргументов у функции, что соответствует "0,{}
", их можно опустить. Например, для файла my_function.m
с одноименной функцией без параметров запуск имеет вид:
mlrun -np 8 -maxtime 20 my_function
где 8 - число процессов, 20 - максимальное время счета в минутах.
Запуск параллельной программы в окне Matlab
В командном окне Matlab (Command Window) вызвать служебную функцию imm_sch
, которой в качестве параметров передать число процессов, время выполнения и предназначенную для параллельных вычислений функцию с аргументами или без, сохраняя (рекомендуется) или не сохраняя в переменной (например, job
) ссылку на созданный объект Job
(имя функции набирается с символом "@" или в одиночных кавычках):
job = imm_sch(np,maxtime,@my_function,k {arg1,...,argn});
или
job = imm_sch(np,maxtime,'my_function',k,{arg1,...,argn});
Так, для примера выше запуск в окне Matlab будет иметь вид:
job = imm_sch(8,20,@my_function);
Доступ к объекту Job, состояние работы
Все работы хранятся на кластере. При необходимости доступа к работе, на которую в текущий момент отсутствует ссылка, можно (1) в окне Job Monitor правой кнопкой мыши выделить нужную работу и выбрать соответствующую опцию в контекстном меню или (2) по идентификатору (ID
) определить ссылку на работу (обозначенную ниже job
), используя, например, команды:
c = parallel.cluster.Generic
job = c.findJob('ID',1)
Состояние работы (State
) можно:
(1) увидеть в окне Job Monitor или
(2) выдать в окне Command Window, набрав
job.State
Основные значения состояния работы следующие:
pending
(ждет постановки в очередь)
queued
(стоит в очереди)
running
(выполняется)
finished
(закончилась)
Окончания счета (состояние finished
) можно ждать с помощью функции wait
, wait(job)
или job.wait()
Примечание.
Вышеприведенные команды предназначены для версий MatLab с профилем кластера, т.е. начиная с R2012a. В ранних версиях (с конфигурацией кластера) следует набирать:
s = findResource('scheduler', 'type', 'generic')
job = findJob(s,'ID',1)
При этом в поле DataLocation
структуры s
должен быть текущий каталог (тот, в котором ищем работу). Если каталог другой, то можно выполнить
clear all
и повторить предыдущие команды.
В окне Matlab (с R2012a) для работы job
и любой ее задачи (Task
) с номером n=1,2,...
можно выдать (далее для удобства n=1)
1) протокол сеанса:
job.Tasks(1).Diary
2) информацию об ошибках (поле ErrorMessage
):
job.Tasks(1)
или job.Tasks(1).ErrorMessage
3) результаты (значения выходных параметров) работы job
в целом (по всем Task
-ам):
out = job.fetchOutputs
Тогда для 1
-ой задачи (Task
) значение единственного выходного параметра:
res = out{1}
В случае нескольких выходных параметров соответственно имеем для 1-го, 2-го, ... :
res1 = out{1,1}
res2 = out{1,2}
Другой способ выдачи результатов по задачам
out1 = job.Tasks(1).OutputArguments
Замечания.
1. Эту же информацию можно выдать, запустив Matlab в интерактивном текстовом режиме (matlab -nodisplay
) и набирая затем упомянутые команды.
2. Если ссылка на работу (job
) отсутствует, то ее можно найти по идентификатору.
3. Для ранних версий (до R2012a) следует использовать следующие команды, чтобы выдать
1) протокол сеанса:
job.Tasks(1).CommandWindowOutput
3) результаты (значения выходных параметров) работы job
в целом (по всем Task
-ам):
out = job.getAllOutputArguments
1. Начать работу на кластере рекомендуется с запуска своей последовательной программы в тестовом однопроцессном варианте, например,
mlrun -np 1 -maxtime 20 my_function
где my_function
– функция без параметров, максимальное время счета 20 минут.
2. После преобразования последовательной программы в параллельную её работоспособность можно проверить, выполняя шаги, приведенные в пункте Как убедиться в работоспособности программы при рассмотрении примеров с распределенными массивами.
Пример запуска программы
Для запуска программы на кластере используем функцию rand
, вызываемую для генерации 2х3 матрицы случайных чисел (традиционный вызов функции: y = rand(2,3)
).
Для получения 4 экземпляров матрицы задаем число процессов, равное 4. Максимальное время счета пусть будет равно 5 минутам.
Запускать функцию будем на кластере "Уран" (umt) в каталоге test
, специально созданном заранее в домашнем каталоге пользователя /home/u9999
, где u9999
– login пользователя (см. Схема работы на кластере и Базовые команды ОС UNIX).
Для запуска функции rand
из командной строки используется команда mlrun
,
а из системы Matlab – служебная функция imm_sch
.
Для запуска из командной строки войти на umt через PuTTY и выполнить команду
mlrun -np 4 -maxtime 5 rand '1,{2,3}'
Для запуска из окна Matlab войти на umt из MobаXterm, вызвать Matlab командой
matlab &
и в открывшемся окне набрать
job = imm_sch(4,5,@rand,1,{2,3});
где job
– ссылка на сформированную работу.
Можно работать в системе Matlab, войдя на umt через PuTTY и запустив её в интерактивном текстовом режиме командой
matlab -nodisplay
В ответ на приглашение (>>
) следует соответственно набрать
job = imm_sch(4,5,@rand,1,{2,3});
Выход из Matlab осуществляется по команде exit
.
После выполнения mlrun
или imm_sch
выдается строка вида
Job output will be written to: /home/u9999/test/Job1.mpiexec.out
где Job1
- имя сформированной работы, 1
- идентификатор (номер) работы.
Если ресурсов кластера достаточно, задача войдет в решение (см. Запуск задач на кластере). Иначе для ускорения запуска на кластере небольших (отладочных) задач можно вместо выделенного задаче раздела назначить debug
командой вида:
scontrol update job 8043078 partition=debug
где 8043078 — уникальный идентификатор (JOBID) задачи.
Дожидаемся окончания задачи, т.е. job.State
должно быть finished
.
В окне Matlab контролировать состояние задачи удобно с помощью Job Monitor.
Результаты выдаем с помощью команд:
со всех процессов
out = job.fetchOutputs
а для выдачи матрицы, полученной 1-ым процессом (т.е. Task1
)
out{1}
и т.д.
Для выдачи результатов ранее посчитанной работы, на которую в текущий момент нет ссылки, следует обеспечить к ней доступ, например используя Job Monitor.