Takuya Miyashita
This site
Web
Start:
*Julia から Fortran の subroutine を呼び出す [#x947bacd]
#contents
**はじめに [#r30b4559]
ccall という関数で Fortran の subroutine と function を使...
使用法について,まずは公式ドキュメント
-[[Calling C and Fortran Code>https://docs.julialang.org/...
と下のリンクを読む.
-[[JuliaからFortranのsubroutineを呼び出す - Qiita>https:/...
-[[JuliaからFortranの構造体を引数にもつsubroutineを呼び出...
**使用例1 テスト [#qff22c28]
実行バージョンは Julia v1.3.1~
***Fortran 側 [#gc22704d]
例として下にあるような簡単な Fortran の subroutine を使う.
#codeprettify(lang-fortran){{
subroutine test1(n,a,b,c) bind(c, name="test1")
implicit none
integer , intent(in) :: n
real*8, intent(in) :: a
real*8, intent(out) :: b, c
b = a**n
c = n*a
! 確認
print *, "b = ",b
print *, "c = ",c
return
end subroutine test1
}}
整数 n と倍精度実数 a を入力して,倍精度実数 b, c を返す...
このコードが書いてあるファイル( ccalltest.f90 とする)を,...
#codeprettify{{
ifort ccalltest.f90 -o ccalltest.so -fPIC -shared # gf...
}}
***Julia 側 [#j0e7f576]
この生成された ccalltest.so から test1 をJulia 上で呼ぶこ...
Fortran の integer, real*8 型は それぞれ Julia の Int32, ...
#codeprettify(lang-julia){{
n = Int32(5)
a = Float64(2.0)
b = [Float64(0.0)] # 配列にする b = zeros(Float64, 1) 等...
c = [Float64(0.0)] # 配列にする
ccall((:test1, "./ccalltest.so"), Nothing, (Ref{Int32}, R...
}}
ここで最後の行に着目すると,ccall の引数は
#codeprettify(lang-julia){{
ccall((function_name, library), returntype, (argtype1, .....
}}
であり,注意すべきは Fortran の subroutine では returntyp...
この Ref{} がないと Julia が強制終了してしまうので注意.~
subroutine ではなく function を ccall で呼び出す場合,ret...
~
上の Julia のコードを実行すると
b = 32.0000000000000
c = 10.0000000000000
[32.0]
[10.0]
となる.~
~
もう1つ気をつける点は,値が返される変数は配列でなくても V...
b, c を配列でなく
#codeprettify(lang-julia){{
b = Float64(0.0)
c = Float64(0.0)
}}
のようにしてしまうと,実行結果は
b = 32.0000000000000
c = 10.0000000000000
0.0
0.0
となり,処理は問題なく実行できるにも関わらず,値が Julia ...
~
**使用例2 実践 [#n11c0adc]
F77 形式で書かれている防災科研の DC3D モデル (Okada, 1992...
ソースコードは [[断層モデルによる地殻変動計算プログラム>h...
呼び出すためにまずはコンパイル.~
#codeprettify{{
ifort DC3Dfortran.f -fPIC -shared -o DC3Dfortran.f.so
}}
次に,subroutine DC3D を呼び出す時の名前を,nm コマンドで...
#codeprettify{{
nm DC3Dfortran.f.so
}}
実行すると
0000000000004640 T dc3d_
のように サブルーチン名にアンダースコア("_")がついた文字...
FORTRAN のソースが単精度浮動小数点数なことに注意して,呼...
引数が多いとだいぶ面倒くさい.
#codeprettify{{
function DC3Df(x::T, y::T, z::T, depth::T, dip::T,
L1::T, L2::T, W1::T, W2::T,
Δu₁::T, Δu₂::T, Δu₃::T; α::T=2/3) where T ...
# convert
α, x, y, z, depth, dip, L1, L2, W1, W2, Δu₁, Δu₂, Δu₃...
[α, x, y, z, depth, dip, L1, L2, W1, W2, Δu₁, Δu₂, Δu...
# args
ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz, uyz, u...
IRET = zeros(Int32,1)
# call
ccall((:dc3d_, "./DC3Dfortran.f.so"), Nothing,
( # argtype
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32}, Ref{...
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32}, Ref{...
),
α, x, y, z, depth, dip, L1, L2, W1, W2, Δu₁, Δ...
ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz,...
)
# convert
ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz, uyz, u...
[ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz, uyz, ...
# return
return [ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz...
end
}}
適当な値を入力してこの function を使ってみる.
#codeprettify(lang-julia){{
X = -99.0:2.0:99.0
Y = X
nx = length(X)
ny = length(Y)
L1 = -50.0
L2 = 50.0
W1 = -50.0
W2 = 50.0
z = -30.0
depth = 50.0
dip =70.0
Δu₁ = 200.0
Δu₂ = -150.0
Δu₃ = 100.0
uz = [DC3Df(X[j], Y[i], z, depth, dip, L1, L2, W1, W2, Δu...
# plot
using Plots
plotlyjs()
plt = plot(X, Y, uz, linetype=:surface, c=:balance, clims...
}}
#htmlinsert(Julia/DC3D.html)
End:
*Julia から Fortran の subroutine を呼び出す [#x947bacd]
#contents
**はじめに [#r30b4559]
ccall という関数で Fortran の subroutine と function を使...
使用法について,まずは公式ドキュメント
-[[Calling C and Fortran Code>https://docs.julialang.org/...
と下のリンクを読む.
-[[JuliaからFortranのsubroutineを呼び出す - Qiita>https:/...
-[[JuliaからFortranの構造体を引数にもつsubroutineを呼び出...
**使用例1 テスト [#qff22c28]
実行バージョンは Julia v1.3.1~
***Fortran 側 [#gc22704d]
例として下にあるような簡単な Fortran の subroutine を使う.
#codeprettify(lang-fortran){{
subroutine test1(n,a,b,c) bind(c, name="test1")
implicit none
integer , intent(in) :: n
real*8, intent(in) :: a
real*8, intent(out) :: b, c
b = a**n
c = n*a
! 確認
print *, "b = ",b
print *, "c = ",c
return
end subroutine test1
}}
整数 n と倍精度実数 a を入力して,倍精度実数 b, c を返す...
このコードが書いてあるファイル( ccalltest.f90 とする)を,...
#codeprettify{{
ifort ccalltest.f90 -o ccalltest.so -fPIC -shared # gf...
}}
***Julia 側 [#j0e7f576]
この生成された ccalltest.so から test1 をJulia 上で呼ぶこ...
Fortran の integer, real*8 型は それぞれ Julia の Int32, ...
#codeprettify(lang-julia){{
n = Int32(5)
a = Float64(2.0)
b = [Float64(0.0)] # 配列にする b = zeros(Float64, 1) 等...
c = [Float64(0.0)] # 配列にする
ccall((:test1, "./ccalltest.so"), Nothing, (Ref{Int32}, R...
}}
ここで最後の行に着目すると,ccall の引数は
#codeprettify(lang-julia){{
ccall((function_name, library), returntype, (argtype1, .....
}}
であり,注意すべきは Fortran の subroutine では returntyp...
この Ref{} がないと Julia が強制終了してしまうので注意.~
subroutine ではなく function を ccall で呼び出す場合,ret...
~
上の Julia のコードを実行すると
b = 32.0000000000000
c = 10.0000000000000
[32.0]
[10.0]
となる.~
~
もう1つ気をつける点は,値が返される変数は配列でなくても V...
b, c を配列でなく
#codeprettify(lang-julia){{
b = Float64(0.0)
c = Float64(0.0)
}}
のようにしてしまうと,実行結果は
b = 32.0000000000000
c = 10.0000000000000
0.0
0.0
となり,処理は問題なく実行できるにも関わらず,値が Julia ...
~
**使用例2 実践 [#n11c0adc]
F77 形式で書かれている防災科研の DC3D モデル (Okada, 1992...
ソースコードは [[断層モデルによる地殻変動計算プログラム>h...
呼び出すためにまずはコンパイル.~
#codeprettify{{
ifort DC3Dfortran.f -fPIC -shared -o DC3Dfortran.f.so
}}
次に,subroutine DC3D を呼び出す時の名前を,nm コマンドで...
#codeprettify{{
nm DC3Dfortran.f.so
}}
実行すると
0000000000004640 T dc3d_
のように サブルーチン名にアンダースコア("_")がついた文字...
FORTRAN のソースが単精度浮動小数点数なことに注意して,呼...
引数が多いとだいぶ面倒くさい.
#codeprettify{{
function DC3Df(x::T, y::T, z::T, depth::T, dip::T,
L1::T, L2::T, W1::T, W2::T,
Δu₁::T, Δu₂::T, Δu₃::T; α::T=2/3) where T ...
# convert
α, x, y, z, depth, dip, L1, L2, W1, W2, Δu₁, Δu₂, Δu₃...
[α, x, y, z, depth, dip, L1, L2, W1, W2, Δu₁, Δu₂, Δu...
# args
ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz, uyz, u...
IRET = zeros(Int32,1)
# call
ccall((:dc3d_, "./DC3Dfortran.f.so"), Nothing,
( # argtype
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32}, Ref{...
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32},
Ref{Float32}, Ref{Float32}, Ref{Float32}, Ref{...
),
α, x, y, z, depth, dip, L1, L2, W1, W2, Δu₁, Δ...
ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz,...
)
# convert
ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz, uyz, u...
[ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz, uyz, ...
# return
return [ux, uy, uz, uxx, uyx, uzx, uxy, uyy, uzy, uxz...
end
}}
適当な値を入力してこの function を使ってみる.
#codeprettify(lang-julia){{
X = -99.0:2.0:99.0
Y = X
nx = length(X)
ny = length(Y)
L1 = -50.0
L2 = 50.0
W1 = -50.0
W2 = 50.0
z = -30.0
depth = 50.0
dip =70.0
Δu₁ = 200.0
Δu₂ = -150.0
Δu₃ = 100.0
uz = [DC3Df(X[j], Y[i], z, depth, dip, L1, L2, W1, W2, Δu...
# plot
using Plots
plotlyjs()
plt = plot(X, Y, uz, linetype=:surface, c=:balance, clims...
}}
#htmlinsert(Julia/DC3D.html)
Page:
Edit with a page name which already exists