Vsebniki za grafične procesne enote
Računanje na GPE
Grafična procesna enota (angl. Graphics Processing Unit, GPU) ali krajše GPE je poseben procesor, v osnovi namenjen izrisovanju slike na zaslon. Grafične procesne enote so zato optimizirane za hitro računanje podatkovno paralelnih poslov, na primer za obdelavo slik ali video posnetkov. Čeprav niso primerne za reševanje splošnih problemov, se izkaže, da znajo hitro izvesti mnoge operacije, uporabne tudi v drugih domenah. Pri globokem učenju programski paketi, na primer PyTorch in Tensorflow, izkoriščajo grafične procesne enote za hitro računanje operacij nad matrikami in vektorji. Podporo za grafične procesne enote najdemo tudi v orodjih za molekulsko dinamiko, na primer GROMACS in v orodjih za simulacijo tekočinskega toka, na primer RapidCFD.
Mandelbrotova množica na GPE
Programu za izris Mandelbrotove množice dodajmo podporo za računanje na grafičnih procesnih enotah. Izračun konvergence izvajamo za vsako točke v kompleksnem prostoru, neodvisno od ostalih točk. Gre torej za izjemno podatkovno paralelen problem, ki se nam ga splača izvajati na grafični procesni enoti.
Tudi za računanje na grafičnih procesnih enotah uporabimo knjižnico numba
, le da moramo tokrat zaradi drugačnega programskega modela
precej spremeniti funkciji mandelbrot
in mandelbrot_color
, ki smo jih zato tudi preimenovali.
Celoten program za izdelavo slike Mandelbrotove množice na grafični procesni enoti:
Koda programa mandelbrot-gpu.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
|
Če malo poenostavimo, funkcija mandelbrot_gpu
(vrstice 62 do 85) na grafični procesni enoti zažene toliko niti, kot je točk na sliki, nato pa vsaka nit v funkciji mandelbrot_color_kernel
(vrstice 19 do 59), ki teče na grafični procesni enoti, preveri konvergenco in določi barvo slikovne točke.
Obvestilo
Mnogo več o programiranju grafičnih procesnih enot izveste na delavnici Programiranje grafičnih procesnih enot.
Vsebnik s podporo za GPE
Delo s posebno strojno opremo, kot so grafične procesne enote, moramo ob zagonu vsebnika posebej zahtevati. Poleg tega moramo poskrbeti, da so na gostitelju nameščeni ustrezni gonilniki. Ogrodje apptainer podpira grafične procesne enote Nvidia (CUDA) in AMD (ROCm). Pri klicu vsebnika dodamo stikalo --nv
za grafične procesne enote Nvidia in --rocm
za grafične procesne enote AMD. Zdaj ogrodje Apptainer na gostitelju poišče ustrezne gonilnike in jih poveže z vsebnikom.
Stikalo --nv
:
- Lahko uporabljamo z ukazi
apptainer shell
,apptainer run
inapptainer exec
. - Zagotovi, da so zapisi
/dev/nvidia*
o grafičnih procesnih enotah na gostitelju vidni tudi v vsebniku. - Poišče in poveže osnovne knjižnice CUDA z gostitelja v vsebnik. Tako so knjižnice na voljo v vsebniku in ustrezajo gonilnikom grafičnih procesnih enot na gostitelju.
- Nastavi spremenljivko okolja
LD_LIBRARY_PATH
v vsebniku, da programi v vsebniku kličejo knjižnice na gostitelju.
Za uporabo grafičnih procesnih enot Nvidia moramo v vsebnik namestiti knjižnice CUDA. To lahko namestimo sami, tako kot smo delali do sedaj. Veliko lažje pa je, če naše aplikacije dodamo v vsebnik, ki ima knjižnice že nameščene. Na repozitoriju dockerhub Nvidia objavlja raznorazne vsebnike. Najdemo jih na povezavi https://hub.docker.com/r/nvidia/cuda. Izberemo vsebnik 12.0.0-base-ubuntu20.04
, ki vključuje le najosnovnejše knjižnice.
Do sedaj smo knjižnice za python nameščali s programom pip3
(angl. Package Installer for Python3). Zelo priljubljeno pa je nameščanje programskih paketov z ogrodjem conda
, saj nam poleg namestitve omogoča tudi nastavljanje okolij (spremenljivk okolja). Ker gre za obsežno ogrodje, se mu v vsebniku raje izognemo. Uporabimo raje manjši različico Miniconda; za namestitev sledimo dokumentaciji.
Namestimo še pakete numpy
, pillow
, numba
in za računanje na grafičnih procesnih enotah še ustrezen paket cudatoolkit
.
Poskrbimo, da v vsebnik prenesemo program mandelbrot-gpu.py
in konfiguracijsko datoteko default.conf
.
Vsebnik mb-gpu.def
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
|
Zgrajen vsebnik zaženemo z ukazom
$ srun --gpus=1 --partition=gpu apptainer exec --nv mb-gpu.sif mandelbrot-gpu.py
srun: job 48543178 queued and waiting for resources
srun: job 48543178 has been allocated resources
INFO: Setting 'NVIDIA_VISIBLE_DEVICES=all' to emulate legacy GPU binding.
INFO: Setting --writable-tmpfs (required by nvidia-container-cli)
GPU: size: (3840, 2160) iterations: 256 time: 1.662 s
srun --gpus=1 --partition=gpu apptainer exec --nv mb-gpu.sif mandelbrot-gpu.py
S stikalom --gpus=1
smo od razvrščevalnika Slurma zahtevali, da nam dodeli en procesor in eno grafično procesno enoto. S stikalom --partition=gpu
smo zahtevali, da se naš posel izvaja na particiji gpu
. Na koncu pa smo s stikalom --nv
zahtevali, da ogrodje Apptainer poišče gonilnike na gostitelju in jih poveže z vsebnikom.
Preveri svoje znanje
Vaja
Za pripravo recepta in gradnjo vsebnika sledimo navodilom: Vaja 06.