Опции
если число процессов (tasks) не задано, то по умолчанию n=1.
при отсутствии заказа времени для решения задачи выделяется по умолчанию 30 минут. Максимальное время для счета задачи:
20 часов — в будние дни (с 9 часов понедельника до 16 часов пятницы);
85 часов — на выходные (с 16 часов пятницы до 9 часов понедельника плюс 20 часов), т.е. на 85 часов задача запустится, если она войдет в решение в 16 часов ближайшей пятницы, иначе будет ждать следующей; аналогично, на 84 часа есть шанс запустить до 17 часов пятницы и т.д
до 9 часов понедельника;
100 часов — если к выходным добавляются праздничные дни.
Время может быть задано в виде:
минуты
минуты:секунды
часы:минуты:секунды
дни-часы
дни-часы:минуты
дни-часы:минуты:секунды
задает число узлов (nodes) для задачи, если пользователю это важно.
Для увеличения оперативной памяти можно воспользоваться опциями:
задаёт минимальную память в расчёте на одно ядро в мегабайтах ; если не задано, то по умолчанию 1 ГБ;
задаёт память на узле в мегабайтах.
Эти опции взаимно исключают друг друга.
задаёт запуск программы на узлах с GPU. Если не задан, то количество GPU=0, т.е
GPU при счете не используются. Если не указан тип GPU, то автоматически назначается младшая модель (m2090). Типы GPU в 2020 году m2090, k40m, v100
или позволяет указать раздел (partition) кластера для запуска задачи.
Основные разделы: tesla, apollo, v100 и debug. Эти разделы покрывают весь кластер и взаимно не пересекаются, т.е. содержат разные узлы (см. Кластер «Уран»). Список всех разделов выдается командой .
Если раздел не задан пользователем явно, то по умолчанию будет выбран раздел apollo, но при отсутствии в нем нужного числа свободных процессоров будет задействован раздел tesla. позволяет запускать задачи в специально выделенном для отладки программ разделе debug с максимальным временем счета 30 минут. Например,
Опции , , позволяют более гибко регулировать список узлов, допустимых для запуска задачи (см. ).
Например:
- — выделить заданию ресурсы узлов tesla5, tesla6, tesla7, tesla15, а если на них не хватит, то и другие узлы;
- — не выделять заданию ресурсы узла tesla22;
-
— выделять задаче только те узлы, которые имеют ресурс с именем (Feature), указанным после . На кластере имеются ресурсы с именами: tesla, a2017, a2019 (поколения узлов); bigmem (узлы с большим объёмом ОЗУ).
Информацию о том, какие ресурсы есть на конкретном узле, можно получить командой вида .
Описание всех опций и примеры команд можно посмотреть в руководстве man с помощью команд:
По умолчанию стандартный вывод пакетной задачи и стандартный поток ошибок направляются в файл с именем slurm-%j.out, где %j заменяется уникальным идентификатором (номером) задачи.
Перенаправление ввода-вывода можно выполнить, указав программе sbatch опции
При задании имени файла (filename pattern) можно использовать символы замены, в частности, заменяется на JobID, — на номер процесса в рамках задания. Таким образом при каждом запуске задачи сгенерирует уникальные имена для каждого процесса.
Выдаваемые результаты конкретной команды srun можно поместить вместо стандартного в указанный файл, добавив после команды символ перенаправления вывода .
Можно (чаще, при интерактивном запуске) параллельно просматривать результаты и сохранять их в файле, например:
Веб-интерфейс
Многие современные пакеты, такие как Jupiter Notebook или Tensor Board имеют встроенный веб-сервер, который обеспечивает взаимодействие с программой через веб-браузер. В этом случае возможно запустить сервер на узле, а браузер на хост-машине или на домашнем компьютере пользователя.
Запуск браузера на домашнем компьютере требует дополнительных настроек, связанных с пробросом портов, и здесь рассматриваться не будет.
Далее предполагается, что пользователь кластера использует подключение с поддержкой графической среды XWindow (клиенты X2Go, Mobaxterm и т.п.). Поскольку запускаемые скрипты требуют выполнения нескольких команд, они оформлены в виде файлов, которые могут запускаться как через srun, так и через sbatch.
В скриптах номера портов TCP выбираются на основе UID пользователя и базового смещения большего 1024. Это должно обеспечить возможность одновременного запуска скрипта на одном узле несколькими пользователями. Если порт случайно оказался занят, то можно поменять базу (в пределах 2000-20000) и попробовать запустить скрипт снова.
Запуск Jupiter Notebook
Для запуска Jupiter Notebook на узле, необходимо передать ему опцию —no-browser и IP адрес сетевой карты (иначе будет использован IP 127.0.0.1). Можно настроить авторизацию по паролю, отредактировав файл ~/.jupyter или выполнив команду , но авторизации по токену будет достаточно.
Скрипт запуска jupiter_slurm.sh
Запустив скрипт и дождавшись сообщения с URL и токеном можно запустить браузер и подключиться к своему JupiterNotebook.
Запуск Tensor Board
Запуск Tensor Board в целом аналогичен запуску Jupiter Notebook. В отличие от Jupiter Notebook у Tensor Board нет парольной защиты, так что теоретически возможно подключение к вашей Tensor Board какого-то пользователя кластера. При необходимости, эта проблема будет решаться административным путём — отключением слишком любопытных пользователей.
Скрипт запуска tensorboard_slurm.sh
Запуск:
Запуск интерактивной программы
Для взаимодействия с пользователем через текстовый интерфейс программа обращается к специальному устройству — псевдотерминалу (pseudo teletype, PTY). Для создания такого устройства на узлах необходимо указать команде srun опцию —pty.
В примере ниже для задачи выделено два узла, но интерактивный интерпретатор командной строки запущен только на первом из них.
Если вы работаете в графической среде XWindow (клиенты X2Go, Mobaxterm и т.п.), то по такой же схеме можно запускать на узлах задачи с графическим интерфейсом. Единственное отличие — при запуске надо добавить опцию —x11. По умолчанию графический вывод возможен с любого из выделенных узлов.
Безопасность
Для Debian или Ubuntu стоит настроить брандмауэр. А для Rocky Linux / CentOS — отключить SELinux (если только мы не собираемся его настраивать).
Debian / Ubuntu
По умолчанию, в системах на базе deb брандмауэр работает по принципу полного разрешения. Желательно, это поправить. Введем стартовые настройки.
Разрешаем SSH:
iptables -I INPUT -p tcp —dport 22 -j ACCEPT
* если мы подключаемся к SSH по нестандартному порту, то меняе 22 на нужное значение.
Создаем правила для нормальной работы apt-get или yum:
iptables -I INPUT -m state —state ESTABLISHED,RELATED -j ACCEPT
Разрешаем ICMP (для выполнения команды ping):
iptables -I INPUT -p icmp -j ACCEPT
Разрешаем все входящие на адрес локальной петли:
iptables -I INPUT -i lo -j ACCEPT
Ставим политику запрета на входящие и разрешаем все исходящие:
iptables -P INPUT DROP
Для сохранения правил ставим пакет iptables-persistent:
apt-get install iptables-persistent
Для сохранения правил вводим команду:
netfilter-persistent save
Rocky Linux / CentOS
В системах на базе RPM брандмауэр работает на запрет пакетов и не требует начальной настройки. Но в данных системах используется SELinux. Его, чаще, предпочитают отключать. Это делается двумя командами:
setenforce 0
sed -i ‘s/^SELINUX=.*/SELINUX=disabled/g’ /etc/selinux/config
Подробнее в инструкции Как отключить SELinux. Если мы хотим его настроить, читаем инструкцию Настройка SELinux в CentOS.
Правильное время
Настраиваем временную зону:
timedatectl set-timezone Europe/Moscow
* В данном примере мы задаем зону по московскому времени.
* Список всех доступных зон можно посмотреть командой timedatectl list-timezones. Если мы увидим только одну зону UTC, скорее всего, у нас установлена минимальная версия Ubuntu. Для установки всех зон вводим apt-get install tzdata.
Устанавливаем утилиту для синхронизации времени, разрешаем запуск демона и стартуем его.
а) если на системе Ubuntu / Debian:
apt-get install chrony
systemctl enable chrony
б) если на системе Rocky Linux / CentOS / Red Hat:
yum install chrony
systemctl enable chronyd —now
Примеры запуска
В результате интерактивного запуска программы выдаётся имя узла, на котором запущен соответствующий процесс, например:
При запуске в пакетном режиме команда запуска программы задаётся либо в скрипте, либо через опцию , например,
или
где скрипт mybat:
Внимание!
- Команда внутри скрипта может запрашивать ресурсы только в тех пределах, которые установлены командой .
- Скрипт запускается только на первом из выделенных узлов.
- Запуск нескольких процессов осуществляется командой . При этом все опции, указанные в командной строке или самом скрипте в строках , приписываются к каждой команде данного скрипта, если не переопределены в ней. Так, результирующий файл приведённого примера будет содержать 2 строки с именами узлов (возможно, одинаковых), на которых выполнятся 2 процесса задачи, сформированные командой srun.
- Если команды srun запускаются в фоновом режиме (символ в конце строки), то они при наличии ресурсов могут выполняться одновременно.
Настройка vi (Debian или Ubuntu)
Некоторые дистрибутивы Linux используют версию vi, с которой работать не совсем удобно. Как правило, это относится к системам на основе deb.
Многие пользователи используют другие редакторы, например, nano. Но если мы хотим использовать, именно, vi, попробуем сделать работу с ним приятнее.
Tiny vi
Ставим пакет:
apt-get install vim vim.tiny
Выбираем редактор по умолчанию:
update-alternatives —config editor
Выбираем вариант с vim.tiny, например:
* 3 /usr/bin/vim.tiny 15 manual mode
* в данном примере, выбираем 3.
Выбираем вариант vi:
update-alternatives —config vi
Также выбираем вариант с vim.tiny, например:
* 2 /usr/bin/vim.tiny 15 manual mode
* в данном примере, выбираем 2.
Вводим команду:
alias vi=»vim.tiny»
Добавим в файл:
vi /etc/bash.bashrc
* для всех.
… или:
vi ~/.bashrc
* для текущего пользователя.
… строку:
alias vi=»vim.tiny»
Готово.
Set paste (вставка json и yaml)
При вставке текста с форматом специального назначения, например json и yaml, vi неправильно определяет синтаксис, что приводит к сбиванию формата строк.
Для решения проблемы нужно ввести команду :set paste.
Можно немного упростить процесс — добавляем в конфиг опцию set pastetoggle=<F3>.
а) для настройки всем пользователям:
vi /etc/vim/vimrc
б) только для текущего:
vi ~/.vimrc
Добавим строку:
set pastetoggle=<F3>
* в данном примере мы настроим быструю клавишу F3, при нажатии которой мы введем опцию set paste.
Теперь переходим в редактор, нажимаем F3, переходим в режим вставки (i) — можно вставлять код.
Позиция курсора после выхода из vim
В Debian после выхода из редактора vi, позиция курсора оказывается в верхней части экрана и на него накладывается предыдущий текст. Данное поведение мешает работать.
Для решения проблемы открываем на редактирование:
а) для настройки всем пользователям:
vi /etc/vim/vimrc
б) только для текущего:
vi ~/.vimrc
Добавим строку:
set t_ti= t_te=
Упрощённые команды
, замена , — запуск программы на кластере, аналог команды .
— выдача информации об узлах и очереди заданий с помощью команд и ( из команд и ). или — выдача информации об узлах и задачах только самого пользователя., — отмена выполнения задачи (ожидающей старта или уже стартовавшей), действуют как команда .
Команда (замена , аналог ) запускает в пакетном режиме успешно откомпилированную С- или Fortran-программу, например
где для mytest затребовано формирование 8 процессов (опция или ) с выделением каждому по умолчанию 1950 MB (т.е. 1950) и установкой входного файла () при ограничении времени счета 20-ю минутами ( или ). Так как не указаны опции и , то стандартными выходными файлами будут автоматически созданные , .
В ответ в строке вида выдаётся уникальный идентификатор () задачи в очереди заданий, здесь 1475. Уникальный идентификатор используется в командах отмены выполнения задания, например
Внимание!
1. В каталогах вида имя_программы.номер номера возрастают, начиная с 1
Пользователь должен сам удалять ненужные каталоги.
2. Для выдачи опций следует набрать
3. При необходимости можно указать команды в качестве значения параметра команды , например:
Сервер сокетов
Мы сохраним программу сервера сокетов, как socket_server.py. Чтобы использовать соединение, нам нужно импортировать модуль сокета.
Затем последовательно нам нужно выполнить некоторую задачу, чтобы установить соединение между сервером и клиентом.
Мы можем получить адрес хоста с помощью функции socket.gethostname(). Рекомендуется использовать адрес порта пользователя выше 1024, поскольку номер порта меньше 1024 зарезервирован для стандартного интернет-протокола.
Смотрите приведенный ниже пример кода сервера:
import socket def server_program(): # get the hostname host = socket.gethostname() port = 5000 # initiate port no above 1024 server_socket = socket.socket() # get instance # look closely. The bind() function takes tuple as argument server_socket.bind((host, port)) # bind host address and port together # configure how many client the server can listen simultaneously server_socket.listen(2) conn, address = server_socket.accept() # accept new connection print("Connection from: " + str(address)) while True: # receive data stream. it won't accept data packet greater than 1024 bytes data = conn.recv(1024).decode() if not data: # if data is not received break break print("from connected user: " + str(data)) data = input(' -> ') conn.send(data.encode()) # send data to the client conn.close() # close the connection if __name__ == '__main__': server_program()
Итак, наш сервер сокетов работает на порту 5000 и будет ждать запроса клиента. Если вы хотите, чтобы сервер не завершал работу при закрытии клиентского соединения, просто удалите условие if и оператор break. Цикл while используется для бесконечного запуска серверной программы и ожидания клиентского запроса.
Вывод
Чтобы увидеть результат, сначала запустите программу сервера сокетов. Затем запустите клиентскую программу. После этого напишите что-нибудь из клиентской программы. Затем снова напишите ответ от серверной программы.
Наконец, напишите «до свидания» из клиентской программы, чтобы завершить обе программы. Ниже короткое видео покажет, как это работало на моем тестовом прогоне примеров программ сервера сокетов и клиента.
pankaj$ python3.6 socket_server.py Connection from: ('127.0.0.1', 57822) from connected user: Hi -> Hello from connected user: How are you? -> Good from connected user: Awesome! -> Ok then, bye! pankaj$
pankaj$ python3.6 socket_client.py -> Hi Received from server: Hello -> How are you? Received from server: Good -> Awesome! Received from server: Ok then, bye! -> Bye pankaj$
Обратите внимание, что сервер сокетов работает на порту 5000, но клиенту также требуется порт сокета для подключения к серверу. Этот порт назначается случайным образом при вызове клиентского соединения
В данном случае это 57822.