Проект

Общее

Профиль

Ответы на часто задаваемые вопросы

См. руководство.

Компиляция

Устаревшая архитектура

При компиляции появляется предупреждение:

$ nvcc file.cu -o file.o
nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).

Оно означает, что в используемой сейчас CUDA версии 8.0 архитектура compute_20 считается устаревшей и при переходе на версию 9.0 её поддержка будет удалена. Это своего рода глобальное широковещательное предупреждение от разработчиков CUDA для пользователей о тенденциях в поддержке архитектур в долгосрочной перспективе. Его можно отключить с помощью ключа -Wno-deprecated-gpu-targets.

Производительность системы

Медленный обмен с диском

В настоящее время домашние каталоги пользователей кластера раздаются на узлы через относительно медленный ethernet (nfs). Для задач, критичных к скорости обмена с диском, необходимо либо предварительно копировать данные на конкретный узел выполнения в папку /tmp (она для каждого узла своя), либо запускать задачу на узле jupiter1 (к нему физически подключен каталог /home), указывая этот узел в строке запроса ресурсов :host=jupiter1.

Как ставить задачу в очередь?

Задача ожидает, но ресурсы есть

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

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

Если вы можете оценить время выполнения своей задачи, например, она будет вычисляться не более 24 часов, то можно задать параметр walltime при запросе ресурсов:

#PBS -l walltime=24:00:00

Для уже запущенной задачи можно изменить этот параметр с помощью команды:

qalter -l walltime=24:00:00 <номер задачи>

Планировщик может пропускать вперед другие задачи, для которых задан этот параметр.

Странные ошибки

Одна из регулярно появляющихся ошибок связана с тем, что файл задачи, который интерпретирует планировщик, сохранен в кодировке windows-1251. Это типичная проблема Windows и Unix кодировок: CRLF и LF.

В случае появления в логе ошибок вида:

$'\r': command not found
или
cd: /home/username/directoryM: No such file or directory
и полностью непонятного поведения системы при постановке задачи в очередь даже с простейшими файлами задачи, скорее всего проблема именно в этом.

Решение: создать файл в кодировке linux (по-умолчанию это utf8), скопировать туда нужный текст файла задачи и сохранить его.

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

Количество mpi-процессов

В случае несимметричных запросов, например

#PBS -l select=1:mpiprocs=10:ncpus=80+4:mpiprocs=20:ncpus=160
использование mpirun параметра -npernode некорректно, поскольку этот параметр указывает на количество mpi-процессов, которые будут запущены на каждом узле. А при таком запросе на 1 узле будет 10 mpi-процессов, а на остальных — по 20. Параметр -np должен быть согласован с общим количеством mpi-процессов, здесь он должен быть равен 90.

Параметр mem

Запущенная задача потребляет какое-то количество оперативной памяти. Для каждой запущенной (и для завершенной, информация о которой еще хранится в планировщике) задачи это значение (в килобайтах) можно выяснить, выполнив команду:

qstat -xf xxxxx | grep used.mem
где xxxxx — номер задачи. Например, это значение оказалось таким:
resources_used.mem = 118936448kb
Это означает, что необходимо в строке запроса ресурсов указать параметр mem, например так:
#PBS -l select=1:mpiprocs=1:ncpus=8:mem=122gb
здесь значение указывается в гигабайтах. Если заказать памяти меньше, чем потребит задача, она завершится с ошибкой, когда планировщик зафиксирует превышение. Поэтому, значение надо выбирать с небольшим запасом, оценивая сверху. Если заказать памяти гораздо больше, чем потребит задача, это приведет к тому, что планировщик не сможет размещать другие задачи и ресурсы будут простаивать. Для задач, которые потребляют много памяти - десятки и сотни гигабайт, бывает сложно "пристреляться" к оптимальной оценке. В таком случае рекомендуется двигаться от больших значений к меньшим: случай завышения оценки размера памяти лучше, чем случай, когда задача принужденно снимается планировщиком.

Что может произойти если для задач, запущенных на общем узле, не указан этот параметр. Планировщик не сможет установить, что очередную задачу необходимо разместить на другом узле. Вследствие этого, размер оперативной памяти узла (порядка 251 Гб) окажется превышен, и ОС начнет свопить данные на жесткий диск, что в значительной степени негативно скажется на быстродействии.

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

Заявленные ресурсы не соответствуют потребляемым

Например, задача запрашивает

#PBS -l select=1:mpiprocs=16:ncpus=4:ngpus=1
т.е. 4 потока CPU и 1 GPU. При этом, она не потребляет GPU совсем, и при выполнении создает 16 процессов. В этом случае, правильным запросом ресурсов был бы такой:
#PBS -l select=1:mpiprocs=16:ncpus=128:mem=200gb
поскольку каждому процессу наиболее комфортно занимать 8 потоков CPU (20 процессорных ядер на узле соответствуют 160 потокам CPU).

Превышение размера чанка

Такой запрос

#PBS -l select=1:mpiprocs=2:ncpus=16:ngpus=4
никогда не выполнится, поскольку на каждом узле доступно 2 GPU и чанка (части узла) с 4 GPU нет. Правильным был бы такой запрос:
#PBS -l select=2:mpiprocs=1:ncpus=8:ngpus=2
в котором запрашиваются те же ресурсы, но двумя чанками, вместо одного. Они разместятся на двух узлах.

Ошибка Ncpus resource is not a multiple of 8 при постановке задачи в очередь

Теперь количество ncpus, указываемое в скрипте, должно быть кратно 8. Необходимо изменить соответствующие значения: ncpus=1 поменять на ncpus=8, ncpus=2 на ncpus=16 и так далее. Если значение ncpus уже было кратно 8, то менять его не обязательно, но следует учитывать, что значение ncpus/8 соответствует числу процессорных ядер, которое будет выделено для задачи. Рекомендуется выделять по 1 ядру на каждый mpi-процесс.

Простой запуск задачи

Наиболее простой способ использования планировщика — это интерактивный запуск управляющей консоли. При этом все дальнейшие действия пользователя в консоли будут выполнятся в рамках созданной планировщиком задачи.

Пример запуска Jupyter Notebook в интерактивной задаче

В данном примере https://github.com/AlbertDeFusco/qJuypter запускается интерактивная консоль, в ней запускается Jupyter Notebook с использованием случайного порта, для доступа к произвольному узлу кластера используется SSH туннель.

Запуск задачи через скрипт

Для постановки любой задачи в очередь используется скрипт запуска. В случае, если необходимо запустить какую-то непараллельную задачу (не использующую mpiexec или mpirun), например, скрипт на питоне, то необходимо просто указать строку запроса ресурсов, минимально необходимых для задачи

#PBS -l select=1:ncpus=8:mem=1gb
или
#PBS -l select=1:ncpus=8:ngpus=1:memg=1gb
в случае запроса одного GPU.

Полный скрипт запуска может выглядеть так:

[user@jupiter solver]$ cat job.qsub
#PBS -k oe
#PBS -l select=1:ncpus=8:memg=1gb
#PBS -r n
#PBS -M user@mail.com
#PBS -m abe
#PBS -q workq
#PBS -N solver
#!/bin/sh

cd /home/user/test/solver

python script.py

exit 0

Подробно о всех значениях параметров скрипта запуска написано в руководстве.

Ограничения планировщика

При определенных условиях задача может не запускаться планировщиком.

Пример неудачного совпадения ограничений

Задача требует ресурсы 1:ncpus=20:ngpus=1:memg=4gb:host=jupiter1, то есть фиксирует хост выполнения значением jupiter1. Такое расположение обусловлено требованием задачи к скорости дисковой подсистемы, которая ограничена тем, что NFS пока работает через Ethernet, а не через Infiniband.

В то же время, половина узла jupiter1[0] отдана быстрой очереди fastq, то есть недоступна для обычных задач.

Поэтому, какая-то задача не может быть запущена, хотя формально ресурсы jupiter1[0] свободны.

Кроме того, если какой-то пользователь запускает свои задачи в обход планировщика, то формально доступные в планировщике ресурсы на самом деле оказываются занятыми.

Странное поведение системы

При использовании утилит tmux или screen, процесс, из под которого запускаются остальные процессы, может иметь очень большое время жизни, т.е. он был запущен очень давно. Настройки окружения на кластере периодически обновляются, а в этом случае наследуемые процессы будут запущены с устаревшими настройками. Рекомендуется перезапустить tmux (screen), чтобы эти процессы стартовали с актуальными настройками окружения.

Превышена квота

Посмотреть текущее значение квоты можно командой:

quota -s -f /home
При этом текущее значение занятого места выводится в столбце space.
При необходимости можно увеличить дисковую квоту, связавшись с технической поддержкой.
Частая причина роста занятого места — дублирование путем копирования объемных входных данных задач вместо того, чтобы использовать одни и те же данные на диске для разных задач, применяя, например, символьные ссылки.

Задачи остаются висеть со статусом E

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

#PBS -k oe
которая означает, что планировщик будет размещать эти файлы в домашней директории пользователя, не копируя их в директорию запуска задачи.

Обновление ПО

TODO: Сформулировать порядок обновления ПО на кластере, в том числе в контейнерах.

Общесистемные версии пакетов ограничиваются значениями, доступными из репозиториев, например:

singularity.ppc64le                                         2.2.1-3.el7                                         epel

Примеры CUDA и opencv

Файл helper_cuda.h входит в набор samples стандартной поставки cuda и доступен здесь:

/usr/local/cuda-8.0/samples/common/inc/helper_cuda.h

В различных файлах Makefile, которые встречаются при сборке примеров из samples, путь используется относительный, например:
INCLUDES  := -I../../common/inc

Обычно копируется весь набор samples/common
cp -R /usr/local/cuda-8.0/samples/common project-path/
и пути до common/inc прописываются самостоятельно.

Пакет opencv-devel версии 2.4.5 установлен, список файлов можно посмотреть командой:

repoquery --list opencv-devel

Библиотеки расположены в стандартном месте /usr/lib64, а путь к include файлам также является стандартным относительно /usr/include. Поэтому, в каждом проекте эти пути добавляются самостоятельно.

Обновление версии Singularity

Мы собираем новые версии из исходников

$ ls /opt/soft/singularity/
2.3  2.3.1  2.4  2.4.2
и тестируем их.

keras в модуле tensorflow/1.1.0

Если ввести команды:

module add tensorflow/1.1.0
python-pai
import keras
keras.__version__
то видно, что версия 2.0.8. В версии 2.0.9 в утилитах есть поддержка распараллеливания по нескольким GPU.

Установить образ

Вопрос установки какого-либо образа Docker (например, docker pull tensorflow/tensorflow:latest-gpu) или Singularity (например, singularity pull shub://belledon/tensorflow-keras:latest).

Проблема ppc64le

Основная проблема НЕ в том, использовать ли Docker или Singularity, поскольку Linux-контейнеры, в принципе, стандартизированы. И можно с помощью Singularity, например, запускать Docker-контейнеры.

Основная проблема в том, что:
1) для архитектуры x86 все хорошо, можно собрать контейнер на домашнем компьютере и запустить его на кластере с соответствующей архитектурой. Или использовать готовый контейнер из множества доступных: https://hub.docker.com/explore/, в том числе и tensorflow/tensorflow.
2) Но для архитектуры ppc64le процессоров POWER8 кластера jupiter.febras.net ситуация иная. Множество доступных контейнеров Docker Hub ограничивается списком https://hub.docker.com/u/ppc64le/. Например, официально поддерживаемого контейнера Tensorflow для ppc64le просто нет, в отличии от x86. Есть официально поддерживаемые базовые контейенеры Ubuntu, CentOS и некоторые другие, на основе которых можно собирать требуемые контейнеры.

Мы ведем работы в направлении сборки нужных контейнеров под ppc64le на основе базового контейнера ppc64le/ubuntu, например:

$ ls /opt/soft/powerai/container/
python-265  python27-294  python35-294  python-pai
Собрано несколько контейнеров по заявкам 74, 265, 294, здесь описан процесс использования контейнера TensorFlow.

Зачем использовать образ?

Подразумевается, что образ(контейнер) содержит некоторый UDSS (User Defined Software Stack; Набор пакетов, определяемый пользователем). Было бы удобно взять набор пакетов (Software Stack), связанных между собой и решающих определенную пользовательскую задачу (User Defined), сборка и отладка которых уже была осуществлена однажды кем-то, и использовать его повторно на другом оборудовании.

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

В случае архитектуры ppc64le, круг людей, заинтересованных в создании и использовании образов под эту архитектуру, ограничивается администраторами и пользователями соответствующих кластеров.

Создать образ

Насколько сложно, имея рецепт создания образа(контейнера) для x86, например Dockerfile или Singularity, пересоздать его под архитекутуру ppc64le? В некоторых случаях достаточно просто, если все пакеты из UDSS внутри этого образа, безболезненно устанавливаются под архитектурой ppc64le. В остальных случаях, для каждого отдельного пакета приходится решать задачу по его сборке на ppc64le, что может оказаться достаточно трудным делом. Кроме того, зачастую образы создаются на основе других, а это означает, что необходимо воссоздать под ppc64le все образы в этой цепочке, вплоть до базового (например, базовый образ ubuntu). Также, надо учитывать, что есть репозитории готовых пакетов, собранных под ppc64le: использовать такой готовый пакет, пусть не самой новой версии, всегда легче, чем собирать его заново из исходников.

Насколько целесообразно в нашем случае создавать образы? Если какой-то пакет, например Power MLDL (https://public.dhe.ibm.com/software/server/POWER/Linux/mldl/ubuntu/) есть только в deb-формате (в rpm нет), то его можно установить под Ubuntu, а под CentOS не получится. Поэтому, работая в CentOS, нет другого способа кроме использования контейнера с Ubuntu. Если какие-то пакеты используют, например, только pip или conda (https://anaconda.org/anaconda/repo) установщики, то они не зависят от используемой ОС, и использование контейнера для этого случая не обязательно — можно установить те же самые пакеты и в CentOS.

Нужно иметь в виду, что хотя использования образов (контейнеров) в многих случаях очень удобно, оно также имеет свои "накладные расходы", поскольку, кроме собственно установки пользовательских пакетов, приходится еще и работать с образами. То есть изучать дополнительные команды (Docker, Singularity).

Предоставить root-права

Вопросы расширения прав, чтобы можно было запустить Docker, собрать контейнер Docker/Singularity/LXC/..., использовать libvirt, chroot или какую либо еще технологию Linux, позволяющую, если говорить в общем, использовать UDSS.

В некоторых случаях, например, при использовании установщиков pip или conda для установки UDSS, повышение прав не требуется.

Что такое UDSS?

User Defined Software Stacks (UDSS) — это набор пакетов, определяемый пользователем. В некоторых случаях удобно использовать образы(контейнеры) для использования UDSS, см. Зачем использовать образ?. В других случаях, можно попробовать обойтись без них.

Не получается поменять пароль

В строке (current) LDAP Password: необходимо ввести еще раз текущий пароль, а затем в строке New password: новый пароль, который удовлетворяет требованиям входа в систему.