Планировщик задач Altair PBS Pro
Документация
Описание планировщика и работы с ним содержит много нюансов, полный перевод которых занял бы слишком много времени, а также усложнил бы первоначальное понимание. При возникновении вопросов, не описанных на сайте, рекомендуется обратиться к официальной документации:
- PBS Professional 19.2 User's Guide - руководство пользователя
- PBS Professional 19.2 Reference Guide - справочные материалы
Краткое описание
Программы, выполняемые на комплексе, не запускаются пользователями сразу на выполнение - вместо этого они помещаются в очередь ожидающих задач. Для этого используется команда qsub из пакета Altair PBS Pro, которой в качестве параметра передается скрипт на языке bash, содержащий всю необходимую информацию - какую программу надо запустить и какие ресурсы ей потребуются (количество процессов, оперативной памяти, максимальное время работы, …).
Проверив скрипт и поместив его в очередь, qsub выводит на экран идентификатор задачи вида «XXXXX.vm-pbs», где XXXXX - номер задачи, уникальный для данного управляющего сервера PBS Pro.
Посмотреть статус задачи в очереди можно при помощи команды qstat, в качестве параметра которой опционально можно указать идентификатор интересующей задачи. Удалить свою задачу из очереди можно командой qdel с идентификатором в качестве параметра.
Работающий на сервере планировщик задач контролирует текущее состояние комплекса и при наличии необходимых свободных ресурсов запускает очередной скрипт из очереди. Скрипт запускается только на одном из узлов (называемом 'Mother Superior'), задача распараллеливания возлагается на пользователя и его программу. (В свою очередь, использование в программе стандартов MPI или OpenMP позволяет данную задачу облегчить). Имена узлов, выделенных задаче, и ряд других дополнительных параметров передаются скрипту через переменные окружения.
После завершения скрипта его стандартные потоки вывода и ошибок (stdout и stderr) сохраняются в той же директории в файлы с названиями вида «НазваниеСкрипта.oXXXXX» и «НазваниеСкрипта.еXXXXX» соответственно. Подробнее описано на этой странице. Следует отметить, что при одновременном выводе (например, в stdout) несколькими потоками MPI/OpenMP порядок сообщений в файле будет неопределённым - никакого упорядочивания не производится.
С момента постановки задачи в очередь и до её завершения нельзя изменять файлы, относящиеся к данной задаче - ни скрипт для qsub, ни запускаемое приложение, ни исходные данные. Именно эти самые самие файлы, а не их копии, будут использоваться при работе задачи - поэтому их модификация с большой вероятностью прервёт работу либо приведёт к некорректным результатам.
Основные термины
- cpu (central processing unit, процессор) - микросхема, выполняющая код работающих на компьютере программ. Слово 'процессор' часто некорректно используется вместо термина 'ядро процессора', описанного ниже.
- cpu core (ядро процессора) - часть процессора, способная выполнять свой собственный набор команд. Процессор, содержащий только одно ядро, вынужден постоянно делить его между всеми запущенными программами, выделяя каждой из них своё время. Но в любой момент времени он выполняет только какую-то одну программу. Процессор, содержащий несколько ядер, в каждый момент времени выполняет пропорционально большее количество программ. Для простоты можно представить четырёхядерный процессор как четыре одноядерных, находящихся в корпусе одной микросхемы.
- host - любой компьютер, т.е. физический сервер.
- node (узел) - компьютер, предназначенный для выполнения на нём пользовательских задач с использованием PBS.
- resource (ресурс) - одно из основных понятий, используемых PBS. Ресурсы узла состоят как минимум из его ядер и оперативной памяти. Ресурсы, необходимые задаче пользователя, включают как количество ядер/памяти, так и время, необходимое задаче для работы. Также в виде ресурсов могут выступать, например, лицензии на коммерческое программное обеспечение. Более подробное описание находится ниже.
- vnode (virtual node, виртуальный узел) - часть аппаратных ресурсов узла, для удобства логически объединенная в абстрактный объект. Например, узлы, содержащие по три графических ускорителя, могут быть представлены как три виртуальных узла, каждый из которых содержит по одной карте и равному количеству процессорных ядер и оперативной памяти. Термин 'виртуальный' не подразумевает обязательного использования какого-либо механизма виртуализации и означает только логическое выделение части ресурсов физического узла.
- job (задача) - набор директив, передаваемых пользователем планировщику PBS, с помощью которых указывается, какие ресурсы необходимы и какую программу запускать. Удобно оформлять задачу как скрипт на языке 'bash', хотя возможна и передача всех данных через параметры команды 'qsub'.
- сhunk (блок) - набор ресурсов, выделяемых задаче как целая часть, гарантированно находящаяся на одном узле или виртуальном узле.
- queue ([kju:], очередь) - имеющий собственное имя контейнер для задач, обрабатываемых PBS. Очередь содержит как уже выполняющиеся, так и ожидающие запуска задачи. Завершившиеся задачи очередь покидают. Планировщик использует несколько очередей, например, для запуска задач на узлах разных типов. Каждая задача может находиться только в одной очереди. Буква 'q' в начале названий многих утилит PBS происходит как раз от слова 'queue'. Подробное описание основных очередей находится на этой станице.
Запрос ресурсов
Ресурсы могут относиться к серверу PBS, к очередям или к узлам (виртуальным узлам). Задача запрашивает необходимые ей ресурсы. Ресурсы выделяются, при этом некоторые из них (например, процессорные ядра или оперативная память узла) при выполнении задачи потребляются и освобождаются только после её завершения. Виртуальные узлы, находящиеся на одном сервере, могут разделять свои ресурсы друг с другом.
Ресурсы, относящиеся к серверу PBS или к очереди, используются всей задачей и в запросе указываются в следующем виде: '-l Ресурс=Значение'. Пример такого ресурса - 'walltime', время, необходимое задаче для работы. Если по истечении этого времени задача не завершится сама, то будет прервана принудительно. Указывается в виде 'часы:минуты:секунды'. Например, следующий запрос означает, что задаче достаточно полторы минуты работы:
-l walltime=00:01:30
Ресурсы, относящиеся к узлам (или виртуальным узлам), запрашиваются и выделяются в виде блоков (chunk). Запрос в большинстве случаев можно представить в следующем виде: '-l select=N:chunk', где строка 'chunk' имеет вид 'Ресурс1=Значение1[:Ресурс2=Значение2 …]', а число 'N' - сколько таких блоков требуется. Если нужны блоки разных типов, можно использовать следующую форму запроса: '-l select=N1:chunk1[+N2:chunk2 …]'.
В частности, именно так запрашивается необходимое количество ядер (параметр 'ncpus', хотя логичнее было бы назвать его 'ncores') и оперативной памяти ('mem'). При использовании MPI или OpenMP также надо указать, сколько потоков должно быть запущено в этом блоке, для этого используются параметры 'mpiprocs' и 'ompthreads' соответственно. Например, следующий запрос означает, что задаче необходимы два блока, каждый из которых содержит 4 ядра и 8000 МБ памяти, и на каждом из этих блоков будут запущены 4 MPI процесса:
-l select=2:ncpus=4:mpiprocs=4:mem=8000m
Для указания нужного расположения выделяемых блоков на узлах используется запрос '-l place=[arrangement][:sharing]'
- 'Arrangement' имеет смысл только при запросе более одного блока. Может иметь одно из значений:
- 'pack' - все выделенные блоки должны быть на одном узле.
- 'scatter' - все блоки должны быть на разных серверах.
- 'free' - произвольным образом.
- 'Sharing' может иметь одно из значений:
- 'exclhost' - только эта задача может использовать выделенный узел. Неиспользуемые на узле ресурсы будут недоступны другим задачам.
- 'excl' - только эта задача может использовать выделенный виртуальный узел.
- 'shared' - значение по умолчанию. Задача может разделять ресурсы узла (или виртуального узла) с другими задачами.
Приведённые на сайте примеры задач часто используют 'place=scatter', но это сделано исключительно для демонстрации распараллеливания на несколько узлов. В реальных задачах при использовании распараллеливания использовать scatter не надо, рекомендуется наоборот, по возможности занимать узел целиком. Это позволит исключить взаимное влияние задач разных пользователей друг на друга и упростит мониторинг потребляемых ресурсов. Для этого следует запрашивать количество 'ncpus', равное количеству ядер на используемом сервере.
Важно понимать, что в общем случае запрошенное количество ядер и ОЗУ не приводит автоматически к ограничению запускаемого приложения именно этим количеством ядер и памяти. Интеграция PBS с OpenMP и MPI позволяет передавать запрошенное количество ядер приложению, чтобы оно знало, сколько потоков запустить, но в случае использования каких-то других механизмов распараллеливания это надо отслеживать самостоятельно. Запрашиваемое количество ОЗУ как правило никак не передаётся приложению, для того чтобы оно самостоятельно ограничивало свои потребности, и также не ограничивает память, выделяемую приложению операционной системой. Вместо этого пользователь должен самостоятельно оценивать, сколько памяти потребуется его приложению при работе и сообщать это PBS, чтобы тот учитывал это при планировании.
При запросе ресурсов также необходимо учитывать интересы других пользователей комплекса. В частности, запрашиваемые задачей ресурсы должны совпадать с реально используемыми. Нельзя запрашивать больше, чем будет использоваться, т.к. при этом неиспользуемое будет считаться занятым и будет недоступно другим пользователям, хотя и будет простаивать. Пример - запуск меньшего числа процессов, чем было запрошено процессорных ядер. С другой стороны, использовать больше ресурсов, чем было запрошено, также нельзя, т.к. при этом Вы начинаете использовать ресурсы, которые планировщик считает свободными и выделяет другим задачам. Например, нельзя запускать более одного ресурсоёмкого процесса на одно ядро, кроме случаев, когда задача использует весь узел целиком.
Примеры
Два MPI процесса, каждому требуется по 100 МБ ОЗУ:
- на одном и том же узле:
#PBS -l select=1:ncpus=2:mpiprocs=2:mem=200m
или
#PBS -l select=2:ncpus=1:mpiprocs=1:mem=100m,place=pack
- на разных узлах:
#PBS -l select=2:ncpus=1:mpiprocs=1:mem=100m,place=scatter
- произвольно:
#PBS -l select=2:ncpus=1:mpiprocs=1:mem=100m,place=free
Процесс с 4 потоками под управлением OpenMP, где каждому из четырех потоков требуется по 2000 МБ ОЗУ:
#PBS -l select=1:ncpus=4:ompthreads=4:mem=8000m
Пример задачи
Создадим скрипт «submit.sh» следующего вида:
#!/bin/bash #PBS -l select=1:ncpus=1:mem=2000m #PBS -l walltime=00:01:00 #PBS -m n cd $PBS_O_WORKDIR echo "I run on node: `uname -n`" echo "My working directory is: $PBS_O_WORKDIR" echo "Assigned to me nodes are:" cat $PBS_NODEFILE sleep 15
Строки, начинающиеся с '#PBS', содержат директивы, используемые планировщиком. В частности, запросы ресурсов. Заметим, что для языка 'bash' все строки, начинающиеся с символа '#', являются комментариями и не влияют на работу самого скрипта.
Поставим в очередь командой 'qsub':
qsub submit.sh
15434.vm-pbs
15434 - идентификатор получившейся задачи. Посмотрим её состояние командой 'qstat':
qstat 15434
Job id Name User Time Use S Queue ---------------- ---------------- ---------------- -------- - ----- 15434.vm-pbs submit.sh admin 0 Q workq
Спустя некоторое время в текущей директории появляются файлы «submit.e15434» и «submit.o15434». Первый из них содержит сообщения об ошибках и в случае корректной работы как правило должен быть пустым. Второй файл содержит вывод скрипта и должен выглядеть примерно так:
I run on node: cn15 My working directory is: /mnt/storage/home/admin/examples/pbs Assigned to me nodes are: cn15
После запуска скрипта на узле его текущей директорией будет домашняя директория пользователя. Рекомендуется начинать скрипт с выполнения команды «cd $PBS_O_WORKDIR», изменяющей текущей директории на ту, в которой была выполнена команда 'qsub' при постановке данной задачи в очередь.
Интерактивный режим
В случае, если необходимо интерактивное взаимодействие с работающей программой, используется соответствующий режим запуска задач. В этом режиме после постановки задачи в очередь команда qsub не завершается, а ждёт, когда планировщик выделит запрошенные ресурсы, после чего предоставляет shell на выделенном узле. Если запрошено несколько узлов, доступ предоставляется к одному из них, называемому 'Mother Superior'.
Вторая важная особенность интерактивного режима заключается в том, что из скрипта, передаваемого qsub, используются только опции PBS (строки '#PBS …'), содержимое скрипта не выполняется. Поэтому после получения shell необходимую программу надо запустить самостоятельно, после чего с ней можно работать в интерактивном режиме.
Для запроса у планировщика интерактивного режима надо при вызове qsub дополнительно указать параметр '-I':
qsub -I submit.sh
Либо можно указать этот параметр внутри скрипта submit.sh:
#PBS -I
Может быть удобным отказаться от использования скрипта и все параметры передавать qsub через командную строку:
qsub -I -l select=1:ncpus=1:mem=2000m,walltime=1:0:0
В случае, если будет использоваться система X Window для запуска на узлах программ с графическим интерфейсом, необходимо добавить ключ '-X':
qsub -I -X -l select=1:ncpus=1:mem=2000m,walltime=1:0:0
Если ваша программа отработала и завершилась до истечения walltime, то для завершения самой интерактивной задачи выполните команду 'exit'.
Нюансы
- Вычислительные узлы разных типов доступны при помощи разных очередей задач. Все имеющиеся очереди описаны на этой странице. Очередь можно не указывать, при этом будет использоваться очередь по умолчанию.
- Число полностью свободных узлов каждого типа, а также количество свободных на них ядер, можно узнать с помощью команды 'qfree' или 'qfree -s'. Например:
qfree -s
Free resources: bl2x220g7_long: 10 entire nodes, 185 cores bl2x220g7_mid: 21 entire nodes, 318 cores bl2x220g7_short:22 entire nodes, 330 cores dl560g10_long: 0 entire nodes, 207 cores dl560g10_middle:1 entire nodes, 287 cores dl560g10_short: 2 entire nodes, 367 cores xl230g9_long: 4 entire nodes, 126 cores xl230g9_middle: 6 entire nodes, 174 cores xl230g9_short: 7 entire nodes, 198 cores
- Текущее состояние задач на сервере a6500g10q с ускорителями NVIDIA Tesla V100 можно посмотреть несколькими способами, например, командой 'a6500g10q'.
- Наличие свободных ресурсов не означает, что ваша задача запустится сразу после постановки в очередь. Причины могут быть разные. Например, имеется ограничение на количество ядер, которые пользователь может занять одновременно. Также возможна ситуация, когда планировщий придерживает запуск задач, чтобы набрать необходимые ресурсы для запуска другой задачи, давно ожидающей в очереди.
- Имеется возможность получать по электронной почте уведомления, что задача запустилась, завершилась или была принудительно прервана. Подробное описание есть в PBS User's Guide (ссылка находится в верху страницы) в разделе 'Specifying Email Notification'. Например, для получения всех возможных уведомлений, в скрипт для PBS надо добавить строку:
#PBS -m abe
- Возможно объединение потоков ошибок и стандартного вывода и сохранение их в общий файл, для этого в скрипт нужно добавить:
#PBS -j oe
- Планировщик рассчитывает ориентировочное время запуска задач. Для отображения этой информации используйте команду вида:
qstat -T -u ваш_логин
Или, для определённой задачи:
qstat -f идентификатор_задачи|grep estimated
Ориентировочное время запуска может изменяться и в каких-то ситуациях отсутствовать.
- В некоторых случаях может быть удобно использовать qsub без дополнительного скрипта, указав qsub не только необходимые ресурсы (как в примере использования интерактивного режима), но и какую команду выполнить. Команда указывается после параметра '--', без использования дополнительных кавычек. Например так:
qsub -l select=1:ncpus=1:mem=100m,walltime=0:0:10 -- /bin/uname -a
или, если необходимо выполнить несколько команд:
qsub -l select=1:ncpus=1:mem=100m,walltime=0:0:10 -- /bin/bash -c 'cd $PBS_O_WORKDIR;uname -a;date'
- Если необходимо выполнить большое количество однотипных вычислений (например, обработать 1000 файлов или получить результат какого-то вычисления при большом количестве разных исходных данных) - не надо усложнять и запускать из одной задачи PBS одновременно несколько процессов. Вместо этого следует написать простой скрипт, который на интерфейсном сервере создаст и поставит в очередь столько задач, сколько необходимо.
- Пользователям, ставящим в очередь много задач одновременно, иногда бывает нужно удалить их все (или часть) из очереди. Для этого можно использовать примерно такую команду (в данном случае первые 5 задач будут пропущены):
qdel $( qstat -u ИмяВашейУчетнойЗаписи | awk -F. '{if (NR>5) print $1}' )
Ограничения
Работающие задачи каждого пользователя могут одновременно занять не более 80 ядер. В рамках очереди по умолчанию или очереди xl230g9q действует дополнительное ограничение - не более 72 ядер.
Ограничения на количество доступных GPU сервера a6500g10 описаны на соответствующей странице.