Taulukkotyöt
Taulukkotyöt ovat Slurmin oma mekanismi useiden samankaltaisten, toisistaan riippumattomien alatehtävien lähettämiseen yhdellä komennolla, esimerkiksi useiden aineistojen analysointiin samalla tavalla tai saman simulaation ajamiseen useilla eri parametreilla.
Taulukkotyöt sopivat hyvin tilanteisiin, joissa kunkin alatehtävän suoritusaika on riittävän pitkä (yli noin 30 minuuttia), jotta Slurmin ajastuksen yleiskustannus on merkityksetön. Kun suoritukset ovat hyvin lyhyitä, alatehtäviä on erittäin paljon tai tehtävillä on riippuvuuksia, katso suurteholaskenta ja työnkulut sopivampien työkalujen, kuten HyperQueuen, osalta.
Taulukkotyön määrittely
Slurmissa taulukkotyö määritellään valinnalla --array tai -a, esimerkiksi
ei käynnistä vain yhtä erätyötä, vaan 100 erätyötä, joissa alatyökohtaisen ympäristömuuttujan
$SLURM_ARRAY_TASK_ID arvo vaihtelee välillä 1–100. Tätä muuttujaa voidaan sitten hyödyntää
varsinaisissa työn käynnistyskomennoissa niin, että kukin alatehtävä tulee käsitellyksi. Kaikki
alatyöt lähetetään erätyöjärjestelmään kerralla, ja ne suoritetaan käyttäen niin monta prosessoria
kuin on saatavilla.
Työalueen määrittelyn lisäksi voit antaa myös luettelon työindeksien arvoista, esimerkiksi
käynnistäisi kolme työtä arvoilla $SLURM_ARRAY_TASK_ID 4, 7 ja 22.
Voit myös sisällyttää askelkoon työalueen määrittelyyn. Taulukkotyön määrittely
ajaisi viisi työtä arvoilla $SLURM_ARRAY_TASK_ID: 1, 21, 41, 61 ja 81.
Joissakin tapauksissa voi olla järkevää rajoittaa samanaikaisesti käynnissä olevien prosessien
määrää. Tämä tehdään merkinnällä %max_number_of_jobs. Esimerkiksi tilanteessa, jossa sinulla on
100 työtä mutta lisenssi vain viidelle samanaikaiselle prosessille, voit varmistaa, ettei lisenssi
lopu kesken, käyttämällä määrittelyä
Yksinkertainen esimerkki taulukkotyöstä
Ensimmäisessä taulukkotyöesimerkissä oletetaan, että meillä on 50 aineistoa (data_1.inp, data_2.inp
... data_50.inp), jotka haluamme analysoida ohjelmalla my_prog, joka käyttää syntaksia
Kukin alatehtävä vaatii alle kaksi tuntia laskenta-aikaa ja alle 4 Gt muistia. Voimme suorittaa kaikki 50 analyysitehtävää seuraavalla erätyöskriptillä:
#!/bin/bash -l
#SBATCH --job-name=array_job
#SBATCH --output=array_job_out_%A_%a.txt
#SBATCH --error=array_job_err_%A_%a.txt
#SBATCH --account=<project>
#SBATCH --partition=small
#SBATCH --time=02:00:00
#SBATCH --ntasks=1
#SBATCH --mem-per-cpu=4000
#SBATCH --array=1-50
# run the analysis command
my_prog data_${SLURM_ARRAY_TASK_ID}.inp data_${SLURM_ARRAY_TASK_ID}.out
Erätyöskriptissä rivi #SBATCH --array=1-50 määrittelee, että 50 alatyötä lähetetään.
Muut #SBATCH-rivit viittaavat yksittäisiin alatöihin. Tässä tapauksessa yksi alatyö käyttää
enintään yhtä prosessoria (--ntasks=1), 4 Gt muistia (--mem-per-cpu=4000) ja voi kestää
enintään kaksi tuntia (--time=02:00:00). Kaikkien 50 tehtävän käsittelyyn tarvittavaa
kokonaisseinäkelloaikaa ei kuitenkaan rajoiteta.
Työn suorituskomennoissa skripti hyödyntää muuttujaa $SLURM_ARRAY_TASK_ID
syöte- ja tulostiedostojen määrittelyssä niin, että ensimmäinen alatyö suorittaa komennon
toinen suorittaa komennon
ja niin edelleen.
Työ voidaan nyt käynnistää komennolla
Yleensä kaikkia töitä ei suoriteta kerralla. Jonkin ajan kuluttua suuri määrä töitä voi kuitenkin
olla käynnissä samanaikaisesti. Kun erätyö on valmis, hakemisto data_dir sisältää 50
tulostiedostoa.
Taulukkotyön lähettämisen jälkeen komento
paljastaa, että sinulla on yksi odottava työ ja mahdollisesti useita muita töitä käynnissä
erätyöjärjestelmässä. Kaikilla näillä töillä on jobid, joka koostuu kahdesta osasta:
taulukkotyön jobid-numerosta ja alatyön numerosta. Kunkin alatyön tulosteen ohjaamista omaan
tiedostoonsa suositellaan, koska tiedostojärjestelmä voi epäonnistua, jos useat kymmenet prosessit
yrittävät kirjoittaa samaan tiedostoon samaan aikaan. Jos tulostiedostot täytyy yhdistää yhdeksi
tiedostoksi, se voidaan usein tehdä helposti taulukkotyön päätyttyä. Esimerkiksi yllä olevassa
tapauksessa voisimme kerätä tulokset yhteen tiedostoon komennolla
Vakiotulosteen ja virhetulosteen tiedostoissa, jotka on määritelty #SBATCH-riveillä, voit käyttää
määrittelyjä %A ja %a antaaksesi yksilölliset nimet kunkin alatyön tulostiedostoille.
Tiedostonimissä %A korvataan taulukkotyön tunnuksella ja %a korvataan arvolla
$SLURM_ARRAY_TASK_ID.
Tiedostonimiluettelon käyttäminen taulukkotyössä
Yllä olevassa esimerkissä pystyimme käyttämään muuttujaa $SLURM_ARRAY_TASK_ID viittaamaan
syötetiedostojen järjestysnumeroihin. Jos tällainen lähestymistapa ei ole mahdollinen, voidaan
käyttää ennen erätyön lähettämistä luotua tiedosto- tai komentoluetteloa. Oletetaan, että meillä
on yllä määritellyn kaltainen tehtävä, mutta tiedostonimet eivät sisällä numeroita vaan ovat
muodossa data_aa.inp, data_ab.inp, data_ac.inp ja niin edelleen. Tällöin meidän on ensin
tehtävä luettelo analysoitavista tiedostoista. Tässä tapauksessa voisimme kerätä tiedostonimet
tiedostoon namelist komennolla
Komento
lukee tietyn rivin nimiluettelotiedostosta. Tässä tapauksessa varsinainen komentoskripti voisi olla
#!/bin/bash -l
#SBATCH --job-name=array_job
#SBATCH --output=array_job_out_%A_%a.txt
#SBATCH --error=array_job_err_%A_%a.txt
#SBATCH --account=<project>
#SBATCH --partition=small
#SBATCH --time=02:00:00
#SBATCH --ntasks=1
#SBATCH --mem-per-cpu=4000
#SBATCH --array=1-50
# set the input file to process
name=$(sed -n ${SLURM_ARRAY_TASK_ID}p namelist)
# run the analysis
my_prog ${name} ${name}.out
Tämä esimerkki on muuten samanlainen kuin ensimmäinen, paitsi että siinä luetaan analysoitavan
tiedoston nimi tiedostosta namelist. Tämä arvo tallennetaan muuttujaan ${name}, jota käytetään
työn suorituskomennoissa. Koska luettava rivinumero määritellään muuttujalla $SLURM_ARRAY_TASK_ID,
kukin tiedostossa namelist lueteltu datatiedosto käsitellään eri alatyönä. Huomaa, että koska
käytämme nyt myös ${name}-muuttujaa tulosteen määrittelyssä, tulostiedoston nimi on muodossa
data_aa.inp.out, data_ab.inp.out, data_ac.inp.out ja niin edelleen.