本日は
色々言語を学んでくると言語間の連携に興味が出てきます.
Pythonは便利だから使いたい.でもC,C++がメインで開発されてきた資源を活用したい
といったときはBoostだったりCythonを使って呼び出すわけです(大変ですが・・・).
同じようにJuliaとPythonの間を繋げたいみたいなときもいつかは出て来るはずです.
Calling julia functions from python
によるとPythonからJuliaを呼び出すことはできるようです.やってみませう.
Julia0.7対応に合わせて、以下の内容を2018/9/17日に大幅に修正しました。
環境
Macで動作を確認しています.
python は pyenv でバージョンを切り替えています。これらのPythonと対応させるために
- macOSでpyenvで入れたpythonをPyCallで使うには
- HighSierraにしてpyenvからpython入れようとしたら失敗した”The Python ssl extension was not compiled. Missing the OpenSSL lib?”
などに目を通しておくと良さそうです。
0.7 の場合
Pythonは(pyenv で導入したminiconda3-3.19.0)3.5.5、Juliaは0.7
$ python
Python 3.5.5 | packaged by conda-forge | (default, Feb 13 2018, 05:40:31)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: https://docs.julialang.org
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.7.0 (2018-08-08 06:46 UTC)
_/ |\__'_|_|_|\__'_| | Official http://julialang.org/ release
|__/ | x86_64-apple-darwin14.5.0
julia>versioninfo()
Julia Version 0.7.0
Commit a4cb80f3ed (2018-08-08 06:46 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin14.5.0)
CPU: Intel(R) Core(TM) M-5Y51 CPU @ 1.10GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.0 (ORCJIT, broadwell)
Environment:
JULIA_BINDIR = /Applications/Julia-0.7.app/Contents/Resources/julia/bin/
JULIA_HOME = /Applications/Julia-0.7.app/Contents/Resources/julia/bin/
1.0 の場合
0.7で試したPythonでもOKでしたが、
pyenvによる次のコマンドで導入したPythonでも試しました。
$ CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install -v 3.6.3
$ python
Python 3.6.3 (default, Sep 28 2018, 17:02:21)
[GCC 4.2.1 Compatible Clang 5.0.1 (tags/RELEASE_501/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.0.0 (2018-08-08)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> versioninfo()
Julia Version 1.0.0
Commit 5d4eaca0c9 (2018-08-08 20:58 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin14.5.0)
CPU: Intel(R) Core(TM) M-5Y51 CPU @ 1.10GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.0 (ORCJIT, broadwell)
やってみませう(準備).
pyjulia は pip を使うことでも導入できます。
$ pip install julia # 今回はこれを使わない。
しかし、現在は Juliaのバージョン、0.7、1.0 対応が進んでいるため直接リポジトリをもってきてインストールした方が良さそうです(Julia1.0の場合はリポジトリから直接インストールしないとダメでした。)。下記のコマンドを実行します。
$ git clone https://github.com/JuliaPy/pyjulia.git
$ cd pyjulia
$ pip install .
また、 Julia 側の準備としては PyCall
を使うらしいので、Julia の REPL を使って導入します。Julia ENV["PYTHON"] を呼び出すPythonのパスを指定して PyCall のビルドをする必要があります。ここら辺の準備はPyCallの設定の話になるので PyCallのREADMEを参照しましょう。
呼び出してみやう
呼び出してみたい Julia の関数を書いてみます。配列の各々の要素を2倍するいたってシンプルなものです。
function twice_array(x::Array{T}) where T <: Number
return 2x
end
呼び出す側の Python のコードは下記のようになります。
include の仕方は
How to include source written in julia ? の Issue
にて教えてもらいました。
import numpy as np
def main():
from julia import Julia
julia = Julia()
julia.eval("@eval Main import Base.MainInclude: include")
from julia import Main
Main.include("test.jl")
arr = np.array([1, 2, 3])
ret = Main.twice_array(arr)
print("arr =", arr)
print("ret =", ret)
if __name__ == '__main__':
main()
実行結果は
$ python calljl.py
arr = [1 2 3]
ret = [2 4 6]
できましたね。
from julia import Main
でもってきた Main
というオブジェクトにJuliaの変数やら関数のオブジェクトを紐づけることができるようです。例えば、
\sin\left(\frac{\pi}{4}\right) = \frac{\sqrt{2}}{2}
などの確認は、
# Python のスクリプトでこれを書く
jlsin = Main.sin
Main.rad45degree = np.pi / 4
print(jlsin(Main.rad45degree), np.sqrt(2) / 2)
のようにしてPython上で記述できます。
トラブルシューティング
(Pythonのバージョンを切り替えたとき)
pyenv global <べつのPythonのバージョン>
で用いるPythonを変更した後は
JuliaのREPLでPyCallをビルドし直す必要があります。
julia> ENV["PYTHON"]="/Users/terasakisatoshi/.pyenv/shims/python"
"/Users/terasakisatoshi/.pyenv/shims/python"
(v1.0) pkg> build PyCall
Building Conda ─→ `~/.julia/packages/Conda/hsaaN/deps/build.log`
Building PyCall → `~/.julia/packages/PyCall/rUul9/deps/build.log`
(~/.pyenv/shims/python
だとPyCallのビルドが終わらない・・・)
最後に
Julia 0.7, および 1.0 で動作確認できました。
色々うまくいかないことがあれば、GitHubのイシューなどで調べると解決策が見つかるかもしれません。
また、pyjulia ライブラリは 0.1.5 から 0.2 のバージョンアップが試みられており、Julia 0.6 対応は捨てられるとのことです。