This shows you the differences between two versions of the page.
|
asc:laboratoare:01 [2026/03/12 01:26] tudor.calafeteanu [CPU] |
asc:laboratoare:01 [2026/04/10 17:27] (current) tudor.calafeteanu [Comenzi uzuale SLURM] |
||
|---|---|---|---|
| Line 73: | Line 73: | ||
| </code> | </code> | ||
| - | Explicații coloane: **CPUS** = număr total de thread-uri hardware per nod, **MEMORY** = RAM în MB per nod, **GRES** = resurse generice (GPU-uri: tip și număr per nod), **AVAIL** = starea partiției. | + | Explicații coloane: **CPUS** = număr total de thread-uri hardware **per nod**, **MEMORY** = RAM **per nod** (în MB), **GRES** = resurse generice (GPU-uri: tip și număr **per nod**), **AVAIL** = starea partiției. |
| Asteriscul din dreptul partiției (''haswell*'' în cazul nostru) indică **partiția implicită**. Dacă nu specificați o partiție, SLURM va aloca jobul pe partiția implicită. | Asteriscul din dreptul partiției (''haswell*'' în cazul nostru) indică **partiția implicită**. Dacă nu specificați o partiție, SLURM va aloca jobul pe partiția implicită. | ||
| Line 116: | Line 116: | ||
| ¹ Sockets/Node x Cores/Socket x Threads/Core = Threads/Node \\ | ¹ Sockets/Node x Cores/Socket x Threads/Core = Threads/Node \\ | ||
| - | ² Pe AMD EPYC, fiecare socket expune 4 NUMA nodes datorită arhitecturii chiplet (CCD/CCX). Fiecare NUMA node conține 16 core-uri și o porțiune de memorie locală. Pe Intel, de regulă 1 socket = 1 NUMA node. | + | ² Pe AMD EPYC, fiecare socket expune 4 NUMA nodes datorită arhitecturii chiplet (CCD/CCX). Fiecare NUMA node conține 16 core-uri și o porțiune de memorie locală. Pe Intel, de regulă, 1 socket = 1 NUMA node. |
| + | <spoiler Alte informații utile (click pentru detalii)> | ||
| <note tip> | <note tip> | ||
| Toate partițiile folosesc arhitectura x86_64 cu 16 registre generale de 64 biți (RAX, RBX, ..., R8–R15). Partițiile mai noi (Sapphire Rapids, Ice Lake) dispun și de 32 registre AVX-512 de 512 biți, iar Sapphire Rapids adaugă registre AMX (tile registers) pentru operații matriceale. | Toate partițiile folosesc arhitectura x86_64 cu 16 registre generale de 64 biți (RAX, RBX, ..., R8–R15). Partițiile mai noi (Sapphire Rapids, Ice Lake) dispun și de 32 registre AVX-512 de 512 biți, iar Sapphire Rapids adaugă registre AMX (tile registers) pentru operații matriceale. | ||
| </note> | </note> | ||
| - | ==== Ierarhie de memorie ==== | + | </spoiler> |
| + | \\ | ||
| + | ==== Ierarhia de memorie ==== | ||
| ^ Partiție ^ Linie cache ^ L1d SRAM/core ^ L1i SRAM/core ^ L2 SRAM/core ^ L3 SRAM/socket ^ DRAM/nod¹ ^ | ^ Partiție ^ Linie cache ^ L1d SRAM/core ^ L1i SRAM/core ^ L2 SRAM/core ^ L3 SRAM/socket ^ DRAM/nod¹ ^ | ||
| - | | dgxh100 | 64B | 32 KB | 48 KB | 2 MB | 105 MB | ~2 TB DDR5-4800; 8 canale; ~307 GB/s | | + | | dgxh100 | 64B | 48 KB | 32 KB | 2 MB | 105 MB | ~2 TB DDR5-4800; 8 canale; ~307 GB/s | |
| | dgxa100 | 64B | 32 KB | 32 KB | 512 KB | 256 MB | ~2 TB DDR4-3200; 8 canale; ~204 GB/s | | | dgxa100 | 64B | 32 KB | 32 KB | 512 KB | 256 MB | ~2 TB DDR4-3200; 8 canale; ~204 GB/s | | ||
| | ucsx | 64B | 48 KB | 32 KB | 1.25 MB | 24 MB | ~512 GB DDR4-3200; 4 canale; ~102 GB/s | | | ucsx | 64B | 48 KB | 32 KB | 1.25 MB | 24 MB | ~512 GB DDR4-3200; 4 canale; ~102 GB/s | | ||
| Line 132: | Line 135: | ||
| ¹ capacitate tip; canale per socket; bandwidth teoretic per socket | ¹ capacitate tip; canale per socket; bandwidth teoretic per socket | ||
| + | <spoiler Alte informații utile (click pentru detalii)> | ||
| <note tip> | <note tip> | ||
| Bandwidth-ul teoretic per socket se calculează astfel: \\ | Bandwidth-ul teoretic per socket se calculează astfel: \\ | ||
| Line 137: | Line 141: | ||
| De exemplu, pentru ''dgxh100'': 8 × 4800 MT/s × 8 B/T = ~307 GB/s. | De exemplu, pentru ''dgxh100'': 8 × 4800 MT/s × 8 B/T = ~307 GB/s. | ||
| </note> | </note> | ||
| + | </spoiler> | ||
| + | \\ | ||
| ==== GPU ==== | ==== GPU ==== | ||
| Line 148: | Line 154: | ||
| ² capacitate tip; bus; bandwidth teoretic | ² capacitate tip; bus; bandwidth teoretic | ||
| + | <spoiler Alte informații utile (click pentru detalii)> | ||
| + | <note tip> | ||
| + | Un Streaming Multiprocessor (SM) este unitatea fundamentală de execuție pe GPU, echivalentul unui core pe CPU. Fiecare SM conține multiple CUDA cores (pentru operații generale FP32/INT32) și Tensor Cores (pentru operații matriceale accelerate, folosite în deep learning). Toate CUDA cores dintr-un SM partajează aceleași resurse: registre, shared memory și cache L1. | ||
| + | </note> | ||
| + | |||
| + | <note tip> | ||
| + | Compute Capability (sm_XX) determină ce instrucțiuni și funcționalități hardware sunt disponibile. Este esențial la compilarea CUDA: ''nvcc -arch=sm_90'' pentru H100, ''sm_80'' pentru A100. Un binar compilat pentru un anumit compute capability nu rulează pe GPU-uri cu o versiune mai veche. | ||
| + | </note> | ||
| + | </spoiler> | ||
| + | \\ | ||
| ===== Ce este FEP-ul? ===== | ===== Ce este FEP-ul? ===== | ||
| FEP-ul reprezintă nodul de acces către clusterul HPC al universității. Pe scurt, este serverul prin intermediul căruia utilizatorii se conectează la infrastructură pentru a pregăti și lansa job-urile pe resursele de calcul ale clusterului. | FEP-ul reprezintă nodul de acces către clusterul HPC al universității. Pe scurt, este serverul prin intermediul căruia utilizatorii se conectează la infrastructură pentru a pregăti și lansa job-urile pe resursele de calcul ale clusterului. | ||
| Line 244: | Line 260: | ||
| module help | module help | ||
| module avail # afișează modulele disponibile | module avail # afișează modulele disponibile | ||
| - | module load libraries/cuda-13.0 # încarcă biblioteca CUDA corespunzătoare | + | module load libraries/cuda-13.0 # încarcă modulul de CUDA corespunzător |
| module list # arată modulele active în sesiunea curentă | module list # arată modulele active în sesiunea curentă | ||
| module unload libraries/cuda-13.0 # dezactivează un modul | module unload libraries/cuda-13.0 # dezactivează un modul | ||
| module purge # dezactivează toate modulele încărcate | module purge # dezactivează toate modulele încărcate | ||
| </code> | </code> | ||
| - | |||
| - | <note important> | ||
| - | În prezent, modulefile-urile nu sunt disponibile pe cluster. Până la rezolvarea acestei probleme, configurarea mediului CUDA se face manual prin variabilele de mediu: | ||
| - | |||
| - | <code bash> | ||
| - | export PATH=/usr/local/cuda/bin:$PATH # pentru a găsi compilatorul nvcc | ||
| - | export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH # pentru a găsi bibliotecile CUDA la runtime | ||
| - | </code> | ||
| - | |||
| - | Când modulefile-urile vor fi disponibile, cele două linii de export vor fi înlocuite cu: | ||
| - | <code bash> | ||
| - | module load libraries/cuda-13.0 | ||
| - | </code> | ||
| - | </note> | ||
| ===== Utilizare SLURM ===== | ===== Utilizare SLURM ===== | ||
| SLURM este scheduler-ul de joburi folosit pe clusterul UPB. Rolul său este să primească cererile utilizatorilor, să le pună în coadă și să aloce resursele disponibile (CPU-uri, GPU-uri, memorie) în mod echitabil. Fiecare cont are restricții per partiție: în primul rând dacă are acces sau nu, timp maxim per job (de exemplu maximum 10 minute pentru conturile voastre, după cum ați văzut mai sus), număr maxim de joburi simultane, număr maxim de noduri folosite per job, limită de RAM per job, etc. | SLURM este scheduler-ul de joburi folosit pe clusterul UPB. Rolul său este să primească cererile utilizatorilor, să le pună în coadă și să aloce resursele disponibile (CPU-uri, GPU-uri, memorie) în mod echitabil. Fiecare cont are restricții per partiție: în primul rând dacă are acces sau nu, timp maxim per job (de exemplu maximum 10 minute pentru conturile voastre, după cum ați văzut mai sus), număr maxim de joburi simultane, număr maxim de noduri folosite per job, limită de RAM per job, etc. | ||
| Line 364: | Line 366: | ||
| #SBATCH --partition=ucsx | #SBATCH --partition=ucsx | ||
| #SBATCH --gres=gpu:1 | #SBATCH --gres=gpu:1 | ||
| - | # Configurare manuală CUDA (vezi secțiunea "Configurarea mediului de lucru") | + | module load libraries/cuda-13.0 |
| - | export PATH=/usr/local/cuda/bin:$PATH | + | |
| - | export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH | + | |
| nvcc -o hello_cuda hello_cuda.cu | nvcc -o hello_cuda hello_cuda.cu | ||
| ./hello_cuda | ./hello_cuda | ||
| Line 397: | Line 397: | ||
| srun --partition=ucsx --gres=gpu:1 ./hello_cuda # rulare interactivă simplă | srun --partition=ucsx --gres=gpu:1 ./hello_cuda # rulare interactivă simplă | ||
| srun --partition=ucsx --gres=gpu:1 --pty bash # sesiune interactivă pe nodul de calcul | srun --partition=ucsx --gres=gpu:1 --pty bash # sesiune interactivă pe nodul de calcul | ||
| + | srun --partition=haswell -w haswell-wnxx --pty bash # rulare interactivă simplă pe un anumit nod (xx se inlocuieste cu un numar anume de sistem) de pe partitia haswell | ||
| # === Informații despre cluster === | # === Informații despre cluster === | ||
| Line 428: | Line 429: | ||
| * Cât RAM e disponibil per nod vs. maximul permis per job? (hint: ''scontrol show partition <nume>'') | * Cât RAM e disponibil per nod vs. maximul permis per job? (hint: ''scontrol show partition <nume>'') | ||
| * Cum vedeți joburile care se execută în prezent pe cluster? Cum opriți un job specific? | * Cum vedeți joburile care se execută în prezent pe cluster? Cum opriți un job specific? | ||
| + | * Cum puteti rula un job (interactiv sau nu) pe un anumit nod din cluster (Hint, explorati optiunea -w de la srun) | ||
| * Rulați cel puțin un program C multi-threaded și un program CUDA, atât cu ''sbatch'', cât și cu ''srun''. Verificați rezultatele. Care este diferența dintre cele două comenzi? | * Rulați cel puțin un program C multi-threaded și un program CUDA, atât cu ''sbatch'', cât și cu ''srun''. Verificați rezultatele. Care este diferența dintre cele două comenzi? | ||
| * Scrieți un program C multi-threaded care face calcule intensive (de exemplu suma unei serii pe fiecare thread). Rulați-l o dată cu ''%%--cpus-per-task=N%%'' și o dată fără ''%%--cpus-per-task=N%%'', unde N este numărul de thread-uri din program. Comparați timpii de execuție (hint: ''time ./program'') și explicați diferența. | * Scrieți un program C multi-threaded care face calcule intensive (de exemplu suma unei serii pe fiecare thread). Rulați-l o dată cu ''%%--cpus-per-task=N%%'' și o dată fără ''%%--cpus-per-task=N%%'', unde N este numărul de thread-uri din program. Comparați timpii de execuție (hint: ''time ./program'') și explicați diferența. | ||
| Line 435: | Line 437: | ||
| * [[https://slurm.schedmd.com/mc_support.html | SLURM Support for Multi-core/Multi-thread Architectures]] | * [[https://slurm.schedmd.com/mc_support.html | SLURM Support for Multi-core/Multi-thread Architectures]] | ||
| * https://infrastructure.pages.upb.ro/wiki/docs/grid/ | * https://infrastructure.pages.upb.ro/wiki/docs/grid/ | ||
| + | * https://guides.upb.ro/docs/grid/apptainer-usage | ||