Nahajate se tukaj

Nadzornik računskih virov -- Load Sharing Facility - LSF

Za večopravilnost in razporejanje računskih virov glede na predpisano politiko poslov skrbi sistemska programska oprema LSF (Load Sharing Facility). Vzporedni posli se običajno popisujejo v skriptah ukazne školjke. Običajno je, da se celoten nadzor opravlja iz ukazne vrstice. Najbolj pogosti ukazi so:

  1. bsub -J ime-posla < skripta.lsf
  2. bjobs
  3. bkill ime-ali-številka-posla

S prvim ukazom zaženemo program s predpisanimi parametri v skripti. Če poganjamo več istih programov z različnimi vhodnimi podatki, je potrebno zagotoviti, da se rezultati pišejo v ločene datoteke.
Drugi ukaz prikazuje trenutno stanje čakalne vrste poslov uporabnika. Kdaj se požene kakšen posel je odvisno od stanja vseh poslov na superračunalniku. Tretji ukaz ustavi delujoči posel in ga izbriše iz vrste. Poleg navedenih najbolj uporabljanih ukazov obstajajo še ukazi, s katerimi lahko podrobneje spremljano stanje LSF in uporabniških računov. Trenutno obremenitev sistema in zgodovino lahko spremljamo tudi preko spletnega vmesnika. Podrobnejša navodila za LSF so na voljo na nazdornem vozlišču http://prelog/lsf/9.1.1

Potek izvajanja poslov

  1. Vzpostavitev posla - Z nadzornega vozlišča (lahko tudi od drugje) z ukazom bsub  pošljemo zahtevo za izvajanje posla
  2. Uvrstitev v čakalno vrsto - LSF na nadzornem vozlišču preuči možnosti za izvajanje posla in ga požene takoj, ko je to mogoče
  3. Razvrstitev posla - Nadzorno vozlišče pošlje posel na prosta računska vozlišča
  4. Poganjanje posla na računskih vozliščih
  5. Vračanje rezultatov  v obliki izpisa programa
  6. Pošiljanje pošte se izvaja neposredno iz vozlišča, ki je prevzel nalogo

Skripte

Skripte za zagon pišemo zaradi tega, da je poganjanje programov enostavnejše saj v njih nastavimo vse pramametre za program in jih tako ni potrebno podajati v ukazni vrstici. Primer za MPI je naslednji:

#!/bin/sh
# Primer LSF skripte pi-mpi.lsf za poganjanje v OpenMPI okolju
# Vzporedni posli morajo biti uvrščeni v vrsto 'normal'.
#BSUB -a openmpi
#BSUB -q normal
#BSUB -n 24
#BSUB -o pi-mpi.out
#BSUB -e pi-mpi.err

mpiexec pi-mpi

Pisanje skript no obvezno, saj so običajno že privzete vrednosti dovolj kratke. Tako bi lahko zgornji ukaz lahko namesto

bsub < pi-mpi.lsf

pognali tudi brez skripte z ukazom

bsub -a openmpi -n24 mpiexec pi-mpi

in si ogledali rezultat posla v poštnem sporočilu.

Pogosto uporabljeni ukazi LSF in primerjava z PBS

Portable Batch System (PBS)  in LSF sta si podobna v tem, da oba opravljata nalogo upravljanja s posli uporabnikov in razvrščanju le teh po sestavu. Za uporabnike z izkušnjami na PBS, TORQUE ali SGE so primerljivi naslednji ukazi:

Primerjava ukazov za čakalne vrste med PBS in LSF
PBSLSFDescription
qsub scriptbsub < scriptVstavi skript posla za izrševanje v čakalnih vrstah
qstatbjobsPokaži stanje tekočih poslov in poslov, ki čakajo na izvršitev.
bjobs -u all izpiše trenutne posle vseh uporabnikov.
tracejobbhistPrikaži zgodovino poslov.
qdel

bkill ID

bkill 0

Končaj posel ID

Končaj vse (moje) posle.

qholdbstopZaustavi posel.
qstat -Q
qstat -Qf
bqueuesPrikaži nastavitve čakalnih vrst.
 busersPrikaži informacije o uporabnikih in skupinah.
qpeekbpeekPoglej v stderr in stdout še nedokončanega posla.
 bacctPrikaži poročilo o obračunu končanih posl
 bhosts
lsload
Povzemi obremenitev po vozliščih.

Dodatne ukaze pri zagonu običajno napišemo kar v same skripte tako, da dodajamo na začetku skripte posebne (pragma) ukaze, ki jih interpretira ukaz za pošiljanje posla v vrsto. Vsi ti ukazi se v skriptah pričnejo z #BSUB in nato sledijo običajna stikala s katerim povemo še dodatne zahteve, katere bi morali tipkati v ukazni vrstici. Da se izognemo temu vse te ukaze pišemo v skripti ukazne školjke. Velja pa pravilo, da stikala ki jih podamo v ukazni vrstici prevladajo pred tistimi v skriptu. Pri LSF je potrebno poudariti, da je za interpretiranje ukazov v skriptu obvezno potrebno uporabiti redirekcijo v obliki 

bsub < skripta

Tak način podajanja skripte ima prednost v tem, da se ukazu bsub priredi vsebina skripte takoj in ne šele ob zagonu posla. Se pravi, da lahko skripto popravljamo takoj po zagonu in bodo še vedno veljali ukazi, ki smo jih podali takrat. Če v skripte pišemo pragmatične ukaze #BSUB, je priporočljivo, da se skripti da končnico .lsf.

Pogosto uporabljeni ukazi v skriptah:

 
PBSLSFOption
#PBS -N jobname#BSUB -J jobnamePriredi ime poslu
#PBS -M email_address
#PBS -m b
#BSUB -BPošlji e-pošto ob začetku posla
#PBS -m e#BSUB -NPošlji e-pošto ob zaključku posla
#PBS -e errfile#BSUB -e errfile
#BSUB -eo errfile
Preusmeri stderr v podano datoteko z dopisovanjem
Preusmeri stderr v podano datoteko s prepisovanjem
#PBS -o out_file#BSUB -o out_file
#BSUB -oo out_file
Preusmeri stdout v podano datoteko z dopisovanjem
Preusmeri stdout v podano datoteko s prepisovanjem
 #BSUB -a applicationPodaj serijijske/paralelne opcije
#PBS -A project_name#BSUB -P project_nameObračunaj posel podanem projektu
#PBS -l walltime=runtime#BSUB -W runtimeNastavi najdaljši šas izvajanja
(LSF runtime = hh:mm)
(PBS runtime = hh:mm:ss)
#PBS -q queue_name#BSUB -q queue_namePodaj čakalno vrsto
#PBS -l select=chunk specification#BSUB -n num_proc

Podaj število procesorjev

 #BSUB -R "span[ptile=procs_per_node]"

Podaj zahteve za MPI vire

V imenu datoteke, ki jo preusmerjamo (out_file, errfile) lahko uporabimo spremenljivko %J za številko posla.

V zahtevnejših skriptah lahko uporabljamo tudi spremenljivke okolja (environment variables), običajno pa to ni potrebno. Pomembno je še omeniti, da za prenos spremenljivk okolja iz nadzornega vozlišča v sam posel, ki se požene na računskih vozliščih, skrbi LSF. Če torej napišemo module load openmpi, ki nastavlja spremenljivki PATH in LD_LIBRARY_PATH se bo ob zagonu bsub vse to preneslo v sam posel ob zagonu.

Primerjava spremenljivk

PBSLSFOpis spremenljivke
PBS_JOBIDLSB_JOBIDŠtevilka posla
PBS_ARRAY_INDEXLSB_JOBINDEXŠtevilka posla v nizu poslov
PBS_JOBNAMELSB_JOBNAMEIme posla
PBS_TASKNUMLS_JOBPIDSistemski ID procesa posla
PBS_ARRAY_ID Oznaka za posle v nizu. 
PBS_NODEFILELSB_HOSTSDatoteka, ki vsebuje seznam vozlošč prirejenega posla
PBS_O_WORKDIRLS_SUBCWDAbsolutna pot imenika iz katerega je bil posel pognan.

 

OpenMPI

Na sestavu HPCFS je OpenMPI najbolj priporočen MPI za uporabo saj je dobro integriran z LSF. Predvsem to velja za prenos okoljskih spremenljivk (environment), kot tudi za poganjanje procesov na vozliščih saj je lsb_launch() rutina vgrajena v OpenMPI ORTE (Open Run Time Environment). OpenMPI je podprt tudi za vse nameščene prevajalnike, ki jih naložimo z okoljem modules. Na primer:

[leon@prelog ~]$ module load intel/12.0 openmpi
  Loading intel/12.0
  Loading openmpi/1.5.1 for compiler intel-12.0

naloži prevajalnike Intel XE 2011 in zanj še ustrezne OpenMPI ovoje. Tako imamo na voljo standardne MPI prevajalnike:

  • mpicc - C prevajalnik za MPI
  • mpiCC, mpic++, mpicxx,  - C++ prevajalnik za MPI
  • mpif77, mpif90 - Fotran prevajalnik za MPI

Poganjanje OpenMPI programov je možno v skripti ali kar iz ukazne vrstice tako, da namesto klasičnega zaganjalnika  mpirun ali mpiexec uporabimo LFS skripto mpirun.lsf, ki pomaga nastaviti spremenljivke za zagon MPI programov in na koncu programa še izpiše stanje programov. Če želimo pognati naš program z okoljem OpenMPI je potrebno podati še aplikacijsko stikalo -a openmpi. V eni vrstici tako naš program pošljemo z ukazom

bsub -a openmpi -n 12,384 mpirun moj-mpi-program argumenti-programa

ki požene program na vsaj 12 procesorjih, če je možno pa tudi na tja do 384 procesorjih. Način s podajanjem obsega še sprejemljivega načina zagona je priporočen, vendar odločitev o velikosti prepuščamo uporabnikom glede na trenutne razmere zasedenosti sestava in želje po čimprejšnjem izračunu problema.  mpirun in mpiexec, kot tudi skripta mpirun.lsf, ki na koncu požene mpurun skrbi tudi za posredovanje argumenta -np , ki podaja število procesov in zato le tega ni potrebno podajati. Za  mpirun lahko napišemo še dodatne argumente kot so argumenti iz skupine MCA.

OpenMP

OpenMP (www.openmp.org) je zelo enostaven način paraleliziranja programov z nitkanjem v enem procesu. Na enem računskem vozlišču lahko poganjamo programe z največ 24 niti. Običajno je, da se porabi na enem vozlišču vse niti. Program podamo v čakalne vrste z ukazom:

bsub -a openmp -n 12 -R "span[hosts=1]" ./program -argumenti

Če okoljska spemenljivka OMP_NUM_THREADS ni nastavljena, potem bo program porabil vseh 24 niti na vozlišču. Le če program ne potrebuje oziroma deluje tako, da ne rabi več niti, lahko nastavimo tudi manj niti. V takih primerih je bolje napisati LSF skripto. Primer skripte za program, ki ne deluje več kot s štirimi nitmi:

#!/bin/sh
#BSUB -a openmp
#BSUB -n 4
#BSUB -R "span[hosts=1]"
#BSUB -J moments -N
export OMP_NUM_THREADS=${LSB_DJOB_NUMPROC}

# poišči aplikacijo v starševskem imeniku
APPLICATION=vdf
BASEDIR=$PWD
while test ! -x ${BASEDIR}/${APPLICATION} ; do
  BASEDIR=${BASEDIR%/*}
  if [ "${BASEDIR}" = "" ] ; then
        echo "Error: ${APPLICATION} not found in parent directory"
        exit 2
  fi
done
${BASEDIR}/${APPLICATION} 1.0 -6 6 -10

Program poženemo z ukazom

bsub < ../../moments.lsf

Ker nismo nastavili nikakršne preusmeritve v izhodno datoteko, bo obvestilo o izračunu prišlo v poštni predal. Če pa bi vseeno želeli še med delovanjem preveriti, ali program deluje pravilno, to naredimo z vpogledom v izpiše z:

[leon@prelog Tn10]$ bjobs
JOBID   USER    STAT  QUEUE      FROM_HOST   EXEC_HOST   JOB_NAME   SUBMIT_TIME
438     leon    RUN   normal     prelog      4*cn52      moments    Dec 28 17:11
[leon@prelog Tn10]$ bpeek 438
<< output from stdout >>
Using Tn = 10 B = 0.166643 n = 2401 from psi.dat
Output shifted to origin by -0
Calculating and writing moments.dat ...
[-0.0%]{11:0.01}{11:0.005}{11:0.01}{11:0.01}{11:0.01}{11:0.005}{11:0.005}{11:0.005}[0.1%][0.2%][0.3%][0.4%]
[0.5%][0.6%][0.7%][0.8%][0.9%][1.0%][1.1%][1.2%][1.3%][1.4%][1.5%]{21:-0.16}{21:-0.16}{21:-0.16}{18:-0.16}
[1.6%]{21:-0.16}{21:-0.16}{18:-0.16}[1.7%]{21:-0.16}{21:-0.16}{21:-0.16}{18:-0.16}[1.8%][1.9%][2.0%][2.1%]
[2.2%][2.3%][2.4%][2.5%][2.6%][2.7%][2.8%][2.9%][3.0%][3.1%][3.2%][3.3%][3.4%][3.5%][3.6%][3.7%][3.8%][3.9%]
[4.0%][4.1%][4.2%][4.3%][4.4%][4.5%][4.6%][4.7%][4.8%][4.9%][5.0%]

S takim načinom dela, ko izhodnih datotek ne pišemo ohranjamo čisto okolje v podimenikih. Ko program po uri ali dveh konča, pa lahko na hitro pregledamo pošto in tudi njo pobrišemo. Če pa želimo le obvestilo za programe, ki delujejo zanesljivo lahko preiumerimo izhod z -o /dev/null in dobimo le obvestilo.

Interaktivne seje

Za delo z grafičnimi programi in za razvoj programov je priporočljivo, da od LSF zahtevamo računsko vozlišče, ki pripada samo nam za določen čas. S tem razbremenimo nadzorno vozlišče in pridobimo večjo zmogljivost. Interaktivno sejo dobimo z ukazom

bsub -n 12 -R "span[hosts=1]" -Is /bin/bash -l

ki rezervira celotno vozlišče za uporabnika. Tak način dela, da nekdo za nedoločen čas rezervira celotno vozlišče, seveda ni zaželjen s strani porabe sistemskih virov. Poleg tega se uporabniku obračunava vseh 12 procesorjev vozlišča za ves čas, ko je prijavljen. Da ukazne vrstice na vozliščih ne bi ostajale v nedogled je v $HOME/.bash_profile nastavljena vrstica

test ${HOSTNAME%%[0-9]*} = cn && TMOUT=3600

ki avtomatsko odjavi uporabnika iz vozlišča, če eno uro ni odtipkal nobenega ukaza, ukazna lupina pa je čakala na ukaze. Delo na vozlišču razvoju programov ne bi smelo biti nič drugačno kot na nadzornem vozlišču. Mogoče je le, da je na vozlišču manj sistemsko naloženih programov, vendar pa mora okolje modules normalno delovati. Zanimivo je še, da se vse okoljske spremenljivke iz nadzornega vozlišča prenesejo tudi na vozlišče. Naslednji primer

[leon@prelog ~]$ module list
No Modulefiles Currently Loaded.
[leon@prelog ~]$ module load intel openmpi
  Loading intel/12.0
  Loading openmpi/1.5.1 for compiler intel-12.0
[leon@prelog ~]$ single
Job <426> is submitted to default queue .
[leon@cn52 ~]$ module list
Currently Loaded Modulefiles:
  1) intel/12.0      2) openmpi/1.5.1
[leon@cn52 ~]$ echo $TMOUT
3600
[leon@cn52 ~]$ env|grep -i cpu
LSB_MCPU_HOSTS=cn52 1

kaže (vrstice 10-12), da se okolje prenese na vozlišče na katerem velja ena ura nedejavnosti (vrstici 13-14). S sistemskim aliasom single se je dodelil le en procesor na vozlišču 52 (vrstica 16). Kateri procesor (od 12) je dodeljen ni določeno. Uporabnika nič ne omejuje, da na vozlišču (začasno) uporabi tudi več procesorjev. Običajno pa uporabniki pri razvoju uporabljajo le en procesor. Ker ima vsako vozlišče 24 niti,tako ni težav, če je na enem vozlišču hkrati odprtih 12 interaktivnih sej 12-ih uporabnikov. Za lažje interaktivno premikanje iz preloga na računska vozlišča cn?? sto nastavljeni naslednji sistemski aliasi:

  • node - dodeli in rezervira celotno vozlišče za uporabnika. Uporabnik lahko na njem poganja interaktivne OpenMP programe na največ 24-ih nitih.
  • half - dodeli 6 procesorska jedra na enem vozlišču. Ostalih 6 je na voljo ostalim nalogam.
  • single - dodeli en sam procesor in največ dve procesni niti na prostem vozlišču.

V primeru prekoračenja nastavljenih virov se procesi za single in half avtomatično pobijejo. Pri node ni omejitev. Prav tako s single deluje večina GUI programov, saj ne jemljejo preveč procesorjev imajo pa lahko procesnih 50 niti! Omejitve so naslednje:

Nastavljene omejitve interatkivnih ukazov
UkazŠt. procesorjevŠt. OpenMP nitiOmejitev procesov
single126
half6612
node1224ni omejitve

Priporočamo, da za vsa naprednejša interaktivna dela uporabljate node. Single in half pa samo za nezahtevna GUI dela kot je Mathematica, serijski R, plot, edit, debug,...,  in ostalo zaporedno obdelavavo podatkov. Ker se procesi pobijejo brezopozorila, lahko to preverite z bhist -l. V primeru,d a obvisijo jih lahkovse pobijete z bkill -r 0. Grafični interaktivni programi vozlišč se prikazujejo v seji NX na prijavnem vozlišču prelog. Za avtomatsko dodeljevanje pravic pisanja vozlišč po DISPLAY-u preloga je bilo izvedeno z xauth ob prijavi v sejo.

Če želimo večje število procesorjev oz. vozlišč v interaktivnem načinu, to lahko zahtevamo z dodatnim specificiranjem stikala -n. Interaktivne seje na večini sestavov niso zaželjene in zato sistemski opravitelji za take seje nastavljajo tudi najdaljše trajanje interaktivnih sej na največ uro ali dve. Običajno je onemogočen tudi ssh na vozlišča. Na HPCFS takih omejitev ni, za seje ssh je uvedena le omejitev porabe procesorjev za uporabnike z nastavitvijo ulimit -t 300, ki prepreči, da bi v  seji ssh porabil več kot 5 minut procesorskega časa na svojem programu.

Interaktivne seje so torej priročne za uporabnike, žal pa veliko manj za upravitelje sestava in zato velja priporočilo, da se interaktivnih sej poslužujemo s pametjo, kar pomeni, da upoštevamo trenutno obremenitev nadzornega vozlišča in računskih vozlišč. Če se le da, pa naj se uporablja "batch" način s čakalnimi vrstami.

Pripenjanje procesov

Prevajalnik Intel z OpenMP knjižnico omogoča vplivanje pripenjanje OpenMP niti na fizične procesne enote. Informacije o tem so možne na spletni strani Intel. Na HPCFS za pripenjanje skrbi nadzornik poslov, ki pripenja procese NUMA arhitekture. Če uporabnik želi spremeniti te nastavitve, je potrebno eksplicitno izključiti privzete nastavitve. Poleg pripenjanja procesov je možno tudi pripenjanje spomina Memory Binding). Običajno za vse to uporabnikom ni potrebno skrbeti saj že samo jedro Linux dokaj dobro skrbi za pravilno razporeditev.

Naslednji primer pojasnjuje splošen pristop nastavljanja OpenMP programov:

export OMP_NUM_THREADS=24
export KMP_AFFINITY=verbose,scatter
./program

    Pri MPI programih lahko zahtevamo tudi manjše število procesov na vozlišče in tako pridobimo več spomina na proces. Če želimo v MPI programu uporabiti le en proces na vozlišče in tako imeti na voljo ves spomin vozlišča za en proces to napišemo kot

    #BSUB -R "span[ptile=1]”

    Največje število procesov je ptile=12. Če želimo izvedeti, kakšne so spremenljivke ob zagonu programa v ozadju je najenostavneje, da poženemo ukaz env in si ogledamo izpis v vrnjeni e-pošti. Taki ukaza za OpenMPI, OpenMP in pošto so na primer:

    [leon@prelog ~]$ bsub -a openmpi -n 24 env
    [leon@prelog ~]$ bsub -a openmp env
    [leon@prelog ~]$ mutt

    Turbo način

    Turbo način omogoče avtomatsko zvišanje frekvence procesorjev pod določenimi pogoji  (Intel Turbo Boost Technology). Nominalna frekvenca procesorjev 2.933 GHz se lahko poveča do največ 3.3 GHz, če sta na procesorju aktivni največ dve jedri. Pri 4 jedrih je ta frekvenca 3.2GHz. Turbo tehnlogija lahko torej prinese do 10% hitrejše računanje serijskih poslov ali MPI poslov, pri katerih omejimo največje število procesov na vozlišče. Turbo Boost je na sestavu HPCFS stalno vklopljen. Frekvenco procesorjev nadzoruje še upravitelj, ki jo poveča ob večji obremenitvi. Neobremenjeno vozlišče ima najmanjšo delovno frekvenco 1.6GHz.

    Podatke o dejanski frekvenci lahko v skripti izvemo izpisom naslednjih  datotek:

    cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
    

    Kontrolna točka poslov, zaustavljanje in ponovni zagon - Checkpointing

    Daljši posli morajo vsebovati možnost zaustavitve s strani nadzornika poslov. Enkrat dnevno tako LSF pošlje takim procesom signal SIGUSR2 s katerim sporoči aplikaciji, da naj se zaustavi in shrani svoje stanje za vnovičen zagon. Če aplikacija vrne status 55, 34, 78 ali 99, potem LSF po zaustavitvi ponovno zažene posel vendar ne nujno na istih vozliščih. To omogoča nadzorniku poslov boljše razporejanje poslov po sestavu ali vključevanje prioritetnih poslov.

    Nameščena je tudi sistemska knjižnica BLCR, ki omogoča "checkpointing" na nivoju jedra. Uporabniki, kot tudi sistem LSF, bodo lahko s tem dodatkom tekoče posle poljubno ustavili z bchkpnt. Pri tem se program shrani na disk in se lahko kasneje restarta z brestart. Če je uporabljena kompatibilna MPI knjižnica OpenMPI ali MVAPICH, se lahko vse skupaj prepakira na druga vozlišča z bmig. Aplikacija pri tem nič ne ve kaj jo je zadelo. Lahko pa se BLCR vključi tudi v lastne programe, kar je najbolj priporočljivo.

    PriponkaVelikost
    PDF icon PlatformLSF_XEON_Intel4.pdf1.56 MB