Podstawy:SLURM: Różnice pomiędzy wersjami
(Dodanie całej strony; bazowanie na https://kdm.cyfronet.pl/portal/Prometheus:Podstawy#Uruchamianie_zada.C5.84 (thx Jacek:))) |
|||
(Nie pokazano 39 wersji utworzonych przez 4 użytkowników) | |||
Linia 1: | Linia 1: | ||
{{DISPLAYTITLE:Podstawy SLURM}} | {{DISPLAYTITLE:Podstawy SLURM}} | ||
[[Category:Podstawy]] | [[Category:Podstawy]] | ||
− | |||
− | ==Uruchamianie zadań | + | __TOC__ |
− | Do uruchamiania zadań | + | |
+ | ==Co to jest system kolejkowy SLURM== | ||
+ | |||
+ | System kolejkowy SLURM jest wygodnym narzędziem uruchamiania zadań na zasobach obliczeniowych. Umożliwia on sprawne dobieranie zasobów obliczeniowych do potrzeb użytkownika zdefiniowanych poprzez komendy systemu kolejkowego. W zależności od potrzeb, system kolejkowy umożliwia uruchamianie zadań zrównoleglonych, rozproszonych, tablicowych czy zadań wykorzystujących dodatkowe zasoby sprzętowe (i.e. karty graficzne lub koprocesory przyspieszające obliczenia) lub dedykowane oprogramowanie, w tym zadania umożliwiające interaktywną pracę na zasobach obliczeniowych klastrów i superkomputerów. Dodatkowo system kolejkowy umożliwia tworzenie zależności między zleconymi zadaniami, może informować użytkownika o dacie i czasie rozpoczęcia, czy też zakończenia wykonywania danego zadania na wskazany adres e-mail. | ||
+ | |||
+ | Rodzaje zadań zlecanych w systemie kolejkowym: | ||
+ | * [[#Uruchamianie zadań wsadowych|Zadanie wsadowe]] (ang. batch job) - zostanie wykonane na zasobach obliczeniowych wedle poleceń umieszczonych w tzw. skrypcie obliczeniowym. Skrypt obliczeniowy może być napisany w dowolnym języku skryptowym dostępnym na klastrze obliczeniowym (np. Bash, tcsh, Python). | ||
+ | ** [[#Zadania tablicowe|Zadanie tablicowe]] - grupa zadań wsadowych, które wykorzystują ten sam skrypt obliczeniowy jednakże są uruchamiane z jako tablica zadań, co umożliwia np. efektywne przeprowadzenie obliczeń dla różnych warunków początkowych i tego samego schematu obliczeń. | ||
+ | * [[#Uruchamianie zadań interaktywnych|Zadanie interaktywne]] - umożliwia interaktywną pracę na zasobach obliczeniowych. Po uruchomieniu zadania użytkownik otrzymuje dostęp do konsoli na węźle obliczeniowym. | ||
+ | |||
+ | System kolejkowy SLURM, pozwala (w odróżnieniu od np. PBS) na wyspecyfikowanie wewnętrznej organizacji zasobów wykorzystywanych przez obliczenia. SLURM operuje na pojęciach: | ||
+ | |||
+ | * Zadanie (job), które działa w ramach przydzielonej alokacji zasobów | ||
+ | * Proces (task), który odpowiada jednej instancji procesu aplikacji. Procesy zawierają się w zadaniu, zadanie domyślnie posiada 1 proces. Proces jest ograniczony do wielkości jednego węzła. Wykonywanie obliczeń na wielu węzłach wymaga użycia wielu procesów. | ||
+ | * Rdzeń (core), który odpowiada alokacji jednego rdzenia procesora. Każdy proces ma przypisaną liczbę rdzeni, domyślnie jest to 1. | ||
+ | |||
+ | Więcej informacji można znaleźć w dokumentacji SLURMa: https://slurm.schedmd.com/quickstart.html Wewnętrzna organizacja zasobów przekłada się np. na działanie aplikacji MPI, dlatego warto dokładnie specyfikować zasoby dla zadania. | ||
+ | |||
+ | ==Uruchamianie zadań wsadowych== | ||
+ | Do uruchamiania zadań wsadowych (ang. batch job) służy komenda <tt>sbatch</tt>. W tym przypadku wszystkie komendy dla systemu kolejkowego podaje jako argumenty polecenia <tt>sbatch</tt> lub umieszcza się w pliku zawierającym skrypt obliczeniowy. W takim pliku linijki zawierające instrukcje sterujące dla systemu kolejkowego muszą zaczynać się ciągiem znaków <tt>#SBATCH</tt>. Należy je umieścić na początku pliku, przed innymi poleceniami, które mają być wykonane w ramach zadania na węźle obliczeniowym. Dzięki temu system kolejkowy jest w stanie odczytać opcje jemu właściwe właśnie z tych linijek i uruchomić pozostałe instrukcje, dotyczące już samego zadania obliczeniowego, z dalszej części pliku. Przykładowy [[#Zadania wykorzystujące MPI|skrypt obliczeniowy]]. | ||
+ | |||
+ | |||
==Uruchamianie zadań interaktywnych== | ==Uruchamianie zadań interaktywnych== | ||
− | Możliwe jest również | + | Możliwe jest również uruchomienie zadań interaktywnych, czyli dających bezpośredni dostęp do konsoli na węźle obliczeniowym. Do tego celu służy polecenie <tt>srun</tt>. Dla zadania interaktywnego opcje systemu kolejkowego podaje się jako argumenty polecenia <tt>srun</tt>. Obowiązkowym parametrem dla polecenia <tt>srun</tt> jest opcja <tt>--pty</tt> ustalająca konsole, która zostanie uruchomiona jako powłoka na maszynie zdalnej (np. <tt>/bin/bash</tt> lub <tt>/bin/tcsh</tt>). W celu wybrania konsoli Bash, która jest domyślną konsolą na klastrach w ACK Cyfronet AGH, należy użyć opcji <tt>--pty /bin/bash</tt>. |
+ | |||
+ | W przypadku zadań wsadowych polecenie <tt>srun</tt> może być umieszczone w skrypcie obliczneniowym, odpowiada ono wtedy za uruchomienie komendy podanej jako argument polecenia <tt>srun</tt> w ramach zaalokowanych zasobów, jednak w przypadku, gdy zasoby nie zostały wcześniej zaalokowane, komenda ta uprzednio dokonuje ich rezerwacji tuż przed uruchomieniem obliczeń. Przykładowe [[#Zadanie interaktywne|zadanie interaktywne]]. | ||
+ | |||
+ | |||
+ | |||
+ | ==Opcje i parametry komend <tt>sbatch</tt> i <tt>srun</tt>== | ||
Najważniejsze opcje i parametry komend <tt>sbatch</tt> oraz <tt>srun</tt> zawiera poniższa tabela. | Najważniejsze opcje i parametry komend <tt>sbatch</tt> oraz <tt>srun</tt> zawiera poniższa tabela. | ||
{| class="wikitable" | {| class="wikitable" | ||
− | ! width=15% |Opcja !!width= | + | ! width=15% |Opcja !!width=15%|Parametry !! width="50%" |Opis !!Wartość domyślna |
|- | |- | ||
| <tt>-N (--nodes=) || <liczba węzłów></tt> || Parametr służy do specyfikacji liczby węzłów || 1 | | <tt>-N (--nodes=) || <liczba węzłów></tt> || Parametr służy do specyfikacji liczby węzłów || 1 | ||
|- | |- | ||
− | | <tt>--ntasks-per-node= || <liczba | + | | <tt>-n (--ntasks=) || <liczba procesów></tt> || Liczba żądanych procesów (rdzeni) dla całego zadania. Może być użyte łącznie lub wymiennie z <tt>--ntasks-per-node</tt>|| 1 |
+ | |- | ||
+ | |||
+ | | <tt>--ntasks-per-node= || <liczba procesów></tt> || Liczba żądanych procesów na każdym węźle. Może być użyte łącznie lub wymiennie z <tt>-n (--ntasks=)</tt> || 1 | ||
|- | |- | ||
− | | <tt>--cpus-per-task= || <liczba rdzeni></tt> || Liczba żądanych rdzeni do dyspozycji każdego | + | | <tt>--cpus-per-task= || <liczba rdzeni></tt> || Liczba żądanych rdzeni do dyspozycji każdego procesu || 1 |
|- | |- | ||
| <tt>--mem-per-cpu= || <ilość pamięci></tt> || Ilość pamięci operacyjnej dla każdego zaalokowanego rdzenia obliczeniowego. Wartość należy podawać w bajtach, megabajtach lub gigabajtach stosując odpowiednie przedrostki, np. 1GB. || 4000Mb | | <tt>--mem-per-cpu= || <ilość pamięci></tt> || Ilość pamięci operacyjnej dla każdego zaalokowanego rdzenia obliczeniowego. Wartość należy podawać w bajtach, megabajtach lub gigabajtach stosując odpowiednie przedrostki, np. 1GB. || 4000Mb | ||
Linia 27: | Linia 56: | ||
| <tt>-J (--job-name=)</tt> || <tt><nazwa zadania></tt> || Nazwa zadania w systemie kolejkowym || nazwa pliku batchowego lub <tt>bash</tt> jeśli zadanie interaktywne | | <tt>-J (--job-name=)</tt> || <tt><nazwa zadania></tt> || Nazwa zadania w systemie kolejkowym || nazwa pliku batchowego lub <tt>bash</tt> jeśli zadanie interaktywne | ||
|- | |- | ||
− | | <tt>--mail-type</tt> || <tt>NONE</tt>, <tt>BEGIN</tt>, <tt>END</tt>, <tt>FAIL</tt>, <tt>REQUEUE</tt>, <tt>ALL</tt>, <tt>TIME_LIMIT</tt>, <tt>TIME_LIMIT_90</tt>, <tt>TIME_LIMIT_80</tt>, <tt>TIME_LIMIT_50</tt> || System kolejkowy wyśle e-mail do użytkownika jeśli zadanie osiągnie jeden z zadanych stanów. || NONE | + | | <tt>--mail-type</tt> || <tt>NONE</tt>, <tt>BEGIN</tt>, <tt>END</tt>, <tt>FAIL</tt>, <tt>REQUEUE</tt>, <tt>ALL</tt>, <tt>TIME_LIMIT</tt>, <tt>TIME_LIMIT_90</tt>, <tt>TIME_LIMIT_80</tt>, <tt>TIME_LIMIT_50</tt> || System kolejkowy wyśle e-mail do użytkownika jeśli zadanie osiągnie jeden z zadanych stanów (funkcjonalność dostępna tylko na klastrze Prometheus). || NONE |
|- | |- | ||
− | | <tt>--mail-user</tt> || <tt><adres@e-mail.użytkownika></tt> || Adres e-mail użytkownika na który ma zostać wysłana wiadomość o stanie zadania || informacja brana z Portalu PLGrid | + | | <tt>--mail-user</tt> || <tt><adres@e-mail.użytkownika></tt> || Adres e-mail użytkownika na który ma zostać wysłana wiadomość o stanie zadania (funkcjonalność dostępna tylko na klastrze Prometheus). || informacja brana z Portalu PLGrid |
|- | |- | ||
| <tt>-p (--partition=)</tt> || <tt><nazwa partycji></tt> || Specyfikuje nazwę partycji (odpowiednika kolejki w PBS) do której ma trafić zadanie || plgrid | | <tt>-p (--partition=)</tt> || <tt><nazwa partycji></tt> || Specyfikuje nazwę partycji (odpowiednika kolejki w PBS) do której ma trafić zadanie || plgrid | ||
Linia 62: | Linia 91: | ||
==Przydatne zmienne systemu kolejkowego== | ==Przydatne zmienne systemu kolejkowego== | ||
− | * <tt>$SLURM_NTASKS</tt> Zmienna wskazuje na ilość | + | * <tt>$SLURM_NTASKS</tt> Zmienna wskazuje na ilość procesów przydzielonych dla zadania. Najczęściej wykorzystywany do określania liczby rdzeni przydzielonej zadaniu np.: |
<pre> | <pre> | ||
mpiexec -np $SLURM_NTASKS moja_aplikacja | mpiexec -np $SLURM_NTASKS moja_aplikacja | ||
</pre> | </pre> | ||
+ | Podawanie parametrów <code>-np</code> i <code>-n</code> do komendy <code>mpiexec</code> jest najczęściej opcjonalne. W większości przypadków biblioteka MPI jest w stanie automatycznie dobrać odpowiednią liczbę procesów, dopasowaną do alokacji zadania. | ||
* <tt>$SLURM_SUBMIT_DIR</tt> Zmienna wskazuje na katalog, z którego uruchomiono obliczenia. Najczęściej wykorzystywana do wskazania plików dla zadania np.: | * <tt>$SLURM_SUBMIT_DIR</tt> Zmienna wskazuje na katalog, z którego uruchomiono obliczenia. Najczęściej wykorzystywana do wskazania plików dla zadania np.: | ||
<pre> | <pre> | ||
Linia 71: | Linia 101: | ||
</pre> | </pre> | ||
* <tt>$SLURM_JOB_ID</tt> Zmienna wskazuje na numer zadania w systemie kolejkowym. | * <tt>$SLURM_JOB_ID</tt> Zmienna wskazuje na numer zadania w systemie kolejkowym. | ||
+ | |||
+ | ==Tabela pomagająca przenieść skrypty pomiędzy PBS a SLURM== | ||
+ | |||
+ | Tabelę, która porównuje systemy kolejkowe SLURM oraz PBS/Torque pod względem opcji, komend oraz zmiennych systemowych można znaleźć '''[[Podstawy:SLURM_vs_PBS|tutaj]]''' | ||
==Przykłady== | ==Przykłady== | ||
Linia 76: | Linia 110: | ||
Uruchomienie zadanie interaktywnego w kolejce "plgrid-testing" z możliwością pracy w trybie tekstowym wymagające jednego rdzenia na jednym węźle obliczeniowym przez 20 minut. | Uruchomienie zadanie interaktywnego w kolejce "plgrid-testing" z możliwością pracy w trybie tekstowym wymagające jednego rdzenia na jednym węźle obliczeniowym przez 20 minut. | ||
<pre> | <pre> | ||
− | srun | + | srun -p plgrid-testing -t 20:00 --pty /bin/bash |
</pre> | </pre> | ||
− | Uruchomienie zadanie interaktywnego w kolejce "plgrid" z możliwością pracy w trybie | + | Uruchomienie zadanie interaktywnego w kolejce "plgrid" z możliwością pracy w trybie interaktywnym wymagające 12 rdzeni na jednym węźle obliczeniowym przez 3h. |
<pre> | <pre> | ||
− | srun -N 1 -- | + | srun -N 1 --cpus-per-task=12 -p plgrid -t 3:0:0 --pty /bin/bash |
</pre> | </pre> | ||
− | |||
===Zadanie jednordzeniowe=== | ===Zadanie jednordzeniowe=== | ||
Uruchomienie z linii poleceń zadania w kolejce "plgrid" wymagające jednego rdzenia na jednym węźle obliczeniowym przez 2h: | Uruchomienie z linii poleceń zadania w kolejce "plgrid" wymagające jednego rdzenia na jednym węźle obliczeniowym przez 2h: | ||
Linia 90: | Linia 123: | ||
sbatch -p plgrid -t 2:0:0 nazwa_skryptu_do_uruchomienia | sbatch -p plgrid -t 2:0:0 nazwa_skryptu_do_uruchomienia | ||
</pre> | </pre> | ||
+ | W powyższym przykładzie nie podajemy parametrów <code>-n</code> itp. ze względu na ich wartości domyslne. | ||
+ | |||
W przypadku skryptu należy użyć poniższych wpisów: | W przypadku skryptu należy użyć poniższych wpisów: | ||
<pre> | <pre> | ||
Linia 96: | Linia 131: | ||
</pre> | </pre> | ||
− | ===Zadanie | + | ===Zadanie wykorzystujące cały węzeł obliczeniowy === |
− | W | + | Należy ustalić, ile rdzeni znajduje się w jednym węźle obliczeniowym. Liczba rdzeni jest różna w zależności od typu węzła, informacje o dostępnych typach można znaleźć na tym wiki lub sprawdzić w systemie kolejkowym konkretny węzeł za pomocą komendy <code>scontrol show node nazwa_wezla</code>. |
+ | |||
+ | Uwaga! W przypadku SLURMa istotne jest, czy aplikacja jest wielowątkowa (np. OpenMP) czy wieloprocesowa (np. MPI). W przypadku korzystania z aplikacji wielowątkowej należy specyfikować jeden węzeł (<tt>-N 1</tt>), jeden proces (tak jest domyślnie) i wiele procesorów (<tt>--cpus-per-task</tt>) przypisanych do tego procesu. W przypadku aplikacji wieloprocesowych należy specyfikować cały węzeł (<tt>-N 1</tt>), wiele procesów (<tt>-n 12</tt>) i jeden rdzeń per proces (tak jest domyślnie). | ||
+ | |||
+ | ==== Węzeł 12-rdzeniowy Zeusa ==== | ||
+ | |||
+ | Uruchomienie z linii poleceń zadania w kolejce "plgrid" alokujące cały 12-rdzeniowy węzeł obliczeniowy z domyślnym maksymalnym czasem trwania kolejki: | ||
<pre> | <pre> | ||
− | sabtch -N 1 -- | + | sabtch -N 1 --cpus-per-task=12 -p plgrid nazwa_skryptu_do_uruchomienia |
</pre> | </pre> | ||
W przypadku skryptu należy użyć poniższych wpisów: | W przypadku skryptu należy użyć poniższych wpisów: | ||
Linia 105: | Linia 146: | ||
#SBATCH -p plgrid | #SBATCH -p plgrid | ||
#SBATCH -N 1 | #SBATCH -N 1 | ||
− | #SBATCH -- | + | #SBATCH --cpus-per-task=12 |
+ | |||
+ | |||
+ | </pre> | ||
+ | |||
+ | ==== Węzeł 64-rdzeniowy Zeusa ==== | ||
+ | |||
+ | Uruchomienie z linii poleceń zadania w kolejce "plgrid" alokujące cały 64-rdzeniowy węzeł obliczeniowy z domyślnym maksymalnym czasem trwania kolejki: | ||
+ | <pre> | ||
+ | sabtch -N 1 --cpus-per-task=64 -p plgrid nazwa_skryptu_do_uruchomienia | ||
+ | </pre> | ||
+ | W przypadku skryptu należy użyć poniższych wpisów: | ||
+ | <pre> | ||
+ | #SBATCH -p plgrid | ||
+ | #SBATCH -N 1 | ||
+ | #SBATCH --cpus-per-task=64 | ||
+ | |||
+ | |||
+ | </pre> | ||
+ | |||
+ | ==== Węzeł 24-rdzeniowy Prometheusa ==== | ||
+ | |||
+ | Uruchomienie z linii poleceń zadania w kolejce "plgrid" alokujące cały 24-rdzeniowy węzeł obliczeniowy z domyślnym czasem trwania kolejki: | ||
+ | <pre> | ||
+ | sabtch -N 1 --cpus-per-task=24 -p plgrid nazwa_skryptu_do_uruchomienia | ||
+ | </pre> | ||
+ | W przypadku skryptu należy użyć poniższych wpisów: | ||
+ | <pre> | ||
+ | #SBATCH -p plgrid | ||
+ | #SBATCH -N 1 | ||
+ | #SBATCH --cpus-per-task=24 | ||
</pre> | </pre> | ||
− | ===Zadanie | + | ===Zadanie korzystające z wielu węzłów obliczeniowych === |
− | |||
− | Uruchomienie z linii poleceń zadania w kolejce "plgrid" | + | Uruchomienie z linii poleceń zadania w kolejce "plgrid" alokujące X węzłów, na każdym alokujemy Y procesów, każdy proces zajmuje jeden rdzeń: |
<pre> | <pre> | ||
sbatch -N X --ntasks-per-node=Y -p plgrid nazwa_skryptu_do_uruchomienia | sbatch -N X --ntasks-per-node=Y -p plgrid nazwa_skryptu_do_uruchomienia | ||
Linia 123: | Linia 193: | ||
#SBATCH --ntasks-per-node=Y | #SBATCH --ntasks-per-node=Y | ||
</pre> | </pre> | ||
+ | W powyższym przykładzie alokujemy X węzłów, po Y procesów, sumaryczna ilość procesów (np. dla MPI) będzie wynosić X*Y. | ||
=== Zadania tablicowe === | === Zadania tablicowe === | ||
Linia 147: | Linia 218: | ||
#SBATCH -p plgrid-testing | #SBATCH -p plgrid-testing | ||
## Plik ze standardowym wyjściem | ## Plik ze standardowym wyjściem | ||
− | #SBATCH --output="output.out" | + | #SBATCH --output="output-%A_%a.out" |
## Plik ze standardowym wyjściem błędów | ## Plik ze standardowym wyjściem błędów | ||
− | #SBATCH --error="error.err" | + | #SBATCH --error="error-%A_%a.err" |
## Parametr wyznaczający indeksy zadania tablicowego | ## Parametr wyznaczający indeksy zadania tablicowego | ||
#SBATCH --array=0-100 | #SBATCH --array=0-100 | ||
Linia 160: | Linia 231: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | Domyślnie (bez specyfikowania opcji <tt>-e</tt> oraz <tt>-o</tt>) SLURM zachowuje pliku wyjściowe zarówno <tt>stdout</tt> jak i <tt>stderr</tt> dla zadań tablicowych w plikach o formacie: <tt>slurm-${SLURM_ARRAY_JOB_ID}_${SLURM_ARRAY_TASK_ID}.out</tt>. W powyższym przykładzie rozdzielono pliki z <tt>stdout</tt> oraz <tt>stderr</tt>, tak że dla każdego zadania będą one przyjmowały postać <tt>output-${SLURM_ARRAY_JOB_ID}_${SLURM_ARRAY_TASK_ID}.out</tt> oraz <tt>error-${SLURM_ARRAY_JOB_ID}_${SLURM_ARRAY_TASK_ID}.out</tt>. | |
+ | |||
+ | === Zadania wykorzystujące MPI === | ||
Opis dotyczy uruchamiania zadań MPI na klastrze wyposażonych w system kolejkowy SLURM integrujący się z bibliotekami MPI. W przypadku KDM w ACK Cyfronet AGH dostępne są różne wersje bibliotek MPI (najczęściej OpenMPI i IntelMPI) dla większości dostępnych kompilatorów. Podczas uruchamiania aplikacji proszę nie podawać explicite parametru <code>-n</code> lub <code>-np</code> system dobierze odpowiednie wartości na podstawie parametrów alokacji (umieszczonych w skrypcie startowym) i zostaną one zastosowane. W uzasadnionych przypadkach, gdzie aplikacja wymaga specyficznej konfiguracji (np. lokalne wątkowanie), można podać wspomniane parametry. | Opis dotyczy uruchamiania zadań MPI na klastrze wyposażonych w system kolejkowy SLURM integrujący się z bibliotekami MPI. W przypadku KDM w ACK Cyfronet AGH dostępne są różne wersje bibliotek MPI (najczęściej OpenMPI i IntelMPI) dla większości dostępnych kompilatorów. Podczas uruchamiania aplikacji proszę nie podawać explicite parametru <code>-n</code> lub <code>-np</code> system dobierze odpowiednie wartości na podstawie parametrów alokacji (umieszczonych w skrypcie startowym) i zostaną one zastosowane. W uzasadnionych przypadkach, gdzie aplikacja wymaga specyficznej konfiguracji (np. lokalne wątkowanie), można podać wspomniane parametry. | ||
Linia 198: | Linia 271: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Dobrą praktyką jest kompilowanie i uruchamianie aplikacji przy pomocy środowiska budowanego tym samym zestawem modułów. Zalecamy korzystanie z wrappera <code>mpiexec</code>. Wielkość alokacji, w tym przypadku 2 węzły po 12 rdzenie, przekłada się bezpośrednio na 24 | + | Dobrą praktyką jest kompilowanie i uruchamianie aplikacji przy pomocy środowiska budowanego tym samym zestawem modułów. Zalecamy korzystanie z wrappera <code>mpiexec</code>. Wielkość alokacji, w tym przypadku 2 węzły po 12 rdzenie, przekłada się bezpośrednio na 24 procesy dostępne dla aplikacji korzystającej z MPI. Dopuszczalne jest uruchomienie serii aplikacji MPI w jednym skrypcie, ale najczęściej, ze względu na długi czas wykonania, nie jest to optymalny sposób prowadzenia obliczeń. Niedopuszczalne jest jednoczesne uruchomienie wielu aplikacji MPI w ramach jednej alokacji, taka praktyka prowadzi do kłopotów związanych z alokacją zasobów na wyłączność dla danej aplikacji. |
− | + | === Proste zrównoleglenie wielu niezależnych zadań === | |
Dość częstym przypadkiem użycia klastra jest przetworzenie wielu paczek danych, gdzie każda paczka jest przetwarzana niezależnie. Dobrym przykładem takich zadań jest przetwarzanie wielu obrazów w ten sam sposób. SLURM umożliwia proste zrównoleglenie takiego przetwarzania poprzez użycie komendy '''srun'''. Przykładowy skrypt, który zrównolegli uruchomienie wielu instancji obliczeń, gdzie stopień równoległości jest ustalany na podstawie parametrów zadania, znajduje się poniżej: | Dość częstym przypadkiem użycia klastra jest przetworzenie wielu paczek danych, gdzie każda paczka jest przetwarzana niezależnie. Dobrym przykładem takich zadań jest przetwarzanie wielu obrazów w ten sam sposób. SLURM umożliwia proste zrównoleglenie takiego przetwarzania poprzez użycie komendy '''srun'''. Przykładowy skrypt, który zrównolegli uruchomienie wielu instancji obliczeń, gdzie stopień równoległości jest ustalany na podstawie parametrów zadania, znajduje się poniżej: |
Aktualna wersja na dzień 09:50, 21 sty 2019
Spis treści
- 1 Co to jest system kolejkowy SLURM
- 2 Uruchamianie zadań wsadowych
- 3 Uruchamianie zadań interaktywnych
- 4 Opcje i parametry komend sbatch i srun
- 5 Usuwanie zadań
- 6 Monitorowanie kolejek, partycji, węzłów, zadań i zasobów
- 7 Przydatne zmienne systemu kolejkowego
- 8 Tabela pomagająca przenieść skrypty pomiędzy PBS a SLURM
- 9 Przykłady
Co to jest system kolejkowy SLURM
System kolejkowy SLURM jest wygodnym narzędziem uruchamiania zadań na zasobach obliczeniowych. Umożliwia on sprawne dobieranie zasobów obliczeniowych do potrzeb użytkownika zdefiniowanych poprzez komendy systemu kolejkowego. W zależności od potrzeb, system kolejkowy umożliwia uruchamianie zadań zrównoleglonych, rozproszonych, tablicowych czy zadań wykorzystujących dodatkowe zasoby sprzętowe (i.e. karty graficzne lub koprocesory przyspieszające obliczenia) lub dedykowane oprogramowanie, w tym zadania umożliwiające interaktywną pracę na zasobach obliczeniowych klastrów i superkomputerów. Dodatkowo system kolejkowy umożliwia tworzenie zależności między zleconymi zadaniami, może informować użytkownika o dacie i czasie rozpoczęcia, czy też zakończenia wykonywania danego zadania na wskazany adres e-mail.
Rodzaje zadań zlecanych w systemie kolejkowym:
- Zadanie wsadowe (ang. batch job) - zostanie wykonane na zasobach obliczeniowych wedle poleceń umieszczonych w tzw. skrypcie obliczeniowym. Skrypt obliczeniowy może być napisany w dowolnym języku skryptowym dostępnym na klastrze obliczeniowym (np. Bash, tcsh, Python).
- Zadanie tablicowe - grupa zadań wsadowych, które wykorzystują ten sam skrypt obliczeniowy jednakże są uruchamiane z jako tablica zadań, co umożliwia np. efektywne przeprowadzenie obliczeń dla różnych warunków początkowych i tego samego schematu obliczeń.
- Zadanie interaktywne - umożliwia interaktywną pracę na zasobach obliczeniowych. Po uruchomieniu zadania użytkownik otrzymuje dostęp do konsoli na węźle obliczeniowym.
System kolejkowy SLURM, pozwala (w odróżnieniu od np. PBS) na wyspecyfikowanie wewnętrznej organizacji zasobów wykorzystywanych przez obliczenia. SLURM operuje na pojęciach:
- Zadanie (job), które działa w ramach przydzielonej alokacji zasobów
- Proces (task), który odpowiada jednej instancji procesu aplikacji. Procesy zawierają się w zadaniu, zadanie domyślnie posiada 1 proces. Proces jest ograniczony do wielkości jednego węzła. Wykonywanie obliczeń na wielu węzłach wymaga użycia wielu procesów.
- Rdzeń (core), który odpowiada alokacji jednego rdzenia procesora. Każdy proces ma przypisaną liczbę rdzeni, domyślnie jest to 1.
Więcej informacji można znaleźć w dokumentacji SLURMa: https://slurm.schedmd.com/quickstart.html Wewnętrzna organizacja zasobów przekłada się np. na działanie aplikacji MPI, dlatego warto dokładnie specyfikować zasoby dla zadania.
Uruchamianie zadań wsadowych
Do uruchamiania zadań wsadowych (ang. batch job) służy komenda sbatch. W tym przypadku wszystkie komendy dla systemu kolejkowego podaje jako argumenty polecenia sbatch lub umieszcza się w pliku zawierającym skrypt obliczeniowy. W takim pliku linijki zawierające instrukcje sterujące dla systemu kolejkowego muszą zaczynać się ciągiem znaków #SBATCH. Należy je umieścić na początku pliku, przed innymi poleceniami, które mają być wykonane w ramach zadania na węźle obliczeniowym. Dzięki temu system kolejkowy jest w stanie odczytać opcje jemu właściwe właśnie z tych linijek i uruchomić pozostałe instrukcje, dotyczące już samego zadania obliczeniowego, z dalszej części pliku. Przykładowy skrypt obliczeniowy.
Uruchamianie zadań interaktywnych
Możliwe jest również uruchomienie zadań interaktywnych, czyli dających bezpośredni dostęp do konsoli na węźle obliczeniowym. Do tego celu służy polecenie srun. Dla zadania interaktywnego opcje systemu kolejkowego podaje się jako argumenty polecenia srun. Obowiązkowym parametrem dla polecenia srun jest opcja --pty ustalająca konsole, która zostanie uruchomiona jako powłoka na maszynie zdalnej (np. /bin/bash lub /bin/tcsh). W celu wybrania konsoli Bash, która jest domyślną konsolą na klastrach w ACK Cyfronet AGH, należy użyć opcji --pty /bin/bash.
W przypadku zadań wsadowych polecenie srun może być umieszczone w skrypcie obliczneniowym, odpowiada ono wtedy za uruchomienie komendy podanej jako argument polecenia srun w ramach zaalokowanych zasobów, jednak w przypadku, gdy zasoby nie zostały wcześniej zaalokowane, komenda ta uprzednio dokonuje ich rezerwacji tuż przed uruchomieniem obliczeń. Przykładowe zadanie interaktywne.
Opcje i parametry komend sbatch i srun
Najważniejsze opcje i parametry komend sbatch oraz srun zawiera poniższa tabela.
Opcja | Parametry | Opis | Wartość domyślna |
---|---|---|---|
-N (--nodes=) | <liczba węzłów> | Parametr służy do specyfikacji liczby węzłów | 1 |
-n (--ntasks=) | <liczba procesów> | Liczba żądanych procesów (rdzeni) dla całego zadania. Może być użyte łącznie lub wymiennie z --ntasks-per-node | 1 |
--ntasks-per-node= | <liczba procesów> | Liczba żądanych procesów na każdym węźle. Może być użyte łącznie lub wymiennie z -n (--ntasks=) | 1 |
--cpus-per-task= | <liczba rdzeni> | Liczba żądanych rdzeni do dyspozycji każdego procesu | 1 |
--mem-per-cpu= | <ilość pamięci> | Ilość pamięci operacyjnej dla każdego zaalokowanego rdzenia obliczeniowego. Wartość należy podawać w bajtach, megabajtach lub gigabajtach stosując odpowiednie przedrostki, np. 1GB. | 4000Mb |
--mem= | <ilość pamięci> | Ilość pamięci operacyjnej dla całego zadania na węzeł obliczeniowy. Wartość należy podawać w bajtach, megabajtach lub gigabajtach stosując odpowiednie przedrostki, np. 1GB. | |
-t (--time=) | <czas obliczeń> | Maksymalny czas obliczeń. Czas należy podawać w formacie DD-GG:MM:SS gdzie DD, GG, MM, SS oznaczają odpowiednio żądaną liczbę dni, godzin, minut i sekund na zadanie. | zależne od kolejki |
-J (--job-name=) | <nazwa zadania> | Nazwa zadania w systemie kolejkowym | nazwa pliku batchowego lub bash jeśli zadanie interaktywne |
--mail-type | NONE, BEGIN, END, FAIL, REQUEUE, ALL, TIME_LIMIT, TIME_LIMIT_90, TIME_LIMIT_80, TIME_LIMIT_50 | System kolejkowy wyśle e-mail do użytkownika jeśli zadanie osiągnie jeden z zadanych stanów (funkcjonalność dostępna tylko na klastrze Prometheus). | NONE |
--mail-user | <adres@e-mail.użytkownika> | Adres e-mail użytkownika na który ma zostać wysłana wiadomość o stanie zadania (funkcjonalność dostępna tylko na klastrze Prometheus). | informacja brana z Portalu PLGrid |
-p (--partition=) | <nazwa partycji> | Specyfikuje nazwę partycji (odpowiednika kolejki w PBS) do której ma trafić zadanie | plgrid |
-A | <nazwa grantu> | Specyfikuje nazwę grantu z którego zasoby będą brane do obliczeń | grant domyślny wybrany w Portalu PLGrid |
-o (--output=) | <nazwa pliku> | Specyfikuje nazwę pliku do którego zostanie zapisane standardowe wyjście | slurm-<JOBID>.out, gdzie JOBID to numer zadania, np. slurm-12345678.out |
-e (--error=) | <nazwa pliku> | Specyfikuje nazwę pliku do którego zostanie zapisane standardowe wyjście błędu | slurm-<JOBID>.out, gdzie JOBID to numer zadania, np. slurm-12345678.out |
Usuwanie zadań
Do usuwania zadań służy komenda scancel. W celu sunięcia zadania z kolejki potrzebny jest również jego identyfikator numeryczny (JOBID), który można wyświetlić komendą squeue. Cała sekwencja może wyglądać następująco:
scancel 12345678910
Jeśli zadania nie da się usunąć należy skontaktować się z administratorem komputera.
Monitorowanie kolejek, partycji, węzłów, zadań i zasobów
- Narzędzia systemu SLURM
squeue
- lista aktualnie zakolejkowanych/uruchomionych zadańscontrol show job [<ID_zadania>]
- szczegóły zadaniasstat -a -j <ID_zadania>/<ID_zadania.batch>
- zużycie zasobów w ramach kroków (step) działającego zadaniascancel <ID_zadania>
- usunięcie zadania (działającego lub zakolejkowanego)sacct
- zużycie zasobów zakończonego już zadania/krokuscontrol show partition [<nazwa_partycji>]
- właściwości partycjisinfo
- lista węzłówscontrol show node [<nazwa_węzła>]
- właściwości węzła
Więcej informacji znajduje się w pomocy danego polecenia możliwej do wywołania za pomocą opcji --help.
Przydatne zmienne systemu kolejkowego
- $SLURM_NTASKS Zmienna wskazuje na ilość procesów przydzielonych dla zadania. Najczęściej wykorzystywany do określania liczby rdzeni przydzielonej zadaniu np.:
mpiexec -np $SLURM_NTASKS moja_aplikacja
Podawanie parametrów -np
i -n
do komendy mpiexec
jest najczęściej opcjonalne. W większości przypadków biblioteka MPI jest w stanie automatycznie dobrać odpowiednią liczbę procesów, dopasowaną do alokacji zadania.
- $SLURM_SUBMIT_DIR Zmienna wskazuje na katalog, z którego uruchomiono obliczenia. Najczęściej wykorzystywana do wskazania plików dla zadania np.:
cd $SLURM_SUBMIT_DIR
- $SLURM_JOB_ID Zmienna wskazuje na numer zadania w systemie kolejkowym.
Tabela pomagająca przenieść skrypty pomiędzy PBS a SLURM
Tabelę, która porównuje systemy kolejkowe SLURM oraz PBS/Torque pod względem opcji, komend oraz zmiennych systemowych można znaleźć tutaj
Przykłady
Zadanie interaktywne
Uruchomienie zadanie interaktywnego w kolejce "plgrid-testing" z możliwością pracy w trybie tekstowym wymagające jednego rdzenia na jednym węźle obliczeniowym przez 20 minut.
srun -p plgrid-testing -t 20:00 --pty /bin/bash
Uruchomienie zadanie interaktywnego w kolejce "plgrid" z możliwością pracy w trybie interaktywnym wymagające 12 rdzeni na jednym węźle obliczeniowym przez 3h.
srun -N 1 --cpus-per-task=12 -p plgrid -t 3:0:0 --pty /bin/bash
Zadanie jednordzeniowe
Uruchomienie z linii poleceń zadania w kolejce "plgrid" wymagające jednego rdzenia na jednym węźle obliczeniowym przez 2h:
sbatch -p plgrid -t 2:0:0 nazwa_skryptu_do_uruchomienia
W powyższym przykładzie nie podajemy parametrów -n
itp. ze względu na ich wartości domyslne.
W przypadku skryptu należy użyć poniższych wpisów:
#SBATCH -p plgrid #SBATCH -t 2:0:0
Zadanie wykorzystujące cały węzeł obliczeniowy
Należy ustalić, ile rdzeni znajduje się w jednym węźle obliczeniowym. Liczba rdzeni jest różna w zależności od typu węzła, informacje o dostępnych typach można znaleźć na tym wiki lub sprawdzić w systemie kolejkowym konkretny węzeł za pomocą komendy scontrol show node nazwa_wezla
.
Uwaga! W przypadku SLURMa istotne jest, czy aplikacja jest wielowątkowa (np. OpenMP) czy wieloprocesowa (np. MPI). W przypadku korzystania z aplikacji wielowątkowej należy specyfikować jeden węzeł (-N 1), jeden proces (tak jest domyślnie) i wiele procesorów (--cpus-per-task) przypisanych do tego procesu. W przypadku aplikacji wieloprocesowych należy specyfikować cały węzeł (-N 1), wiele procesów (-n 12) i jeden rdzeń per proces (tak jest domyślnie).
Węzeł 12-rdzeniowy Zeusa
Uruchomienie z linii poleceń zadania w kolejce "plgrid" alokujące cały 12-rdzeniowy węzeł obliczeniowy z domyślnym maksymalnym czasem trwania kolejki:
sabtch -N 1 --cpus-per-task=12 -p plgrid nazwa_skryptu_do_uruchomienia
W przypadku skryptu należy użyć poniższych wpisów:
#SBATCH -p plgrid #SBATCH -N 1 #SBATCH --cpus-per-task=12
Węzeł 64-rdzeniowy Zeusa
Uruchomienie z linii poleceń zadania w kolejce "plgrid" alokujące cały 64-rdzeniowy węzeł obliczeniowy z domyślnym maksymalnym czasem trwania kolejki:
sabtch -N 1 --cpus-per-task=64 -p plgrid nazwa_skryptu_do_uruchomienia
W przypadku skryptu należy użyć poniższych wpisów:
#SBATCH -p plgrid #SBATCH -N 1 #SBATCH --cpus-per-task=64
Węzeł 24-rdzeniowy Prometheusa
Uruchomienie z linii poleceń zadania w kolejce "plgrid" alokujące cały 24-rdzeniowy węzeł obliczeniowy z domyślnym czasem trwania kolejki:
sabtch -N 1 --cpus-per-task=24 -p plgrid nazwa_skryptu_do_uruchomienia
W przypadku skryptu należy użyć poniższych wpisów:
#SBATCH -p plgrid #SBATCH -N 1 #SBATCH --cpus-per-task=24
Zadanie korzystające z wielu węzłów obliczeniowych
Uruchomienie z linii poleceń zadania w kolejce "plgrid" alokujące X węzłów, na każdym alokujemy Y procesów, każdy proces zajmuje jeden rdzeń:
sbatch -N X --ntasks-per-node=Y -p plgrid nazwa_skryptu_do_uruchomienia
W przypadku skryptu należy użyć poniższych wpisów:
#SBATCH -p plgrid #SBATCH -N X #SBATCH --ntasks-per-node=Y
W powyższym przykładzie alokujemy X węzłów, po Y procesów, sumaryczna ilość procesów (np. dla MPI) będzie wynosić X*Y.
Zadania tablicowe
Zadania tablicowe to mechanizm pozwalający na zlecanie dużej ilości zadań wsadowych, które są do siebie podobne. Zadania tablicowe posiadają swój indeks, dostępny jako zmienną środowiskowa $SLURM_ARRAY_TASK_ID wewnątrz zadania, dzięki któremu można odpowiednio parametryzować uruchamianą aplikację. Sposób zlecania zadania jest analogiczny jak w przypadku zwykłych zadań wsadowych, a przykładowy skrypt zawierający parametr --array
-a
, definiujący zakres indeksów, wygląda następująco:
UWAGA! To jest przykładowy skrypt, którego NIE NALEŻY uruchamiać. Przed jego uruchomieniem należy przeglądnąć podane opcje i dostosować je do własnych potrzeb, zmieniając m.i. nazwę grantu, nazwę partycji, czas trwania zadania, itp.
#!/bin/bash -l
## Nazwa zlecenia
#SBATCH -J testjob
## Liczba alokowanych węzłów
#SBATCH -N 1
## Liczba zadań per węzeł (domyślnie jest to liczba alokowanych rdzeni na węźle)
#SBATCH --ntasks-per-node=1
## Ilość pamięci przypadającej na jeden rdzeń obliczeniowy (domyślnie 4GB na rdzeń)
#SBATCH --mem-per-cpu=1GB
## Maksymalny czas trwania zlecenia (format DD-HH:MM:SS)
#SBATCH --time=01:00:00
## Nazwa grantu do rozliczenia zużycia zasobów
#SBATCH -A <grant_id>
## Specyfikacja partycji
#SBATCH -p plgrid-testing
## Plik ze standardowym wyjściem
#SBATCH --output="output-%A_%a.out"
## Plik ze standardowym wyjściem błędów
#SBATCH --error="error-%A_%a.err"
## Parametr wyznaczający indeksy zadania tablicowego
#SBATCH --array=0-100
## przejscie do katalogu z ktorego wywolany zostal sbatch
cd $SLURM_SUBMIT_DIR
myCalculations $SLURM_ARRAY_TASK_ID
Domyślnie (bez specyfikowania opcji -e oraz -o) SLURM zachowuje pliku wyjściowe zarówno stdout jak i stderr dla zadań tablicowych w plikach o formacie: slurm-${SLURM_ARRAY_JOB_ID}_${SLURM_ARRAY_TASK_ID}.out. W powyższym przykładzie rozdzielono pliki z stdout oraz stderr, tak że dla każdego zadania będą one przyjmowały postać output-${SLURM_ARRAY_JOB_ID}_${SLURM_ARRAY_TASK_ID}.out oraz error-${SLURM_ARRAY_JOB_ID}_${SLURM_ARRAY_TASK_ID}.out.
Zadania wykorzystujące MPI
Opis dotyczy uruchamiania zadań MPI na klastrze wyposażonych w system kolejkowy SLURM integrujący się z bibliotekami MPI. W przypadku KDM w ACK Cyfronet AGH dostępne są różne wersje bibliotek MPI (najczęściej OpenMPI i IntelMPI) dla większości dostępnych kompilatorów. Podczas uruchamiania aplikacji proszę nie podawać explicite parametru -n
lub -np
system dobierze odpowiednie wartości na podstawie parametrów alokacji (umieszczonych w skrypcie startowym) i zostaną one zastosowane. W uzasadnionych przypadkach, gdzie aplikacja wymaga specyficznej konfiguracji (np. lokalne wątkowanie), można podać wspomniane parametry.
UWAGA! To jest przykładowy skrypt, którego NIE NALEŻY uruchamiać. Przed jego uruchomieniem należy przeglądnąć podane opcje i dostosować je do własnych potrzeb, zmieniając m.i. nazwę grantu, nazwę partycji, czas trwania zadania, itp.
#!/bin/bash -l
## Nazwa zlecenia
#SBATCH -J MPITest
## Liczba alokowanych węzłów
#SBATCH -N 2
## Liczba zadań per węzeł (domyślnie jest to liczba alokowanych rdzeni na węźle)
#SBATCH --ntasks-per-node=12
## Ilość pamięci przypadającej na jeden rdzeń obliczeniowy (domyślnie 4GB na rdzeń)
#SBATCH --mem-per-cpu=4GB
## Maksymalny czas trwania zlecenia (format HH:MM:SS)
#SBATCH --time=01:00:00
## Nazwa grantu do rozliczenia zużycia zasobów
#SBATCH -A <grant_id>
## Specyfikacja partycji
#SBATCH -p plgrid-testing
## Plik ze standardowym wyjściem
#SBATCH --output="output.out"
## Plik ze standardowym wyjściem błędów
#SBATCH --error="error.err"
srun /bin/hostname
## Zaladowanie modulu IntelMPI w wersji domyslnej
module add plgrid/tools/impi
## przejscie do katalogu z ktorego wywolany zostal sbatch
cd $SLURM_SUBMIT_DIR
mpiexec ./calcDiff 100 50
Dobrą praktyką jest kompilowanie i uruchamianie aplikacji przy pomocy środowiska budowanego tym samym zestawem modułów. Zalecamy korzystanie z wrappera mpiexec
. Wielkość alokacji, w tym przypadku 2 węzły po 12 rdzenie, przekłada się bezpośrednio na 24 procesy dostępne dla aplikacji korzystającej z MPI. Dopuszczalne jest uruchomienie serii aplikacji MPI w jednym skrypcie, ale najczęściej, ze względu na długi czas wykonania, nie jest to optymalny sposób prowadzenia obliczeń. Niedopuszczalne jest jednoczesne uruchomienie wielu aplikacji MPI w ramach jednej alokacji, taka praktyka prowadzi do kłopotów związanych z alokacją zasobów na wyłączność dla danej aplikacji.
Proste zrównoleglenie wielu niezależnych zadań
Dość częstym przypadkiem użycia klastra jest przetworzenie wielu paczek danych, gdzie każda paczka jest przetwarzana niezależnie. Dobrym przykładem takich zadań jest przetwarzanie wielu obrazów w ten sam sposób. SLURM umożliwia proste zrównoleglenie takiego przetwarzania poprzez użycie komendy srun. Przykładowy skrypt, który zrównolegli uruchomienie wielu instancji obliczeń, gdzie stopień równoległości jest ustalany na podstawie parametrów zadania, znajduje się poniżej:
UWAGA! To jest przykładowy skrypt, którego NIE NALEŻY uruchamiać. Przed jego uruchomieniem należy przeglądnąć podane opcje i dostosować je do własnych potrzeb, zmieniając m.i. nazwę grantu, nazwę partycji, czas trwania zadania, itp.
#!/bin/bash -l
## Nazwa zlecenia
#SBATCH -J testjob
## Liczba alokowanych węzłów
#SBATCH -N 2
## Liczba zadań per węzeł (domyślnie jest to liczba alokowanych rdzeni na węźle)
#SBATCH --ntasks-per-node=12
## Ilość pamięci przypadającej na jeden rdzeń obliczeniowy (domyślnie 4GB na rdzeń)
#SBATCH --mem-per-cpu=4GB
## Maksymalny czas trwania zlecenia (format HH:MM:SS)
#SBATCH --time=01:00:00
## Nazwa grantu do rozliczenia zużycia zasobów
#SBATCH -A <grant_id>
## Specyfikacja partycji
#SBATCH -p plgrid-testing
## Plik ze standardowym wyjściem
#SBATCH --output="output.out"
## Plik ze standardowym wyjściem błędów
#SBATCH --error="error.err"
module load plgrid/tools/imagemagick
## przejscie do katalogu z ktorego wywolany zostal sbatch
cd $SLURM_SUBMIT_DIR
ls *.tif | xargs -t -d "\n" -P ${SLURM_NTASKS} -n 1 srun -n 1 -N 1 --mem=4gb mogrify -format png
Powyższy skrypt dla każdego pliku *tif w katalogu uruchomi aplikację mogrify
, tak aby skonwertować obraz do pliku png. Pierwszą czynnością jest wylistowanie plików wejściowych, następnie wynik jest przekazywany do komendy xargs
, która przez parametr -P zapewnia równoległe uruchomienie dalszego polecania srun
. Do każdej instancji srun
zostanie przekazany jeden parametr, maksymalna równoległość wyniesie ${SLURM_NTASKS}. Każdy srun
uruchomi aplikację mogrify
na jednym rdzeniu z przydzielonym 4GB pamięci.