Содержание

Планировщик задач Altair PBS Pro

Документация

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

Краткое описание

Программы, выполняемые на комплексе, не запускаются пользователями сразу на выполнение - вместо этого они помещаются в очередь ожидающих задач. Для этого используется команда 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, ни запускаемое приложение, ни исходные данные. Именно эти самые самие файлы, а не их копии, будут использоваться при работе задачи - поэтому их модификация с большой вероятностью прервёт работу либо приведёт к некорректным результатам.

Основные термины

Запрос ресурсов

Ресурсы могут относиться к серверу 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]'

  1. 'Arrangement' имеет смысл только при запросе более одного блока. Может иметь одно из значений:
    • 'pack' - все выделенные блоки должны быть на одном узле.
    • 'scatter' - все блоки должны быть на разных серверах.
    • 'free' - произвольным образом.
  2. 'Sharing' может иметь одно из значений:
    • 'exclhost' - только эта задача может использовать выделенный узел. Неиспользуемые на узле ресурсы будут недоступны другим задачам.
    • 'excl' - только эта задача может использовать выделенный виртуальный узел.
    • 'shared' - значение по умолчанию. Задача может разделять ресурсы узла (или виртуального узла) с другими задачами.


Приведённые на сайте примеры задач часто используют 'place=scatter', но это сделано исключительно для демонстрации распараллеливания на несколько узлов. В реальных задачах при использовании распараллеливания использовать scatter не надо, рекомендуется наоборот, по возможности занимать узел целиком. Это позволит исключить взаимное влияние задач разных пользователей друг на друга и упростит мониторинг потребляемых ресурсов. Для этого следует запрашивать количество 'ncpus', равное количеству ядер на используемом сервере.

Важно понимать, что в общем случае запрошенное количество ядер и ОЗУ не приводит автоматически к ограничению запускаемого приложения именно этим количеством ядер и памяти. Интеграция PBS с OpenMP и MPI позволяет передавать запрошенное количество ядер приложению, чтобы оно знало, сколько потоков запустить, но в случае использования каких-то других механизмов распараллеливания это надо отслеживать самостоятельно. Запрашиваемое количество ОЗУ как правило никак не передаётся приложению, для того чтобы оно самостоятельно ограничивало свои потребности, и также не ограничивает память, выделяемую приложению операционной системой. Вместо этого пользователь должен самостоятельно оценивать, сколько памяти потребуется его приложению при работе и сообщать это PBS, чтобы тот учитывал это при планировании.

При запросе ресурсов также необходимо учитывать интересы других пользователей комплекса. В частности, запрашиваемые задачей ресурсы должны совпадать с реально используемыми. Нельзя запрашивать больше, чем будет использоваться, т.к. при этом неиспользуемое будет считаться занятым и будет недоступно другим пользователям, хотя и будет простаивать. Пример - запуск меньшего числа процессов, чем было запрошено процессорных ядер. С другой стороны, использовать больше ресурсов, чем было запрошено, также нельзя, т.к. при этом Вы начинаете использовать ресурсы, которые планировщик считает свободными и выделяет другим задачам. Например, нельзя запускать более одного ресурсоёмкого процесса на одно ядро, кроме случаев, когда задача использует весь узел целиком.

Примеры

Два MPI процесса, каждому требуется по 100 МБ ОЗУ:


Процесс с 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'.

Нюансы

  1. Вычислительные узлы разных типов доступны при помощи разных очередей задач. Все имеющиеся очереди описаны на этой странице. Очередь можно не указывать, при этом будет использоваться очередь по умолчанию.
  2. Число полностью свободных узлов каждого типа, а также количество свободных на них ядер, можно узнать с помощью команды '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
  3. Текущее состояние задач на сервере a6500g10q с ускорителями NVIDIA Tesla V100 можно посмотреть несколькими способами, например, командой 'a6500g10q'.
  4. Наличие свободных ресурсов не означает, что ваша задача запустится сразу после постановки в очередь. Причины могут быть разные. Например, имеется ограничение на количество ядер, которые пользователь может занять одновременно. Также возможна ситуация, когда планировщий придерживает запуск задач, чтобы набрать необходимые ресурсы для запуска другой задачи, давно ожидающей в очереди.
  5. Имеется возможность получать по электронной почте уведомления, что задача запустилась, завершилась или была принудительно прервана. Подробное описание есть в PBS User's Guide (ссылка находится в верху страницы) в разделе 'Specifying Email Notification'. Например, для получения всех возможных уведомлений, в скрипт для PBS надо добавить строку:
    #PBS -m abe
  6. Возможно объединение потоков ошибок и стандартного вывода и сохранение их в общий файл, для этого в скрипт нужно добавить:
    #PBS -j oe
  7. Планировщик рассчитывает ориентировочное время запуска задач. Для отображения этой информации используйте команду вида:
    qstat -T -u ваш_логин

    Или, для определённой задачи:

    qstat -f идентификатор_задачи|grep estimated 

    Ориентировочное время запуска может изменяться и в каких-то ситуациях отсутствовать.

  8. В некоторых случаях может быть удобно использовать 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'
  9. Если необходимо выполнить большое количество однотипных вычислений (например, обработать 1000 файлов или получить результат какого-то вычисления при большом количестве разных исходных данных) - не надо усложнять и запускать из одной задачи PBS одновременно несколько процессов. Вместо этого следует написать простой скрипт, который на интерфейсном сервере создаст и поставит в очередь столько задач, сколько необходимо.
  10. Пользователям, ставящим в очередь много задач одновременно, иногда бывает нужно удалить их все (или часть) из очереди. Для этого можно использовать примерно такую команду (в данном случае первые 5 задач будут пропущены):
    qdel $( qstat -u ИмяВашейУчетнойЗаписи | awk -F. '{if (NR>5) print $1}' )

Ограничения

Работающие задачи каждого пользователя могут одновременно занять не более 80 ядер. В рамках очереди по умолчанию или очереди xl230g9q действует дополнительное ограничение - не более 72 ядер.

Ограничения на количество доступных GPU сервера a6500g10 описаны на соответствующей странице.