Překlad a spouštění MPI úloh¶
MPI je na našich strojích v těchto implementacích:
plus nezávislé MPI implementace v dockerovských obrazech. Je vhodné používat MPI implementaci konzistentní s překladačem programu a volanými numerickými knihovnami.
Při spouštění MPI úlohy na jediném stroji stačí určit počet procesů. Při spouštění MPI úlohy na více strojích je třeba nastavit bezheslový přístup, specifikovat hostitelské počítače a rozložení procesů na nich a specifikovat komunikační hardware a protokol. Vybrat lze rychlý InfiniBand (při QDR teoretických 32 Gbit/s), dostupný na geofxyzw a některých geof.0, nebo pomalejší Ethernet (1 Gbit/s), dostupný všude. Horní hranice přenosové rychlosti (bandwidth) může ve sdílené paměti našich strojů dosáhnout 10-20 GB/s, s InfiniBandem 3.5 GB/s a Ethernetem mírně nad 0.1 GB/s; rychlost významně závisí na velikosti předávaných dat, jak lze ověřit pomocí níže zmíněných MPI benchmarků.
Open MPI (default)¶
Default implementace MPI v Ubuntu 22.04 je Open MPI v4.1.2 vhodná pro GNU překladače v11. Programy se překládají pomocí wrapperů mpif90 (nověji mpifort) a mpicc. Aktuální překladový řádek se odhalí příkazem mpif90 -show, požadovaný překladač lze upřesnit pomocí proměnných prostředí OMPI_FC a OMPI_CC a přidat volby pro překlad pomocí proměnných OMPI_FCFLAGS a OMPI_CFLAGS nebo rovnou na řádku, např.:
# Open MPI Fortran compilation
export OMPI_FCFLAGS="-Ofast -march=native"
mpif90 file.f90 # using gfortran
mpif90 -Ofast -march=native file.f90 # an alternative
OMPI_FC=gfortran-12 mpif90 file.f90 # using gfortran v12
Úlohy se spouštějí pomocí loaderu mpirun (synonymum mpiexec), obvykle s volbou -n (též -np) udávající počet procesů. Pro běh procesů na jediném stroji není třeba zadávat víc, komunikace je implicitně vedena ovladačem sdílené paměti z komponenty ob1 (výslovnost Obi-Wan, explicitně: -mca pml ob1 -mca btl self,vader). Může být (stojí za test), že komunikace poběží o něco rychleji s užitím komponenty ucx (pouze na strojích s InfiniBandem):
# Open MPI local run
mpirun -n 8 -mca pml ob1 a.out # point-to-point message layer: ob1
mpirun -n 8 -mca pml ucx a.out # point-to-point message layer: ucx
mpirun -n 8 a.out # hosts with InfiniBand: ucx, without IB: ob1
Pro běh úloh na více strojích je nutné nastavit bezheslový přístup (viz níže Poznámky) a je vhodné připravit hostfile se seznamem hostitelů (co řádek, to jméno hostitele), přičemž stroje by si měly být podobné (např. všechny s InfiniBandem), popsat rozložení procesů na strojích (např. volbou -N pro počet procesů na každém stroji) a spouštět úlohy ve sdíleném adresáři zadaném absolutní cestou. Místo v hostfile lze seznam strojů a počty procesů na nich popsat v rámci volby -H. Pomocí parametru -mca pml ucx se aktivuje UCX komunikace vhodná pro InfiniBand, komponentu ob1 (píše se -mca pml ob1) je pro InfiniBand možné využít také (v této variantě zvané IPoIB bývá méně výkonný). Na strojích bez InfiniBandu poskytuje komponenta ob1 komunikaci přes Ethernet. S ob1 je třeba explicitně zadávat jména adaptérů, u nás mib0 pro InfiniBand a eno1 pro Ethernet:
# Open MPI distributed run
cd /AbsolutePath
mpirun -n 16 -N 8 -hostfile hostfile -mca pml ucx a.out # hosts with InfiniBand
mpirun -n 16 -N 8 -hostfile hostfile -mca pml ob1 -mca btl_tcp_if_include mib0 a.out # InfiniBand via IPoIB
mpirun -n 16 -N 8 -hostfile hostfile -mca pml ob1 -mca btl_tcp_if_include eno1 a.out # Ethernet only
MCA (modular component architecture) parametry loaderu lze nastavit trvaleji pomocí proměnných prostředí (máme to tak) a úlohy na více strojích pak spouštět jednodušším příkazem, zde včetně výčtu strojů s počty jejich procesů na příkazovém řádku místo v hostfile:
# Open MPI distributed run with predefined environment variables
export OMPI_MCA_pml=ucx # hosts with InfiniBand
export OMPI_MCA_pml=ob1 # hosts without InfiniBand
export OMPI_MCA_btl_tcp_if_include=mib0 # hosts with InfiniBand
export OMPI_MCA_btl_tcp_if_include=eno1 # hosts without InfiniBand
cd /opt/osu-benchmarks/open-mpi/mpi/pt2pt # OSU benchmarks of MPI bandwidth, latency etc.
mpirun -n 2 -H geofA:1,geofB:1 osu_bw
Při nestandardním nastavení proměnných prostředí (typicky proměnné PATH) na spouštějícím stroji může být nutné exportovat tyto proměnné poomcí volby -x. Příkladem může být spouštění programu aspect: cesta k němu se lokálně nastavuje voláním source load_aspect a takto změněnou hodnotu proměnné PATH je třeba explicitně distribuovat.
# Open MPI distributed run with exported environment variables
source load_aspect
cd /AbsolutePath
mpirun -x PATH -n 72 -H geofA:24,geofB:24,geocC:24 aspect file.prm # more variables: -x VAR1 -x VAR2
Pro ujištění, které MCA komponenty jsou aktivní, lze zvýšit verbosity level pomocí parametrů jako -mca pml_base_verbose 100, -mca btl_base_verbose 100 aj. Jejich přehled podává příkaz ompi_info -a. Ověřit rozložení procesů na strojích lze volbou mpirun -display-map.
Intel MPI¶
Pro aktivaci MPI z Intel oneAPI HPC Toolkitu je určen místní příkaz source load_intel pro načtení Intel oneAPI konfigurace. Fortranské překladové wrappery jsou dva, mpiifort volající Intel Fortran a mpif90 pro GNU Fortran, pro Intel C jsou určeny mpiicc a mpiicpc a pro GNU C mpicc a mpicxx. Default volby wrapper přizná při volbě -show, další volby pro překlad se přidají pomocí proměnných I_MPI_FCFLAGS a I_MPI_CFLAGS nebo rovnou na řádek (více překladových proměnných):
# Intel MPI Fortran compilation
source load_intel
mpiifort file.f90 # using ifort
mpiifort -Ofast -xHost file.f90 # with additional compiler options
mpif90 file.f90 # using gfortran
mpif90 -Ofast -march=native file.f90 # with additional compiler options
Pro spouštění úloh lze použít loadery mpirun a mpiexec, typicky s volbou -n (též -np) udávající počet procesů. Volba komunikačního protokolu se provádí pomocí proměnné prostředí I_MPI_FABRICS, její obvyklou hodnotou je shm:ofi (shared memory pro komunikaci uvnitř stroje, jinak ofi s libfabric knihovnou). Dodat proměnné prostředí příkazu lze i touto formou (více běhových proměnných):
# Intel MPI local run
source load_intel
I_MPI_FABRICS=shm mpirun -n 8 ./a.out # local communication via shared memory
I_MPI_FABRICS=ofi mpirun -n 8 ./a.out # local communication via ofi library
Pro běh úloh na více strojích je nutné nastavit bezheslový přístup (viz níže Poznámky) a je vhodné připravit hostfile se seznamem hostitelů (co řádek, to jméno hostitele), popsat rozložení procesů na strojích (např. volbou -ppn, processes per node, pro počet procesů na každém stroji) a spouštět úlohy ve sdíleném adresáři zadaném absolutní cestou. Pomocí proměnné I_MPI_OFI_PROVIDER se nastavuje OFI komunikace buď přes InfiniBand (mlx = Mellanox), IPoIB (tcp na strojích s InfiniBandem) nebo Ethernet (tcp na strojích bez InfiniBandu):
# Intel MPI distributed run
source load_intel
cd /AbsolutePath
I_MPI_OFI_PROVIDER=mlx mpirun -n 16 -ppn 8 -f hostfile ./a.out # hosts with InfiniBand
I_MPI_OFI_PROVIDER=tcp mpirun -n 16 -ppn 8 -f hostfile ./a.out # hosts without InfiniBand
S předdefinovanými proměnnými prostředí lze úlohy spouštět jednodušeji, zde včetně výčtu strojů na příkazovém řádku místo v hostfile:
# Intel MPI distributed run with predefined environment variables
source load_intel
export I_MPI_FABRICS=shm:ofi # default for both intra- and inter-node communication
export I_MPI_OFI_PROVIDER=mlx # using fast InfiniBand
export I_MPI_OFI_PROVIDER=tcp # using slower IPoIB or slow Ethernet
cd /opt/osu-benchmarks/intel-mpi/mpi/pt2pt # OSU benchmarks of MPI bandwidth, latency etc.
mpirun -n 2 -ppn 1 -hosts geofA,geofB ./osu_bw
Diagnostiku lze vyžádat nastavením proměnné I_MPI_DEBUG na kladné hodnoty 1–100 (rozumná volba: 5). K dispozici je MPI profiler: nastaví se proměnná I_MPI_STATS na kladnou hodnotu 1–5 a po skončení běhu se získá statistika navrženým voláním příkazu aps (application performance snapshot).
Open MPI pro Nvidia¶
Nvidia HPC Software Development Kit (SDK) obsahuje MPI implementace v.3 a v.4 vhodné pro Nvidia překladače. Pro aktivaci Open MPI v.4 je určen místní příkaz source load_nv. Jména wrapperů, loaderů a proměnných odpovídají default Open MPI pro GNU překladače, viz tedy jejich popis výše. Nvidia Open MPI v.3 (místní příkaz source load_nv_mpi3) nemá zabudovanou podporu UCX komunikace, pro InfiniBand (IPoIB) lze použít komponentu ob1 s adaptérem mib0:
# Nvidia Open MPI run with predefined environment variables
source load_nv # activation of Nvidia Open MPI v.4
export OMPI_MCA_pml=ucx # hosts with InfiniBand
export OMPI_MCA_pml=ob1 # hosts without InfiniBand
export OMPI_MCA_btl_tcp_if_include=mib0 # hosts with InfiniBand
export OMPI_MCA_btl_tcp_if_include=eno1 # hosts without InfiniBand
cd /opt/osu-benchmarks/open-mpi/mpi/pt2pt # OSU benchmarks of MPI bandwidth, latency etc.
mpirun -n 2 osu_bw # local run
mpirun -H geofA,geofB osu_bw # distributed run with Open MPI v.4, with and without InfiniBand
source load_nv_mpi3 # activation of Nvidia Open MPI v.3
mpirun -H geofA,geofB -mca pml ob1 osu_bw # distributed run with Open MPI v.3, with InfiniBand
mpirun -H geofA,geofB osu_bw # distributed run with Open MPI v.3, without InfiniBand
MPICH¶
MPICH je implementace MPI konkurenční k Open MPI. V repozitářích Ubuntu ji lze nalézt a paralelizovaný software bývá nabízen jak pro Open MPI, tak pro MPICH. Na našich strojích je Open MPI nastaveno jako default, a tedy další software máme nachystán pro Open MPI. Ukáže-li se v ojedinělých případech problém s Open MPI, je možné obrátit se k MPICH. (Např. Coarray Fortran není v Ubuntu 22.04 schopen s Open MPI běhu na více strojích, s MPICH problém není.)
Pro překlad a spouštění samostatných programů lze obdobně jako výše použít wrappery mpif90.mpich a mpicc.mpich a loader mpirun.mpich. Volby těchto skriptů jsou většinou odchylné od voleb skriptů Open MPI; Intel MPI je odvozeno od MPICH, volby MPICH skriptů jsou tedy blízké výše popsaným volbám Intel MPI. Pro spojení s MPI paralelizovanými knihovnami je třeba mít tyto knihovny instalované ve verzi pro MPICH (nikoliv Open MPI).
# MPICH Fortran compilation and run
mpif90.mpich file.f90 # compilation using gfortran
mpirun.mpich -n 8 ./a.out # local run
mpirun.mpich -n 16 -ppn 8 -hosts geofA,geofB ./a.out # distributed run
Obdobně jako výše lze volit např. mpif90 -show pro zjištění použitých voleb wrapperu. Wrapper mpif90.mpich je ekvivalentní s mpifort.mpich a loader mpirun.mpich je totéž co mpiexec.mpich. Na volby loaderu se lze ptát příkazem mpirun.mpich -help. Užitečná může být proměnná prostředí MPIEXEC_TIMEOUT. Repozitářová MPICH knihovna je přeložena bez podpory UCX; dostupný komunikační protokol spolupracuje s InfiniBandem jen v podobě IPoIB.
Poznámky¶
Pro bezheslové spojení mezi stroji je třeba na stroji A vytvořit soukromý a veřejný klíč pomocí ssh-keygen -t rsa (při potížích ssh-keygen -t ecdsa). Vzniknou soubory ~/.ssh/id_rsa a ~/.ssh/id_rsa.pub. Obsah druhého z nich se přidá na stroji B do souboru ~/.ssh/authorized_keys, čímž se povolí jednosměrný přístup z A na B. Přenos veřejného klíče je třeba provést všemi směry, které mají volné připojení umožnit. K adresáři ~/.ssh smí mít právo k zápisu jen vlastník, jinak mohou být klíče nefunkční.
Na strojích máme předdefinovány proměnné prostředí OMPI_MCA_pml, OMPI_MCA_btl_tcp_if_include, I_MPI_FABRICS a I_MPI_OFI_PROVIDER tak, aby se s Open MPI v.4 a Intel MPI přednostně využívala komunikace pomocí InfiniBandu.
Pro ověření funkčnosti MPI systému a zvolených runtime parametrů lze využít sadu OSU micro-benchmarks (Ohio State University), dostupnou v adresáři /opt/osu-benchmarks jak pro Open MPI, tak Intel MPI. K témuž účelu mohou posloužit také Intel MPI benchmarks v /opt/intel/oneapi/mpi/latest/benchmarks/imb.