Slurm Kaynak Yöneticisi

TRUBA Wiki Sayfası sitesinden

Git ve: kullan, ara

Mevcut hesaplama kaynaklarının verimli kullanabilmesini sağlamak amacı ile tüm hesaplama sunucuları hesaplama kuyrukları ile organize edilerek SLURM kaynak yöneticisi ile yönetilmekte ve kullanılmaktadır.. Kaynak yöneticisi hakkında detaylı bilgiye üreticinin web sayfasından (https://slurm.schedmd.com/documentation.html) erişmek mümkündür.

Konu başlıkları

Temel SLURM komutları

Temelde sbatch ve squeue komutları iş göndermek işinizin durumunu izlemek için yeterli olsa da ek bazı SLURM komutlarını biliyor ve kullanıyor olamak, kullanım sırasında karşılaşılabilecek pek çok sorunu hızlıca çözmek ve sistemin genelini daha iyi kavramak açısından önemlidir.
Aşağıda sık kullanılan bazı komutların temel fonksiyonları hakkında özet bilgiler verilmiştir. Ancak bu komutlar pek çok ek ve özelliği, komut yanına yazılacak parametrelerle sağlayabilmektedir. Komutların ek özellikleri ve detayları hakkında pek çok bilgiye, komutların yardım sayfalarından (man pages) yada SLURM'un web sitedinden ulaşılabilir. Komutların yarım sayfasına, kullanıcı arayüzü sunucularından aşağıdaki komutla ulaşılabilir.


$> man <komut_adi>
sinfo: İş kuyruklarının güncel kullanım durumunu ekrana basar. Buradan edilinecek bilgi ile kuyruğa gönderilecek işin kaynak miktarı planlanarak en hızlı şekilde başlayabileceği kuyruğa yönlendirilebilir.Kullanılacak ek parametrelerle, listelenecek bilginin türü ve miktarı değiştirilebilir.
squeue: Kullanıcının kuyrukta bekleyen ve çalışan işlerini görüntüler. Kullanılacak ek parametrelerle, listelenecek bilginin türü ve miktarı değiştirilebilir. Kullanıcının tüm işleri listelenebileceği gibi (varsayılan), işin iş numarası parametre olarak verilerek, o işe özel bilgilerin dökümü de alınabilir.
sbatch: Hazırlanan iş betiğini kuyruğa göndermek için kullanılır. Parametreler betik dosyasında verilebilecegi gibi komutun yanına da yazılabilir. İşin akışını, verimini ve kontrolünü sağlayacak pek çok parametresi vardır.
srun: Alternatif olarak işler sbatch yerine srun komutu ile de çalıştırılabilir. Srun kullanılırken çalıştırılacak komut doğrudan srun ve parametrelerinin sonuna yazılır. Basit ve küçük işleri çalıştırmak için hızlı bir yöntemdir. Sbatch'de olduğu gibi pek çok önemli parametresi vardır.
scancel : Kuyrukta sırada bekleyen yada o anda çalışmakta olan işleri iptal etmek için kullanılır.
salloc: Komut satırından interaktif iş çalıştırmak için kullanılır. Salloc komutu ile öncelikle istenilen kaynak miktarı “allocate” edilerek salloc komut satırına geçilir, sonrasında srun komutu işe işler interaktif olarak çalıştırılır. Çalışma sırasında kullanıcı işin çalışmasına müdehale edebilir.
scontrol: Küme, kuyruk (partition) yada herhangi bir iş ile ilgili bilgilerin dökümü alınabilir, izin verildiği ölçüde, müdehale edilebilir. Kuyruğa gönderilmiş olan işler üzerinde, işleri silmeden güncelleme yapılmasına imkan sağlar.
sacct: Beklemede, çalışmakta yada daha önce çalışmış ve sonlanmış olan işler yada tek bir iş hakkında ayrıntılı rapor ve bilgi alınmasına imkan verir. Pek çok parametre içerir. Örneğin belli tarihler arasında başlamış ve bitmiş işlerin listesi, çalışma süresi, kullandığı bellek miktarı, üzerinde çalıştığı sunucuların adresleri vs, gibi iş/işler ile ilgili bilgi alınması mümkündür.
sstat Çalışmakta olan işin kullandığı, kullanmakta olduğu sistem kaynakları hakkında bilgi verir. --format= ile verilecek bilgi türleri seçilebilir.

SLURM betiği özellikleri

Herhangi bir SLURM betiği aslında BASH kabuk betiğidir. BASH kabuk programlama dilinin tüm öğelerini bu betikte kullanarak, pek çok detaylı analizi iş kuyruklarında yaptırmak mümkün.dür. BASH dilini betikte kullanarak, SLURM'un (yada herhangi bir başla kaynak yöneticisinin) sağlayamayacağı esnekliği betiklere eklemek mümkündür. Kabuk programlama ile ilgili wiki sayfamızda bulunan “Temel Kabuk Programlama” dökümanına göz atabilirsiniz.


Kabuk programlamadan bağımsız olarak, Herhangi bir SLURM betiği temel olarak 3 ana bölümden oluşur. Başlangıç (Parametreler, tanımlar), gövde ve iş başlatma/çıkış.
Başlangıç
Bu bölümde, hesaplama sırasında kullanılacak banka hesabı ve işin çalışacağı yer, zaman sınırı, çekirdek ve node sayısı gibi işin temel özellikleri tanımlanır. Her tanım satırı #SBATCH işe başlar. Bu bölümde işin akışını belirleyecek pek çok tanım yapılabileceği gibi, temel birkaç tanımın yapılması işin çalışması için yeterlidir.
Bu tanımların bir kısmı betik dosyasının içerisinde yapılabilecegi gibi, bir kısmı sbatch komutu ile dosya kuyruğa gönderilirken komutun yanında parametre olarak da kullanılabilir. örnegin sbatch -N 4 -n 16 is_dosyasi_adi


#!/bin/bash Betiği yorumlayacak interptreter. Bu şekilde kalması gerekir.
#SBATCH -p İşin çalıştırılacağı kuyruk adı (partition)
#SBATCH -A İş için kullanılacak kullanıcak bankaccount. Grup halinde yapılan çalışmalarda kullanıcı adından farklı olabilir. ARDEB kanalı ile açılan TBAG proje hesaplarına ayrıcalıklı olarak iş göndermek için, bu kısıma ilgili (ve kullanıcı hesabınız için izin verilen) tbag hesabının yazılması gerekir.
#SBATCH -J İşin kuyrukta görülecek adı.
#SBATCH -n Görev sayısı (mpi işleri için, uygulamanın çalıştırılacağı kopya sayısı). Normalde sbatch herhangi bir görev çalıştırmaz. İş, çalışacağı sunucuya düşüp, master nodda çalışmaya başladığında, betik linux komut satırından çalıştırılmış gibi davranır. Betikte işin çalıştırılacağı komut satırında özel bir durum belirtilmemişse işin tek kopyası çalıştırılır. Ancak satırda mpirun yada mpiexec komutları kullanılmışsa, ilgili uygulamanın -n kopyası çalıştırılır.
#SBATCH -c Her bir görev için kullanılabilecek en fazla çekirdek sayısını belirtir (cores per task) . Varsayılan değeri 1'dir. Eğer hibrid işler (mpi+openmp) yada multitask (openmp sadece) çalıştırılacaksa, bu parametrenin kullanılması gerekir.. Değeri OMP_NUM_THREADS değişkeninin değeri işe aynı olacak şekide seçilmelidir. Değeri 1 sunucudaki çekirdek sayısından fazla olamaz.. Eğer aynı sunucusu uzerinden 1 den fazla task (n) çalıştırılacaksa, sunucu başına düşen görev sayısı x görev başına düşen çekirdek miktarı en fazla ilgili sunucudaki çekirdek sayısı kadar olabilir. Örnegin 2 adet 28 çekirdekli sunucunun tamamı kullanarak 8 processli (task) bir MPI+openmp hibrid işi çalıştırılacaksa, process başına en fazla 7 çekirdek kullanılabilir. (sunucu başına 4 process düşer, sunucuda toplam 28 çekirdek varsa, her bir process için en fazla 7 çekirdek kullanılabilir)
#SBATCH --threads işlemcilerin hyperthreading özelliklerini kullanmak için tanımlanır.. Mevcut işlemcilerde çekirdek başına 2 thread düşmektedir. Örnegin 28 çekirdekli bir sunucuda, bir openmp işini 56 threadle (OMP_NUM_THREADS=56) çalıştırabilmek için -N 1 -n1 -c28 --threads=2 tanımı kullanılabilir..
#SBATCH --mem= Bu parametre ile iş için toplamda en fazla ne kadaar bellek kullanılacağı belirtilmektedir. kullanımı zorunlu değildir. Eğer Bu parametre kullanılmazda her bir çekirdek için DefMemPerCore kadar bellek ayrılır.. Eğer daha fazla belleğe ihtiyaç duyulacaksa, bu parametre ile ihtiyaç duyulan bellek miktarı arttırılabilir. Ancak bu değer en fazla çekirdek_sayisi x MaxMemPerCore kadar arttırılabilir.
#SBATCH --mem-per-core= Bu parametre ile her bir çekirdek için ihtiyaç duyulan bellek miktarı belirtilir. Kullanımı zorunlu değildir. Eğer Bu parametre kullanılmazda her bir çekirdek için DefMemPerCore kadar bellek ayrılır.. Eğer daha fazla bellege ihtiyaç duyulacaksa, bu paramere ile ihtiyaç duyulan bellek miktarı arttırılabilir. Ancak bu değer en fazla MaxMemPerCore kadar olabilir.


#SBATCH –time= İşin en fazla çalışma süresi. Bu süre zarfında tamamlanmamış olan işler, zaman dolduğunda otomatik olarak öldürülürler. Burada verilecek değer ilgili kümenin sınırından yüksek olamaz. Herhangi bir değer verilmeden gönderilen işler, çalışmaya başladıktan 1 dakika sonrasında sistem tarafından otomatik olarak sonlandırılırlar.
#SBATCH –no-requeue İş çalışırkan bazı durumlarda, hesaplama suncusundan kaynaklı sebeplerle, iş hata alarak sonlanabilir, bu durumda işi kuyruğa otomatik olarak yeniden gönderilir. İşin kuyruğa yeniden gönderilmesi genelde faydalı bir özelliktir, ancak eğer iş kaldığı yerden devam edecek şekilde yapılandırılmamışsa yada kullanılan uygulamanın böyle bir özelliği yoksa ve o ana kadar üretilen verilerin üzerine yeni verilerin yazılma ihtimali varsa, bu opsiyon kullanılarak işin kuyruğa otomatik olarak yeniden gönderilmesi engellenebilir.


#SBATCH –output= İş çalışırlen, kullandığınız uygulamanın ya da betiğinizde kullandığınız bash programla öğelerinin ekrana basacağı (STDOUT) bilgilerin yazılacağı dosyabın tam adresi ve adı. Bu adresin scratch dizinde olması zorunludur.
#SBATCH –error= İş çalışırlen, kullandığınız uygulamanın ya da betiğinizde kullandığınız bash programla öğelerinin ekrana basacağı hata mesajlarının (STDERR) yazılacağı dosyanın tam adresi ve adı. Bu adresin scratch dizinde olması zorunludur.
Eğer --error ve --output parametreleri belirtilmezse, tüm ekran çıktısı otomatik olarak slurm-JOBID.out dosyasına yönlendirilir.


#SBATCH -N Hesaplama sırasında, kullanıcak çekirdeklerin kaç farklı node tarafından sağlanacağını belirler. Herhangi bir tanım girilmemişse, çekirdekler rasgele sayındaki nodelardan rastgele sayıda sağlanırlar. Node sayısı için herhangi bir tanımlama yapmamak işlerin mümkün olan en hızlı şekilde başlamasını sağlar, ancak performans testlerinde alıncak sonuç, her iş için farklı olabilir, Eğer talep edilen çekirdeklerin nodelar tarafından eşit sayıda sağlanması istemiyorsa, -n -N parametresi yerine --ntasks-per-node ve -N parametreleri birlikte kullanılmalıdır. Örnegin işiniz için toplamda 16 çekirdeğin 4 sunucu tarafından eşit sayıda sağlanmasını istiyorsanız -N 4 --ntasks-per-node=4 parametresini kullanmalısınız.
Not: --ntask-per-node parametresi openmpi-1.6.5 sürümü ile düzgün çalışmamaktadır. O nedenle eşit çekirdek sayısının elzem olduğu durumlarda en az openmpi-1.8.8 sürümü kullanılmalıdır. Bu parametre impi ve diğer mpi sürümleri ile kontrol edilmemiştir.


#SBATCH -M Birden fazla hesaplama kümesin tek bir arayüz üzerinden hizmet verdiği durumlarda, işin gideceği kümeyi belirtir. TRUBA'da şu an için farklı hesaplama kümeleri farklı kullanıcı arayüzlerinden hizmet vermektedirler.
#SBATCH –workdir= işin başlayıp, output err dosyalarının yazılacağı dizinin adresidir. Scratch dizini işaret ediyor olması zorunludur. Eğer herhangi bir tanımlama yapılmaz ise, varsayılan olarak iş gönderilirken o an içinde bulunan dizin workdir dizini olarak kabul edilir.
#SBATCH –gres= Ekstra özelliklerin sunulduğu kuytuklarda bu ekstra özelliklerin ve onlardan ne kadarının kullanılacağını belirtir. Cuda kuyruğundaki GPU kartlarını kullanabilmek için bu tanımın yapılması gerekir. Örnegin SBATCH –gres=gpu:1
#SBATCH –mail-type= İş kuyruğa gönderildikten sonra, iş ile ilgili ne tür e-postaların gönderileceğini tanımlar. BEGIN, END, FAIL, REQUEUE, ALL değerlerini alabilir. Herhangi bir tanım yapılmaz ise kullanıcı e-posta ile bilgilendirilmez.
#SBATCH –mail-user= Yukarıda tanımlanan durumlarda e-postanın gönderileceği adresi tanımlar.
Gövde
Her program ve kullanıcı için gövde kısmı farklı olabilir. Bu kısımda işi çalıştırmadan önce yapılması gereken ön çalışma yapılır; load edilmesi gereken kütüphaneler, varsa çevre değişkenler vs. yüklenir. Kabuk dili öğeleri kullanılarak ön kontroller yapılarak gereki dosyaların varlığı, içeriği vs. kontrol edilebilir. Bu kısım kullanıcın deneyimine ve ihtiyaçlarına göre şekillenir. Ancak standart olarak iş ile ilgili temel bilgilerin STDOUT'a yazılması daha sonra işi analiz yada debug etmek için faydalı olabilir. Örneğin: aşağıdaki kısım da herhangi bir gaussian işini çalıştırmak için ihtiyaç duyulan kütüphaneler load edilerek çevre değişkenleri ayarlanıyor ve kullanılan kaynağın özellikleri STDOUT'a basılıyor.


echo "SLURM_NODELIST $SLURM_NODELIST" 
echo "NUMBER OF CORES $SLURM_NTASKS" 
export OMP_NUM_THREADS=1 
export g09root=$HOME 
export GAUSS_SCRDIR=/tmp 
. $g09root/g09/bsd/g09.profile
İşin çalıştırılması ve bitiş
Gövde kısmında işin programın çalıştırılması için gereki kütüphaneler, çevre değişkenleri load edildikten ve gerekli kontroller yapıldıktan sonra, sıra işin çalıştırılmasına gelir. İş çalıştırma satırı, normalde işi komut satırından elle çalıştırırken kullanılan komut satırı ile aynıdır. Herhangi bir gaussian işi işin bu satır aşağıdaki gibi olabilir örnegin:


$g09root/g09/g09 < gaussian_egitim.com
exit
MPI işler için SLURM'un sağladığı bazı esneklikler ve kullanım kuralları vardır. Hesaplama sırasında kullanılak cekirdek sayısı ve host bilgisi yazılmasına OpenMPI (ve diğer bazı MPI kütüphanelerinde) gerek yoktur. Bu bilgi mpirun komutuna doğrudan kaynak yöneticisi tarafından sağlanır. Örneğin komut satırından bir MPI işini 4 çekirdek çalıştırıken normalde


mpirun -np 4 –machinefile=hosts_dosyasi <uygulamanin_tam_adresi_ve_adi>
exit


gibi bir komut verilmesi gerekirken SLURM betiğinde aşağıdaki satır kullanılmalıdır.


mpirun <uygulamanin_tam_adresi_ve_adi>
exit


Eğer işin o ana kadar kullanmış olduğu sistem kaynakları (bellek, walltime, runtime, disk vs) hakkında detaylı bilgi alınmak isteniyorsa exit satırından önce
sstat -j $SLURM_JOB_ID
komutunu yazabilirsiniz.

Örnek betik dosyaları

Her kullanıcın deneyimi, ve kullanacağı uygulamanın yeri, özellikleri, versiyonu , ihtiyaç duyduğu kaynak türü ve miktarı, derlendiği ortam ve kütüphanelere göre, herhangi bir uygulamayı çalıştırmak için kullanılabilecek betik dosyası farklılıklar gösterebilir.
Teknik birim tarafından, tüm kullanıcıların kullanımı için standart özelliklerle derlenerek ortak dizine kurulmuş uygulamaların pek çoğu için örnek betik dosyaları hazırlanarak, kullanıcıların kullanımına sunulmuştur.
Örnek betik dosyalarına /truba/sw/scripts dizininden ulaşılabilir. Kullanıcıların burdaki betik dosyalarını kullanabilmeleri için, onları scratch'deki kendi dizinlerine kopyalamaları ve betik dosyasında verilmiş tanımları kendi hesaplanın ve işlerinin özelliklerine göre değiştirmeleri gereklidir.
Betik dosyalarını içinde bulundukları dizinle birlikte kopyalamakta fayda vardır. Zira ilgili dizin içinde, uygulamanın test amacı ile çalıştırılması için örnek input dosyaları da bulunmaktadır.

İşlerin Önceliklendirilmesi ve Başlatılması

Herhangi bir iş kuyruğa gönderildiğinde, kaynak yöneticisi belli parametrelere göre işin öncelik değerini (priority) hesaplar, ve işi kuyruğa alır.. Öncelik değeri ne kadar yüksek ise, iş, iş kuyruğunun o kadar önünde yer alır.. Bu işin daha önce başlatılması anlamına gelir ( kullandığımız backfill algoritması, daha düşük öncelikli işlerin de başlatılmasına olanak verir).
Kullanıcılar işlerinin öncelik değerini squeue --format=%Q yada sprio komutları ile ögrenebilirler.
TRUBA'daki kuyruk sisteminde SLURM tarafından sağlanan multifactor algoritması kullanılmaktadır. Bu algoritmaya göre, herhangi bir işin önceliği hesaplanırken iş gönderilirlen tanımlanmış parametrelere ve sistem yöneticisi tarafından belirlenmiş parametre ağırlıklarına bakılır.
PriorityWeightAge, PriorityWeightJobSize, PriorityWeightPartition,PriorityWeightQOS değerleri, sistem yöneticisi tarafından belirlenmiş, her parametrenin öncelik hesaplamasında ne kadar ağırlığı olduğunu belirleyen değerlerdir. TRUBA'da bu değerler:
PriorityWeightAge =1000 
PriorityWeightJobSize =10000 
PriorityWeightPartition =10000
PriorityWeightQOS =10000
dir. Herhangi bir kullanıcı arayüzünde, kullanıcılar sprio -w komutu ile güncel değerleri görebilirler..
İş önceliği formulü:
Job_priority =
                       (PriorityWeightAge) * (age_factor) +
                       (PriorityWeightFairshare) * (fair-share_factor) +
                       (PriorityWeightJobSize) * (job_size_factor) +
                       (PriorityWeightPartition) * (partition_factor) +
                       (PriorityWeightQOS) * (QOS_factor) +
                       SUM(TRES_weight_cpu * TRES_factor_cpu,TRES_weight_<type> * TRES_factor_<type>,...)
TRUBA'daki öncelik hesaplamasında TRES ve Fairshare parametreleri hesaba katılmamaktadır. Dolayısı ile formülümüz aşağıdaki gibidir:
Job_priority =
                       (PriorityWeightAge) * (age_factor) +
                       (PriorityWeightJobSize) * (job_size_factor) +
                       (PriorityWeightPartition) * (partition_factor) +
                       (PriorityWeightQOS) * (QOS_factor) +


Job_size_factor'u şu şekilde hesaplanır:
Job_node_number_factor=(node_number_in_job/total_node_number_in_cluster)
Job_cpu_number_factor = (cpu_number_in_job/total_cpu_number_in_cluster)
job_size_factor= (Job_node_number_factor+ job_cpu_number_factor)
Eğer büyük işler öncelikliyse:
JOBSIZE_priority= (PriorityWeightJobSize/2) * job_size_factor
Eğer küçük işler öncelikliyse:
JOBSIZE_priority= PriorityWeightJobSize - (PriorityWeightJobSize/2) * job_size_factor
Örneğin 100 nodedan oluşmuş 1000 çekirdekli bir kümede, -n20 -N4 ile gönderilecek bir işin JOBSIZE_priority değeri:
jOBSIZE_priority=(10000/2) * ( 4/100 + 20/1000)
                          = 300 
Eğer küçük işler öncelikli ise:
jOBSIZE_priority=10000 -300 =9700 
olacaktır.


age_factor değeri şu şekilde hesaplanır:
Herhangi bir işin kuyrukta en fazla bekleme süresi MaxAge olarak sistem yöneticisi tarafından tanımlanır.
age_factor=job_age/MaxAge
dolayısı ile AGE_Priority
 AGE_priority=PriorityWeightAge*job_age/MaxAge
Örneğin en faza bekleme süresi 15 gün ve PriorityWeightAge değeri 1000 olan TRUBA'da herhangi bir kuyrukta 10 gün bekleyen işin AGE_priority değeri aşağıdaki gibi olacaktır.
  AGE_priority=(10/15)*1000 = 667 
Eğer iş kuyrukta 15 gün yada daha fazla bekleyecek olursa, işin AGE_priority değeri en fazla 1000 olacaktır.
QOS_factor değeri şu şeklde hesaplanır:
İşin gönderildiği anda, tüm hesaplar arasında, QOS tanımlarında priority değeri en yüksek olan hesabın priority değeri tavan limit olarak kabul edilir.. İşi gönderen kullanıcının QOS tanımındaki priority degeri bu tavan limitle normalize edilir.
QOS_factor=QOS_priority_of_user/max_qos_priorty_in_cluster
QOS_priority=PriorityWeightQOS*QOS_factor
QOS öncelik değeri 1500 olan bir kullanıcı, tavan limiti 5000 ve PriorityWeightQOS değeri 10000 olan bir kümeye iş gönderecek olursa, ilgili işin aşağıdaki gibi olacaktır.
QOS_priority=1500/5000 * 10000 = 3333


partition_factor değeri, öncelik değeri en yüksek olan kuyruğun değeri tavan kabul edilerek, işin gönderildiği kuyruğun değerinin bu tavan değere bölünmesi ile hesaplanır.
partition_factor = priority_value_of_partition_of_job/max_priortity_value_of_partitions
Partition_priority=PriorityWeightPartition*partition_factor
Kuyrukların öncelik değerleri scontrol show partition komutu ile görülebilir.
Kişisel araçlar