KOBE HPC サマースクール(初級)2023 講義9

134 Views

November 21, 23

スライド概要

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

KOBE HPC サマースクール 2023(初級) 8. 分散メモリ型並列計算機とは何か? - SPMDプログラミングによる Hello World! 2023/9/20 KOBE HPCサマースクール 2023 1

2.

プロセス並列とスレッド並列の違い スレッド並列(OpenMP)は,一つのプロセス内で行う並列処理. メモリ空間は一つだった. どのスレッドも,共有メモリ上の変数をアクセスできた. プロセス並列は,複数のプロセスによる並列処理. プロセスは,独立したメモリ空間を持っている. あるプロセスは,他のプロセスのメモリ上の変数にアクセスできない. 他のプロセスの持つ変数の値が欲しい場合には,プロセス間でデータのやり取り(送受信)をし ないといけない. プロセス間でデータのやり取りを記述する方法が必要. 2023/9/20 KOBE HPCサマースクール 2023 2

3.

共有メモリ型並列計算機 複数のプロセッサ(PE)が,単一のメモリ空間を共有 どの PE も同じメモリ領域にアクセス可能 PE0 PE1 PEn バス,またはネットワーク 特徴 メモリ空間が単一なので,プログラミングが容易 PE の数が多いと,同一メモリアドレスへのアクセス 競合が生じ,性能が低下 メモリ プログラミング方法 OpenMP,または自動並列化 ただし,MPIプログラムを実行することも可能 2023/9/20 KOBE HPCサマースクール 2023 3

4.

分散メモリ型並列計算機 複数のプロセッサがネットワークで接続されており, それぞれのプロセッサ(PE)が,メモリを持っている. 各PE が自分のメモリ領域のみアクセス可能 特徴 数千から数万PE規模の並列システムが可能 PE の間のデータ分散を意識したプログラミングが必要. PE0 PE1 PEn メモリ メモリ メモリ インターコネクト・ネットワーク プログラミング方法 メッセージ・パシング・インターフェイス(MPI)によるプログラ ミング 2023/9/20 KOBE HPCサマースクール 2023 4

5.

メッセージ・パッシング・インターフェイス(MPI) Message Passing Interface (MPI) とは... 複数の独立したプロセス間で,並列処理を行うためのプロセス間メッセージ 通信の標準規格 1992年頃より米国の計算機メーカ,大学などを中心に標準化 MPI規格化の歴史 1994 MPI-1.0 1997 MPI-2.0(一方向通信など) 2012 MPI-3.0 http://www.mpi-forum.org/docs/mpi-3.0/mpi30-report.pdf 2023/9/20 KOBE HPCサマースクール 2023 5

6.

MPIの実装ライブラリ MPIは規格であって,それを実現しているのが実装ライブラリ 共通の規格なので,他の計算機システムでコンパイル,実行することが可能. 代表的なMPIライブラリ MPICH :米国アルゴンヌ国立研究所が開発 MVAPICH :米国オハイオ州立大学 Open MPI :Open MPIコンソーシアム (FT-MPI,LA-MPI,LAM/MPI,PACX-MPIの 統合プロジェクト) xxxxx :各計算機ベンダーの独自MPIライブラリ 例.MPT: SGI Message Passing Toolkit ⇒ 本授業で使用 ※ 各メーカのハードウェア機構を活かす独自仕様が含まれている場合がある. 2023/9/20 KOBE HPCサマースクール 2023 6

7.

MPIの実行モデル:SPMD(Single Program, Multiple Data) 複数のプロセスにより並列実行 実行開始から終了まで,全プロセスが同じプログラムを実行 各MPIプロセスは固有の番号(ランク番号)を持つ P個のプロセスで実行する場合,プロセス番号は 0 から (P-1) までの整数 各プロセスで処理を変えたいときは,ランク番号を使った分岐により,各プロセ スの処理を記述する. 実行開始 rank=0 プロセス a.out rank=1 プロセス rank=2 プロセス a.out rank=3 プロセス a.out 並列実行部分 a.out 実行終了 2023/9/20 KOBE HPCサマースクール 2023 7

8.

MPIの実行モデル(続き) 複数のプロセスにより並列実行 実行開始から終了まで,全プロセスが同じプログラムを実行 各MPIプロセスは固有の番号(ランク番号)を持つ ⇒ ある単一の MPIプログラムを実行するとき,各プロセスが処理する内容を頭 の中でイメージ(頭の中で動作をシミュレート)することが重要 実行開始 calc0(); if( rank == 0 ) { calc1(); } else { /*if( rank == 1)*/ calc2(); } calc3(); rank=0 プロセス rank=1 プロセス calc0 calc0 calc1 calc2 calc3 calc3 KOBE HPCサマースクール 2023 calc0(); calc1(); calc3(); ➢ プロセス1 実行終了 2023/9/20 ➢ プロセス0 calc0(); calc2(); calc3(); 8

9.

MPIの実行モデル(続き) メモリ空間 プロセスごとに独立したメモリ空間を保持 プログラム中で定義された変数や配列は,同じ名前で独立に各プロセスのメモリ上に割り当てられる. 同じ変数や配列に対して,プロセスごとに違う値を与えることが可能 他のプロセスの持つ変数や配列には,直接にアクセスできない. 実行開始 rank=0 プロセス rank=1 プロセス a.out int k; double x[100]; k = 138 x[62] = 4.254 a.out int k; double x[100]; 直接にアクセス 不可能 k = 5478 x[62] = 2847.45 実行終了 2023/9/20 KOBE HPCサマースクール 2023 9

10.

MPIの実行モデル(続き) プロセス間通信 他のプロセスの持つ変数や配列のデータにアクセスできない. ⇒ プロセス間通信によりデータを送ってもらう. メッセージパッシング方式:メッセージ(データ)の送り手と受け手 この方式によるプロセス間通信関数の集合 ≒ MPI 実行開始 rank=0 プロセス データを送る (例:MPI_Send) rank=1 プロセス a.out int k; double x[100]; MPI関数による プロセス間通信 2023/9/20 KOBE HPCサマースクール 2023 a.out int k; double x[100]; データを受取る (例:MPI_Recv) 実行終了 10

11.
[beta]
MPIプログラムのスケルトン
#include <stdio.h>
#include <mpi.h>

MPIモジュールの取り込み(おまじない1)

int main(int argc, char **argv)
{
int nprocs, myrank;

MPIで使う変数の宣言

MPI_Init( &argc, &argv );
MPI_Comm_size( MPI_COMM_WORLD, &nprocs );
MPI_Comm_rank( MPI_COMM_WORLD, &myrank );

MPIの初期化(おまじない2)
MPIで使うプロセス数を nprocs に取得
自分のプロセス番号を myrank に取得

(この部分に並列実行するプログラムを書く)
MPI_Finalize() ;
return 0 ;

MPIの終了処理(おまじない3)

}

 それぞれのプロセスで異なった処理をする場合は,myrankの値で場合分けし,うまく仕事が振り分け
られるようにする(後出).
2023/9/20

KOBE HPCサマースクール 2023

11

12.

MPIプログラムの基本構成 int MPI_Init( int *argc, char ***argv ) MPIの初期化を行う.MPIプログラムの最初に必ず書く. int MPI_Comm_size( MPI_Comm comm, int *nprocs ) MPIの全プロセス数を取得し,2番目の引数 nprocs(整数型)に取得する. MPI_COMM_WORLDはコミュニケータと呼ばれ,最初に割り当てられるすべてのプロセスの集合 int MPI_Comm_rank( MPI_Comm comm, int *myrank ) 自分のプロセス番号(0からnprocs-1のどれか)を,2番目の引数 myrank(整数型)に取得 する. int MPI_Finalize(void) MPIの終了処理をする.MPIプログラムの最後に必ず書く. 2023/9/20 KOBE HPCサマースクール 2023 12

13.
[beta]
MPIプログラム(hello_mpi.c): Hello, world!
#include <stdio.h>
#include <mpi.h>
int main( int argc, char **argv )
{
int nprocs, myrank ;
MPI_Init( &argc, &argv );
MPI_Comm_size( MPI_COMM_WORLD, &nprocs );
MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
printf (“Hello, World! My rank number and nprocs are %d and %d.¥n", myrank, nprocs);
MPI_Finalize();
return 0;
}

2023/9/20

KOBE HPCサマースクール 2023

13

14.

県立大 Rokko システムの SGI版MPI を使う手順 環境設定:インテルコンパイラ,SGI版MPI を使えるようにする. $ $ module load intel module load mpt コンパイル方法 $ icc prog.c -lmpi (アイ シー シー :prog.cはコンパイルしたいプログラムのファイル名 prog.c ハイフン(-) エル エム ピー アイ) バッチジョブ・スクリプト:ファイル名は 「***.sh」(たとえば jobm.sh など)としておくと良い #!/bin/bash #PBS -q WS #PBS -l select=1:ncpus=2:mpiprocs=2 #PBS -N hello #PBS -j oe source /etc/profile.d/modules.sh module load intel module load mpt cd ${PBS_O_WORKDIR} mpiexec_mpt -np XX dplace –s1 ./a.out 2023/9/20 キューの設定:スクール専用キューWS(9/19~10/1の期間に使用可) select:ノード数,ncpus:ノード内コア数 MPIだけの並列プログラム実行の場合はncpus と mpiprocs の値は同じにする. helloは,出力ファイルヘッダ XX: MPI並列数 -np XX を指定しない場合は,スクリプトの値が使われる. KOBE HPCサマースクール 2023 14

15.

演習8-1:Hello, world! を並列に出力する. MPI版 “Hello, world!” を 2,4,及び8プロセスで実行し,結果を確認せよ! 以下 は実行例. $ $ mkdir␣MPI cd␣MPI 今日の演習用のディレクトリを作成する. ※ ␣はスペースを表わす. $ $ mkdir␣M-1 cd␣M-1 演習M-1用のディレクトリを作成する. $ cp␣/home/guest60/share/hello_mpi.c␣./ ソースプログラム hello_mpi.c をカレントディレクトリにコピーする. ※ 中身を見て,プログラムを確認すること. $ icc␣hello_mpi.c␣-lmpi ソースプログラムをコンパイル $ cp␣/home/guest60/share/jobm.sh␣./ ジョブスクリプト jobm.sh をコピーする. (プロセス数の指定など,必要な部分をeditする) $ qsub␣jobm.sh nnnnnn.rokko1 ジョブを投入し,実行結果を確認する. ※ nnnnnn はジョブ番号 $ ※ hello は,jobm.sh内で指定した jobname のこと cat␣hello.onnnnn 2023/9/20 KOBE HPCサマースクール 2023 15

16.

プログラム M-1の実行結果の確認 2プロセスでの実行結果 Hello, world! Hello, world! My rank number and nprocs are 0, 2. My rank number and nprocs are 1, 2. 4プロセスでの実行結果 Hello, Hello, Hello, Hello, world! world! world! world! My My My My rank rank rank rank number number number number and and and and nprocs nprocs nprocs nprocs are are are are 2, 0, 3, 1, 4. 4. 4. 4. (注意)出力はランク順に並ぶとは限らず,また,実行ごとに出力の順番が異なることがある. ポイント •各プロセスが同じプログラムを実行している. •各プロセスが持っているランク番号(myrankの値)が異なっている. 2023/9/20 KOBE HPCサマースクール 2023 16

17.

2プロセス時の変数の値(SPMD) メモリ空間 プロセスごとに独立したメモリ空間を保持 プログラム中で定義された変数や配列は,同じ名前で独立に各プロセスのメモリ上に割り当てられる. 同じ変数名や配列名だが保持するプロセスが異なれば「実体は別物」.つまりプロセスごとに違う値を 与えることが可能. 実行開始 rank=0 プロセス rank=1 プロセス a.out int myrank; int nprocs; myrank = 0 nprocs = 2 a.out int myrank; int nprocs; myrank = 1 nprocs = 2 実行終了 2023/9/20 KOBE HPCサマースクール 2023 17

18.

参考:Fortran版 2023/9/20 KOBE HPCサマースクール 2023 18

19.

MPIプログラムのスケルトン program main use mpi implicit none MPIモジュールの取り込み(おまじない1) integer :: nprocs, myrank, ierr MPIで使う変数の宣言 call mpi_init( ierr ) call mpi_comm_size( MPI_COMM_WORLD, nprocs, ierr ) call mpi_comm_rank( MPI_COMM_WORLD, myrank, ierr ) MPIの初期化(おまじない2) MPIで使うプロセス数を nprocs に取得 自分のプロセス番号を myrank に取得 (この部分に並列実行するプログラムを書く) call mpi_finalize( ierr ) MPIの終了処理(おまじない3) end program main  それぞれのプロセスが何の計算をするかは,myrank の値で場合分けし,うまく仕事が振り分けられるようにする. 2023/9/20 KOBE HPCサマースクール 2023 19

20.

MPIプログラムの基本構成(説明) call mpi_init( ierr ) MPI の初期化を行う.MPIプログラムの最初に必ず書く. call mpi_comm_size( MPI_COMM_WORLD, nprocs, ierr ) MPI の全プロセス数を取得し,2番目の引数 nprocs(整数型)に取得する. MPI_COMM_WORLD はコミュニケータと呼ばれ,最初に割り当てられるすべてのプロセスの集合 call mpi_comm_rank( MPI_COMM_WORLD, myrank, ierr ) 自分のプロセス番号(0からnprocs-1のどれか)を,2番目の引数 myrank(整数型)に取得す る. call mpi_finalize( ierr ) MPI の終了処理をする.MPIプログラムの最後に必ず書く. 2023/9/20 KOBE HPCサマースクール 2023 20

21.

プログラム(hello_mpi.f90) の説明 program hello_by_mpi (おまじない) MPI用のモジュールをインクルード use mpi implicit none integer :: nprocs, myrank, ierr (おまじない) MPI の初期化 MPI で使うプロセス数を nprocs に取得 自分のプロセス番号を myrank に取得 call mpi_init( ierr ) call mpi_comm_size( MPI_COMM_WORLD, nprocs, ierr ) call mpi_comm_rank( MPI_COMM_WORLD, myrank, ierr ) print *, 'Hello, world! My rank number and nprocs are', myrank, ',', nprocs 各プロセスで myrank と nprocs を出力す る. ※ myrank はプロセスごとに異なる ※ nprocs はすべてのプロセスで同じ (おまじない) MPIの終了処理 call mpi_finalize( ierr ) end program hello_by_mpi 2023/9/20 KOBE HPCサマースクール 2023 21

22.

演習8-1:Hello, world! を並列に出力する. MPI版 “Hello, world!” を 2,4,及び8プロセスで実行し,結果を確認せよ! 以下 は実行例. 今日の演習用のディレクトリを作成する. ※ ␣はスペースを表わす. $ $ mkdir␣MPI cd␣MPI $ $ mkdir␣M-1 cd␣M-1 $ cp␣/home/guest60/share/hello_mpi.f90␣./ ソースプログラム hello_mpi.c をカレントディレクトリにコピーする. ※ 中身を見て確認すること. $ ifort␣hello_mpi.f90␣-lmpi ソースプログラムをコンパイル $ cp␣/home/guest60/share/jobm.sh␣./ ジョブスクリプト jobm.sh をコピーする. (プロセス数の指定など,必要な部分をeditする) スペース 演習M-1用のディレクトリを作成する. $ qsub␣jobm.sh nnnnnn.rokko1 ジョブを投入し,実行結果を確認する. ※ nnnnnn はジョブ番号 $ ※ hello は,jobm.sh内で指定した jobname のこと cat␣hello.onnnnn 2023/9/20 KOBE HPCサマースクール 2023 22