Překlad a spouštění OpenMP úloh¶
Překlad a spouštění OpenMP (vláknově paralelizovaných) programů poskytují na našich strojích s Ubuntu 22.04 (přehled strojů v klastru) následující překladače Fortranu a C/C++:
GNU překladače
gfortran
,gcc
,g++
verze 11, použít lze i verze 9:gfortran-9
ad. a 12:gfortran-12
ad.,(po
source load_intel
) překladače Intel oneAPI HPC Toolkitu 2022.x, jednak Classicifort
,icc
,icpc
, jednak novější na bázi LLVMifx
,icx
,icpx
,(po
source load_nv
) Nvidia překladače verze 22.xnvfortran
,nvc
,nvc++
(na bázi LLVM),(po
source load_amd
) AMD překladače verze 3.xflang
,clang
,clang++
(na bázi LLVM).
Překladače podporují specifikace OpenMP 4.5 až 5.x. Překladače na bázi LLVM (Intel, Nvidia, AMD) mohou poskytnout jiný (lepší i horší) výkon aplikací než klasické překladače (GNU a Intel Classic), včetně účinnosti OpenMP a optimalizace; s výjimkou Intelu nejsou LLVM fortranské překladače dosud k dispozici pro Windows. GNU a Nvidia překladače nabízejí OpenMP (a také OpenACC) podporu grafických karet Nvidia (GPU), Intel LLVM překladače mají OpenMP pro grafické karty Intel, AMD překladače deklarují podporu AMD GPUs. Vláknová paralelizace je zabudována v řadě instalovaných knihoven (Intel MKL, BLAS, LAPACK, FFTW ad.); je vhodné uvážit, zda využít OpenMP paralelizaci vlastními direktivami, paralelizaci zabudovanou v knihovnách nebo obojí.
Při překladu programů je třeba přidat volbu pro aktivaci OpenMP, obvykle také pro optimalizaci a případně pro diagnostiku. Před spuštěním programu se nastavuje počet vláken a bývá vhodné zajistit se proti přetečení zásobníku. Pro překlad i spouštění s jinými než GNU překladači je na našem klastru nezbytné použít příkazy pro upřednostnění cest k potřebným knihovnám příslušných překladačů: source load_intel
, source load_nv
nebo source load_amd
.
OpenMP s GNU překladači¶
Default GNU Compiler Collection (GCC) v Ubuntu 22.04 je ve verzi 11.2.0. Těmito překladači jsou zpracovány i knihovny v repozitářích Ubuntu, tyto knihovny je tedy vhodné používat právě s default GNU překladači:
# GNU Fortran compilation with OpenMP (Linux, Windows)
gfortran -fopenmp -Ofast file.f90 # with optimization
gfortran -fopenmp -fopt-info-all-omp file.f90 # with diagnostics
gfortran file.f90 -llapack # with a parallelized library
Instalovány jsou i starší a novější verze GNU překladačů (v9.4.0 a v12.0.1). Jejich OpenMP může a nemusí být kompatibilní s vláknově paralelizovanými knihovnami z repozitářů Ubuntu, smysluplné je jejich použití spíše pro soběstačné programy bez vnějších knihoven. Verze 9 může pomoci s překladem starších programů s vlastnostmi mimo současný standard, verze 12 může naopak podpořit novinky.
# Compilation with other versions of GNU Fortran
gfortran-9 -fopenmp -Ofast file.f90
gfortran-12 -fopenmp -Ofast file.f90
GNU překladače jsou k dispozici i pro Windows.
Před spuštěním vláknově paralelizovaného programu je dobré vědět, kolik má daný stroj hardwarových jader (naše tabulka), uvážit využití hyper-threadingu (osazení jednoho jádra dvěma vlákny) a ověřit si, kolik jader je vytíženo jinými úlohami (lokálně programy uptime
a top
, pro celý klastr skript guptime
nebo link guptime NOW). Počet požadovaných vláken je pak vhodné nastavit explicitně pomocí proměnné prostředí OMP_NUM_THREADS
, neboť defaulty překladačů jsou různé a především, na našem klastru je tato proměnná předdefinována hodnotou 1
.
# Setting the thread count
export OMP_NUM_THREADS=8 # Linux
set OMP_NUM_THREADS=8 # Windows
# Running a multi-threaded process
./a.out # Linux
OMP_NUM_THREADS=8 ./a.out # one-line alternative
a # Windows
Pokud paralelizovaný program po spuštění padá (Segmentation fault, Stack overflow apod.), ačkoliv jako neparalelizovaný běží, může být příčinou odlišné zacházení paralelizovaného programu se zásobníkem. V Linuxu může pomoci uvolnění default limitu na velikost zásobníku příkazem shellu ulimit
, někdy také zvýšení velikosti zásobníku pomocí proměnné prostředí OMP_STACKSIZE
:
# Preventing stack overflow
ulimit -s unlimited # removing a bash limit on stacksize
ulimit -a # check all actual limits
export OMP_STACKSIZE=256M # increasing OpenMP stacksize (in MB); necessary to guess
GNU překladače v Linuxu nabízejí využití OpenMP pro Nvidia (a také AMD) grafické karty (GNU Offloading and Multi-Processing Project, Offloading Support in GCC). K tomu účelu je na našem klastru instalován balíček gcc-11-offload-nvptx
, podporující kromě OpenMP i překlad alternativním systémem OpenACC. Překladové řádky:
# GNU Fortran with OpenMP and OpenACC for Nvidia GPU (Linux only)
gfortran -fopenmp -foffload=nvptx-none -fopt-info-all-omp file.f90 # OpenMP
gfortran -fopenacc -foffload=nvptx-none -fopt-info-all-omp file.f90 # OpenACC
Užitek mohou přinést volby -foffload=
, -foffload-options=
a proměnné prostředí GOMP_DEBUG
, GCC_ACC_NOTIFY
či OMP_TARGET_OFFLOAD
.
Následující ukázky mají dobrý výkon s OpenACC direktivami a nevalný s OpenMP direktivami. Podstatně lepší GPU výkon s OpenMP direktivami poskytují Nvidia překladače.
Link s ukázkovými programy bude doplněn.
OpenMP s Intel překladači¶
Na klastru jsou instalovány Intel oneAPI Base a HPC Toolkits 2022.x, přinášející jednak stagnující Classic překladače ifort
, icc
, icpc
(podpora OpenMP pro CPU, nikoliv pro GPU, podpora Coarray Fortranu), jednak překladače rozvíjené na bázi LLVM ifx
, icx
, icpx
(podpora OpenMP pro CPU a Intel GPU, bez podpory Coarray Fortranu), viz Release Notes. Součástí je i kvalitní (optimalizovaná a paralelizovaná) knihovna Intel Math Kernel Library (MKL) s lineární algebrou (přímé řešiče pro plné i řídké matice, iterativní řešiče), Fourierovou transformací ad. Vše je k dispozici i pro Windows. MKL knihovnu lze připojovat také ke GNU a Nvidia překladačům, v Linuxu i ve Windows (MKL Link Line Advisor, náš link Připojování knihoven). Nejistý je výkon MKL knihovny na AMD procesorech (geofy5-6), na nich je vhodné porovnávat s výkonem ekvivalentních knihoven AMD překladačů. Intel Classic a LLVM překladače sdílejí mnoho voleb, je tam i řada odchylek. Volby překladačů v Linuxu a Windows mohou mít odchylnou syntaxi.
# Intel Fortran Classic compilation with OpenMP (Linux, Windows)
source load_intel # activation of Intel oneAPI compilers
ifort -qopenmp -Ofast file.f90 # with optimization (Linux)
ifort -Qopenmp -Ofast file.f90 # with optimization (Windows)
ifort -qopenmp -diag-enable=openmp file.f90 # with diagnostics (Linux)
ifort -Qopenmp -Qdiag-enable:openmp file.f90 # with diagnostics (Windows)
ifort file.f90 -qmkl # with the MKL library (Linux)
ifort file.f90 -Qmkl # with the MKL library (Windows)
# Intel Fortran LLVM compilation with OpenMP (Linux, Windows)
ifx ... # same options as shown for ifort
Před spuštěním vláknově paralelizovaného programu je dobré vědět, kolik má daný stroj hardwarových jader (naše tabulka), uvážit využití hyper-threadingu (osazení jednoho jádra dvěma vlákny) a ověřit si, kolik jader je vytíženo jinými úlohami (lokálně programy uptime
a top
, pro celý klastr skript guptime
nebo link guptime NOW). Počet požadovaných vláken je pak vhodné nastavit explicitně pomocí proměnné prostředí OMP_NUM_THREADS
a pro knihovnu MKL pomocí proměnné MKL_NUM_THREADS
, neboť na našem klastru jsou obě proměnné předdefinovány hodnotou 1
.
# Setting the thread count
export OMP_NUM_THREADS=8 # OpenMP general setting (Linux)
export MKL_NUM_THREADS=8 # Intel MKL specific setting (Linux)
set OMP_NUM_THREADS=8 # Windows
set MKL_NUM_THREADS=8 # Windows
# Running a multi-threaded process
./a.out # Linux
OMP_NUM_THREADS=8 ./a.out # one-line alternative
file # Windows: executable files retain the first source name
Pokud paralelizovaný program po spuštění padá (Segmentation fault, Stack overflow apod.), ačkoliv jako neparalelizovaný běží, může být příčinou odlišné zacházení paralelizovaného programu se zásobníkem. Pomoci může překlad s preferencí ukládání polí jinam než na zásobník (-heap-arrays
), v Linuxu také uvolnění default limitu na velikost zásobníku příkazem shellu ulimit
, někdy také zvýšení velikosti zásobníku pomocí proměnné prostředí OMP_STACKSIZE
:
# Preventing stack overflow
ifort -qopenmp -heap-arrays file.f90 # arrays on the heap instead of the stack
ulimit -s unlimited # removing bash limit on stacksize
ulimit -a # check all actual limits
export OMP_STACKSIZE=256M # increasing OpenMP stacksize (in MB); necessary to guess
Intel překladače nabízejí využití OpenMP pro Intel grafické karty. Dosud nevyzkoušeno, ostatně nejméně deset našich Nvidia GPU je podstatně výkonnějších než soudobé Intel GPU.
OpenMP s Nvidia překladači¶
Na klastru je instalován balík Nvidia HPC SDK verze 22.x, přinášející překladače nvfortran
, nvc
a nvc++
s podporou jak OpenMP pro CPU a Nvidia GPU, tak i alternativního systému OpenACC (viz Nvidia OpenACC Getting Started Guide). Součástí je také několik paralelizovaných knihoven s lineární algebrou ad. Balík je dodáván pro Linux, dosud nikoliv pro Windows.
# Nvidia Fortran compilation with OpenMP (Linux only)
source load_nv # activation of Nvidia HPC SDK
nvfortran -mp -fast file.f90 # with optimization
nvfortran -mp -Minfo=mp file.f90 # with diagnostics
nvfortran file.f90 -llapack # with a parallelized library
Před spuštěním vláknově paralelizovaného programu je dobré vědět, kolik má daný stroj hardwarových jader (naše tabulka), uvážit využití hyper-threadingu (osazení jednoho jádra dvěma vlákny) a ověřit si, kolik jader je vytíženo jinými úlohami (lokálně programy uptime
a top
, pro celý klastr skript guptime
nebo link guptime NOW). Počet požadovaných vláken je pak vhodné nastavit explicitně pomocí proměnné prostředí OMP_NUM_THREADS
, neboť na našem klastru je tato proměnná předdefinována hodnotou 1
.
# Setting the thread count
export OMP_NUM_THREADS=8
# Running a multi-threaded process
./a.out
OMP_NUM_THREADS=8 ./a.out # one-line alternative
Pokud paralelizovaný program po spuštění padá (Segmentation fault, Stack overflow apod.), ačkoliv jako neparalelizovaný běží, může být příčinou odlišné zacházení paralelizovaného programu se zásobníkem. Pomoci může uvolnění default limitu na velikost zásobníku příkazem shellu ulimit
, někdy také zvýšení velikosti zásobníku pomocí proměnné prostředí OMP_STACKSIZE
:
# Preventing stack overflow
ulimit -s unlimited # removing bash limit on stacksize
ulimit -a # check all actual limits
export OMP_STACKSIZE=256M # increasing OpenMP stacksize (in MB); necessary to guess
Silnou stránkou Nvidia (dříve PGI) překladačů je dlouholetá podpora programování Nvidia GPU. Překladače nabízejí několik přístupů, mezi nimi také OpenMP a alternativní OpenACC, včetně obvykle úspěšného chodu programů paralelizovaných pro GPU paralelizovaně na CPU (CPU fallback). Překladové řádky:
# Nvidia Fortran with OpenMP and OpenACC for Nvidia GPU (Linux only)
nvfortran -mp=gpu -Minfo=mp file.f90 # OpenMP for GPU
nvfortran -mp=multicore -Minfo=mp file.f90 # OpenMP with parallelized CPU fallback
nvfortran -acc -Minfo=accel file.f90 # OpenACC for GPU
nvfortran -acc=multicore -Minfo=accel file.f90 # OpenACC with parallelized CPU fallback
nvfortran -acc=host -Minfo=accel file.f90 # OpenACC with sequential CPU fallback
Užitek mohou přinést proměnné prostředí pro debugging NV_OMP_NOTIFY
a NV_ACC_NOTIFY
, profiling NV_ACC_TIME
a CPU fallback OMP_TARGET_OFFLOAD
.
Nvidia překladače až příliš rychle omezují dolní limit na compute capability (cc) použitelných grafických karet (v22.x: pro OpenACC je minimální cc 3.5, pro OpenMP 7.0; cc našich strojů viz tabulka); soudobé GNU překladače podporují i starší GPU.
Následující ukázky mají výborný výkon s OpenACC i OpenMP: link s ukázkovými programy bude doplněn.
Poznámky¶
Na strojích máme předdefinovány proměnné prostředí OMP_NUM_THREADS
a MKL_NUM_THREADS
hodnotami 1 (běh úlohy na 1 vláknu, bez paralelizace). Je lépe si tyto hodnoty vědomě upravit podle potřeb aplikace a aktuálního zatížení stroje než se spolehnout na default. Počet vláken lze nastavovat i klauzulí NUM_THREADS
ve zdrojovém kódu programů, což je méně operativní a příliš závazné (mající přednost před proměnnou prostředí).
OpenMP programy škálují dobře (zvyšují výkon s počtem jader lineárně s faktorem 1) spíše vzácně; s rostoucím počtem zapojených jader se nemusí dostavit úměrné zvýšení výkonu. Nemusí pak být ekonomické věnovat běhu aplikace všechna jádra stroje. Lze uvážit vhodnost trapné paralelizace (zde: paralelní běh více aplikací běžících každá na nevelkém počtu jader). Negativní roli může hrát i možné snížení frekvence jader při zvýšeném zatížení (teplotě) procesoru; např. CPU Intel i9-9900K může s rostoucím zatížením snižovat frekvenci aktivních jader z 5.0 GHz na 3.6 GHz.