Hyppää sisältöön

Docs CSC now features an automatic Finnish translation. Click here for more information.

Warning!

Puhti and Mahti will be decommissioned after Roihu becomes available. Users should clean up unnecessary files and move any required data by the end of August 2026. See the Roihu data preparation instructions for details.

Puhti scratch is very full: keep only active data there and move or delete everything else. No new Puhti scratch quota will be granted.

GNU Parallel -työvuo monille pienille, riippumattomille ajoille

Tavoitteena on työvuo, joka on

  1. yksinkertainen ymmärtää,
  2. sopii hyvin eräjono-järjestelmään, ja
  3. ei kuormita rinnakkaista tiedostojärjestelmää.

Työvuo-työkaluja on runsaasti. Riippumatta siitä, minkä työkalun valitsee, se ei todennäköisesti sellaisenaan sovi juuri kyseiseen työnkulkuun ja taustalla olevaan laskenta-alustaan. Useimmissa tapauksissa tarvitaan jonkin verran ohjelmointia. Aiheeseen läheisesti liittyvä keskustelu löytyy Taulukkotyöt -luvusta osoitteessa https://docs.csc.fi.

GNU Parallelin vahvuudet

  • Ei vaadi tietokantaa tai pysyvää hallintaprosessia
  • Skaalautuu helposti suureen määrään tehtäviä/solmuja
  • Ajastimen resurssien tehokas käyttö

GNU Parallelin haitat

  • Käyttäjän on organisoitava syöte- ja tulostiedostot huolellisesti
  • Skaalaaminen vaatii järjestelmän I/O-suorituskyvyn huomioimista
  • Bash-skriptauksen perusteiden tuntemus on suositeltavaa
  • Vain sarjallisia alitehtäviä
  • Ei tukea riippuvuuksille tai virheistä palautumiselle

Yhteenveto järjestelmän rajoista

Kunkin käyttäjän kuukaudessa lähettämien töiden enimmäismäärä tulisi pitää alle tuhannessa. Liian suuri määrä eräajoja tuottaa ylimääräistä lokidataa ja hidastaa työnajastinta. Taulukkotyöt ovat käytännössä vain lyhennysmerkintä, joten yksi 100 jäsenen taulukkotyö lasketaan eräjono-järjestelmän näkökulmasta samaksi kuin 100 yksittäistä työtä.

Työn enimmäiskestoa rajoittavat jonon parametrit. Vähimmäiskestoa ei ole rajoitettu, mutta jos työ on liian lyhyt, se aiheuttaa vain suhteettoman suuren ajastusylikuorman eräjärjestelmään.

Tip

Hyvä tavoite on kirjoittaa eräajot niin, että ne valmistuvat jossain kahden tunnin ja kahden päivän välillä.

Rinnakkaiset tiedostojärjestelmät toimivat huonosti, kun yksi asiakas (sovellusohjelma) yrittää tehdä liian paljon tiedosto-operaatioita. Tällaisia tapauksia voivat olla esimerkiksi Conda-paketinhallinnalla suoraan jaettuun tiedostojärjestelmään asennetut sovellukset. Yksi miniconda-ympäristö sisältää helposti yli 20 000 tiedostoa, ja Anaconda-jakelu on vielä paljon pahempi. Monet näistä tiedostoista täytyy avata aina, kun Conda-sovellus käynnistetään. Kun ajetaan paljon suhteellisen lyhyitä töitä, vältä Condalla asennettujen sovellusten käyttöä. Jos sovelluksesi kuitenkin vaatii monimutkaisen ympäristön, käytä Singularity-kontteihin pakattuja sovelluksia, jotka ovat tiedostojärjestelmän näkökulmasta yksittäisiä tiedostoja. Jos haluat kontittaa Conda-ympäristön helposti, katso Tykky-konttikääretyökalu

"Myös "liikaa tiedostoja" -ongelmat ovat yleisiä työvuoissa, jotka koostuvat tuhansista pienistä ajoista. Yleisohjeena pidä tiedostojen määrä yhdessä hakemistossa selvästi alle tuhannen ja järjestä data useisiin hakemistoihin. Käytä myös komentoa csc-workspaces seurataksesi, että projektiesi tiedostojen kokonaismäärä pysyy selvästi rajojen alapuolella. Jos suurin osa tiedostoista on väliaikaisia tai niitä on yksinkertaisesti liikaa, nopeiden paikallisten SSD-levyjen käyttö I/O-solmuissa voi ratkaista ongelman. Voit pakata pieniä tiedostoja suuremmaksi arkistotiedostoksi komennolla tar. Tärkeintä on, että jos tulostiedostoja syntyy, joita et tarvitse, selvitä, miten niiden kirjoittaminen voidaan estää jo alun perin.

Ota yhteyttä osoitteeseen servicedesk@csc.fi, jos työvuosi tarvitsee apua yllä annettuihin rajoihin sovittamisessa.

Esimerkkitapaus: 80000 riippumatonta ajoa

Yleisesti ottaen työvuon suunnitteluun tarvitaan kolme syötettä:

  1. Kuinka monta ajoa on yhteensä?
  2. Kuinka kauan yksi ajo kestää?
  3. Kuinka monta tiedostoa syntyy?

Kaksi ensimmäistä määräävät, miten ajot ryhmitellään eräajoiksi, ja viimeinen määrittää hakemistohierarkian.

Tarkastellaan esimerkkiä, jossa meillä on 80000 riippumatonta, ei-rinnakkaista yhden ytimen ajoa, joista kukin kestää 0:sta 30 minuuttiin, keskimäärin 15 minuuttia. Pahimmassa tapauksessa kaikki eräajon ajot kestävät enimmäisajan eli 30 minuuttia. Näemme, että yksi 40 tunnin eräajo riittää vähintään 80 ajolle yhdellä ytimellä ja 3200 ajolle kaikilla 40 ytimellä yhdessä täydellisessä laskentasolmussa. Näin ollen kaikkien 80000 ajon pitäisi mahtua 25:een 40 tunnin eräajoon, joista kukin varaa yhden kokonaisen laskentasolmun.

Oletetaan, että sovelluksemme on todellinen levytilasyöppö, ja yhden säilytettävän syötetiedoston ja yhden säilytettävän tulostiedoston lisäksi se luo myös 100 väliaikaistiedostoa nykyiseen hakemistoon. Yhdessä hakemistossa voi olla enintään noin 400 syöte- ja tulostiedostoa, ja väliaikaistiedostoille voidaan käyttää I/O-solmujen nopeaa paikallista levyä. Näin 80000 ajolle saadaan 200 hakemistoa, joissa kussakin on 400 ajoa.

many
    dir-001
        input-001
        input-002
        ...
        input-400
    dir-002
    ...
    dir-200

Lisähuomioita tarvitaan, jos yksittäiset ajot ovat rinnakkaisia tai niiden välillä on riippuvuuksia, mutta se on jo toinen tarina.

Katsotaan esimerkkitapauksemme työskriptiä:

#!/bin/bash
#SBATCH --partition=small
#SBATCH --account=<project>
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=40
#SBATCH --time=40:00:00
#SBATCH --mem=160G
#SBATCH --gres=nvme:3600
#SBATCH --array=0-24

module load parallel

cd /scratch/${SLURM_JOB_ACCOUNT}/many

(( from_dir_index = SLURM_ARRAY_TASK_ID * 8 + 1 ))
(( to_dir_index = SLURM_ARRAY_TASK_ID * 8 + 8 ))

job_dirs=$(printf "%dir-%03d " $(seq $from_dir_index $to_dir_index))

find $job_dirs -name 'input-*' | \
    parallel -j $SLURM_CPUS_PER_TASK bash wrapper.sh {}

Eräajo varaa kokonaisen solmun 40 tunniksi. Solmussa käynnistyy yksi tehtävä, jolla on käytössään kaikki solmun 40 CPU-ydintä. Koska varaamme kaikki ytimet, voimme samalla varata kaiken muistin ja kaiken paikallisen levyn, ei ole tarvetta kitsastella tässä. Viimeinen rivi, #SBATCH --array=0,24, kertoo eräjärjestelmälle, että se suorittaa tästä työstä 25 kopiota, joista kukin tunnistetaan yksilöllisellä numerolla ympäristömuuttujassa SLURM_ARRAY_TASK_ID. Jonotilanteesta riippuen monet näistä töistä voivat olla käynnissä rinnakkain.

Seuraavaksi lataamme moduulin, joka tarjoaa GNU parallel. Käytämme tätä työkalua solmun sisällä "ajastamaan" kaikki työn 3200 ajoa niin, että koko ajan kaikki 40 ydintä ovat käytössä mutta eivät ylikuormitettuina.

Seuraavat rivit laskevat, mitkä hakemistot kuuluvat nykyiseen taulukkotyöhön käyttäen SLURM_ARRAY_TASK_ID-ympäristömuuttujaa.

Skriptin pää-"silmukka" on toteutettu GNU parallel -komennolla parallel. Valinnalla -j $SLURM_CPUS_PER_TASK kerromme GNU parallelille, että sen tulee pitää käynnissä 40 komentoa (sovellusta) rinnakkain. Koska meidän täytyy kopioida tiedostoja paikalliselle SSD:lle ja sieltä pois jokaisessa ajossa, käärimme sovelluksemme pieneen komentotulkkiskriptiin wrapper.sh, joka ottaa syötetiedoston nimen argumenttina. Syötetiedostojen nimet syötetään GNU parallelille putken kautta, ja GNU parallel jatkaa komennon bash wrapper.sh <syötetiedosto> suorittamista niin kauan kuin putkessa on argumentteja.

Käärinskriptin erottaminen eräajon skriptistä mahdollistaa sen, että molempia voidaan kehittää ja testata erikseen. Yleisesti kannattaa käyttää pieniä testiaineistoja työvuota kehitettäessä, eikä kannata odottaa saavansa sitä täydelliseksi ensimmäisellä yrittämällä. Voit tutkia ja testata pientä versiota esimerkkitapauksesta komennolla

export SBATCH_ACCOUNT=<your project>
wget -c https://a3s.fi/docs-files/support/tutorials/many.tar.gz -O - | tar xz
cd many
bash create_inputs.sh
tree /scratch/${SBATCH_ACCOUNT}/many
sbatch job.sh

Note

Useiden erillisten töiden ajaminen suuremman varauksen sisällä voi johtaa käyttämättömiin resursseihin. Varmista, että tällaisessa työssä on paljon nopeasti valmistuvia töitä ajettavana, jotta viimeisenä käynnissä oleva työ ei pidä koko varausta pitkään voimassa. Alityön keston tulisi siis olla paljon lyhyempi kuin varauksen kesto, ja alitöiden määrän paljon suurempi kuin yhdessä tehtävässä pyydettyjen ytimien määrä.

Voit käyttää seff -työkalua selvittääksesi, kuinka kauan aiemmat työt ovat kestäneet.

Suomenkielinen tekoälykäännös

Sisällössä voi esiintyä virheellistä tietoa tekoälykäännöksestä johtuen.

Klikkaa tästä antaaksesi palautetta