| . ...+ . . |
| . = o .. |
| o o . ...|
| S . o..+ |
| . . ++ .|
| ..o... |
| .o. E|
| .. | +---+
6. Következő lépésként fűzzük hozzá az A.B.C.D gépen elkészült id_rsa.pub fájl tartalmát a P.Q.R.S gép .ssh könyvtárában található authorized_keys fájl végéhez. Ha nem létezne az authorized_keys állomány, hozzuk létre azt. Ebben a lépésben adjuk meg a publikus kulcsunkat a P.Q.R.S gép felhasználói fiókjának, így az SSH kapcsolat felállításánál egy rövid üzenetváltást követően nagy biztonsággal azonosítani tudja a gépünket. Parancssorban az A.B.C.D gépről ezt az alábbi módon tehetjük meg:
user@A.B.C.D:user> cat .ssh/id_rsa.pub | ssh user@P.Q.R.S 'cat >>
.ssh/authorized_keys' user@P.Q:R.S's password:
Ekkor természetesen még meg kell adnunk a P.Q.R.S gép user fiókjának jelszavát. Ismételjük meg ezen lépést a másik irányba, azaz adjuk hozzá a P.Q.R.S gép user fiókjának publikus kulcsát az A.B.C.D gépen található authorized_keys fájlhoz. Ehhez a P.Q.R.S gépen az alábbi parancsot adjuk ki:
user@P.Q.R.S:user> cat .ssh/id_rsa.pub | ssh user@A.B.C.D 'cat >>
.ssh/authorized_keys' user@A.B.C.D's password:
7. Utolsó lépésként lépjünk be mindkét gépről a másik gép felhasználói fiókjába, megadva a megfelelő felhasználó fiók jelszavát. Ha mindent jól csináltunk, a következő belépésnél már nincs szükség jelszóra, a kapcsolatot a nyilvános kulcsú titkosítás felhasználásával az SSH szerver autentikálja és biztosítja.
3. Fordítás és futtatás
Mielőtt röviden áttekintenénk a legfontosabb OpenMPI függvények specifikációját, nézzük meg, hogy a függvények működésének pontos ismerete nélkül, hogyan tudjuk lefordítani és lefuttatni az OpenMPI eszközeit használó alkalmazásokat!
Elsőként telepítsük az OpenMPI bináris és fejlesztői eszközeit. A szükséges csomagok az elterjedt Linux disztribúciók központi repository-jának részeként elérhetőek, a csomagok neve azonban változó lehet. Debian alapú rendszereken az openmpi-bin és libopenmpi-dev csomagokat kell telepítenünk, parancssoros csomagkezelővel például az alábbi módon:
root@home> apt-get install openmpi-bin libopenmpi-dev
Miután a szükséges header fájlok és programkönyvtárak rendelkezésre állnak, a forráskódok lefordítására két lehetőségünk van. Egyrészt használhatjuk az OpenMPI disztribúciók által tartalmazott mpicc fordítót, amely elfedi előlünk a fordításhoz és linkeléshez szükséges kapcsolók megfelelő beállítását és meghívja a gcc fordítót azokkal a paraméterekkel, amelyeket átadunk neki. A másik lehetőség, hogy az eddig megszokott gcc fordítót direkt módon használjuk. Ekkor azonban hozzá kell adnunk a fordítási parancshoz a megfelelő fordítási és linkelési kapcsolókat, amelyek a feltelepített OpenMPI disztribúciótól (verziójától, függőségeitől, helyétől) függenek. Ezeket a kapcsolókat lekérdezhetjük az mpicc alkalmazással az alábbi módon:
user@home> mpicc --showme:compile
-I/usr/lib/openmpi/include -I/usr/lib/openmpi/include/openmpi -pthread user@home> mpicc --showme:link
pthread L/usr/lib/openmpi/lib lmpi lopenrte lopenpal ldl Wl,exportdynamic -lnsl -lutil -lm -ldl
Nézzünk meg, hogyan fordíthatunk le egy egyszerű, "Hello world!" alkalmazást!
6.1. példa - hellompi.c
#include <stdio.h>
#include <mpi.h>
int main(int argc, char *argv[]) { int numprocs, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
printf("Process %d out of %d\n", rank, numprocs);
MPI_Finalize();
return 0;
}
A példaprogram parancssorból történő fordítását az alábbi, teljesen egyenértékű utasításokkal kivitelezhetjük:
user@home> mpicc hello.c -o hello
user@home> gcc hello.c o hello I/usr/lib/openmpi/include
I/usr/lib/openmpi/include/openmpi pthread L/usr/lib/openmpi/lib lmpi lopenrte -lopen-pal -ldl -Wl,--export-dynamic -lnsl -lutil -lm -ldl
Amint az látható, a gcc utasítást ki kell egészíteni az OpenMPI-hoz kapcsolódó fordítási és linkelési kapcsolókkal. Ezek alapján CMakeLists.txt konfigurációs állományokat is két módon hozhatunk létre. Az első lehetőség, hogy a mpicc fordító használatát specifikáljuk. Ehhez a CMAKE_C_COMPILER változónak kell megfelelően értéket adnunk:
6.2. példa - CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(CMAKE_C_COMPILER mpicc)
AUX_SOURCE_DIRECTORY(. SRC) ADD_EXECUTABLE(hellompi ${SRC}) INCLUDE_DIRECTORIES(.)
SET(CMAKE_MAKEFILE_VERBOSE ON)
A másik lehetőség, hogy továbbra is az alapértelmezett gcc-t használjuk, ekkor viszont be kell állítanunk a megfelelő kapcsolókat a CMakeLists.txt állományban:
6.3. példa - CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} I/usr/lib/openmpi/include
-I/usr/lib/openmpi/include/openmpi -pthread -L/usr/lib/openmpi/lib -Wl,--export-dynamic") AUX_SOURCE_DIRECTORY(. SRC)
ADD_EXECUTABLE(hellompi ${SRC})
TARGET_LINK_LIBRARIES(hellompi mpi open-rte open-pal dl nsl util m dl) INCLUDE_DIRECTORIES(.)
SET(CMAKE_VERBOSE_MAKEFILE on)
A lefordított alkalmazás futtatása nagyban különbözik attól amit általában megszokhattunk: az OpenMPI eszközeinek használatához az alkalmazást az mpirun alkalmazás segítségével kell futtatnunk. Mindenekelőtt össze kell gyűjtenünk egy szöveges fájlba azon számítógépek IP-címeit, amelyeken futtatni szeretnénk az alkalmazásunkat. Ezt a fájlt az OpenMPI terminológiájában machinefile-nak vagy hostfile-nak (magyar szaknyelvben hosztfájl) nevezzük. Ahogy azt korábban már említettük, OpenMPI alkalmazások készítéséhez nincs szükség feltétlenül számítógép klaszterre, egyetlen asztali számítógépet is használhatunk. Ekkor a hosztfájl egyetlen IP-címet tartalmaz: a gép loopback interfészének címét, amely konvencionálisan 127.0.0.1. Természetesen ha az egyes gépekhez nevet rendelünk és a hálózatban konfiguráljuk a nevek feloldását, akkor IP-címek helyett a gépek neveit is felsorolhatjuk a hosztfájlban. Egy gépen történő fejlesztés esetén például az alábbi egy helyes hosztfájl:
6.4. példa - hostfile.home
localhost 127.0.0.1
A fájlban megadtunk két gépet, egyiket a nevével, a másikat az IP-címével, és ebben a speciális esetben mindkét gép az aktuális számítógép. Természetesen tetszőleges számú gépet megadhatunk további IP-címek vagy feloldható nevek felsorolásával és egy gépet akár többször is felsorolhatunk. Az OpenMPI alkalmazás indítása az alábbi módon történik:
user@home> mpirun -np 4 -machinefile hostfile.home hellompi Process 3 on gykovacs-home out of 4
Process 0 on gykovacs-home out of 4 Process 2 on gykovacs-home out of 4 Process 1 on gykovacs-home out of 4
Az eddigi tapasztalataink alapján a kimeneten megjelenő, futtatásról futtatásra más sorrendű számokból sejthetjük, hogy ténylegesen párhuzamos végrehajtás történt. Az mpirun program a következő paramétereket kapta:
1. -np 4 - Number of Processes, ezen kapcsolóval adhatjuk meg, hogy összesen hány folyamatot szeretnénk indítani, azaz az alkalmazás hány példánya fusson egyszerre a klaszteren, esetünkben négy példány indult.
2. -machinefile hostfile.home - ezen kapcsoló segítségével adhatjuk meg a hosztfájl, azaz a klasztert alkotó számítógépek elérhetőségeit tartalmazó szöveges állományt. Esetünkben a hosztfájl a localhost és 127.0.0.1 címeket specifikálja.
3. hellompi - maga a futtatandó alkalmazás. Ha az alkalmazásnak további parancssori argumentumokat szeretnénk átadni, azt az alkalmazás neve után, azok szokásos felsorolásával tehetjük meg.
Az mpirun működését tekintve a következő történik: sorra veszi a hosztfájlban felsorolt gépeket, mindegyikhez kapcsolódik az mpirun-t futtató felhasználó azonosítójával és a felírás sorrendjében mindegyiken elindítja az alkalmazás egy példányát, egészen addig, amíg -np darab alkalmazás el nem indult. Ha az indítandó folyamatok száma meghaladja a hosztfájlban található bejegyzések számát, akkor az mpirun visszatér a hosztfájl elejére és a felírás sorrendjében az alkalmazás újabb példányait indítja el az egyes gépeken, egészen addig, amíg az elindult folyamatok teljes száma el nem éri az -np értéket.
Ha egy klaszteren futtatjuk az alkalmazást, azaz a hosztfájlban több gép IP-címe vagy neve szerepel, ügyeljünk arra, hogy mind az mpirun alkalmazás, mind a lefordított program és az általa használt erőforrások (képek, szöveges fájlok, stb.) elérhetőek legyenek az egyes gépeken, lehetőleg ugyanolyan elérési úton. Szemléletesen úgy képzelhetjük el a háttérben történő dolgokat, hogy az mpirun belép a másik gépre SSH kapcsolattal, majd belép abba a munkakönyvtárba, amelyben kiadtuk az mpirun parancsot és pontosan azt a programot próbálja futtatni pontosan ugyanazon parancssori argumentumokkal, amelyet az mpirun utasítás végén megadtunk. Ha a klaszter egy tetszőleges elemére és a megfelelő könyvtárba belépve ez nem működik, mert egyes programkönyvtárak, erőforrások vagy a lefordított alkalmazásunk nem elérhető, vagy az elérési út nem ugyanaz, akkor az mpirun sem fogja tudni elindítani azon a gépen a megfelelő folyamatokat. Mielőtt tehát OpenMPI alkalmazások futtatásához kezdenénk, mindig ellenőrizzük, hogy a klaszterbe gyűjtött számítógépek szoftverkörnyezete az mpirun szempontjából megegyezik-e! Például ha a hellompi alkalmazást a fenti módon
szeretnénk elindítani egy klaszteren, akkor az ssh klienssel belépve a megfelelő könyvtárban a hellompi futtatható alkalmazásnak minden gépen jelen kell lennie és működnie kell.
Az mpirun használatával kapcsolatban azt kell még megemlítenünk, hogy az egyes folyamatok által a sztenderd kimenetre írt karakterfolyam az mpirun programot indító gép sztenderd kimenetére lesz irányítva: bármely számítógépen is fusson a programunk, az stdout-ra írt karakterek a folyamatok indítására használt konzolban jelennek meg.
Az OpenMPI hátterében működő mechanizmusokról és az mpirun alkalmazás további kapcsolóiról az OpenMPI közösség honlapján 2, illetve az [8] könyvben olvashatunk.