poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675...

123
Poisson方程式の求解 (線形連立一次方程式) 長岡技術科学大学 電気電子情報工学専攻 出川智啓

Upload: vuongque

Post on 20-May-2019

219 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Poisson方程式の求解(線形連立一次方程式)

長岡技術科学大学 電気電子情報工学専攻 出川智啓

Page 2: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

今回の内容

2015/06/18先端GPGPUシミュレーション工学特論675

偏微分方程式の分類

Laplace方程式とその解法 Jacobi法,Gauss‐Seidel法,SOR法

2次元Laplace方程式

共役勾配法

SOR法(RB‐SOR法)

Page 3: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

偏微分方程式の簡単な分類

2015/06/18先端GPGPUシミュレーション工学特論676

2個の独立変数f(x,y)に対する2階線形偏微分方程式 A, B, C, D, E, F, Gは定数もしくはx, yの関数

高階(2階)微分の係数による分類

02

22

2

2

GFf

yfE

xfD

yfC

yxfB

xfA

B2‐4AC 型 物理的挙動

=0 放物型 時間発展

>0 双曲型 時間発展

<0 楕円型 空間平衡

Page 4: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

放物型

2015/06/18先端GPGPUシミュレーション工学特論677

2

2

xf

xfc

tf

移流拡散方程式

−A=(>0), D=c, E=1, B=C=F=G=0 yをtと形式的に置換

移流項によってfが形を保ったまま速度cで移流

拡散項によってfの形状がなだらかに減衰

計算するためには初期値とt>0における境界値が必要

初期値・境界値問題

Page 5: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

双曲型

2015/06/18先端GPGPUシミュレーション工学特論678

波動方程式

−A=c2, C=1, B=D=E=F=G=0 yをtと形式的に置換

時間的に振動する問題を記述

fは時刻t,位置xにおける振動の変位

cは振動の位相速度

計算するためには初期値とt>0における境界値が必要

初期値・境界値問題

2

22

2

2

xfc

tf

Page 6: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

楕円型

2015/06/18先端GPGPUシミュレーション工学特論679

Laplace方程式

A=1, C=1, B=D=E=F=G=0 G≠0の場合はPoisson方程式

式中に時間微分項が存在しない

fの平衡状態(時間的変化が0の定常状態)を表す

計算するためには境界値が重要

境界値問題

02

2

2

2

yf

xf

Page 7: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Laplace方程式

2015/06/18先端GPGPUシミュレーション工学特論680

順問題 関数fの値・形が既知

2階微分を計算

逆問題 関数fのラプラシアンが0 関数fの形状を推定

?2

2

2

2

yf

xf

f

02

2

2

2

yf

xf

?f

Page 8: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Laplace方程式の離散化

x方向2階偏微分の離散化 y方向を固定してx方向に偏微分

y方向2階偏微分の離散化 x方向を固定してy方向に偏微分

2,1,,1

22

2 2),(),(2),(Δx

fffΔx

yΔxxfyxfyΔxxfxf jijiji

21,,1,

22

2 2),(),(2),(Δy

fffΔy

ΔyyxfyxfΔyyxfyf jijiji

先端GPGPUシミュレーション工学特論681 2015/06/18

Page 9: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Laplace方程式の離散化

Laplace方程式

離散化までは拡散方程式と同じ fが未知

離散化されたf同士の関係(差分式)と境界条件から推定

022

21,,1,

2,1,,1

2

2

2

2

Δyfff

Δxfff

yf

xf jijijijijiji

先端GPGPUシミュレーション工学特論682 2015/06/18

Page 10: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

1次元Laplace方程式

2015/06/18先端GPGPUシミュレーション工学特論683

x方向のみを考慮

L=4を5個の離散点に分割 各位置iでの差分式(i=1,5では境界条件が必要)

02

02

02

2543

2432

2321

Δxfff

Δxfff

Δxfff

022

112

2

Δxfff

xf iii

Page 11: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

1次元Laplace方程式

2015/06/18先端GPGPUシミュレーション工学特論684

境界条件(左の境界でf=0, 右の境界でf=1)を課す

f1~f5を未知数とした連立一次方程式

1

02

02

020

5

2543

2432

2321

1

fΔx

fffΔx

fffΔx

ffff

L

f

Page 12: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

1次元Laplace方程式

2015/06/18先端GPGPUシミュレーション工学特論685

行列を用いた表記 係数行列Aの逆行列A−1を左からかければfが求められる

逆行列の計算は計算負荷が高く,多くの誤差が混入

連立一次方程式の求解法を利用してfを求める

10000

1121

121121

1

5

4

3

2

1

fffff

Ax=b

Page 13: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

連立一次方程式の解法

2015/06/18先端GPGPUシミュレーション工学特論686

直接法

係数行列を単位行列(や上三角,下三角行列)に変形することで未知数を求める方法

所定の計算回数で解が得られる

計算量が多く,大規模な問題には適用できない

反復法

係数行列を変更せず,未知数に推定値を代入して所定の計算を行い,推定値が厳密解に十分近づくまで計算を繰り返す方法

よい推定値を選べば非常に高速に解が得られる

Page 14: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Jacobi法

2015/06/18先端GPGPUシミュレーション工学特論687

未知数=...の形に変形し近似値を繰り返し計算 初期の推定値f(0)を基にf(1), f(2), f(3),..., f(m)を計算

f(m)の誤差が十分小さくなればf(m)を解とする(反復が収束)

f(m)を元の方程式に代入して右辺と比較する 等

5.020

020020

5)0(

3)1(

4

)0(4

)0(2

)1(3

)0(31

)1(2

ffffff

fff

1

02

02

020

5

2543

2432

2321

1

fΔx

fffΔx

fffΔx

ffff

Page 15: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Jacobi法

2015/06/18先端GPGPUシミュレーション工学特論688

未知数=...の形に変形し近似値を繰り返し計算 初期の推定値f(0)を基にf(1), f(2), f(3),..., f(m)を計算

f(m)の誤差が十分小さくなればf(m)を解とする(反復が収束)

f(m)を元の方程式に代入して右辺と比較する 等

5.020

25.020020

5)1(

3)2(

4

)1(4

)1(2

)2(3

)1(31

)2(2

ffffff

fff

1

02

02

020

5

2543

2432

2321

1

fΔx

fffΔx

fffΔx

ffff

Page 16: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Jacobi法

2015/06/18先端GPGPUシミュレーション工学特論689

未知数=...の形に変形し近似値を繰り返し計算 初期の推定値f(0)を基にf(1), f(2), f(3),..., f(m)を計算

f(m)の誤差が十分小さくなればf(m)を解とする(反復が収束)

f(m)を元の方程式に代入して右辺と比較する 等

625.020

25.020125.020

5)2(

3)3(

4

)2(4

)2(2

)3(3

)2(31

)3(2

ffffff

fff

1

02

02

020

5

2543

2432

2321

1

fΔx

fffΔx

fffΔx

ffff

Page 17: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Jacobi法

2015/06/18先端GPGPUシミュレーション工学特論690

未知数=...の形に変形し近似値を繰り返し計算 初期の推定値f(0)を基にf(1), f(2), f(3),..., f(m)を計算

f(m)の誤差が十分小さくなればf(m)を解とする(反復が収束)

f(m)を元の方程式に代入して右辺と比較する 等

625.020

375.020125.020

5)4(

3)4(

4

)4(4

)4(2

)4(3

)4(31

)4(2

ffffff

fff

1

02

02

020

5

2543

2432

2321

1

fΔx

fffΔx

fffΔx

ffff

Page 18: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Gauss-Seidel法

2015/06/18先端GPGPUシミュレーション工学特論691

既に計算したf(m+1)の値を同一反復内で利用 更新した値を順次使用するため収束が速くなる

5.020

020020

5)1(

3)1(

4

)0(4

)1(2

)1(3

)0(31

)1(2

ffffff

fff

625.020

25.020020

5)2(

3)2(

4

)1(4

)2(2

)2(3

)1(31

)2(2

ffffff

fff

Gauss‐Seidel法Jacobi法

5.020

020020

5)0(

3)1(

4

)0(4

)0(2

)1(3

)0(31

)1(2

ffffff

fff

5.020

25.020020

5)1(

3)2(

4

)1(4

)1(2

)2(3

)1(31

)2(2

ffffff

fff

Page 19: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Gauss-Seidel法

2015/06/18先端GPGPUシミュレーション工学特論692

既に計算したf(m+1)の値を同一反復内で利用 更新した値を順次使用するため収束が速くなる

0.68820

0.37520125.020

5)3(

3)3(

4

)2(4

)3(2

)3(3

)2(31

)3(2

ffffff

fff

0.71920

0.438200.187520

5)4(

3)4(

4

)3(4

)4(2

)4(3

)3(31

)4(2

ffffff

fff

Gauss‐Seidel法Jacobi法

625.020

25.020125.020

5)2(

3)3(

4

)2(4

)2(2

)3(3

)2(31

)3(2

ffffff

fff

625.020

375.020125.020

5)3(

3)4(

4

)3(4

)3(2

)4(3

)3(31

)4(2

ffffff

fff

Page 20: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

SOR法(逐次過緩和法, Successive 0ver-Relaxation)

2015/06/18先端GPGPUシミュレーション工学特論693

近似解の修正量に係数をかけて過剰に修正 加速係数が0<<2の範囲で収束

1<<2を取ると収束が加速

0<<1なら収束が減速

696.020

36.020020

)1(45

)2(3

)1(4

)2(4

)1(3

)1(4

)2(2

)1(3

)2(3

)1(2

)1(31

)1(2

)2(2

ffffffffff

fffff

6.020

020020

)0(45

)1(3

)0(4

)1(4

)0(3

)0(4

)1(2

)0(3

)1(3

)0(2

)0(31

)0(2

)1(2

ffffffffff

fffff

2.1

Page 21: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

SOR法(逐次過緩和法, Successive 0ver-Relaxation)

2015/06/18先端GPGPUシミュレーション工学特論694

近似解の修正量に係数をかけて過剰に修正 加速係数が0<<2の範囲で収束

1<<2を取ると収束が加速

0<<1なら収束が減速

749.020

498.020242.020

)3(45

)4(3

)3(4

)4(4

)3(3

)3(4

)4(2

)3(3

)4(3

)3(2

)3(31

)3(2

)4(2

ffffffffff

fffff

746.020

475.020216.020

)2(45

)3(3

)2(4

)3(4

)2(3

)2(4

)3(2

)2(3

)3(3

)2(2

)2(31

)2(2

)3(2

ffffffffff

fffff

2.1

Page 22: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

共役勾配法

2015/06/18先端GPGPUシミュレーション工学特論695

Jacobi法などとは異なる種類の反復解法

係数行列が対称である連立一次方程式が対象

丸め誤差が無ければ所定の回数で収束 丸め誤差に弱く,所定の回数で収束しないこともある

Page 23: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

共役勾配法のアルゴリズム

2015/06/18先端GPGPUシミュレーション工学特論696

Compute r0=b−Ax0. Set p0−1=0,−1=0.

For m=0,1,…, until ||r||/||b|| < , Do

p(m) = r(m)+(m−1)p(m−1)

(m) = (r(m), r(m))/(p(m), Ap(m))

x(m+1) = x(m)+(m)p(m)

r(m+1) = r(m)−(m)Ap(m)

(m) = (r(m+1), r(m+1))/{(m)(p(m), Ap(m))}

EndDo Apは係数行列Aとベクトルpの積( , )はベクトル同士の内積||・||はl2−ノルム

Page 24: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

2次元Laplace方程式

2015/06/18先端GPGPUシミュレーション工学特論697

1方向から加熱される金属板の温度分布 Laplace方程式

境界条件

1℃

0℃0℃

0℃

B2

B1

B3

B4

4

3

2

1

on 0on 0on 1on 0

BTBTBTBT

02

2

2

2

yT

xT

xy

Page 25: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

2次元Laplace方程式

2015/06/18先端GPGPUシミュレーション工学特論698

1方向から加熱される金属板の温度分布 Laplace方程式

計算条件

計算領域 Lx=2, Ly=2 離散点の数 Nx=3, Ny=3 格子間隔 x=y=h

02

2

2

2

yT

xT

xy

0

i

1 20

1

2

j

Page 26: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

2次元Laplace方程式

2015/06/18先端GPGPUシミュレーション工学特論699

1方向から加熱される金属板の温度分布 Laplace方程式

Laplace方程式の差分式

02

2

2

2

yT

xT

0

i

1 2

0

1

2

j

T[i][j]

022

21,,1,

2,1,,1

yTTT

xTTT jijijijijiji

04

21,,1,1,,1

hTTTTT jijijijiji

Page 27: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

2次元Laplace方程式

2015/06/18先端GPGPUシミュレーション工学特論700

1方向から加熱される金属板の温度分布 Laplace方程式

Laplace方程式の差分式

0

i

1 2

0

1

2

j

T[]

0 1 2

3 4 5

6 7 8

0222

1472

345

yTTT

xTTT

042

13475

h

TTTTT

02

2

2

2

yT

xT

Page 28: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

連立一次方程式

2015/06/18先端GPGPUシミュレーション工学特論701

Tに関する9元連立一次方程式を解く

111000000

11

11

114111

11

1

8

7

6

5

4

3

2

1

0

TTTTTTTTT

Ax=b

Page 29: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

連立一次方程式

2015/06/18先端GPGPUシミュレーション工学特論702

行列Aを保持する必要は無い SOR法はT=… の形を作り,反復計算を行う

変形した式をプログラムに記述周囲が全て固定値の境界条件なので1回の反復で収束

1110

40000

7531

8

7

6

5

)(4

3

2

1

0

TTTT

TTTT

TTTTT

m

Page 30: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

連立一次方程式

2015/06/18先端GPGPUシミュレーション工学特論703

行列Aを保持する必要は無い 共役勾配法は行列-ベクトル積Axの結果がわかればよい

行列-ベクトル積を計算して得られた式をプログラムに記述

8

7

6

5

75431

3

2

1

0

8

7

6

5

4

3

2

1

0

4

11

11

114111

11

1

TTTT

TTTTTTTTT

TTTTTTTTT

Page 31: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

#include<stdio.h>#include<stdlib.h>#include<math.h>

#define Lx 2.0#define Ly Lx#define Nx 11#define Ny Ny#define dx (Lx/(Nx‐1))#define dy dx#define dxdx (dx*dx)#define dydy (dy*dy)#define Nbytes (Nx*Ny*sizeof(double))#define ERR_TOL 1e‐12#define Accel 1.0

void sor(double *T);void cg(double *T);void init(double *T){

for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){

T[i+Nx*j] = 0.0;}}

}

int main(void){

double *T;T = (double *)malloc(Nbytes);

init(T);sor(T)//cg(T);

return 0;}

CPUプログラム(メイン・初期化)

2015/06/18先端GPGPUシミュレーション工学特論704

laplace.c

Page 32: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

void sor(double *T){int ite_SOR=0;double err_n,err_d,err_relative;double d_t;int ij,ip1j,im1j,ijm1,ijp1;//境界条件の適用for(int i=0;i<Nx;i++){ij = i+Nx*(Ny‐1); //j=Ny‐1T[i+Nx*j] = 1.0;

}

do{err_n = 0.0;err_d = 0.0;

for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );

im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);d_t =( (T[im1j]+T[ip1j])

+(T[ijm1]+T[ijp1]))/(‐4.0) ‐T[ij];

T[ij] += Accel*d_t;err_n += d_t*d_t;err_d += T[ij]*T[ij];

}}

if(err_d<1e‐20)err_d=1.0;err_relative = sqrt(err_n/err_d);ite_SOR++;

}while(err_relative > ERR_TOL);}

CPUプログラム(SOR法)

2015/06/18先端GPGPUシミュレーション工学特論705

laplace.c

Page 33: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

void cg(double *T){double err;int ij,ip1j,im1j,ijm1,ijp1;double *p,*r,*Ap;double alph,beta,rr,pAp;//境界条件の適用for(int i=0;i<Nx;i++){ij=i+Nx*(Ny‐1);//j=Ny‐1T[i+Nx*j] = 1.0;

}

p  = (double *)malloc(Nbytes);r  = (double *)malloc(Nbytes);Ap = (double *)malloc(Nbytes);for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;p [ij] = 0.0;r [ij] = 0.0;

Ap[ij] = 0.0;}}alph=0.0;beta=0.0;

rr = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);r[ij] = ‐( (T[im1j]‐2*T[ij]+T[ip1j])/dxdx

+(T[ijm1]‐2*T[ij]+T[ijp1])/dydy);

rr += r[ij]*r[ij];}}

CPUプログラム(共役勾配法)

2015/06/18先端GPGPUシミュレーション工学特論706

laplace.c

Page 34: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

do{for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;p [ij] = r[ij] + beta*p[ij];

}}

pAp = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);Ap[ij] = (p[im1j]‐2*p[ij]+p[ip1j])/dxdx

+(p[ijm1]‐2*p[ij]+p[ijp1])/dydy;

pAp += p[ij]*Ap[ij];

}}alph = rr/pAp;

rr = 0.0;for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;T[ij] = T[ij] + alph* p[ij];r[ij] = r[ij] ‐ alph*Ap[ij];rr += r[ij]*r[ij];

}}err = sqrt(rr);beta = rr/(alph*pAp);

}while(err > ERR_TOL);}

CPUプログラム(共役勾配法)

2015/06/18先端GPGPUシミュレーション工学特論707

laplace.c

Page 35: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

反復の収束判定

2015/06/18先端GPGPUシミュレーション工学特論708

誤差 真の値からのズレ

近似値 =真値r+誤差

誤差

絶対誤差

相対誤差

rr ˆ

rr ˆ

rrr ˆ

Page 36: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

反復の収束判定

2015/06/18先端GPGPUシミュレーション工学特論709

ベクトル量における誤差の評価 lp−ノルム(pは整数)

l1−ノルム

l2−ノルム

l∞−ノルム

pN

i

p

iip xxl ˆx2

x1

x

22111 ˆˆ xxxxl

2

22

2

112 ˆˆ xxxxl

2211 ˆ,ˆmax xxxxl

11 x̂x

22 x̂x

Page 37: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

反復の収束判定

2015/06/18先端GPGPUシミュレーション工学特論710

l2−ノルムを用いた相対誤差評価

m+1回目の反復の値が真値になれば誤差と一致

反復中に変化量が十分小さくなれば収束と判定

x2

y x

y x

N

j

N

i

mji

N

j

N

i

mji

mji

T

TT

2)1(,

2)(,

)1(,

err_n = 0.0;err_d = 0.0;

for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){

d_t =( (T[im1j]+T[ip1j])+(T[ijm1]+T[ijp1])

)/(‐4.0)  ‐T[ij];T[ij] += Accel*d_t;err_n += d_t*d_t;err_d += T[ij]*T[ij];

}}

if(err_d<1e‐20)err_d=1.0;err_relative = sqrt(err_n/err_d);

Page 38: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

反復の収束判定

2015/06/18先端GPGPUシミュレーション工学特論711

残差 方程式の解に近似値を用いたことによって生じる不整合

残差rの定義

誤差と残差 誤差の計算には真の解が必要

残差は方程式の係数と右辺値がわかれば計算できる

xAbr ˆ

Page 39: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

反復の収束判定

2015/06/18先端GPGPUシミュレーション工学特論712

残差の2乗ノルムを用いた収束判定 右辺の2乗ノルムを用いた相対残差を計算 x2

y x

y x

N

j

N

iji

N

j

N

i

mji

b

r

2,

2)1(,

rr = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){

ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);r[ij] = ‐( (T[im1j]‐2*T[ij]+T[ip1j])/dxdx

+(T[ijm1]‐2*T[ij]+T[ijp1])/dydy);rr += r[ij]*r[ij];

}}・・・//右辺が0でなければ右辺のl2ノルムbbで//割った値の平方根sqrt(rr/bb)を評価err = sqrt(rr);

Page 40: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

計算結果

2015/06/18先端GPGPUシミュレーション工学特論713

前回授業で用いたgnuplotのanim_2d.gplを流用して2次元分布を確認

set xrange [0:2] x軸の表示範囲を0~2に固定set yrange [0:2] y軸の表示範囲を0~2に固定set zrange [0:1] z軸の表示範囲を0~1に固定set view 0,0 真上から見下ろすset size 1,1 グラフの縦横比を1:1set contour 2次元等高線を表示unset surface 3次元で等値面を表示しないunset pm3d カラー表示しないset cntrparam levels incremental 0,0.1,1

等高線を0から1まで0.1刻みに設定以下でファイルを読み込み,3次元表示splot 'T.txt' with line  

Page 41: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

計算結果

2015/06/18先端GPGPUシミュレーション工学特論714

前回授業で用いたgnuplotのanim_2d.gplを流用して2次元分布を確認

set xrange [0:2] x軸の表示範囲を0~2に固定set yrange [0:2] y軸の表示範囲を0~2に固定set zrange [0:1] z軸の表示範囲を0~1に固定set view 0,0 真上から見下ろすset size 1,1 グラフの縦横比を1:1unset contour 2次元等高線を表示unset surface 3次元で等値面を表示しないset pm3d カラー表示しない以下でファイルを読み込み,3次元表示splot 'T.txt' with line  

Page 42: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Poisson方程式への拡張

2015/06/18先端GPGPUシミュレーション工学特論715

Poisson方程式

離散化 右辺が0ではなく関数gの値

gyf

xf

2

2

2

2

jijijijijijiji g

Δyfff

Δxfff

yf

xf

.21,,1,

2,1,,1

2

2

2

2 22

Page 43: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

SOR法で用いる式の拡張

2015/06/18先端GPGPUシミュレーション工学特論716

xとyが等しくない場合 差分式を変形してfi,j=… の形に変形

jijijijijijiji g

Δyfff

Δxfff

.21,,1,

2,1,,1 22

21,1,

2,1,1

.,22

112Δy

ffΔx

ffgf

ΔyΔxjijijiji

jiji

22

22

21,1,

2,1,1

.,2

ΔyΔxΔyΔx

Δyff

Δxff

gf jijijijijiji

Page 44: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

#define dxdxdydy (dxdx*dydy)#define dxdy2 (2.0*(dxdx+dydy))

void sor(double *f, double *g){int ite_SOR=0;double err_n,err_d,err_relative;double d_f;int ij,ip1j,im1j,ijm1,ijp1;do{err_n = 0.0;err_d = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);d_f =( (f[im1j]+f[ip1j])/dxdx

+(f[ijm1]+f[ijp1])/dydy‐(g[ij]) //右辺の影響)*dxdxdydy/dxdy2 ‐f[ij];

f[ij] += Accel*d_f;err_n += d_f*d_f;err_d += f[ij]*f[ij];

}}

if(err_d<1e‐20)err_d=1.0;err_relative = sqrt(err_n/err_d);ite_SOR++;

}while(err_relative > ERR_TOL);

}

CPUプログラム(SOR法)

2015/06/18先端GPGPUシミュレーション工学特論717

poisson.c

Page 45: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

#define dxdxdydy (dxdx*dydy)#define dxdy2 (2.0*(dxdx+dydy))

void sor(double *f, double *g){int ite_SOR=0;double err_n,err_d,err_relative;double d_f;int ij,ip1j,im1j,ijm1,ijp1;do{err_n = 0.0;err_d = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);d_f =( (f[im1j]+f[ip1j])/dxdx

+(f[ijm1]+f[ijp1])/dydy‐(g[ij]) //右辺の影響)*dxdxdydy/dxdy2 ‐f[ij];

f[ij] += Accel*d_f;err_n += d_f*d_f;err_d += f[ij]*f[ij];

}}

if(err_d<1e‐20)err_d=1.0;err_relative = sqrt(err_n/err_d);ite_SOR++;

}while(err_relative > ERR_TOL);

}

CPUプログラム(共役勾配法)

2015/06/18先端GPGPUシミュレーション工学特論718

poisson.c

Page 46: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

do{for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;p [ij] = r[ij] + beta*p[ij];

}}

pAp = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);//右辺の影響は入らないAp[ij] = (p[im1j]‐2*p[ij]+p[ip1j])/dxdx

+(p[ijm1]‐2*p[ij]+p[ijp1])/dydy;

pAp += p[ij]*Ap[ij];}}alph = rr/pAp;

rr = 0.0;for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;f[ij] = f[ij] + alph* p[ij];r[ij] = r[ij] ‐ alph*Ap[ij];rr += r[ij]*r[ij];

}}err = sqrt(rr/bb);beta = rr/(alph*pAp);

}while(err > ERR_TOL);}

CPUプログラム(共役勾配法)

2015/06/18先端GPGPUシミュレーション工学特論719

poisson.c

Page 47: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

CPUプログラム

右辺(ソース項)g

境界条件

for(i=0;i<Nx;i++){for(j=0;j<Ny;j++){

x = (double)i*dx;y = (double)j*dy;g[i*Ny+j] = 2.0*sin(2.0*M_PI*x/Lx)

*sin(2.0*M_PI*y/Ly);}}

先端GPGPUシミュレーション工学特論720 2015/06/18

yxg sinsin2

0sinsin22 yxf

2

2

g2−2

Page 48: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

#include<stdio.h>#include<stdlib.h>#include<math.h>

#define Lx (2.0*M_PI)#define Ly Lx#define Nx 11#define Ny Ny#define dx (Lx/(Nx‐1))#define dy dx#define dxdx (dx*dx)#define dydy (dy*dy)#define dxdxdydy (dxdx*dydy)#define dxdy2 (2.0*(dxdx+dydy))#define Nbytes (Nx*Ny*sizeof(double))#define ERR_TOL 1e‐12#define Accel 1.0void sor(double *f,double *g);void cg(double *f,double *g);

void init(double *f,double *g){for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){g[i+Nx*j] = 2.0*sin(2.0*M_PI*x/Lx)

*sin(2.0*M_PI*y/Ly);f[i+Nx*j] = 0.0;

}}

}int main(void){

double *f, *g;f = (double *)malloc(Nbytes);g = (double *)malloc(Nbytes);

init(f,g);sor(f,g)//cg(f,g);return 0;

}

CPUプログラム(メイン・初期化)

2015/06/18先端GPGPUシミュレーション工学特論721

poisson.c

Page 49: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

void sor(double *f, double *g){int ite_SOR=0;double err_n,err_d,err_relative;double d_f;int ij,ip1j,im1j,ijm1,ijp1;

//境界値は全て0固定なので何もしない

do{err_n = 0.0;err_d = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);

d_f =( (f[im1j]+f[ip1j])/dxdx+(f[ijm1]+f[ijp1])/dydy‐(g[ij]))*dxdxdydy/dxdy2 ‐f[ij];

f[ij] += Accel*d_f;err_n += d_f*d_f;err_d += f[ij]*f[ij];

}}

if(err_d<1e‐20)err_d=1.0;err_relative = sqrt(err_n/err_d);ite_SOR++;

}while(err_relative > ERR_TOL);

}

CPUプログラム(SOR法)

2015/06/18先端GPGPUシミュレーション工学特論722

poisson.c

Page 50: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

void cg(double *f, double *g){double err;int ij,ip1j,im1j,ijm1,ijp1;double *p,*r,*Ap;double alph,beta,rr,pAp,bb;

p  = (double *)malloc(Nbytes);r  = (double *)malloc(Nbytes);Ap = (double *)malloc(Nbytes);for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;p [ij] = 0.0;r [ij] = 0.0;Ap[ij] = 0.0;

}}alph=0.0;beta=0.0;

//境界値は全て0固定なので何もしないbb = 0.0;rr = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);r[ij] = g[ij]‐((f[im1j]‐2*f[ij]+f[ip1j])/dxdx

+(f[ijm1]‐2*f[ij]+f[ijp1])/dydy);

rr += r[ij]*r[ij];bb += g[ij]*g[ij];

}}

CPUプログラム(共役勾配法)

2015/06/18先端GPGPUシミュレーション工学特論723

poisson.c

Page 51: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

do{for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;p [ij] = r[ij] + beta*p[ij];

}}

pAp = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);

Ap[ij] = (p[im1j]‐2*p[ij]+p[ip1j])/dxdx

+(p[ijm1]‐2*p[ij]+p[ijp1])/dydy;

pAp += p[ij]*Ap[ij];}}alph = rr/pAp;

rr = 0.0;for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;f[ij] = f[ij] + alph* p[ij];r[ij] = r[ij] ‐ alph*Ap[ij];rr += r[ij]*r[ij];

}}err = sqrt(rr/bb);beta = rr/(alph*pAp);

}while(err > ERR_TOL);}

CPUプログラム(共役勾配法)

2015/06/18先端GPGPUシミュレーション工学特論724

poisson.c

Page 52: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

計算結果

2015/06/18先端GPGPUシミュレーション工学特論725

前回授業で用いたgnuplotのanim_2d.gplを流用して2次元分布を確認

set xrange [0:2*pi] x軸の表示範囲を0~2に固定set yrange [0:2*pi] y軸の表示範囲を0~2に固定set zrange [‐1:1] z軸の表示範囲を‐1~1に固定set view 0,0 真上から見下ろすset size 1,1 グラフの縦横比を1:1set contour 2次元等高線を表示unset surface 3次元で等値面を表示しないunset pm3d カラー表示しないset cntrparam levels incremental ‐1,0.1,1

等高線を0から1まで0.1刻みに設定以下でファイルを読み込み,3次元表示splot 'f.txt' with line  

Page 53: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

計算結果

2015/06/18先端GPGPUシミュレーション工学特論726

前回授業で用いたgnuplotのanim_2d.gplを流用して2次元分布を確認

set xrange [0:2*pi] x軸の表示範囲を0~2に固定set yrange [0:2*pi] y軸の表示範囲を0~2に固定set zrange [‐1:1] z軸の表示範囲を‐1~1に固定set view 0,0 真上から見下ろすset size 1,1 グラフの縦横比を1:1unset contour 2次元等高線を表示unset surface 3次元で等値面を表示しないset pm3d カラー表示しない以下でファイルを読み込み,3次元表示splot 'f.txt' with line  

Page 54: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

GPUへの移植

2015/06/18先端GPGPUシミュレーション工学特論727

共役勾配法のGPU移植は比較的簡単 これまでの授業内容の知識で実装可能

第7回総和計算

第8回偏微分方程式の差分計算(拡散方程式)

SOR法のGPU移植は非常に困難 処理の過程で格子点のデータに依存性が存在

fi,j(m+1)の値を計算するためにfi−1,j

(m+1), fi,j−1(m+1)の値を利用

特殊な並列化方法を導入

Page 55: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

void cg(double *f, double *g){double err;int ij,ip1j,im1j,ijm1,ijp1;double *p,*r,*Ap;double alph,beta,rr,pAp,bb;

p  = (double *)malloc(Nbytes);r  = (double *)malloc(Nbytes);Ap = (double *)malloc(Nbytes);for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;p [ij] = 0.0;r [ij] = 0.0;Ap[ij] = 0.0;

}}alph=0.0;beta=0.0;

共役勾配法の並列化・GPU移植

2015/06/18先端GPGPUシミュレーション工学特論728

1スレッドが配列の1要素に0を代入容易に並列化・GPU移植可能

Page 56: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

bb = 0.0;rr = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);

r[ij] = g[ij]‐((f[im1j]‐2*f[ij]+f[ip1j])/dxdx

+(f[ijm1]‐2*f[ij]+f[ijp1])/dydy);

rr += r[ij]*r[ij];bb += g[ij]*g[ij];

}}

共役勾配法の並列化・GPU移植

2015/06/18先端GPGPUシミュレーション工学特論729

残差を計算するカーネルと内積を計算するカーネルに分離・残差の計算には拡散方程式のカーネル・内積の計算は総和計算のカーネルを流用

容易ではないが,これまでの知識で並列化・GPU移植可能

Page 57: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

do{for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;p [ij] = r[ij] + beta*p[ij];

}}

共役勾配法の並列化・GPU移植

2015/06/18先端GPGPUシミュレーション工学特論730

ベクトル和と同様に1スレッドが配列の1要素の計算を実行容易に並列化・GPU移植可能

Page 58: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

pAp = 0.0;for(int j=1;j<Ny‐1;j++){for(int i=1;i<Nx‐1;i++){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);

Ap[ij] = (p[im1j]‐2*p[ij]+p[ip1j])/dxdx+(p[ijm1]‐2*p[ij]+p[ijp1])/dydy;

pAp += p[ij]*Ap[ij];}}alph = rr/pAp;

共役勾配法の並列化・GPU移植

2015/06/18先端GPGPUシミュレーション工学特論731

残差を計算するカーネルと内積を計算するカーネルに分離・残差の計算には拡散方程式のカーネル・内積の計算は総和計算のカーネルを流用

容易ではないが,これまでの知識で並列化・GPU移植可能

Page 59: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

rr = 0.0;for(int j=0;j<Ny;j++){for(int i=0;i<Nx;i++){ij = i+Nx*j;f[ij] = f[ij] + alph* p[ij];r[ij] = r[ij] ‐ alph*Ap[ij];rr += r[ij]*r[ij];

}}err = sqrt(rr/bb);beta = rr/(alph*pAp);

}while(err > ERR_TOL);

}

共役勾配法の並列化・GPU移植

2015/06/18先端GPGPUシミュレーション工学特論732

ベクトル和と同様に1スレッドが配列の1要素の計算を実行容易に並列化・GPU移植可能

Page 60: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

//メモリの確保・解放は比較的負荷が高いので,mainで確保して関数に渡すvoid cg(double *f, double *g, double *r, double *p, double *Ap){double err;double alph,beta,rr,pAp,bb;

initAuxVectors<<<Block, Thread>>>(r,p,Ap); cudaThreadSynchronize();alph=0.0;beta=0.0;

bb = dot_product(g,g); cudaThreadSynchronize();computeResidual<<<Block, Thread>>>(f,g,r); cudaThreadSynchronize();rr = dot_product(r,r); cudaThreadSynchronize();

do{computeAuxVector<<<Block, Thread>>>(p,r,beta);cudaThreadSynchronize();

共役勾配法の並列化・GPU移植

2015/06/18先端GPGPUシミュレーション工学特論733

1台のGPUの全スレッドを同期(不要な箇所もある)

Page 61: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

computeMxV<<<Block, Thread>>>(Ap,p); cudaThreadSynchronize();pAp = dot_product(p,Ap); cudaThreadSynchronize();alph = rr/pAp;

update<<<Block, Thread>>>(f,r); cudaThreadSynchronize();rr = dot_product(r,r); cudaThreadSynchronize();

err = sqrt(rr/bb);beta = rr/(alph*pAp);

}while(err > ERR_TOL);

}

共役勾配法の並列化・GPU移植

2015/06/18先端GPGPUシミュレーション工学特論734

Page 62: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

SOR法の並列化

2015/06/18先端GPGPUシミュレーション工学特論735

SOR法の処理の手順 更新手順に依存性が存在

Jacobi法なら依存性問題は回避できるが収束が遅すぎる

並列化の影響で反復毎に更新順序が変化すると収束が保証されない

配列順序・計算順序の並び替え(オーダリング)を導入

f[]

i

j

22

22

2

)1(1,

)(1,

2

)1(,1

)(,1

.

)1(, 2

ΔyΔxΔyΔx

Δyff

Δxff

g

f

mji

mji

mji

mji

ji

mji

Page 63: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Red-Blackオーダリング

2015/06/18先端GPGPUシミュレーション工学特論736

更新順序を2段階に分離 赤色の要素を参照し,黒色の要素全てを更新

黒色の要素を参照し,赤色の要素全てを更新f[]

i

j

i

j

i

fr[] fb[]

Page 64: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Red-Blackオーダリング

2015/06/18先端GPGPUシミュレーション工学特論737

更新順序を2段階に分離 赤色の要素を参照し,黒色の要素全てを更新

黒色の要素を参照し,赤色の要素全てを更新f[]

i

j

fr[]

i

j

fb[]

i

Page 65: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

Red-Black SOR法

2015/06/18先端GPGPUシミュレーション工学特論738

赤色もしくは黒色の要素は常にm+1の値を用いて計算 SOR法よりも速く収束

22

22

2

)(1,

)(1,

2

)(,1

)(,1

.)1(

,2

ΔyΔxΔyΔx

Δyff

Δxff

gfmji

mji

mji

mji

jimji

22

22

2

)1(1,

)1(1,

2

)1(,1

)1(,1

.)1(

,2

ΔyΔxΔyΔx

Δyff

Δxff

gfmji

mji

mji

mji

jimji

even is when ,...5,3,1odd is when ,...6,4,2

,1,2,...,2,1jiji

NNj yy

odd is when ,...5,3,1even is when ,...6,4,2

,1,2,...,2,1jiji

NNj yy

Page 66: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

void rbsor(double *f, double *g){

int ite_SOR=0;double err_n,err_d,err_relative;double d_f;int ij,ip1j,im1j,ijm1,ijp1;

do{err_n = 0.0;err_d = 0.0;//赤色要素を計算for(int j=1;j<Ny‐1;j++){for(int i=1+j%2;i<Nx‐1;i+=2){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);d_f =( (f[im1j]+f[ip1j])/dxdx

+(f[ijm1]+f[ijp1])/dydy‐(g[ij]))*dxdxdydy/dxdy2 ‐f[ij];

f[ij] += Accel*d_f;err_n += d_f*d_f;err_d += f[ij]*f[ij];

}}

CPUプログラム(RB-SOR法)

2015/06/18先端GPGPUシミュレーション工学特論739

poisson.c

Page 67: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

CPUプログラム(RB-SOR法)

2015/06/18先端GPGPUシミュレーション工学特論740

poisson.c

//黒色要素を計算for(int j=1;j<Ny‐1;j++){for(int i=1+(j‐1)%2;i<Nx‐1;i+=2){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);d_f =( (f[im1j]+f[ip1j])/dxdx

+(f[ijm1]+f[ijp1])/dydy‐(g[ij]))*dxdxdydy/dxdy2 ‐f[ij];

f[ij] += Accel*d_f;err_n += d_f*d_f;err_d += f[ij]*f[ij];

}}

if(err_d<1e‐20)err_d=1.0;err_relative = sqrt(err_n/err_d);ite_SOR++;

}while(err_relative > ERR_TOL);

}

Page 68: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

赤色要素の計算

2015/06/18先端GPGPUシミュレーション工学特論741

j=1(奇数)のときに計算するiは2,4,6 j=2(偶数)のときに計算するiは1,3,5 計算の範囲は0<i<Nx‐1,0<j<Ny‐1

f[]

0  1  2  3  4  5  6  70 

1  2  3 

4  5  6  7

iの 小値は1,jが奇数の時+1,偶数の時+0jを2で割った剰余を利用してiの開始点を決定i=1+j%2

for(int j=1;j<Ny‐1;j++){for(int i=1+j%2;i<Nx‐1;i+=2){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);d_f =( (f[im1j]+f[ip1j])/dxdx

+(f[ijm1]+f[ijp1])/dydy‐(g[ij]))*dxdxdydy/dxdy2 ‐f[ij];

f[ij] += Accel*d_f;}}

Page 69: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

黒色要素の計算

2015/06/18先端GPGPUシミュレーション工学特論742

j=1(奇数)のときに計算するiは1,3,5 j=2(偶数)のときに計算するiは2,4,6 計算の範囲は0<i<Nx‐1,0<j<Ny‐1

for(int j=1;j<Ny‐1;j++){for(int i=1+(j+1)%2;i<Nx‐1;i+=2){ij = i+Nx*j;ip1j = (i+1)+Nx*(j  );im1j = (i‐1)+Nx*(j  );ijp1 = (i )+Nx*(j+1);ijm1 = (i )+Nx*(j‐1);d_f =( (f[im1j]+f[ip1j])/dxdx

+(f[ijm1]+f[ijp1])/dydy‐(g[ij]))*dxdxdydy/dxdy2 ‐f[ij];

f[ij] += Accel*d_f;}}

f[]

0  1  2  3  4  5  6  70 

1  2  3 

4  5  6  7

iの 小値は1,jが奇数の時+0,偶数の時+1jを2で割った剰余を利用してiの開始点を決定i=1+(j+1)%2 (=2‐j%2とも書ける)

Page 70: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

GPUへの移植

2015/06/18先端GPGPUシミュレーション工学特論743

赤色要素を計算するカーネルと黒色要素を計算するカーネルを分離

反復のループ制御や収束判定はCPUで実行

収束判定の誤差の指標にはl∞−ノルムを採用 l2−ノルムを用いると内積計算が発生

収束判定用の変数を用意(値を1に初期化)

各スレッドが計算した誤差が許容値より大きい場合は収束判定用変数に0を書き込む

収束していない格子点があれば反復を繰り返す

Page 71: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

#include<stdio.h>#include<stdlib.h>#include<math.h>

#define Lx  (2.0*M_PI)#define Ly  (2.0*M_PI)#define Nx 256#define Ny Nx#define Nbytes (Nx*Ny*sizeof(double))#define dx  (Lx/(Nx‐1))#define dy (Ly/(Ny‐1))

#define THREADX 16#define THREADY 16#define BLOCKX (Nx/THREADX)#define BLOCKY (Ny/THREADY)

void output(double *value, char *name);

#include"rbsor.cu"

__global__ void init(double *f, double *g){

int i=blockIdx.x*blockDim.x+threadIdx.x;int j=blockIdx.y*blockDim.y+threadIdx.y;int ij = i+Nx*j;

double x = (double)i*dx;double y = (double)j*dy;g[ij] = 2.0*sin(2.0*M_PI*x/Lx)

*sin(2.0*M_PI*y/Ly);f[ij] = 0.0; 

}

GPUプログラム(メイン)

2015/06/18先端GPGPUシミュレーション工学特論744

poisson.cu

Page 72: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

int main(void){

double *f,*g;double *dev_f,*dev_g;dim3 Block, Thread;

cudaSetDevice(3);cudaSetDeviceFlags(cudaDeviceMapHost);

cudaMalloc((void **)&dev_f, Nbytes);cudaMalloc((void **)&dev_g, Nbytes);

Thread = dim3(THREADX,THREADY,1);Block  = dim3(BLOCKX,BLOCKY,1);init<<<Block, Thread >>>(dev_f,dev_g);

printf("iteration = %d¥n",rbsor(dev_f,dev_g));

f=(double *)malloc(Nbytes);

g=(double *)malloc(Nbytes);cudaMemcpy(f,dev_f,Nbytes, cudaMemcpyDeviceToHost);cudaMemcpy(g,dev_g,Nbytes, cudaMemcpyDeviceToHost);

output(f,"f.txt");output(g,"g.txt");

cudaFree(dev_f);cudaFree(dev_g);free(f);free(g);return 0;

}

GPUプログラム(メイン)

2015/06/18先端GPGPUシミュレーション工学特論745

poisson.cu

Page 73: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

int rbsor(double *f, double *g){

int ite_SOR=0;int *converged,*conv=(int *)malloc(sizeof(int));dim3 Block= dim3(SORBx,SORBy,1), Thread= dim3(SORTx,SORTy,1);cudaMalloc((void **)&converged, sizeof(int));

do{ite_SOR++;*conv = 1; //1なら収束,0ならどこかの要素の値が収束していないcudaMemcpy(converged, conv, sizeof(int),cudaMemcpyHostToDevice);computeRed <<<Block, Thread>>>(f,g,converged);computeBlack<<<Block, Thread>>>(f,g,converged);//cudaThreadSynchronize();cudaMemcpy(conv, converged, sizeof(int),cudaMemcpyDeviceToHost);

}while(*conv == 0 && ite_SOR<1024*1024*1024);

free(conv);cudaFree(converged);return ite_SOR;

}

RB-SOR法(ループ制御部分)

2015/06/18先端GPGPUシミュレーション工学特論746

rbsor.cu

Page 74: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

int rbsor(double *f, double *g){

int ite_SOR=0;int *converged,*conv;dim3 Block= dim3(SORBx,SORBy,1), Thread= dim3(SORTx,SORTy,1);

//ホストメモリに置かれたconvをGPUから読み書きcudaHostAlloc((void **)&conv, sizeof(int),cudaHostAllocMapped);cudaHostGetDevicePointer(&converged, conv, 0);

do{ite_SOR++;*conv = 1; //1なら収束,0ならどこかの要素の値が収束していないcomputeRed <<<Block, Thread>>>(f,g,converged);computeBlack<<<Block, Thread>>>(f,g,converged);//cudaThreadSynchronize();

}while(*conv == 0 && ite_SOR<1024*1024*1024);

cudaFreeHost(conv);return ite_SOR;

}

RB-SOR法(ループ制御部分)

2015/06/18先端GPGPUシミュレーション工学特論747

rbsor.cu

Page 75: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

__global__ void computeRed(double *f,double *g, int *converged){

int j = blockIdx.y* blockDim.y + threadIdx.y;int i = blockIdx.x*(blockDim.x*2) + threadIdx.x*2 + (j+1)%2;int ij = i+Nx*j;int ip1j = (i+1)+Nx*(j  );int im1j = (i‐1)+Nx*(j  );int ijp1 = (i )+Nx*(j+1);int ijm1 = (i )+Nx*(j‐1);double d_f;

if(0<i && i<Nx‐1 && 0<j && j<Ny‐1){d_f =( (f[im1j]+f[ip1j])/dxdx

+(f[ijm1]+f[ijp1])/dydy‐(g[ij])

)*dxdxdydy/dxdy2 ‐f[ij];f[ij] += Accel*d_f;if(abs(d_f) > ERR_TOL) *converged = 0;

}}

RB-SOR法(赤色要素の計算)

2015/06/18先端GPGPUシミュレーション工学特論748

rbsor.cu

Page 76: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

__global__ void computeBlack(double *f,double *g, int *converged){

int j = blockIdx.y* blockDim.y + threadIdx.y;int i = blockIdx.x*(blockDim.x*2) + threadIdx.x*2 + (j)%2;int ij = i+Nx*j;int ip1j = (i+1)+Nx*(j  );int im1j = (i‐1)+Nx*(j  );int ijp1 = (i )+Nx*(j+1);int ijm1 = (i )+Nx*(j‐1);double d_f;

if(0<i && i<Nx‐1 && 0<j && j<Ny‐1){d_f =( (f[im1j]+f[ip1j])/dxdx

+(f[ijm1]+f[ijp1])/dydy‐(g[ij])

)*dxdxdydy/dxdy2 ‐f[ij];f[ij] += Accel*d_f;if(abs(d_f) > ERR_TOL) *converged = 0;

}}

RB-SOR法(黒色要素の計算)

2015/06/18先端GPGPUシミュレーション工学特論749

rbsor.cu

Page 77: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論750

初期化 1スレッドが一つの配列要素を計算

f[]

0  1  2  3  4  5  6  7

0 1  2  3 

4  5  6  7#define THREADX 16

#define THREADY 16#define BLOCKX (Nx/THREADX)#define BLOCKY (Ny/THREADY)

Thread = dim3(THREADX,THREADY,1);Block  = dim3(BLOCKX,BLOCKY,1);init<<<Block, Thread >>>

(dev_f,dev_g);

i=blockIdx.x*blockDim.x+threadIdx.x;j=blockIdx.y*blockDim.y+threadIdx.y;

Page 78: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論751

RB‐SOR法 i方向の計算に必要なスレッド数は初期化の1/2 必要なブロック数は同じ

f[]

0  1  2  3  4  5  6  7

0 1  2  3 

4  5  6  7#define SORTx (THREADX/2)

#define SORTy (THREADY)#define SORBx (BLOCKX)#define SORBy (BLOCKY)

dim3 Block, Thread;Thread = dim3(SORTx,SORTy,1);Block  = dim3(SORBx,SORBy,1);computeRed<<<Block, Thread>>>

(f,g,converged);

Page 79: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論752

RB‐SOR法 スレッド番号と配列添字をどう対応させるか

j方向は変更無し,i方向のみ変化

f[]

0  1  2  3  4  5  6  7

0 1  2  3 

4  5  6  7#define SORTx (THREADX/2)

#define SORTy (THREADY)#define SORBx (BLOCKX)#define SORBy (BLOCKY)

dim3 Block, Thread;Thread = dim3(SORTx,SORTy,1);Block  = dim3(SORBx,SORBy,1);computeRed<<<Block, Thread>>>

(f,g,converged);

Page 80: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

ストライドアクセス時の配列添字の決定

N=12, <<<3, 2>>>で実行

2015/06/18先端GPGPUシミュレーション工学特論753

c[i]

a[i]

b[i]

0 1 0

+ + + +

1

gridDim.x=3

blockDim.x=2

0 1

+ +

blockDim.x=2 blockDim.x=2blockIdx.x=0 blockIdx.x=1 blockIdx.x=2

threadIdx.x=

i=  0   1   2   3   4   5  6   7  8   9  10 11

Page 81: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の要素番号iの計算

2015/06/18先端GPGPUシミュレーション工学特論754

threadIdx.xとiの対応

iの決定 配列サイズ=ブロックの数×1ブロックあたりのスレッドの数

配列サイズ=ブロックの数×1ブロックあたりのスレッドの数×計算する点の間隔

blockIdx.x 0 1 2

threadIdx.x 0 1 0 1 0 1

i 0 2 4=4+0

6=4+2

8=8+0

10=8+2

i+threadIdx.x×2

Page 82: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

ストライドアクセス時の配列添字の決定

N=12, <<<3, 2>>>で実行

2015/06/18先端GPGPUシミュレーション工学特論755

c[i]

a[i]

b[i]

0 1 0

+ + + +

1

gridDim.x=3

blockDim.x=2

0 1

+ +

blockDim.x=2 blockDim.x=2blockIdx.x=0 blockIdx.x=1 blockIdx.x=2

threadIdx.x=

i=  0   1   2   3   4   5  6   7  8   9  10 11= blockIdx.x*(blockDim.x*2) + threadIdx.x*2

計算する点の間隔 計算する点の間隔

Page 83: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論756

i方向のスレッド番号と配列添字の対応 ストライドアクセス

f[]

0  1  2  3  4  5  6  7

0 1  2  3 

4  5  6  7

j = blockIdx.y* blockDim.y + threadIdx.y;i = blockIdx.x*(blockDim.x*2) + threadIdx.x*2;

j

Page 84: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論757

i方向のスレッド番号と配列添字の対応 ストライドアクセス

開始点の変化(jが奇数のとき0開始,偶数のときは1開始)

f[]

0  1  2  3  4  5  6  7

0 1  2  3 

4  5  6  7

+0+1+0+1

j

(j+1)%2

j = blockIdx.y* blockDim.y + threadIdx.y;i = blockIdx.x*(blockDim.x*2) + threadIdx.x*2

+ (j+1)%2;

Page 85: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論758

RB‐SOR法 スレッド番号と配列添字をどう対応させるか

j方向は変更無し,i方向のみ変化

f[]

0  1  2  3  4  5  6  7

0 1  2  3 

4  5  6  7#define SORTx (THREADX/2)

#define SORTy (THREADY)#define SORBx (BLOCKX)#define SORBy (BLOCKY)

dim3 Block, Thread;Thread = dim3(SORTx,SORTy,1);Block  = dim3(SORBx,SORBy,1);computeBlack<<<Block, Thread>>>

(f,g,converged);

Page 86: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論759

i方向のスレッド番号と配列添字の対応 ストライドアクセス

f[]

0  1  2  3  4  5  6  7

0 1  2  3 

4  5  6  7

j = blockIdx.y* blockDim.y + threadIdx.y;i = blockIdx.x*(blockDim.x*2) + threadIdx.x*2;

j

Page 87: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論760

i方向のスレッド番号と配列添字の対応 ストライドアクセス

開始点の変化(jが奇数のとき0開始,偶数のときは1開始)

f[]

0  1  2  3  4  5  6  7

0 1  2  3 

4  5  6  7

+1+0+1+0

j

(j)%2

j = blockIdx.y* blockDim.y + threadIdx.y;i = blockIdx.x*(blockDim.x*2) + threadIdx.x*2

+ (j)%2;

Page 88: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

RB-SOR法の性能改善

2015/06/18先端GPGPUシミュレーション工学特論761

赤色要素,黒色要素の計算はストライドアクセス グローバルメモリにコアレスアクセスできない

読み込み速度が低下

赤色要素,黒色要素の計算でカーネルを切り替えるため,共有メモリが利用できない

メモリアクセスを改善したい グローバルメモリにコアレスアクセスしたい

赤色要素を格納する配列と黒色要素を格納する配列を分離

Page 89: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論762

色ごとに格納する配列を区別 ストライドアクセスを排除

元の配列を分離,出力時に結合するカーネルを作成

f[]

i

j

fr[]

i

j

fb[]

i

Page 90: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

int rbsor(double *f, double *g){

double *fr,*fb,*gr,*gb;int ite_SOR=0;int *converged,*conv;

dim3 BlockSplit= dim3(SplitBx,SplitBy,1),ThreadSplit= dim3(SplitTx,SplitTy,1);dim3 BlockMerge= dim3(MergeBx,MergeBy,1),ThreadMerge= dim3(MergeTx,MergeTy,1);dim3 BlockSOR = dim3(  SORBx,  SORBy,1),ThreadSOR = dim3(  SORTx,  SORTy,1);

cudaHostAlloc((void **)&conv, sizeof(int),cudaHostAllocMapped);cudaHostGetDevicePointer(&converged, conv, 0);

cudaMalloc((void **)&fr, Nbytes/2);cudaMalloc((void **)&fb, Nbytes/2);cudaMalloc((void **)&gr, Nbytes/2);cudaMalloc((void **)&gb, Nbytes/2);

split<<<BlockSplit, ThreadSplit>>>(f,fr,fb);split<<<BlockSplit, ThreadSplit>>>(g,gr,gb);

RB-SOR法(ループ制御部分)

2015/06/18先端GPGPUシミュレーション工学特論763

rbsor_split.cu

Page 91: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

do{ite_SOR++;*conv = 1;

computeRed <<<BlockSOR, ThreadSOR>>>(fr, fb, gr, gb,converged);computeBlack<<<BlockSOR, ThreadSOR>>>(fb, fr, gb, gr, converged);cudaThreadSynchronize();

}while(*conv == 0 && ite_SOR<1024*1024*1024);

merge<<<BlockMerge, ThreadMerge>>>(f,fr,fb);

cudaFreeHost(conv);cudaFree(fr);cudaFree(fb);cudaFree(gr);cudaFree(gb);

return ite_SOR;}

配列を分離するRB-SOR法(ループ制御部分)

2015/06/18先端GPGPUシミュレーション工学特論764

rbsor_split.cu

Page 92: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

__global__ void split(double *f, double *fr,double *fb){

__shared__ double sf[THREADX][THREADY];__shared__ double sfrb[THREADX][THREADY];

int tx = threadIdx.x;int ty = threadIdx.y;

int j = blockIdx.y* blockDim.y + threadIdx.y;int i = blockIdx.x*(blockDim.x*2) + threadIdx.x;int ij = i+Nx*j;

sf[tx][ty] = f[ij];__syncthreads();

i = blockIdx.x*(blockDim.x*2) + threadIdx.x+ blockDim.x;

ij = i+Nx*j;sf[tx+blockDim.x][ty] = f[ij];__syncthreads();

sfrb[tx ][ty]= sf[tx*2+(j+1)%2][ty];

sfrb[tx+blockDim.x][ty]= sf[tx*2+(j  )%2][ty];

__syncthreads();

i = blockIdx.x*blockDim.x + threadIdx.x;ij= i+Nx/2*j;fr[ij] = sfrb[tx ][ty];fb[ij] = sfrb[tx+blockDim.x][ty];

}

配列を分離するRB-SOR法(配列分離)

2015/06/18先端GPGPUシミュレーション工学特論765

rbsor_split.cu

Page 93: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論766

共有メモリ上に配列を宣言

グローバルメモリからコピーするための配列

並び替え後のデータを格納する配列

f[]__shared__ double sf[THREADX][THREADY];__shared__ double sfrb[THREADX][THREADY];

int tx = threadIdx.x;int ty = threadIdx.y;int j = blockIdx.y* blockDim.y + threadIdx.y;int i = blockIdx.x*(blockDim.x*2) + threadIdx.x;int ij = i+Nx*j;

sf[tx][ty] = f[ij];__syncthreads();

sf[][]

sfrb[][]

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 94: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論767

共有メモリ上に配列を宣言

グローバルメモリからコピーするための配列

並び替え後のデータを格納する配列

グローバルメモリから共有メモリにコピーして同期を取る

f[]__shared__ double sf[THREADX][THREADY];__shared__ double sfrb[THREADX][THREADY];

int tx = threadIdx.x;int ty = threadIdx.y;int j = blockIdx.y* blockDim.y + threadIdx.y;int i = blockIdx.x*(blockDim.x*2) + threadIdx.x;int ij = i+Nx*j;

sf[tx][ty] = f[ij];__syncthreads();

sf[][]

0  1  2  3

0 1  2  3

Page 95: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論768

i方向の位置を変更してさらにグローバルメモリから共有メモリにコピー

f[]

i = blockIdx.x*(blockDim.x*2) + threadIdx.x+ blockDim.x;

ij = i+Nx*j;sf[tx+blockDim.x][ty] = f[ij];__syncthreads();

sf[][]

0  1  2  3

0 1  2  3

Page 96: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論769

共有メモリ上でストライドアクセスして赤色要素と黒色要素を並び替え

jの位置に応じてiの位置を変更

f[]

sfrb[tx ][ty]= sf[tx*2+(j+1)%2][ty];

sf[][]

0  1  2  3

0 1  2  3

sfrb[][]

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 97: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論770

共有メモリ上でストライドアクセスして赤色要素と黒色要素を並び替え

jの位置に応じてiの位置を変更

並び替え後の配列に赤色要素を書込

f[]

sfrb[tx ][ty]= sf[tx*2+(j+1)%2][ty];

sf[][]

0  1  2  3

0 1  2  3

sfrb[][]

+0+1+0+1

(j+1)%2

0  1  2  3

0 1  2  3

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 98: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論771

共有メモリ上でストライドアクセスして赤色要素と黒色要素を並び替え

jの位置に応じてiの位置を変更

f[]

sfrb[tx+blockDim.x][ty]= sf[tx*2+(j  )%2][ty];

__syncthreads();

sf[][]

0  1  2  3

0 1  2  3

sfrb[][]

0  1  2  3

0 1  2  3

Page 99: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論772

共有メモリ上でストライドアクセスして赤色要素と黒色要素を並び替え

jの位置に応じてiの位置を変更

並び替え後の配列に黒色要素を書込

f[]

sfrb[tx+blockDim.x][ty]= sf[tx*2+(j  )%2][ty];

__syncthreads();

sf[][]

0  1  2  3

0 1  2  3

sfrb[][]

+1+0+1+0

(j )%2

0  1  2  3

0 1  2  3

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 100: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論773

共有メモリの赤色,黒色要素を分離した配列に書込

各配列にコアレスアクセスで書込

i = blockIdx.x*blockDim.x + threadIdx.x;ij= i+Nx/2*j;fr[ij] = sfrb[tx ][ty];fb[ij] = sfrb[tx+blockDim.x][ty];

fr[] fb[]

sfrb[][]

0  1  2  3

0 1  2  3

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 101: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の分離

2015/06/18先端GPGPUシミュレーション工学特論774

共有メモリの赤色,黒色要素を分離した配列に書込

各配列にコアレスアクセスで書込

i = blockIdx.x*blockDim.x + threadIdx.x;ij= i+Nx/2*j;fr[ij] = sfrb[tx ][ty];fb[ij] = sfrb[tx+blockDim.x][ty];

fr[] fb[]

sfrb[][]

0  1  2  3

0 1  2  3

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 102: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

__global__ void merge(double *f, double *fr,double *fb){

__shared__ double sf[THREADX][THREADY];__shared__ double sfrb[THREADX][THREADY];

int tx = threadIdx.x;int ty = threadIdx.y;

int j = blockIdx.y*blockDim.y + threadIdx.y;int i = blockIdx.x*blockDim.x + threadIdx.x;int ij = i+Nx/2*j;

sfrb[tx ][ty] = fr[ij];sfrb[tx+blockDim.x][ty] = fb[ij];__syncthreads();

sf[tx*2+(j+1)%2][ty]= sfrb[tx ][ty];

sf[tx*2+(j  )%2][ty]= sfrb[tx+blockDim.x][ty];

__syncthreads();

i = blockIdx.x*(blockDim.x*2) + threadIdx.x;ij= i+Nx*j;f[ij] = sf[tx ][ty];

i = blockIdx.x*(blockDim.x*2) + threadIdx.x+ blockDim.x;

ij= i+Nx*j;f[ij] = sf[tx+blockDim.x][ty];

}

配列を分離するRB-SOR法(配列結合)

2015/06/18先端GPGPUシミュレーション工学特論775

rbsor_split.cu

Page 103: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の結合

2015/06/18先端GPGPUシミュレーション工学特論776

赤色要素をグローバルメモリから読み込み,共有メモリへ書込

コアレスアクセスで書込

__shared__ double sf[THREADX][THREADY];__shared__ double sfrb[THREADX][THREADY];

int tx = threadIdx.x;int ty = threadIdx.y;int j = blockIdx.y*blockDim.y + threadIdx.y;int i = blockIdx.x*blockDim.x + threadIdx.x;sfrb[tx ][ty] = fr[ij];sfrb[tx+blockDim.x][ty] = fb[ij];__syncthreads();

fr[] fb[]

sfrb[][]

0  1  2  3

0 1  2  3

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 104: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の結合

2015/06/18先端GPGPUシミュレーション工学特論777

黒色要素をグローバルメモリから読み込み,共有メモリへ書込

コアレスアクセスで書込

__shared__ double sf[THREADX][THREADY];__shared__ double sfrb[THREADX][THREADY];

int tx = threadIdx.x;int ty = threadIdx.y;int j = blockIdx.y*blockDim.y + threadIdx.y;int i = blockIdx.x*blockDim.x + threadIdx.x;sfrb[tx ][ty] = fr[ij];sfrb[tx+blockDim.x][ty] = fb[ij];__syncthreads();

fr[] fb[]

sfrb[][]

0  1  2  3

0 1  2  3

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 105: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の結合

2015/06/18先端GPGPUシミュレーション工学特論778

並び替え後の配列内の赤色要素を並び替え前の配列へ書込

jの位置に応じてiの位置を変更

sf[tx*2+(j+1)%2][ty]= sfrb[tx ][ty];

sfrb[][]

0  1  2  3

0 1  2  3

sf[][]

0  1  2  3

0 1  2  3

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 106: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の結合

2015/06/18先端GPGPUシミュレーション工学特論779

並び替え後の配列内の赤色要素を並び替え前の配列へ書込

jの位置に応じてiの位置を変更

sf[tx*2+(j+1)%2][ty]= sfrb[tx ][ty];

sfrb[][]

0  1  2  3

0 1  2  3

sf[][]

0  1  2  3

0 1  2  3 +0

+1+0+1

(j+1)%2

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 107: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の結合

2015/06/18先端GPGPUシミュレーション工学特論780

並び替え後の配列内の黒色要素を並び替え前の配列へ書込

jの位置に応じてiの位置を変更

sf[tx*2+(j  )%2][ty]= sfrb[tx+blockDim.x][ty];

__syncthreads();

sfrb[][]

0  1  2  3

0 1  2  3

sf[][]

0  1  2  3

0 1  2  3

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 108: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の結合

2015/06/18先端GPGPUシミュレーション工学特論781

並び替え後の配列内の黒色要素を並び替え前の配列へ書込

jの位置に応じてiの位置を変更

sf[tx*2+(j  )%2][ty]= sfrb[tx+blockDim.x][ty];

__syncthreads();

sfrb[][]

0  1  2  3

0 1  2  3

sf[][]

0  1  2  3

0 1  2  3 +1

+0+1+0

(j  )%2

二つ目の共有メモリsfrb[][]を利用しないと性能はどのように変化するだろうか?

Page 109: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の結合

2015/06/18先端GPGPUシミュレーション工学特論782

共有メモリの内容をコアレスアクセスして元の配列に書き込み

f[]i = blockIdx.x*(blockDim.x*2) + threadIdx.x;ij= i+Nx*j;f[ij] = sf[tx ][ty];

i = blockIdx.x*(blockDim.x*2) + threadIdx.x+ blockDim.x;

ij= i+Nx*j;f[ij] = sf[tx+blockDim.x][ty];

sf[][]

0  1  2  3

0 1  2  3

Page 110: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列の結合

2015/06/18先端GPGPUシミュレーション工学特論783

共有メモリの内容をコアレスアクセスして元の配列に書き込み

f[] sf[][]

0  1  2  3

0 1  2  3

i = blockIdx.x*(blockDim.x*2) + threadIdx.x;ij= i+Nx*j;f[ij] = sf[tx ][ty];

i = blockIdx.x*(blockDim.x*2) + threadIdx.x+ blockDim.x;

ij= i+Nx*j;f[ij] = sf[tx+blockDim.x][ty];

Page 111: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

__global__ void computeRed(double *fr,double *fb, double *gr,double *gb, int *converged){

int j = blockIdx.y*blockDim.y + threadIdx.y;int i = blockIdx.x*blockDim.x + threadIdx.x;int ij = i+Nx/2*j;int iside = i+1‐(j%2)*2;int isidej = (iside)+Nx/2*(j  );int ijp1   = (i )+Nx/2*(j+1);int ijm1   = (i )+Nx/2*(j‐1);double d_f;

if(1‐(j+1)%2<=i && i<Nx/2‐(j+1)%2 && 0<j && j<Ny‐1){d_f =( (fb[isidej]+fb[ij])/dxdx

+(fb[ijm1  ]+fb[ijp1])/dydy‐(gr[ij])

)*dxdxdydy/dxdy2 ‐fr[ij];fr[ij] += Accel*d_f;

if(abs(d_f) > ERR_TOL) *converged = 0;}

}

配列を分離するRB-SOR法(赤色要素の計算)

2015/06/18先端GPGPUシミュレーション工学特論784

rbsor_split.cu

Page 112: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

__global__ void computeBlack(double *fb,double *fr, double *gb,double *gr, int *converged){

int j = blockIdx.y*blockDim.y + threadIdx.y;int i = blockIdx.x*blockDim.x + threadIdx.x;int ij = i+Nx/2*j;int iside = i‐1+(j%2)*2;int isidej = (iside)+Nx/2*(j  );int ijp1   = (i )+Nx/2*(j+1);int ijm1   = (i )+Nx/2*(j‐1);double d_f;

if(0+(j+1)%2<=i && i<Nx/2‐(j  )%2 && 0<j && j<Ny‐1){d_f =( (fr[isidej]+fr[ij])/dxdx

+(fr[ijm1  ]+fr[ijp1])/dydy‐(gb[ij])

)*dxdxdydy/dxdy2 ‐fb[ij];fb[ij] += Accel*d_f;

if(abs(d_f) > ERR_TOL) *converged = 0;}

}

配列を分離するRB-SOR法(黒色要素の計算)

2015/06/18先端GPGPUシミュレーション工学特論785

rbsor_split.cu

Page 113: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論786

i方向のスレッド番号と配列添字の対応が単純化

fr[] fb[]

0  1  2  3

0 1  2  3 

4  5  6  7

j = blockIdx.y*blockDim.y + threadIdx.y;i = blockIdx.x*blockDim.x + threadIdx.x;

Page 114: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列アクセス

2015/06/18先端GPGPUシミュレーション工学特論787

黒色要素の参照点 jによってi方向のどちらを見るかが変化

jが奇数の時はi‐1,偶数の時はi+1fr[] fb[]

0  1  2  3

0 1  2  3 

4  5  6  7

f[]

Page 115: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列アクセス

2015/06/18先端GPGPUシミュレーション工学特論788

黒色要素の参照点 jによってi方向のどちらを見るかが変化

jが奇数の時はi‐1,偶数の時はi+1fr[] fb[]

0  1  2  3

0 1  2  3 

4  5  6  7

f[]

Page 116: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列アクセス

2015/06/18先端GPGPUシミュレーション工学特論789

黒色要素の参照点 jによってi方向のどちらを見るかが変化

iside = i+1‐(j%2)*2;fr[] fb[]

0  1  2  3

0 1  2  3 

4  5  6  7 +1

+0+1+0+1+0+1+0

j%2 +1‐j%2*2

‐1+1‐1+1‐1+1‐1+1

Page 117: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列アクセス

2015/06/18先端GPGPUシミュレーション工学特論790

赤色要素の計算範囲 jによって変化(jの範囲は変更無し 0<j && j<Ny‐1) 1‐(j+1)%2<=i && i<Nx/2‐(j+1)%2

fr[]

0  1  2  3

0 1  2  3 

4  5  6  7

f[]

0‐10

‐10

‐10

‐1

‐(j+1)%2 1‐(j+1)%2

1<=0<=1<=0<=1<=0<=1<=0<=

Nx/2‐(j+1)%2

<4<3<4<3<4<3<4<3

Page 118: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

並列度の指定

2015/06/18先端GPGPUシミュレーション工学特論791

i方向のスレッド番号と配列添字の対応が単純化

fr[] fb[]

0  1  2  3

0 1  2  3 

4  5  6  7

j = blockIdx.y*blockDim.y + threadIdx.y;i = blockIdx.x*blockDim.x + threadIdx.x;

Page 119: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列アクセス

2015/06/18先端GPGPUシミュレーション工学特論792

赤色要素の参照点 jによってi方向のどちらを見るかが変化

jが奇数の時はi+1,偶数の時はi‐1fr[] fb[]

0 1  2  3 

4  5  6  7

f[]

0  1  2  3

Page 120: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列アクセス

2015/06/18先端GPGPUシミュレーション工学特論793

赤色要素の参照点 jによってi方向のどちらを見るかが変化

jが奇数の時はi+1,偶数の時はi‐1fr[] fb[]

0 1  2  3 

4  5  6  7

f[]

0  1  2  3

Page 121: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列アクセス

2015/06/18先端GPGPUシミュレーション工学特論794

赤色要素の参照点 jによってi方向のどちらを見るかが変化

iside = i‐1+(j%2)*2;fr[] fb[]

0  1  2  3

0 1  2  3 

4  5  6  7

‐1+j%2*2

+1‐1+1‐1+1‐1+1‐1

+1+0+1+0+1+0+1+0

j%2

Page 122: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

配列アクセス

2015/06/18先端GPGPUシミュレーション工学特論795

黒色要素の計算範囲 jによって変化(jの範囲は変更無し 0<j && j<Ny‐1) 0+(j+1)%2<=i && i<Nx/2‐(j  )%2

fb[]

0  1  2  3

0 1  2  3 

4  5  6  7

f[] 0+(j+1)%2

0<=1<=0<=1<=0<=1<=0<=1<=

Nx/2‐(j  )%2

<3<4<3<4<3<4<3<4

0+10

+10

+10

+1

+(j+1)%2

Page 123: Poisson方程式の求解 (線形連立一次方程式)»Š回の内容 675 先端GPGPUシミュレーション工学特論 2015/06/18 偏微分方程式の分類 Laplace方程式とその解法

レポート課題4(提出期限は1学期末)

共役勾配法を用いてPoisson方程式を解くプログラムを作成せよ. 境界条件等は授業で紹介した条件を用いよ

右辺(ソース項)

境界条件

必ずcudaSetDevice命令を利用してGPUを選択せよ

カーネルは独自に 適化せよ

配列のサイズも自身で決定せよ

先端GPGPUシミュレーション工学特論796 2015/06/18

yxg sinsin2

0sinsin22 yxf