• 検索結果がありません。

Reedbush-Uアカウントの発行

N/A
N/A
Protected

Academic year: 2021

シェア "Reedbush-Uアカウントの発行"

Copied!
77
0
0

読み込み中.... (全文を見る)

全文

(1)

Reedbushスーパーコンピュータシステム

の利用とMPIプログラムの実行

松本 正晴

大学院情報理工学系研究科コンピュータ科学専攻

(2)

本日の講義資料

ITC-LMSの授業スライドにある「計算科学概論0409.pdf」

(前回分の資料)と「計算科学概論0416.pdf」(今回の資料)

を各自ダウンロードしてください。

(3)

前提とする知識,条件

 C言語またはFortranによるプログラミングの経験は無くてもいいが、今日 は上記の経験がある程度あることを前提に話を進めます。  UNIX環境についての基本的な知識と利用経験  UNIXの基本コマンド,及び,プログラムの基本がわかってないと厳しい  個別に,集中的に教えるよう配慮しますので,遠慮なく聞いてください  知ってる人は近くの人にどんどん教えてあげるとよい。知らない人同士で相 談しながらやるのもよし。  情報基盤センター教育用計算機システム(ECCS)のアカウントを予め取得 しておくこと http://www.ecc.u-tokyo.ac.jp/doc/announce/newuser.html  今日はReedbushスーパーコンピュータシステムの使い方、ならびにMPIの 基礎についての実習です。OpenMPやGPUを使った計算は扱いません。

(4)

Reedbushアカウントの発行

1. 本人証明ができるものを用意。

• 学生証、運転免許証、など • 無い場合は、ECCSにログインできることで証明。

2. 名前を呼びます。

3. 本人確認の上、アカウントが記載された紙を

配布します。

4. 授業で指示があるまで、ログイン作業を行わ

ないでください。

(先週までに名簿登録した者のみです。)

(5)

ECCSにログイン

1. ECCSのマシンにログインする

ユーザ名、パスワードを間違えずに!

今配った<スパコンのアカウント>ではない。

2. デスクトップ画面下の「ターミナル」をクリックする。

3. コンソール画面が表示される。

(以降、macでの説明です。)

(6)

ユーザ名の確認

ユーザ名(利用者番号):

t03xxx

(xxxは3桁番号)

グループ名(課金プロジェクト名):

gt03

紙に書いてある情報が間違えている場合は教えてく

ださい。

(7)

秘密鍵/公開鍵の作成

1. ターミナルを起動して、以下を入力する $ ssh-keygen -t rsa 2. 鍵の収納先を聞かれるので、リターンを押す(以前に別の鍵を 作成してそれを使っている場合は、ファイル名を変更しないと上 書きしてしまうので注意) 3. 鍵を使うためのパスワードを聞かれるので、自分の好きなパス ワードを入れる(パスフレーズと呼ぶ) 4. もう一度、上記のパスフレーズを入れる 5. 鍵が生成される。

(8)

鍵の利用(1/2)

1. 生成した鍵は以下に入っている .ssh/ 2. 以下を入力する $ cd .ssh/ 3. 以下を入力すると、ファイルが見える(以下は例) $ ls

id_rsa id_rsa.pub known_hosts • 以下が生成した鍵ファイル

id_rsa :秘密鍵

(9)

鍵の利用(2/2)

4. 以下を入力して、公開鍵を表示する $ cat id_rsa.pub <公開鍵が表示される> 5. “ssh-rsa…”で始まる部分を、マウスでカットアンド ペーストし、公開鍵の登録に使う (“.u-tokyo.ac.jp”まで)

(10)

公開鍵の登録(1/2)

1. Webブラウザ(Safari)を起動 2. 以下のポータルサイトのアドレスを入力する https://reedbush-www.cc.u-tokyo.ac.jp/ 3. 「ユーザ名」にセンターから配布された“利用者番号”を入力する 4. 「パスワード」に、センターから配布された“初期パスワード”を入力 する 記載されている文字列はパスワードではないので注意 【次ページを参照】 5. “Login”ボタンを押すと、“初期パスワード”を変更するよう指示され るので、新しいパスワードを入力して変更する 鍵を作成した際のパスフレーズとは別の文字列を使うこと

(11)

正しいパスワードの確認とログイン

表示されている文字列の奇数番号(1, 3, 5, 7, 9,

11, 13, 15)の8文字列をつなぎ合わせたもの

例:

P9aesWsbw6oZrrd5

→ Password

(12)

ポータル画面(ログイン前)

(13)

公開鍵の登録(2/2)

5. パスワードの変更が完了したら、利用者番号と新

しいパスワードを入力して、

“Login”ボタンを押す

6. ログインメッセージが出る

7. (“Change Language”メニューで言語を変更)

8. 左側メニューの「公開鍵アップロード」をクリック

9. 画面に、公開鍵をカットアンドペーストする

10.「作成」ボタンを押す

(14)

言語の変更

“Change Language”で日本語に変更できます • “Japanese (JA_JP.UTF-8”)を選んで“Change”を押す • 終わったら、ブラウザを再読み込み 1.ここをクリック 2.ここを選択 3.ここをクリック

(15)

ポータル画面(日本語選択後)

(16)

ポータル画面(公開鍵登録)

1.ここに公開鍵をペースト

(17)

ポータル画面(公開鍵登録成功)

ペーストした鍵が表示 されていればOK

(18)

Reedbushへログイン

 ターミナルから、以下を入力 $ ssh reedbush-u.cc.u-tokyo.ac.jp -l t03xxx 「-l」はハイフンと小文字のL 「t03xxx」は利用者番号(t+数字)  接続するかと聞かれるので、yesを入力する  鍵作成時に自分で決めたパスフレーズを入力する  成功するとログインできる 鍵の名前がid_rsaじゃない場合や、.ssh/に無い場合はオプショ ン「-i」で鍵を指定できる  ログイン時は必ず/home/gt03/t03XXX/に入る。

(19)

ReedbushのデータをローカルPCに取り込む

 ローカルPC(ECCS)のターミナルでscpコマンドを使う。 $ scp t03xxx@reedbush-u.cc.u-tokyo.ac.jp:~/a.f90 ./ • 「t03xxx」は利用者番号 • 上の例はReedbush上のホームディレクトリにあるa.f90を ローカルPCのカレントディレクトリに取ってくる • ディレクトリごとダウンロードする場合は-rを指定 $ scp –r t03xxx@reedbush-u.cc.u-tokyo.ac.jp:~/SAMPLE ./ • SAMPLEディレクトリをディレクトリごとダウンロード

(20)

ローカルPCのファイルをReedbushに置く

 同様にローカルPC(ECCS)のターミナルでscpコマンドを使う。 $ scp ./a.f90 t03xxx@reedbush-u.cc.u-tokyo.ac.jp: • 「t03xxx」は利用者番号 • 上の例はローカルPCのカレントディレクトリにあるa.f90を Reedbush上のホームディレクトリに置く • ディレクトリごとアップロードする場合は-rを指定 $ scp –r ./SAMPLE t03xxx@reedbush-u.cc.u-tokyo.ac.jp: • SAMPLEディレクトリをディレクトリごとアップロード

(21)

GUIによるファイル操作(主にWindowsユーザ向け)

FileZillaやWinSCPを使えば手元のパソコンとReedbush間のファイル転 送をGUI操作で行うことができる

FileZilla

• https://filezilla-project.org

• “Download Filezilla Client”からダウンロード

• サイトマネージャにてプロトコルをSFTPに設定、ログオンの種類を鍵ファイルにす る(Putty形式の公開鍵ファイルが必要、puttygenによって変換すると良い) WinSCP • https://winscp.net/eng/download.php • プロトコルをSFTPまたはSCPに設定する • ホスト設定画面の設定からSSH-認証を選び、秘密鍵を指定する(OpenSSH形 式・Putty形式の両方に対応)

(22)

異なるパソコンの公開鍵登録

1. 同様の手順により、異なるパソコンで公開鍵を作成 2. 「公開鍵のアップロード」メニューの中で、複数登録する ことが可能 3. 鍵認証なので、家のパソコンや自分のノートパソコンか らでも接続可能です。

(23)

Reedbushにおける注意点

• ログイン時に始めに入る/homeファイルシステムは容量が小 さく(最大2GB)、ログインに必要な設定ファイルだけを置くた めの場所です。 • /homeに置いたファイルは計算ノードから参照できません。 ジョブの実行もできません。 ⇒ ログイン後は/lustreファイルシステムを利用してください。 • ホームディレクトリ:/home/gt03/t03xxx • cdコマンドで移動できます。 • Lustreディレクトリ:/lustre/gt03/t03XXX • cdwコマンドで移動できます。

(24)

Reedbushにおける計算の仕方

 Reedbush-U( CPU only )

 Reedbush-H( w/ GPU )

(25)

Reedbush-U 1ノードの構成

メモリ 128GB

Intel Xeon E5-2695 v4 (Broadwell-EP) 18コア DDR4 DDR4 DDR4 DDR4 QPI QPI メモリ 128GB

Intel Xeon E5-2695 v4 (Broadwell-EP) 18コア DDR4 DDR4 DDR4 DDR4 76.8GB/s 76.8GB/s 76.8GB/s 1ノード当たり36コア、256GB × 420ノード G3 x16 Infin ib an d EDR HCA  一般的なスーパーコンピュータで は、ノード単位で計算資源を数え ることが多い。  Reedbush-Uの場合、1ノード当た り36コア、256GB(18コア、 128GBが2つ)。これが全部で420 ノードある。  ノード内は共有メモリ型計算機な ので、OpenMPによる並列化が 可能。  ノード間で並列化する際はMPIに よるデータ通信が必要(分散メモ リ型計算機)。

(26)

(ちなみに)Reedbush-Hノードのブロック図

26 NVIDIA Pascal NVIDIA Pascal NVLinK 20 GB/s Intel Xeon E5-2695 v4 (Broadwell-EP) NVLinK 20 GB/s QPI 76.8GB/s 76.8GB/s IB FDR HCA G 3x 1 6 15.7 GB/s 15.7 GB/s DDR4 128GB EDR switch E D R 76.8GB/s 76.8GB/s Intel Xeon E5-2695 v4 (Broadwell-EP) QPI DDR4 DDR4 DDR4 DDR4 DDR4 DDR4 DDR4 128GB PCIe sw G 3 x1 6 PCIe sw G 3 x1 6 x16 G3 IB FDR HCA ×120

(27)

Reedbush-Uで利用できるコンパイラ

Intelコンパイラ

• Fortranコンパイラ :ifort (逐次実行)

:mpiifort (MPI実行,Intel MPI)

• Cコンパイラ :icc (逐次実行)

:mpiicc (MPI実行,Intel MPI)

• C++コンパイラ :icpc (逐次実行)

:mpiicpc (MPI実行,Intel MPI)

ソースファイルをコンパイルして実行ファイルを作成した後にそ れを実行するには“ジョブ”を投げる必要がある。

(28)

Reedbush-Hで利用できるGPU用コンパイラ(PGI)

• moduleコマンドを利用して、コンパイラ環境、パスを設定。

$ module load cuda/(バージョン番号) $ module load pgi/(バージョン番号)

• CUDA C

$ nvcc –gencode arch=compute_60,code=sm_60 [options] hoge.cu

• CUDA Fortran

$ pgfortran –Mcuda=cc60 [options] hoge.cuf

• OpenACC

• Fortran: $ pgfortran –acc –ta=tesla,cc60 [options] hoge.f90 • C: $ pgcc –acc –ta=tesla,cc60 [options] hoge.c

(29)

Reedbush-Uスーパーコンピュータシステムでのジョブ実行形態

 インタラクティブジョブ実行(本実習では利用不可) • PCでの実行のように、コマンドを入力して実行 • スパコン環境では、あまり一般的でない • あくまでもデバッグ用。大規模実行はできない • Reedbush-Uでは、以下に限定 • 1ノード(36コア)、30分まで • 4ノード(144コア)、10分まで  バッチジョブ実行 • バッチジョブシステムに処理を依頼して実行する • スパコン環境では一般的な方法。大規模実行用。 • 一般利用では、最大128ノード(4,608コア)、24時間まで。 • 本実習では最大8ノード(288コア)、10分まで。 Reedbush-Uに限らず、スパコン環境では以下の2通りがほとんど。

(30)

バッチ処理とは?

ユーザ スパコン バッチ処理 システムが ジョブを取り出す 実行 バッチキュー ジョブの依頼 • 一般的なスパコン環境で大規模計算を行う場合、通常、インタラクティ ブ実行(コマンドラインで実行すること)はできません • ジョブはバッチ処理で実行します • キュー(Queue):待ち行列

(31)

バッチキューの設定の仕方

• バッチ処理はAltair社のバッチシステムPBS Professionalで管理され ている • 以下、主要なコマンドの説明 • ジョブの投入 :qsub <ジョブスクリプトファイル名> • 自分が投入したジョブの状況確認 :rbstat • 投入ジョブの削除 :qdel <ジョブID> • バッチキューの状態を見る :rbstat --rsc • バッチキューの詳細構成を見る :rbstat --rsc -x • 投げられているジョブ数を見る :rbstat –b • 過去の投入履歴を見る :rbstat –H • 同時に投入できる数/実行できる数を見る :rbstat --limit

(32)

Jobスクリプトのサンプルの説明

C言語,Fortran共通 #!/bin/bash #PBS -q u-lecture #PBS –W group_list=gt24 #PBS -l select=8:mpiprocs=4:ompthreads=9 #PBS -l walltime=00:10:00 cd $PBS_O_WORKDIR . /etc/profile.d/modules.sh mpirun ./a.out リソースグループ名 :u-lecture → 授業時間中はu-lecture3 利用グループ名:gt03 利用ノード数 1ノード当たりのMPIプロセス数 実行時間制限:10分 カレントディレクトリ設定、環境変数設定 (必ず記入しておく) 上の例では、ジョブを32プロセス9スレッドの288並列(コア)で実行 (1ノード当たり4プロセス9スレッドでそれが8ノード分) 1プロセス当たりOpenMP スレッド数 Reedbush-Uは1ノー ド当たり36コア。

(33)

本講義でのキュー名

本演習時間中のキュー名:u-lecture3(Reedbush-U, CPU only) 最大8ノード(288コア),10分まで h-lecture3(Reedbush-H, w/GPU) 最大2ノード、10分まで (CPU:36コア+GPU:2台)×2ノード 本演習時間以外(24時間)のキュー名: u-lecture(Reedbush-U) h-lecture(Reedbush-H) 利用条件は上と同じ ジョブスクリプトの#PBS -qの部分に記載するキューの種類

(34)

サンプルプログラムの起動

1.並列版Helloプログラムの実行

(35)

UNIXコマンド備忘録(1/3)

emacsエディタの起動: emacs 編集ファイル名 • ^x ^s (^は「controlを押しながら」) :テキストの保存 • ^x ^c :終了 (^zで終了すると、スパコンの負荷が上がる。絶対にしないこと) • ^g :訳がわからなくなったとき • ^k :カーソルより行末まで消す。 消した行は一時的に記憶される。 • ^y :^kで消した行を、現在のカーソルの場所にコピー • ^s 文字列 :文字列の箇所まで移動(検索) • ^M x goto-line :指定した行まで移動 (^MはESCキーを押して離す)

(36)

UNIXコマンド備忘録(2/3)

• rm ファイル名 :ファイルを消す • ls :現在いるフォルダの中身を見る • cd ディレクトリ名 :ディレクトリに移動する • cd .. :一つ上のディレクトリへ移動する • cd :ホームディレクトリへ行く • cat ファイル名 :ファイルの中身を見る • make :Makefileがある場合、実行ファイルを作る • make clean :実行ファイルを消す (cleanがMakefile内で定義されていないと実行できない。)

(37)

UNIXコマンド備忘録(3/3)

• less ファイル名 :ファイルの中身を見る (catでは画面がいっぱいになってしますとき) • スペースキー :1画面スクロール • / 文字列 :文字列の箇所まで移動 • q :終了(訳がわからなくなったとき)

(38)

サンプルプログラム名

• C言語版・Fortran版共通ファイル: Samples.tar • tarで展開後、C言語とFortranのディレクトリが作られる。 C/ :C言語用 F/ :Fortran用 • 上記ファイルが置いてある場所 /lustre/gt03/t03000

(39)

Samples.tarの中身

• Hello/ • 並列版Helloプログラム • Mat-vec/ • 行列・ベクトル積の計算プログラム • MPI/ • MPI集団通信のサンプルプログラム • Wa1/ • 逐次転送方法による総和演算プログラム • Wa2/ • 二分木通信方式による総和演算プログラム

(40)

並列版Helloプログラムをコンパイル(1/2)

1. cdwコマンドを実行してlustreファイルシステムへ移動 $ cdw 2. サンプルプログラムの場所/lustre/gt03/t03000にある Samples.tarを自分のディレクトリにコピーする $ cp /lustre/gt03/t03000/Samples.tar ./ 3. Samples.tarを展開する $ tar xvf Samples.tar 4. Samplesディレクトリへ移動 $ cd Samples C言語 : $ cd C Fortran : $ cd F 5. Helloディレクトリへ移動 $ cd Hello

(41)

並列版Helloプログラムをコンパイル(2/2)

6. ソースファイルをコンパイルする。すでにcompileファイルとい う実行ファイルが用意されているので、それを実行する。

$ ./compile

(以下のコマンドでもコンパイル可)

C言語 :mpiicc hello.c –o hello Fortran :mpiifort hello.f –o hello

7. 実行ファイル(hello)ができていることを確認する

(42)

並列版Helloプログラムの実行(ピュアMPI)

• このサンプルのJobスクリプトは hello.bash です。 • サンプルでは、キュー名が“u-lecture”,グループ名が “gt00”になっています。 • $ emacs hello.bash で、キュー名とグループ名をそれぞれ書き換えてください。 u-lecture3 gt03

(43)

並列版Helloプログラムの実行(ピュアMPI)

1. Helloディレクトリの中で以下を実行 $ qsub hello.bash 2. 自分の導入されたジョブを確認 $ rbstat 3. 実行が終了すると、以下のファイルが生成される hello.bash.exxxxxx hello.bash.oxxxxxx (xxxxxxはJobID) 4. 上記の標準出力ファイルを見てみる cat hello.bash.oxxxxxx

5. “Hello parallel world!”が36プロセス×8ノード =288表示されていたら実行成功。

(44)

バッチジョブ実行時の標準出力と標準エラー出力

• バッチジョブの実行が終了すると、標準出力ファイルと標準エ ラー出力ファイルがジョブ投入時のディレクトリに作成される。 • 標準出力ファイルにはジョブ実行中の標準出力、標準エラー出 力ファイルにはジョブ実行中のエラーメッセージが出力される。 ジョブ名.oXXXXX --- 標準出力ファイル ジョブ名.eXXXXX --- 標準エラー出力ファイル (XXXXX はジョブ投入時に表示されるジョブのJobID)

(45)

並列版Helloプログラム(C言語)

#include <stdio.h> #include <mpi.h>

int main(int argc, char *argv[]){ int myid,nprc,ierr;

ierr=MPI_Init(&argc,&argv);

ierr=MPI_Comm_rank(MPI_COMM_WORLD,&myid); ierr=MPI_Comm_size(MPI_COMM_WORLD,&nprc);

printf("Hello parallel world! MyID: %d %d¥n",myid, nprc); ierr=MPI_Finalize(); return 0; } MPIの初期化 自分のrank IDを取得 :各プロセスで値は異なる 全体のプロセッサ台数 を取得 :各プロセスで値は同じ (演習環境では 最大288) MPIの終了 このプログラムは、全PEで起動される

(46)

program main implicit none include "mpif.h" integer::myid,nprc,ierr call mpi_init(ierr) call mpi_comm_rank(mpi_comm_world,myid,ierr) call mpi_comm_size(mpi_comm_world,nprc,ierr)

print *, "Hello parallel world! MyID:", myid, nprc call mpi_finalize(ierr)

stop

end program main

並列版Helloプログラム(Fortran)

MPIの初期化 自分のrank IDを取得 :各プロセスで値は異なる 全体のプロセッサ台数 を取得 :各プロセスで値は同じ (演習環境では 最大288) MPIの終了 このプログラムは、全PEで起動される

(47)

MPIの集団通信プログラム

前回の資料(計算科学概論0409.pdf)の85ページ

からを参照

プログラムをよく読んで、コンパイル・実行し、結果

を確認してください。

(48)

サンプルプログラムの起動

(49)

Samples.tarの中身

• Hello/ • 並列版Helloプログラム • Mat-vec/ • 行列・ベクトル積の計算プログラム • MPI/ • MPI集団通信のサンプルプログラム • Wa1/ • 逐次転送方法による総和演算プログラム • Wa2/ • 二分木通信方式による総和演算プログラム

(50)

行列・ベクトル積の計算プログラム(Mat-vec)

実行結果が、

N = 10000

Elapsed time = 0.286047 [sec.] 699.185843 [MFLOPS] OK! N = 10000 Elapsed time[sec.] = 1.46469116210938 MFLOPS = 136.547557037191 OK! (C言語) (Fortran) のような結果が出たらOK

(51)

サンプルプログラムの説明

本プログラムでは、全プロセスが行列Aとベクトルxのデータ を持ち、y=Axの計算をしている。 (C言語) #define N 10000 (Fortran) integer,parameter::N=10000 Nを変更すると、行列サイズを変更できます。 (C言語) #define debug 1 (Fortran) integer,parameter::debug=1 「1」としてコンパイルすると、演算結果が正しいことがチェッ クできます。

(52)

レポート課題(I)

下記について、実験環境(8ノード、288コア)を駆使して、問題サイズ や並列数を変化させるなどにより性能を評価し、レポートにまとめよ。 1. サンプルプログラムを並列化せよ。このとき、行列Aおよびベクト ルx、yのデータは、全PEでN×Nのサイズを確保してよい。 2. サンプルプログラムを並列化せよ。このとき、行列Aは、初期状態 では、各PEに割り当てられた分の領域しか確保してはいけない。

(53)

レポート課題(I)の注意

 本課題では、MPI通信関数は不要です。  このサンプルプログラムでは、演算結果検証部分 (debug=1にした場合に実行される部分)が並列化され ていないため、MatVec関数のみを並列化しても、検証 部でエラーとなります。  検証部分も、計算されたデータに各PEで対応するよう に、並列化してください。検証部分においても、行列-ベ クトル積と同様のループとなります。

(54)

本実習プログラムのTIPS

• myid, nprcは大域変数です myid (=自分のID)、および、nprc(=全プロセス数)の変数 は大域変数です。MyMatVec関数内で、引数設定や宣 言なしに、参照できます。 • myid, nprcの変数を使う必要があります MyMatVec関数を並列化するには、 myidおよび、nprc変 数を利用しないと、並列化ができません。

(55)

並列化の考え方(C言語)

for ( j=0; j<N; j++) { 内積( j, i ) } PE0 for ( j=0; j<N/4; j++) { 内積( j, i ) } PE1 for ( j=N/4; j<(N/4)*2; j++) { 内積( j, i ) } PE2 for ( j=(N/4)*2; j<(N/4)*3; j++) { 内積( j, i ) } PE3 for ( j=(N/4)*3; j<N; j++) { 内積( j, i ) } 各PEで 重複して 所有する 行列A ベクトルx n n SIMDアルゴリズムの考え方(4PEの場合)

(56)

並列化の考え方(Fortran言語)

do j=1, N 内積( j, i ) enddo PE0 do j=1, N/4 内積( j, i ) enddo PE1 do j=N/4+1, (N/4)*2 内積( j, i ) enddo PE2 do j=(N/4)*2+1, (N/4)*3 内積( j, i ) enddo PE3 do j=(N/4)*3+1, N 内積( j, i ) enddo 各PEで 重複して 所有する 行列A ベクトルx n n SIMDアルゴリズムの考え方(4PEの場合)

(57)

PE0 PE1 PE2 PE3

初心者が注意すること

A[N][N] A[N][N] A[N][N] A[N][N]

PE0 PE1 PE2 PE3

myid = 0 myid = 1 myid = 2 myid = 3

各PEでは、独立した配列が個別に確保されます。

myid変数は、MPI_Comm_rank()関数が呼ばれた段階で、各PE

(58)

1. 全PEで行列AをN×Nの大きさ、ベクトルx、yをNの大きさ、確保してよいと する。 2. 各PEは、担当の範囲のみ計算するように、ループの開始値と終了値を変 更する。ブロック分散方式では、以下になる。 (N が nprc で割り切れる場合) ib = N / nprc;

for ( nj=myid*ib; nj<(myid+1)*ib; nj++) { … }

3. (2の並列化が完全に終了したら)各PEで担当のデータ部分しか行列を確 保しないように変更する。上記のループは、以下のようになる。

for ( nj=0; nj<ib; nj++) { … }

(59)

1. 全PEで行列AをN×Nの大きさ、ベクトルx、yをNの大きさ、確保してよいと する。 2. 各PEは、担当の範囲のみ計算するように、ループの開始値と終了値を変 更する。ブロック分散方式では、以下になる。 (N が nprc で割り切れる場合) ib = N / nprc

do nj=myid*ib+1, (myid+1)*ib …. enddo

3. (2の並列化が完全に終了したら)各PEで担当の データ部分しか行列を確保しないように変更する。 上記のループは、以下のようになる。

do nj=1, ib …. enddo

(60)

並列化の方針(行列-ベクトル積)(C言語)

PE0 PE1 PE2 PE3 for ( nj=0; nj<(N/4); nj++) { 内積( nj, ni ) } for ( nj=(N/4); nj<(N/4)*2; nj++) { 内積( nj, ni ) } for ( nj=(N/4)*2; nj<(N/4)*3; nj++) { 内積( nj, ni ) } for ( nj=(N/4)*3; nj<N; nj++) { 内積( nj, ni ) } ※各PEで使われない領域が出るが、担当範囲指定がしやすいので実装がしやすい。 全PEでN×N行列を持つ場合

(61)

並列化の方針(行列-ベクトル積)(Fortran言語)

PE0 PE1 PE2 PE3 do nj=1, N/4 内積( nj, ni ) enddo do nj=N/4+1, (N/4)*2 内積( nj, ni ) enddo do nj=(N/4)*2+1, (N/4)*3 内積( nj, ni ) enddo do nj=(N/4)*3+1, N 内積( nj, ni ) enddo 全PEでN×N行列を持つ場合 ※各PEで使われない領域が出るが、担当範囲指定がしやすいので実装がしやすい。

(62)

並列化の方針(行列-ベクトル積)

PE0 PE1 PE2 PE3 = = = = この方針では、y=Axのベクトルyは、以下のように一部分しか計 算されないことに注意!

(63)

並列化時の注意

 演習環境は、最大288PEです。  並列化は、<できた>と思ってもバグっていることが多い!  このサンプルの検証部分(debug=1の時に実行される部分)は、PE0がベ クトルyの要素すべてを所有することが前提となっています。  出力結果を考慮して検証部分も並列化してください。  Nを小さくして、printfで結果(ベクトルy)を目視することも、デバックになり ます。しかし、Nを目視できないほど大きくする場合にバグることがありま す。目視のみデバックは、経験上お勧めしません。  数学ライブラリ開発では、できるだけ数学(線形代数)の知識を利用した 方法で、理論的な解と結果を検証することをお勧めします。

(64)

時間計測方法(C言語)

double t0, t1, t2, t_w; .. ierr = MPI_Barrier(MPI_COMM_WORLD); t1 = MPI_Wtime(); <ここに測定したいプログラムを書く> t2 = MPI_Wtime(); t0 = t2 - t1;

ierr = MPI_Reduce(&t0, &t_w, 1, MPI_DOUBLE,MPI_MAX, 0, MPI_COMM_WORLD); バリア同期後、時間を 習得し保存 各プロセッサ(プロセス)で、 t0の値は異なる。 この場合は、最も遅いもの の値をプロセスID = 0 (rank0)が受け取る。

(65)

double precision t0, t1, t2, t_w double precision MPI_WTIME

..

call MPI_BARRIER(MPI_COMM_WORLD, ierr) t1 = MPI_WTIME(ierr) <ここに測定したいプログラムを書く> t2 = MPI_WTIME(ierr) t0 = t2 - t1 call MPI_REDUCE(t0, t_w, 1, & MPI_DOUBLE_PRECISION,

& MPI_MAX, 0, MPI_COMM_WORLD, ierr)

時間計測方法(Fortran)

バリア同期後、時間を 習得し保存 各プロセッサ(プロセス)で、 t0の値は異なる。 この場合は、最も遅いもの の値をプロセスID = 0 (rank0)が受け取る。

(66)

サンプルプログラムの起動

(67)

Samples.tarの中身

• Hello/ • 並列版Helloプログラム • Mat-vec/ • 行列・ベクトル積の計算プログラム • MPI/ • MPI集団通信のサンプルプログラム • Wa1/ • 逐次転送方法による総和演算プログラム • Wa2/ • 二分木通信方式による総和演算プログラム

(68)

総和演算プログラム(Wa1, 逐次転送方式)

 各MPIプロセスが所有するデータを、全プロセスで加算し、あるプロセス1つが結果 を所有するという処理を考える。  素朴な方法(逐次転送方式) 1. (rankIDが0でなければ)左隣のプロセスからデータを受信 2. 左隣のプロセスからデータが来ていたら 1. 受信する 2. <自分のデータ>と<受信データ>を加算する 3. (255番でなければ)右隣のプロセスに<2の結果>を送信する 4. 処理を終了する  実装上の注意 • 左隣とは、(myid-1)のIDをもつプロセス • 右隣とは、(myid+1)のIDをもつプロセス • myid=0のプロセスは左隣はないので、受信はしない • myid=p-1のプロセスは右隣はないので、送信はしない

(69)

逐次転送方式(バケツリレー方式)による加算

CPU0 CPU1 CPU2 CPU3

0 1 2 3 0 所有データ 0 + 1 1 + 3 3 + 送信 送信 送信 最終結果 所有データ 所有データ 所有データ

(70)

1対1通信利用例(Wa1, 逐次転送方式、C言語)

void main(int argc, char* argv[]) { … MPI_Status istatus; … dsendbuf=(double)myid; drecvbuf=0.0; if(myid!=0){ ierr=MPI_Recv(&drecvbuf,1,MPI_DOUBLE,myid-1,0,MPI_COMM_WORLD,&istatus); } dsendbuf=dsendbuf+drecvbuf; if(myid!=nprc-1){ ierr=MPI_Send(&dsendbuf,1,MPI_DOUBLE,myid+1,0,MPI_COMM_WORLD); } if(myid==nprc-1) printf("Total=%4.2lf¥n",dsendbuf); … } 受信用システム配列の確保 自分より一つ少ないID番号(myid-1)から、double 型データ1つを受信しdrecvbuf変数に代入 自分より一つ多いID番号(myid+1)に、dsendbuf変数 に入っているdouble型データ1つを送信

(71)

program main … integer istatus(mpi_status_size) … dsendbuf=dble(myid) drecvbuf=0.0d0 if(myid/=0) then call mpi_recv(drecvbuf,1,mpi_double_precision,myid-1,0,& mpi_comm_world,istatus,ierr) endif dsendbuf=dsendbuf+drecvbuf if(myid/=nprc-1) then call mpi_send(dsendbuf,1,mpi_double_precision,myid+1,0,& mpi_comm_world,ierr) endif if(myid==nprc-1) then

print *,"Total = ",dsendbuf endif

end program main

1対1通信利用例(Wa1, 逐次転送方式、Fortran)

受信用システム配列の確保 自分より一つ少ないID番号(myid-1)から、double precision型データ1つを受信しdrecvbuf変数に代入 自分より一つ多いID番号(myid+1)に、dsendbuf変数 に入っているdouble precision型データ1つを送信

(72)

総和演算プログラム(Wa2, 二分木通信方式)

 二分木通信方式

(256プロセスでの計算であることに注意)

1. nj = 1;

2. for (ni=0; ni < log2(nprc); ni++) 3. if ( (myid & nj) == nj) • (myid – nj)番プロセスからデータを受信; • 自分のデータと、受信データを加算する; • nj = nj * 2; 4. else • (myid + nj)番プロセスに、データを転送する; • 処理を終了する;

(73)

総和演算プログラム(Wa2, 二分木通信方式)

0 1 2 3 4 5 6 7 1段目 1 3 5 7 2段目 3 7 3段目=log2(8)段目 0 1 2 3 4 5 6 7 1 3 5 7 3 7 7

(74)

総和演算プログラム(Wa2, 二分木通信方式)

 実装上の工夫 • 要点: プロセス番号の2進数表記の情報を利用する • 第ni段において、受信するプロセスの条件は、以下で書ける: myid & nj が nj と一致 ここで、nj = 2^(ni-1) 。 つまり、プロセス番号の2進数表記で右からni番目のビットが立っているプロ セスが、送信することにする • また、送信元のプロセス番号は、以下で書ける: myid + nj つまり 、通信が成立するプロセス番号の間隔は2^(ni-1)←二分木なので • 送信プロセスについては、上記の逆が成り立つ。

(75)

総和演算プログラム(Wa2, 二分木通信方式)

 逐次転送方式の通信回数 明らかに、nprocs-1 回  二分木通信方式の通信回数 • 見積もりの前提 • 各段で行われる通信は、完全に並列で行われる (通信の衝突は発生しない) • 段数の分の通信回数となる • つまり、log2(nprocs) 回  両者の通信回数の比較 • プロセッサ台数が増すと、通信回数の差(=実行時間)が とても大きくなる • 1024プロセス構成では、1023回 対 10回! • でも、必ずしも二分木通信方式がよいとは限らない(通信衝突の多発)

(76)

レポート課題(II)

3. 逐次転送方式、2分木通信方式の実行時間を計測(MPI_Wtime 関数の利用)し、どの方式が何台のプロセッサ台数で有効となる かを明らかにせよ。また、その理由について考察せよ。 4. 二分木通信方式について、プロセッサ台数が2のべき乗でないと きにも動作するように、プログラムを改良せよ。 5. MPIとOpenMPとは何か?それぞれについて説明せよ。 下記について、レポートとしてまとめよ。

(77)

Reedbushを利用する上での注意

 Reedbushを利用する上で不明な点があったら、ポータル上にマニュアルが ありますので、それを参考にしてください。 https://reedbush-www.cc.u-tokyo.ac.jp/  それでも解決しない場合は、まずは松本に聞いてください。情報基盤セン ターへ直接問い合わせることは止めてください。  この先、計算科学概論でReedbushを使うか使わないかは各先生によって 異なります。使う先生もいれば、使わない先生もいます。  Reedbushのアカウントは(おそらく)8月末で消滅しますので、それまでに バックアップ等が必要な方は各自の責任でお願いします。  アカウントが消滅するまでは自由に使えますので、余力のある人はGPUを 使った計算などにも是非チャレンジしてみて下さい。(何も説明しないけど。)

参照

関連したドキュメント

といったAMr*&#34;&#34;&#34;erⅣfg&#34;'sDreα

 第1報Dでは,環境汚染の場合に食品中にみられる

※ 硬化時 間につ いては 使用材 料によ って異 なるの で使用 材料の 特性を 十分熟 知する こと

[r]

※証明書のご利用は、証明書取得時に Windows ログオンを行っていた Windows アカウントでのみ 可能となります。それ以外の

(自分で感じられ得る[もの])という用例は注目に値する(脚注 24 ).接頭辞の sam は「正しい」と

34 V1_top Vertical phase 1, top of die 35 LOD_top Lateral overflow drain, top of die 36 VDD_d Amplifier supply, Output D 37 VOUT_d Video output D.. 38 VSS_d Amplifier return, Output