SLURM機能確認
ジョブのメモリーサイズを確認
ジョブ実行後に
# sl -l 19 sugimoto B NewSLURM COMPLETED 00:04:06 2025-03-29T11:32:47 2025-03-29T11:36:53 sun2 19.batch batch COMPLETED 00:04:06 2025-03-29T11:32:47 2025-03-29T11:36:53 1.46G 0 sun2
いちおう出力する気はあるようである.
宣言を超えるメモリー使用量
メモリーを宣言以上に使用しても,エラーしない.デフォルトではslurm.confで DefMemPerCPU=4000 つまり4GBまで許容.ううん?理由は不明だ.
DefMemPerCPU=4000 は,スレッド1つ当たり4GBである. 8CPUで32GBで,「そんな計算機,ないっす」と言われる. そこでジョブ文に #SBATCH --mem=31000 とか書くと, 動く.
あ?メモリーサイズが超えているとしばらく時間がかかるが, CANCELされるぞ.
slurmstepd: error: StepId=70.batch exceeded memory limit (12826103808 > 83886080), being killed slurmstepd: error: Exceeded job memory limit slurmstepd: error: *** JOB 70 ON sun2 CANCELLED AT 2025-03-29T14:19:58 *** slurmstepd: error: StepId=70.batch exceeded memory limit (12826103808 > 83886080), being killed slurmstepd: error: Exceeded job memory limit slurmstepd: error: --task-epilog failed status=9
この例では,JOB文で
#SBATCH --cpus-per-task=8
#SBATCH --mem-per-cpu=10
と書いたので, 10 MB x 8 = 83886080 バイト使用すると申請したのだが,実行中に 12826103808 バイト使用しているのがバレて, 銃殺刑になったのだ.
OMP使うとどうなる?
まずOMPを使うプログラムを作成. ターミナルで実行すると
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
143467 sugimoto 20 0 29.6g 24.0g 3456 R 795.7 78.1 9:40.89 omp
こんな感じだから,できてる.ではジョブを打ってみる.あり?1CPUだなこりゃ
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
143763 sugimoto 20 0 12.0g 795808 3328 D 49.7 2.5 0:25.90 omp
あれえ?ジョブ文に
export OMP_NUM_THREADS=4
とか自分で書いたら動かない. あれ?/usr/local/etc/cgroup.conf でConstrainRAMSpace=no にしたら正常だ.なんだこれ. なんでRAMspaceとコア数が関連するんだ?バグってんじゃん.まあええか.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
148970 sugimoto 20 0 12.0g 11.9g 3456 R 598.3 38.7 0:50.65 omp
まあ動いたな!
MPI使うと死ぬのか
MPIを使ってみる.プログラムはこんなの:
//mpic++ bmpi.cpp -fopenmp -o bmpi -lboost_mpi
#include <omp.h>
#include <boost/asio.hpp>
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/LU>
#include <random>
namespace bmpi = boost::mpi;
int main(int argc, char** argv)
{
bmpi::environment env(argc, argv);
bmpi::communicator world;
std::cout << "Rank : " << world.rank() << "/" << world.size() << " on " << boost::asio::ip::host_name() << std::endl;
unsigned int N=14000,Nr=1;
Eigen::MatrixXd A;
Eigen::VectorXd b;
A.resize(N,N);
b.resize(N);
std::random_device seed_gen;
std::mt19937 engine(seed_gen());
std::uniform_real_distribution<> UNI(-1.,1.);
for(size_t repeat=0;repeat<Nr;repeat++) {
#pragma omp parallel for
for(size_t i=0;i<N;i++) for(size_t j=0;j<N;j++) A(i,j)=UNI(engine);
#pragma omp parallel for
for(size_t i=0;i<N;i++) b(i)=UNI(engine);
auto X=b.transpose()*A*b;
std::cout << "Pass[" << repeat << "]X= " << X << std::endl;
}
return 0;
}
で実行してみると
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
150752 sugimoto 20 0 1745540 1.5g 9344 R 199.3 4.8 0:13.72 bmpi
150750 sugimoto 20 0 1745540 1.5g 9344 R 199.0 4.8 0:13.69 bmpi
150753 sugimoto 20 0 1745540 1.5g 9344 R 199.0 4.8 0:13.69 bmpi
150751 sugimoto 20 0 1745540 1.5g 9472 R 198.3 4.8 0:13.64 bmpi
なるほど. 4Processで2Threadづつ, ちゃんと使っておるな.
$ sq
JOBID PART NAME USER ST TIME TIME_LEFT NODE CPU NODELIST(REASON)
76 B MPIJOB sugimoto R 0:04 3:04:56 1 8 sun2
GANGスケジューリング
GANGスケジューリングとは,優先度の高いジョブが低いジョブの上に乗っかって走るやつである.色々試した挙句, slurm.confが
PreemptType=preempt/partition_prio
PreemptMode=SUSPEND,GANG
...
PartitionName=B Nodes=ALL MaxTime=10-12:0:0 DefaultTime=0-03:05 OverSubscribe=FORCE:2 PriorityTier=20 Default=YES
PartitionName=E Nodes=ALL MaxTime=30-12:0:0 DefaultTime=0-03:05 OverSubscribe=FORCE:2 PriorityTier=10
こんな感じにして,コンピュータそのものを再起動すると,動くみたいである. 同じクラスのジョブなら
$ sq
JOBID PART NAME USER ST TIME TIME_LEFT NODE CPU NODELIST(REASON)
104 E OTHERJOB sugimoto R 0:20 3:04:40 1 8 sun2
103 E MPIJOB sugimoto S 0:54 3:04:06 1 8 sun2
仲良く,お互いにサスペンドしながら進める. 高位ジョブが入ると, メモリー不足ならばなら
$ sq
JOBID PART NAME USER ST TIME TIME_LEFT NODE CPU NODELIST(REASON)
105 B OMPJOB sugimoto PD 0:00 3:05:00 1 8 (Resources)
104 E OTHERJOB sugimoto R 0:44 3:04:16 1 8 sun2
103 E MPIJOB sugimoto S 1:24 3:03:36 1 8 sun2
いくら身分が高いジョブでも,殺しは許可していないので,待ってしまう.メモリーが足りると
$ sq
JOBID PART NAME USER ST TIME TIME_LEFT NODE CPU NODELIST(REASON)
105 B OMPJOB sugimoto R 0:07 3:04:53 1 8 sun2
103 E MPIJOB sugimoto S 2:18 3:02:42 1 8 sun2
高位ジョブが走り始める.身分の高いジョブは,下の者のケアは一切しない.自分が終了するまで,身分の低いジョブを待たせておく.
ま,世の中,そんなものですよね.