オブジェクト指向
Fortranが拓く
(はずだった)
新しい世界
名古屋大学未来材料・システム研究所
システム創成部門
助教 出川智啓
話をすることに
なった経緯
2017/06/072 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/073
第1回のシンポジウム
でわめいた
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/074
保守管理をどうしよう
かと悩んでいるならオ
ブジェクト指向プログ
ラミングやった方がい
いんじゃないスか?
(要約)
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/075
幹事会から打診がきた
第3回目をやるので話を
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/076
ヤバいことになった…
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
何を話すか
2017/06/077 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/078
オブジェクト指向プロ
グラミング(OOP)の
さわり
意図,書き方,考え方,
ちょっとした事例
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/079
OOPが救世主である
という話ではない
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0710
OOPをきっかけにプロ
グラミングについて考
えてみませんか?
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
誰に向けた話か
2017/06/0711 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0712
人外レベル
FORTRAN絶対
殺すマン
授業で習っただけ
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
おことわり
2017/06/0713 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0714
Intel Fortranを使った
結果です
他社コンパイラでは動
きません
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0715
分析,設計,実装をま
とめてオブジェクト指
向プログラミングと呼
びます
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0716
話が過度に誇張・一般
化されています
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0717
色々中途半端です
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
内容
2017/06/0718 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0719
1. オブジェクト指向プ
ログラミング(OOP)
とは
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0720
2. FortranとOOP
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0721
3. 2次元,3次元ベク
トルを使ったOOPの
説明
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0722
4. 簡単な実装例
1次元移流方程式
2次元非圧縮性粘性流れ
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0723
5. まとめ
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0724
1. オブジェクト指向プ
ログラミング(OOP)
とは
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0725
イヌもネコも哺乳類で
…
オブジェクト同士が
メッセージを交換しな
がら相互作用を…
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0726
プログラミング方法論
の一つ
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0727
派生型に関数・サブ
ルーチンを追加
オブジェクト
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0728
オブジェクトとそれら
の関係をうまく設計す
ればいいことがある
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0729
うまく設計するための
コスト<<いいこと
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0730
2. FortranとOOP
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
Fortranユーザと
OOPは相性がよい
2017/06/0731 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0732
保守管理をどうしよう
かと悩んでいる
現状
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0733
OOPは大規模・複雑化
したプログラムの開発,
保守,管理,拡張を効
率化するために誕生
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0734
資産が多くある
現状
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0735
他人のプログラムを信
用している
OOPは積極的に処理を
他のオブジェクトに任
せる
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0736
主目的は物理シミュ
レーション
現状
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0737
OOPはまず概念を設計
問題に応じて実体化
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0738
Fortranユーザは概念
をこねくりまわすこと
に慣れている
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0739
微分方程式を解析対象領域内
で積分した弱形式を形成
領域を要素に分割
各要素の係数行列を作成
領域全体の係数行列を作成
解を求める
有限要素法
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0740
現象の支配方程式
OOPでいう振る舞い
式に含まれる物理量
OOPでいうデータ
微分方程式
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0741
3. 2次元,3次元ベク
トルを使ったOOPの
説明
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0742
大きさと向きを持つ
OOPでいうところの
データ
空間ベクトル
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0743
和が定義される
スカラーとの積が計算
できる
OOPでいうところの振
る舞い
空間ベクトル
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
手続き型プログラ
ミングによる実装
2017/06/0744 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0745
大きさと内積の計算を
実装
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0746
module type_Vector2d
implicit none
type :: Vector2d
real(8) :: x
real(8) :: y
end type Vector2d
module type_Vector3d
implicit none
type :: Vector3d
real(8) :: x
real(8) :: y
real(8) :: z
end type Vector3d
Vector2d.f90
Vector3d.f90
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0747
interface magnitude
procedure :: magnitudeVector2d
end interface
interface dot
procedure :: dotVector2d
end interface
interface magnitude
procedure :: magnitudeVector3d
end interface
interface dot
procedure :: dotVector3d
end interface
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0748
!vectorの大きさ|u|
function magnitudeVector2d(vector) result(magnitude)
implicit none
type(Vector2d),intent(in) :: vector
real(8) :: magnitude    
magnitude = sqrt(vector%x**2+vector%y**2)
end function magnitudeVector2d
!vectorの大きさ|u|
function magnitudeVector3d(vector) result(magnitude)
implicit none
type(Vector3d),intent(in) :: vector
real(8) :: magnitude
magnitude = sqrt( vector%x**2+vector%y**2&
+vector%z**2)
end function magnitudeVector3d
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0749
!ベクトル同士の内積 u.v
function dotVector2d(term1,term2) result(dot)
implicit none
type(Vector2d),intent(in) :: term1
type(Vector2d),intent(in) :: term2
real(8) :: dot
dot = term1%x*term2%x + term1%y*term2%y
end function dotVector2d
!ベクトル同士の内積 u.v
function dotVector3d(term1,term2) result(dot)
implicit none
type(Vector3d),intent(in) :: term1
type(Vector3d),intent(in) :: term2
real(8) :: dot    
dot =  term1%x*term2%x + term1%y*term2%y&
+ term1%z*term2%z
end function dotVector3d
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0750
program main
use type_Vector2d
implicit none
type(Vector2d) :: u,v
u%x = 1d0 !成分に個別代入
u%y = 2d0 !
v = Vector2d(2d0, 1d0) !コンストラクタ
print *,'|u|=',magnitude(u)
print *,'|v|=',magnitude(v)
print '(A,F7.3)','u . v=',dot(u,v)
print '(A,F7.3)','v . u=',dot(v,u)
end program main
|u|=   2.23606797749979
|v|=   2.23606797749979
u . v=  4.000
v . u=  4.000
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0751
program main
use type_Vector3d
implicit none
type(Vector3d) :: u,v
u%x = 1d0 !成分に個別代入
u%y = 2d0 !
u%z = 3d0 !
v = Vector3d(3d0, 2d0, 1d0) !コンストラクタ
print *,'|u|=',magnitude(u)
print *,'|v|=',magnitude(v)
print '(A,F7.3)','u . v=',dot(u,v)
print '(A,F7.3)','v . u=',dot(v,u)
end program main
|u|=   3.74165738677394
|v|=   3.74165738677394
u . v= 10.000
v . u= 10.000
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0752
関数に渡す引数を間違
える可能性がある
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0753
四則演算をするために
関数を呼ばなければな
らない
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0754
似たような処理を複数
箇所で実装しなければ
ならない
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
オブジェクト指向
プログラミングに
よる実装
2017/06/0755 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0756
派生型に成分だけでな
く手続*も持たせる
*サブルーチンと関数の総称
正式には型束縛手続
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0757
module class_Vector2d
implicit none
type :: Vector2d
real(8),public :: x
real(8),public :: y
contains
!ここに手続の宣言を追加する
end type Vector2d
contains
!ここに手続の実装を追加する
end module class_Vector2d
class_Vector2d.f90
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0758
⋮
type :: Vector2d
real(8),public :: x
real(8),public :: y
contains
procedure,public,pass :: magnitude !大きさを計算する手続
end type Vector2d
contains
!magnitudeの実装
real(8) function magnitude(this)
implicit none
class(Vector2d),intent(in) :: this
magnitude = sqrt(this%x**2+this%y**2)
end function magnitude
⋮
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0759
⋮
type :: Vector2d
⋮
procedure,public,pass :: dot !内積を計算する手続
end type Vector2d
⋮
!dotの実装
real(8) function dot(term1,term2)
implicit none
class(Vector2d),intent(in) :: term1
class(Vector2d),intent(in) :: term2
dot = term1%x*term2%x + term1%y*term2%y
end function dot
⋮
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0760
program main
use class_Vector2d
implicit none
type(Vector2d) :: u,v
u%x = 1d0; u%y = 2d0
v%x = 2d0; v%y = 1d0 
print *,'|u|=',u%magnitude()
print *,'|v|=',v%magnitude()
print '(A,F7.3)','u . v=',u%dot(v)
print '(A,F7.3)','v . u=',v%dot(u)
end program main
main.f90
|u|=   2.23606797749979
|v|=   2.23606797749979
u . v=  4.000
v . u=  4.000
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
派生型の拡張
2017/06/0761 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0762
Vector2dの成分と手
続を全て受け継いで
Vector3dを作ることが
できる
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0763
OOPの用語では継承
Fortranの用語では拡張
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
module class_Vector3d
use class_Vector2d
implicit none
type,extends(Vector2d) :: Vector3d
!Vector2dに追加する成分,型束縛手続のみを書く
real(8),public :: z
end type Vector3d
end module class_Vector3d
2017/06/0764
class_Vector3d.f90
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼65
class(Vector2d)
Vector2dとそれを拡張
した全ての派生型
多相的派生型
2017/06/0766
program main
use class_Vector3d
implicit none
type(Vector3d) :: u
u%x = 1d0;u%y = 2d0;u%z = 3d0
print *,'|u|=',u%magnitude()
end program main
main.f90
|u|=   2.23606797749979
正しくは
|u|=   3.74165738677394
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼67
magnitudeの中身はz
成分のないVector2dに
対する実装
型束縛手続の
上書き
2017/06/0768
オーバーライド
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0769
module class_Vector3d
use class_Vector2d
implicit none
type,extends(Vector2d) :: Vector3d
⋮
contains
procedure,public ,pass :: magnitude!magnitudeの上書き
end type Vector3d
contains
!上書きする内容
real(8) function magnitude(this)
implicit none
class(Vector3d),intent(in) :: this
magnitude = sqrt(this%x**2+this%y**2+this%z**2)
end function magnitude
end module class_Vector3d
class_Vector3d.f90
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0770
dotも上書き
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
module class_Vector3d
use class_Vector2d
implicit none
type,extends(Vector2d) :: Vector3d
⋮
procedure,public ,pass :: dot!dotの上書き
end type Vector3d
⋮
!上書きする内容
real(8) function dot(term1,term2)
implicit none
class(Vector3d),intent(in) :: term1
class(Vector3d),intent(in) :: term2
dot =  term1%x*term2%x&
+ term1%y*term2%y&
+ term1%z*term2%z
end function dot
end module class_Vector3d
2017/06/0771
NG
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼72
第1引数以外の型を
変更してはならない
正確にはもう少し細かい条件がある
2017/06/0773
real(8) function dot(temr1, term2)
implicit none
class(Vector3d),intent(in) :: term1
class(Vector2d),intent(in) :: term2
select type(term2)
class is (Vector3d) !type is (Vector3d)でもよい
dot =  term1%x*term2%x&
+ term1%y*term2%y&
+ term1%z*term2%z
class default
stop "error : unsupported class/type"
end select
end function dot
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0774
program main
use class_Vector3d
implicit none
type(Vector3d) :: u
u%x = 1d0;u%y = 2d0;u%z = 3d0
print *,'|u|=',u%magnitude()
end program main
|u|=   3.74165738677394
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
演算子の多重定義
2017/06/0775
オーバーロード
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0776
代入や加減算,大小比
較の度に型束縛手続を
呼ぶのは煩わしい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0777
代入や加算,比較の演
算子と手続を対応付け
ることができる
演算子の多重定義
今回は省略
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
拡張演算
2017/06/0778 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0779
任意の演算を行う演算
子をユーザが定義
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0780
.演算子名.として定義
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0781
2本のベクトルの直交
判定を行う演算子
.orth.
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0782
type :: Vector2d
⋮
procedure,public,pass :: isOrthogonal
!拡張演算と手続の対応付け
generic :: operator(.orth.) => isOrthogonal
end type Vector2d
⋮
logical function isOrthogonal(this,term2) 
implicit none
class(Vector2d),intent(in) :: this
class(Vector2d),intent(in) :: term2
!ゼロベクトルは対象外
if(abs(this%dot(term2))<1d‐14)then !内積が10‐14未満なら
isOrthogonal = .true. !0とみなして直交
else
isOrthogonal = .false. !10‐14以上なら非直交
end if
end function isOrthogonal
class_Vector2d.f90
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0783
program main
use class_Vector2d
implicit none
type(Vector2d) :: u,v
u%x =  2d0; u%y = 1d0
v%x = ‐1d0; v%y = 2d0
if(u .orth. v)then
print *,'u and v are orthogonal to each other'
else
print *,'u and v are not orthogonal to each other'
end if
end program main
main.f90
u and v are orthogonal to each other
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
Vector3dにおける
演算子の多重定義
と拡張演算
2017/06/0784 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0785
派生型を拡張すると演
算子の多重定義も引き
継がれる
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0786
拡張演算も当然引き継
がれる
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0787
.orth.は中で手続dotを
呼んでいるだけ
dotが適切に上書きされ
ていれば何もしなくて
よい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0788
program main
use class_Vector3d
implicit none
type(Vector3d) :: u,v
u%x = 3d0; u%y = 2d0; u%z =  1d0
v%x = 1d0; v%y = 0d0; v%z = ‐3d0
if(u .orth. v)then
print *,'u and v are orthogonal to each other'
else
print *,'u and v are not orthogonal to each other'
end if
end program main
main.f90
u and v are orthogonal to each other
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0789
4. 実装例
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0790
要求に応じたプログラ
ムを設計できる事の例
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
1次元移流方程式
2017/06/0791 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0792
メインルーチンで空間
微分や時間積分を楽に
書きたい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0793
既存のコードを流用し
たい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0794
0





x
f
c
t
f
支配方程式
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0795
初期条件
0 0.2 0.4 0.6 0.8 1
0
0.5
1
    
10
/2cos1
2
1






 xLxxf 
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0796
subroutine initialize(f)
use parameters,only:Nx,dx,Lx,PI2
implicit none
real(8),intent(inout) :: f(Nx)
integer :: i
do i = 1,Nx
f(i)  = ((1d0‐cos(PI2*dble(i‐1)*dx/Lx))/2d0)**10
end do
end subroutine initialize
kernel.f90
    
10
/2cos1
2
1






 xLxxf 
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0797
subroutine computeDifference(d_f_dx,f)
use parameters,only:Nx,dx2
implicit none
real(8),intent(out) :: d_f_dx(Nx)
real(8),intent(in)  ::   f   (Nx)
integer :: i
i=1
d_f_dx(i) = (‐3d0*f(i)+4d0*f(i+1)‐f(i+2))/dx2
do i=2,Nx‐1
d_f_dx(i) = (f(i+1)‐f(i‐1))/dx2
end do
i=Nx
d_f_dx(i) = ( 3d0*f(i)‐4d0*f(i‐1)+f(i‐2))/dx2
end subroutine computeDifference
















Δx
fff
Δx
ff
Δx
fff
dx
df
xxx NNN
ii
2
43
2
2
43
21
11
321
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0798
program convection
use parameters,only:Nx,Nt,dt,c
use kernel,only:initialize,computeDifference
implicit none
real(8),allocatable ::   f   (:)
real(8),allocatable :: d_f_dx(:)
integer :: n
allocate(  f   (Nx))
allocate(d_f_dx(Nx))
call initialize(f)
do n=1,Nt
call computeDifference(d_f_dx,f)
f(:) = f(:) ‐ dt*c*d_f_dx(:)
end do
deallocate(  f   )
deallocate(d_f_dx)
end program convection
main.f90
x
f
tcΔff



n
n1n
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/0799
t=0 s
0.1
0.2
0.3
0.4
0.5
0 0.5 1
0
1
f
x
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
実行結果
2017/06/07100
時間積分法の変更
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07101
Euler法
x
f
tcΔff



n
n1n
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07102
修正Euler法
x
f
tcΔff




n
nn 2
1
















x
f
x
ftcΔ
ff
2
1nn
n1n
2
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07103
call computeDifference(d_f_dx,f)
f05(:) = f(:) ‐ dt*c*d_f_dx(:)
call computeDifference(d_f05_dx,f05)
f(:) = f(:) ‐ dt*c*(d_f_dx(:)+d_f05_dx(:))/2d0
call computeDifference(d_f_dx,f)
f(:) = f(:) ‐ dt*c*d_f_dx(:)
f(:) = f(:) ‐ dt*c*(d_f_dx(:)+d_f05_dx(:))/2d0
call computeDifference(d_f_dx,f)
f05(:) = f(:) ‐ dt*c*d_f_dx(:)
f(:) = f(:) ‐ dt*c*(d_f_dx(:)+d_f05_dx(:))/2d0
call computeDifference(d_f_dx,f)
f05(:) = f(:) ‐ dt*c*d_f_dx(:)
call computeDifference(d_f05_dx,f)
f(:) = f(:) ‐ dt*c*(d_f_dx(:)+d_f05_dx(:))/2d0
(a)
(b)
(c)
(d)
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07104
t=0 s
0.1
0.2
0.3
0.4
0.5
0 0.5 1
0
1
f
x 0 0.5 1
0
1 t=0 s
0.1
0.2
0.3
0.4
0.5
f
x
0 0.5 1
0
1 t=0 s
0.1
0.2
0.3
0.4
0.5
f
x 0 0.5 1
0
1 t=0 s
0.1
0.2
0.3
0.4
0.5
f
x
( ) ( )
( ) ( )
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07105
こういうミスをしない
ために
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07106
real(8) :: f(N), d_f_dx(N)
do n=1, n_end
call computeDifference(f, d_f_dx, N)
f(:) = f(:) ‐ dt*c*d_f_dx(:)
end do
物理量とその微分
値が分離
微分値と微分
の計算が分離
type(Field) :: f
do n=1, n_end
f = f ‐ dt*c*f%x()
end do
物理量と微分値,
微分の計算を包括
書籍等に書かれて
いる式と類似
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
手続き型
OOP
2017/06/07107
物理量を表す派生型
場を表す派生型
物理量を包括
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07108
名前
データ1
データ2…
振る舞い1
振る舞い2
振る舞い3…
オブジェクトの簡易表現
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07109
ScalarVariable
値
空間微分値
値の初期化
空間微分の計算
代入演算子
物理量型
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07110
場を表す型
Field
物理量
場の初期化
空間微分の計算
代入演算子
加算演算子
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07111
既存のサブルーチン
kernel
初期化
空間微分の計算
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07112
program convection_oop
use parameters,only:Nt,c,dt
use class_Field
implicit none
type(Field) :: f  !場を表す派生型の変数
integer :: n
call f%construct() !前処理
call f%initialize() !値の初期化
do n=1,Nt
f = f + f%x()*‐c*dt !時間積分
end do
call f%destruct() !後処理
end program convection_oop
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07113
ScalarVariable
値
空間微分値
値の初期化
空間微分の計算
代入演算子
Field
物理量
場の初期化
空間微分の計算
代入演算子
加算演算子
kernel
初期化
空間微分の計算
type(Field) :: f
integer :: n
call f%initialize()
do n=1,Nt
f = f + f%x()*‐c*dt
end do
参照
委譲
委譲
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07114
subroutine initialize(this)
implicit none
class(Field),intent(inout) :: this
call this%f%initialize()
end subroutine initialize
subroutine initialize(this)
use kernel,only: initializeKernel=>initialize
implicit none
class(ScalarVariable),intent(inout)  :: this
call initializeKernel(this%value)
end subroutine initialize
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
Field
ScalarVariable
2017/06/07115
ScalarVariable
値
空間微分値
値の初期化
空間微分の計算
代入演算子
Field
物理量
場の初期化
空間微分の計算
代入演算子
加算演算子
kernel
初期化
空間微分の計算
type(Field) :: f
integer :: n
call f%initialize()
do n=1,Nt
f = f + f%x()*‐c*dt
end do
参照
委譲
委譲
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
function x(this) result(d_v_dx)
implicit none
class(Field),intent(inout) :: this
real(8),dimension(:),pointer :: d_v_dx
!派生型ScalarVariableの手続x()が戻すアドレスと結合
d_v_dx=>this%f%x()
end function x
2017/06/07116 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
Field
function x(this) result(d_v_dx)
⋮
implicit none
class(ScalarVariable),intent(inout)  :: this
real(8),dimension(:),pointer :: d_v_dx
!微分を計算する必要があるかを判定して,必要があれば微分を計算
if(.not.this%d_v_dxCalculated .or. this%updated)then
call computeDifferenceKernel(this%d_v_dx,this%value)
end if
!微分値を保持する配列へのポインタを返す
call c_f_pointer( (c_loc(this%d_v_dx)), d_v_dx, (/Nx/) )
this%d_v_dxCalculated = .true.
this%updated = .false.
end function x
2017/06/07117 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
ScalarVariable
2017/06/07118
時間積分法の変更
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07119
program convection_oop
use parameters,only:Nt,c,dt
use class_Field
implicit none
type(Field) :: f  !場を表す派生型の変数
integer :: n
call f%construct() !前処理
call f%initialize() !値の初期化
do n=1,Nt
f = f + f%x()*‐c*dt !時間積分
end do
call f%destruct() !後処理
end program convection_oop
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07120
program convection_oop
use parameters,only:Nt,c,dt
use class_Field
implicit none
type(Field) :: f, f05 !場を表す派生型の変数
integer :: n
call f%construct() !前処理
call f05%construct() !
call f%initialize() !値の初期化
do n=1,Nt
f05 = f + f%x()*‐c*dt !時間積分
f   = f + (f%x()+f05%x())/2d0*‐c*dt !
end do
call f%destruct() !後処理
call f05%destruct() !
end program convection_oop
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07121
ミスの入り込む余地が
ない
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07122
fの微分を計算する手
続きが2回呼び出され
ている
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07123
do n=1,Nt
f05 = f + f%x()*‐c*dt
f   = f + (f%x()+f05%x())/2d0*‐c*dt
end do
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
f%d_v_dxCalculated F
f%updated F
f05%d_v_dxCalculated F
f05%updated          F
T
T
T
T
F
2017/06/07124
実行時間の比較
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07125
210 212 214 216 218 220
102
101
100
10-1
10-2
10-3
離散点の個数Nx
1ステップあたりの実行時間[ms] 手続型
OOP
O(Nx)
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07126
最大で4倍ほど遅い
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07127
おそらく微分の手続
(ポインタ)とオー
バーロードされた演算
子が原因
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07128
時間積分が簡単に書け
るけど4倍遅いアルゴ
リズムを使いますか?
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2次元非圧縮性粘性
流れ
2017/06/07129 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07130
Formula Translation
しなくていいから速度
低下を最低限にしたい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07131
圧力Poisson方程式の
ソルバをいい感じに切
り替えたい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07132
連続の式
Navier-Stokes方程式
0





y
v
x
u





















































2
2
2
2
2
2
2
2
1
1
y
v
x
v
y
p
y
v
v
x
v
u
t
v
y
v
x
u
x
p
y
u
v
x
u
u
t
u




並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07133
: x, y方向中間速度
































































2
2
2
2
2
2
2
2
Re
1~
Re
1~
y
v
x
v
y
v
v
x
v
uΔtvv
y
u
x
u
y
u
v
x
u
uΔtuu
nnn
n
n
nn
nnn
n
n
nn
















 
y
v
x
u
Δty
p
x
p nn ~~1
2
12
2
12
















y
p
Δtvv
x
p
Δtuu
n
n
n
n
1
1
1
1
~
~
vu ~,~
Fractional Step法
(1)
(2)
(3)
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07134
こんな風に書きたい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07135
type(Parameter) :: cavity = new Parameter&
(x, y, t, Fluid=Water, Re)
type(FractionalStep) :: fs_cavity= new FlactionalStep&
(Field = cavity, Solver = new SOR(ε, α))
call fs_cavity%integrate(from=0, to=100)
Poissonソルバ
の動的な決定
必要なパラ
メータの設定
離散化情報や
物性値を一括
管理
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07136 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
program main
⋮
implicit none
type(Parameter1d)  :: x,y,t
type(FieldParameter2d) :: cavity
type(FractionalStep)   :: fs_cavity
call cavity%construct( x, y, t ,fluid=Water,Re=Re,...)
!計算条件とPoissonソルバをアルゴリズムに渡して初期化
call fs_cavity%construct(Field  = cavity,&
Solver = SOR(&
error_tolerance = 1d‐9,&
accelaration = 1.925d0))
!時間積分開始
call fs_cavity%integrate(from=1, to=Nt)
end program main
main.f90
2017/06/07137 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
subroutine integrate(this,from,to)
⋮
TimeIntegrate:block
integer :: n
do n=ts,te
call this%computeAuxiliaryVelocity()
call this%computePressure()
call this%computeVelocity()
end do
end block TimeIntegrate
end subroutine integrate
FractionalStep.f90
2017/06/07138 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
subroutine computePressure(this)
implicit none
class(FractionalStep),intent(inout) :: this
call this%solver%solve(this%pres,this%dive)
end subroutine computePressure
FractionalStep.f90
2017/06/07139
Poissonソルバ型
PoissonSolver
許容誤差
solve
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
SOR
加速係数
solve
RedBlackSOR
solve
CG
残差
補助ベクトル
solve
FractionalStep
solver
computePressure
継承
継承
継承
参照
2017/06/07140
計算結果
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼141
0
Ly
0 Lx
2017/06/07142 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
0
0.5
1
0.5 10
x/Lx
y/Lx
0 1−1
0
1
−1
v/U
u/U
計算結果
Ghia et al.
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼143
1計算ステップ(1反
復)あたりの実行時間
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼144
手続型
OOP
1ステップ1反復あたりの実行時間[ms]
(1反復あたり)
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼145
実行時間の増加は1.14
倍∼1.18倍
格子点数を増やしても
この比率は変わらない
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼146
Poissonソルバの切替
Poissonソルバ型変数を
適切にallocateするだけ
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼147
call fs_cavity%construct(Field  = cavity,&
Solver = SOR(&
error_tolerance = 1d‐9,&
accelaration = 1.925d0))
call fs_cavity%construct(Field  = cavity,&
Solver = RedBlackSOR(&
error_tolerance = 1d‐9,&
accelaration = 1.925d0))
call fs_cavity%construct(Field  = cavity,&
Solver = CG(&
error_tolerance = 1d‐9))
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼148
allocate(SOR::solver)
allocate&
(RedBlackSOR::solver)
allocate(CG::solver)
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼149
時間進行の途中で
Poisson方程式のソル
バを簡単に切り替え
deallocate -> allocate
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼150
ベクトルPoisson方程
式のソルバを成分ごと
に変更するのも簡単
2017/06/07151
5. まとめ
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
結局あなたは何が
言いたいの?
2017/06/07152 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07153
OOPはみんなの味方
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07154
近代以降のプログラム
開発方法は,後で楽を
するために導入されて
いる
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07155
よい書き方を積極的に
再利用する文化がある
デザインパターン
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07156
1. 美しい=読みやすい
2. 正しい
3. 速い
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07157
FORTRANは書きやす
いがとても読みにくい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07158
暗黙の型宣言,方言,
大量のグローバル変数,
統一性の無いインデン
ト,行番号,goto,ド
キュメントが論文のみ,
等々
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07159
FORTRANを授業で
教えなくなったから
FORTRAN人口が減少
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07160
FORTRANを教わった
結果,使うのを拒否
した可能性も
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07161
コードが生み出す利益
保守管理に要する費用
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07162
資産を資産として適切
に熟成させていく一つ
の手段がOOP
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07163
OOPの考え方に触れて,
少しずつでいいので
コードの改善を
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
もしFortranにオブ
ジェクト指向プロ
グラミングが普及
していたら
2017/06/07164 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
数値計算に関係
する研究・開発が
効率化
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼165
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼166
コードの保守管理に
かかる手間が減るので,
その時間を研究に充当
できる
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼167
学生が手を入れる範囲
を明確にできるので,
インハウスコードが
汚染されない
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼168
学生の入れ替わりに
対して堅牢になる
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼169
ドキュメントを書く事
が当たり前になるので,
情報の入手が容易に
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼170
エディタや統合開発環
境のサポートが充実し,
入力補完など利便性が
向上
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼171
Unicode対応が行われ,
変数にギリシャ文字を
使えるように(希望)
omega=omega+dt*nu...
ω = ω + Δt*ν*…
Fortranから新しい
開発手法,連携の
形が誕生していた
かも
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼172
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼173
OOPは設計ありき
誰も実現していない方
法の実装には適さない
要求を定義し,仕様書
を書くことが研究
2017/06/07174
ソフトウェア開発方法
論を研究開発に適した
形で取り込む努力をす
るべきだった
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07並列Fortranの現状と展望 ∼現代化か肥大化か?∼175
OOPは設計ありき
設計を書いたら実装は
パートナーさんや他社
に委託
2017/06/07176
Fortranでは計算機に
応じたチューニングが
できてナンボ
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07177
Fortranコミュニティ
の中で,構造を考える
のが得意な人と実装が
得意な人が協調
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
これから
どうしたいの?
2017/06/07178 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07179
使いますか?ではなく
使ってどんなことがで
きるかを考えたい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07180
教育も含めたベスト
プラクティスを蓄積
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07181
その中で使う機能の
性能向上を要求
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07182
救世主はいません
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07183
現状を把握して地道に
やっていくしかない
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07184
OOPは通過点
現代ではなく近代の機能
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07185
OOPの思想自体は古代
からあった
OOPのコストを計算機が
吸収できるようになった
のが近代
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07186
オブジェクト指向言語
Fortranは次にどうい
う言語になるべきか?
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
Take-Home
Message
2017/06/07187 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
FORTRANが嫌い
で嫌いで仕方ない
方へ
2017/06/07188 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07189
Fortranはクソ言語
などと煽ると,
そんなことはない!
という人が現れます
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07190
今のままなら,静観し
ているだけで滅びます
安心して待っていてく
ださい
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
FORTRANユーザ
へ
2017/06/07191 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07192
今日家に帰ったら,
プログラムにimplicit
noneを書きましょう
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07193
それが新しい世界への
第1歩です
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
ご清聴ありがとう
ございました
2017/06/07194 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
自己紹介
2017/06/07195 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07196
 奈良高専電子制御工学科
 奈良高専専攻科機械制御工学専攻
 名古屋大学大学院情報科学研究科
 電気通信大学知能機械工学専攻 助教
 沼津高専電子制御工学科 講師
 長岡技術科学大学電気系 特任准教授
 株式会社トヨタコミュニケーションシステム
エンジニアリングシステム本部ES4部 主任
 名古屋大学未来材料・システム研究所システ
ム創成部門 助教
C
Fortran
CUDA,MPI,OpenMP
Java,OOP
Python
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07197
 奈良高専電子制御工学科
 奈良高専専攻科機械制御工学専攻
 名古屋大学大学院情報科学研究科
 電気通信大学知能機械工学専攻 助教
 沼津高専電子制御工学科 講師
 長岡技術科学大学電気系 特任准教授
 株式会社トヨタコミュニケーションシステム
エンジニアリングシステム本部ES4部 主任
 名古屋大学未来材料・システム研究所システ
ム創成部門 助教
有
限
要
素
法
渦
法
,
差
分
法
コ
ン
パ
ク
ト
差
分
法
有
限
体
積
法
実
験
に
切
替
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07198
数値計算関係の教育が
得意です
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
ある学生の例
2017/06/07199 並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07200
7月末
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07201
10月1日現職着任
並列Fortranの現状と展望 ∼現代化か肥大化か?∼
2017/06/07202
11月
密度界面に衝突する渦輪の
3次元渦法シミュレーション
並列Fortranの現状と展望 ∼現代化か肥大化か?∼

オブジェクト指向Fortranが拓く(はずだった)新しい世界