KOBE HPC サマースクール 2024（初級）12. 熱伝導問題の並列計算
13．ハイブリッド並列2024/8/29

KOBE HPCサマースクール 20241

2次元熱伝導問題
2次元正方形領域 [0,1]×[0,1] に一定の熱を加え続けた時の領域の温度がどうな境界で0.0るか？
𝜕𝑢𝜕2𝑢 𝜕2𝑢= ∆𝑢 + 40 =+ 2 + 40 → 02
𝜕𝑡
𝜕𝑥
𝜕𝑦

境界条件
𝑢 0, 𝑦 = 0.0 (0 ≤ 𝑦 ≤ 1)

𝑢 1, 𝑦 = 0.0 (0 ≤ 𝑦 ≤ 1)

2024/8/29

𝑢 𝑥, 0 = 0.0(0 ≤ 𝑥 ≤ 1)

𝑢 𝑥, 1 = 0.0(0 ≤ 𝑥 ≤ 1)

KOBE HPCサマースクール 20242熱伝導方程式の差分表現
空間（𝑥および𝑦方向）2階微分 ⇒ 中心差分𝑡𝑡𝑡
𝜕2 𝑢 𝑢𝑖+1,𝑗 −2𝑢𝑖,𝑗 +𝑢𝑖−1,𝑗~,𝜕𝑥 2(Δ𝑥)2𝑡𝑡𝑡
𝜕2 𝑢 𝑢𝑖,𝑗+1 −2𝑢𝑖,𝑗 +𝑢𝑖,𝑗−1~
𝜕𝑦 2(Δ𝑦)2

時間微分 ⇒ 前進差分𝑡+∆𝑡𝑡− 𝑢𝑖,𝑗𝜕𝑢 𝑢𝑖,𝑗~𝜕𝑡∆𝑡

熱伝導方程式の差分表現𝑡+∆𝑡𝑡𝑢𝑖,𝑗− 𝑢𝑖,𝑗∆𝑡
2024/8/29=𝑡𝑡
𝑡𝑢𝑖+1,𝑗− 2𝑢𝑖,𝑗+ 𝑢𝑖−1,𝑗(Δ𝑟)2+𝑡𝑡
𝑡𝑢𝑖,𝑗+1− 2𝑢𝑖,𝑗+ 𝑢𝑖,𝑗−1

KOBE HPCサマースクール 2024(Δ𝑟)2+ 403

温度の時間発展方程式の導出
差分表現に直した熱伝導方程式を変形∆𝑡∆𝑡𝑡𝑡𝑡𝑡𝑡𝑡𝑢−2𝑢+𝑢+𝑢−2𝑢+𝑢𝑖+1,𝑗𝑖,𝑗𝑖−1,𝑗𝑖,𝑗+1𝑖,𝑗𝑖,𝑗−1 + 40∆𝑡22(Δ𝑟)(Δ𝑟)
4∆𝑡∆𝑡𝑡+∆𝑡𝑡𝑡𝑡𝑡𝑡𝑇𝑖= 1−𝑢+𝑢+𝑢+𝑢+𝑢𝑖,𝑗𝑖+1,𝑗𝑖−1,𝑗𝑖,𝑗+1𝑖,𝑗−1 + 40∆𝑡22(Δ𝑟)(Δ𝑟)𝑡+∆𝑡𝑡𝑢𝑖,𝑗= 𝑢𝑖,𝑗+𝑡𝑡𝑡𝑡𝑡
𝑇𝑖𝑡+∆𝑡 = 𝛼𝑢𝑖,𝑗+ 𝛽 𝑢𝑖+1,𝑗+ 𝑢𝑖−1,𝑗+ 𝑢𝑖,𝑗+1+ 𝑢𝑖,𝑗−1+ 40∆𝑡,

ただし，𝛼 = 1 − 4𝛽,∆𝑡∆𝑡𝛽=．ここで，𝛽 ==0.25とすると…
22(Δ𝑟)(Δ𝑟)𝑡+∆𝑡𝑡𝑡𝑡𝑡𝑢𝑖,𝑗= 0.25 𝑢𝑖+1,𝑗+ 𝑢𝑖−1,𝑗+ 𝑢𝑖,𝑗+1+ 𝑢𝑖,𝑗−1+ 10(Δ𝑟)2
2024/8/29

KOBE HPCサマースクール 20244有限差分法による熱伝導問題の解法
温度時間発展計算のアルゴリズム
for( i=1; i<=N; i++ ) {for( j=1; j<=N; j++ ) {ui,j(m+1) = (ui-1,j(m)+ui+1,j(m)+ui,j-1(m)+ui,j+1(m))*0.25 + 10.0*dx*dx;};};2024/8/29

KOBE HPCサマースクール 20245

演習12a：プログラム heat2d.c の実行
2次元熱伝導問題の逐次プログラム heat2d.c をコンパイルして実行せよ．
cp /home/guest60/share/heat2d.c ./$ icx heat2d.c$ ./a.out$[Fortran]$
cp /home/guest60/share/heat2d.f90 ./$ifx heat2d.f90$./a.out

プログラムでは N = 128 の時に，反復ベクトルの差のm+1m
ノルム 𝑢𝑖,𝑗− 𝑢𝑖,𝑗が閾値 𝜖 = 1.0 × 10−3 より2小さくなったら反復を停止している．
プログラム実行が正常に完了したら「To visualize data,…」というメッセージが出てくる．これの指示に従うと計算結果をpng画像ファイルに出力できる（gnuplot を用いる．事前に「module load gnuplot」で使用環境を load する）．
2024/8/29

KOBE HPCサマースクール 20246

heat2d.c のMPIによる並列化（Cの場合）
並列化のヒント
1. 2次元配列 u（𝑢 𝑚 ），u_new（𝑢 𝑚+1 ）をブロック行分割しておく．
2. u[is:ie][] の計算をする前に，- 上のプロセスの u の ie 行を下のプロセスの (is-1) 行へ，- 下のプロセスの u の is 行を上のプロセスの (ie+1) 行へ，送る．
並列化 sr_matrix.c を参考にして，MPI_Sendrecv を用いて送受信．

3. u の is ～ ie 行の計算を行う．計算結果は u_new に格納．

上下のプロセスから1行を受信（受信用の領域を確保しておく）

4. 反復ベクトルの差のノルムの部分和を計算し，MPI_Allreduce で総和を取り，収束の判定を行うようにする．
ローカルで残差の部分和を計算し，各プロセスでノルムを計算する．
5. u_new を u に入れなおして，手順2に戻る．
2024/8/29

KOBE HPCサマースクール 2024

7heat2d.f90 のMPIによる並列化（Fortranの場合）
並列化のヒント
1. 2次元配列 u（𝑢 𝑚 ），u_new（𝑢 𝑚+1 ） をブロック列分割しておく．
2. U(:,js:je) の計算をする前に，- 左のプロセスの u の je 列を右のプロセスの (js-1) 列へ，左右のプロセスから1行を受信- 右のプロセスの u の js 列を左のプロセスの (je+1) 列へ，（受信用の領域を確保しておく）送る．
並列化 sr_matrix.f90 を参考にして，MPI_Sendrecv を用いて送受信．

3. u の js ～ je 列の計算を行う．計算結果は u_new に格納．

4. 反復ベクトルの差のノルムの部分和を計算し，MPI_Allreduce で総和を取り，収束の判定を行うようにする．
ローカルで残差の部分和を計算し，各プロセスでノルムを計算する．
5. u_new を u に入れなおして，手順2に戻る．
2024/8/29

KOBE HPCサマースクール 20248

Cの場合の処理のイメージ※Fortranの場合はこれを横に寝かしたようなイメージになる

2024/8/29

rank #0#0がupdateすべき計算格子rank #1#1がupdateすべき計算格子rank #2#2がupdateすべき計算格子rank #3#3がupdateすべき計算格子KOBE HPCサマースクール 20249

Cの場合の処理のイメージ#1はこの範囲の格子点データを持つようにする．

※Fortranの場合は rank #0
これを横に寝かしたようなイメージにrank #1
なるrank #2#2はこの範囲の格子点データを持つようにする．

rank #3

2024/8/29

KOBE HPCサマースクール 202410

ファイルへのデータ出力について
各プロセスは分割された小領域のみ計算を担当
不完全なデータ

2次元配列（ブロック行分割）

rank 0rank 1
rank 2
rank 3

出力

ここは値が0.0

全体領域をファイル出力するためには温度データをプロセス0に集約する必要がある．
⇒ プログラム中の「data output」の直前のタイミング（計3箇所）で実施
2024/8/29

KOBE HPCサマースクール 202411

ファイルへのデータ出力について
データ集約の仕方：配列として全領域を確保している場合⇒ MPI_Reduce を利用

rank 0に完全なデータ⇒ファイル出力集約＋＋＋

注意：各プロセスのデータに重複があると，その部分の値が不正になる

2024/8/29

KOBE HPCサマースクール 202412

ファイルへのデータ出力について
データ集約の仕方：配列として部分領域のみ確保している場合
rank 0に⇒ MPI_Gather を利用
完全なデータ⇒ファイル出力

2024/8/29

KOBE HPCサマースクール 202413

演習12b：heat2d.{c/f90} の並列化
heat2d.c，heat2d.f90 をMPIを用いて並列化せよ．
計算結果を gnuplot 等で図示し，非並列版と同じ結果になることを確認せよ．
計算結果の出力は，プロセス 0 にデータを集め※，ファイルに出力する．
集め方（通信の仕方）は複数ある．考えてみよ．

N=128とし，プロセス数1, 2, 4, 8 として，反復開始から終了までの計算時間を計測し，速度向上率を求めよ．また，それをグラフにせよ．
時間計測時は反復計算途中データのファイル出力を OFF にすると良い．
プログラム中のパラメータ INTV の値を 1 にするとデータのファイル出力が抑制される．
ファイル出力がないので，通信によるデータの収集（上述の※）も反復計算中は必要ない．

2024/8/29

KOBE HPCサマースクール 202414演習13：ハイブリッド並列化
MPI を用いて並列化した heat2d.{c/f90} に，さらに OpenMP のディレクティブを挿入し，スレッド並列とプロセス並列の併用により，実行時間が削減されるこかどうか確認せよ．
#pragma omp parallel などを利用する（C言語）．
冒頭で omp.h をインクルードするのを忘れずに（C言語）．
!$OMP parallel などを利用する（Fortran言語）．
冒頭で !$ use omp_lib を宣言するのを忘れずに（Fortran言語）．
一般にハイブリッド並列はプロセス・スレッド並列単体より高度な並列実装であるが，速度上のメリットが得られるかどうかは，計算の内容や計算機の仕様に依存する．

コンパイルicx –qopenmp xxxxx.c –lmpi
ifx –qopenmp xxxxx.f90 -lmpi
2024/8/29

KOBE HPCサマースクール 202415

【サンプル】Hybrid並列プログラムの実行シェル（jobh.sh）#!/bin/bash

ジョブ名の指定
キューの設定：スクール専用キューWS#PBS -N hybrid#PBS -q WS#PBS -j oe#PBS -l select=4:ncpus=16:mpiprocs=2

select:
計算ノード数ncpus :
1計算ノード内のコア数
mpiprocs: 1計算ノード内のMPIプロセス数

source /etc/profile.d/modules.shmodule load intel
module load mpt
export KMP_AFFINITY=disabledexport OMP_NUM_THREADS=8
cd ${PBS_O_WORKDIR}
mpiexec_mpt omplace -nt ${OMP_NUM_THREADS} ./a.out

2024/8/29

KOBE HPCサマースクール 2024

16

#PBS -l select=N:ncpus=T:mpiprocs=M
T：
M：
N：
NM:

1ノード（共有メモリ）のコア数（≦40）
1ノードのMPIプロセス数
全ノード数
全MPIプロセス数

例えば，コア数を 16，全MPIプロセスを 8 とすると，以下のようなマッピングが考えられる．この
場合，スレッド#PBS -l select=4:ncpus=16:mpiprocs=2

ノード
2024/8/29

KOBE HPCサマースクール 2024

17上級者になるために．．．
大規模問題を解く場合には，1プロセスのメモリ使用容量を少なくする必要が出てくる．
今回のプログラムでは，どのプロセスも u[N+2][N+2], u_new[N+2][N+2] として，計算全領域の変数を宣言したが，外側の領域

PE0

u[N/nprocs+2][N+2]u_new[N/nprocs][N+2]

各プロセスは，これだけの大きさをもてば良いはず．

実行前から並列数（nprocs）が固定されていれば，上記のように，プログラムの先頭で小さい領域を宣言することも出来るが，汎用のプログラムとしては，nprocs を実行開始時に決めたい．
配列を動的に確保する必要がある（C言語：malloc 関数、Fortran言語：allocate文） ．
サンプルプログラム /home/guest60/share/alloc_heat2d.c もしくは alloc_heat3d.f90

2024/8/29

KOBE HPCサマースクール 202418