21
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

PythonからJuliaを呼び出したいんだ(Julia v 0.7 および v1.0 で OK)

本日は

色々言語を学んでくると言語間の連携に興味が出てきます.
Pythonは便利だから使いたい.でもC,C++がメインで開発されてきた資源を活用したい
といったときはBoostだったりCythonを使って呼び出すわけです(大変ですが・・・).

同じようにJuliaとPythonの間を繋げたいみたいなときもいつかは出て来るはずです.

Calling julia functions from python

によるとPythonからJuliaを呼び出すことはできるようです.やってみませう.

Julia0.7対応に合わせて、以下の内容を2018/9/17日に大幅に修正しました。

環境

Macで動作を確認しています.
python は pyenv でバージョンを切り替えています。これらのPythonと対応させるために

などに目を通しておくと良さそうです。

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倍するいたってシンプルなものです。

test.jl
function twice_array(x::Array{T}) where T <: Number
    return 2x
end

呼び出す側の Python のコードは下記のようになります。
include の仕方は

How to include source written in julia ? の Issue
にて教えてもらいました。

calljl.py
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 対応は捨てられるとのことです。

Release PyJulia 0.2?

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
21
Help us understand the problem. What are the problem?