Hello GraalVM & Graal Python

こんにちは。まーやです。PyLadies Tokyo 秋合宿 2019 in 秩父からこんにちは。
今日は合宿2日目にもくもくしてみたGraalVMインストールからGraal Python実行までを自分の手順メモ的に(Pythonユーザ的)記録しておきたいと思います。

そしてこのブログはPyLadies Japan Advent Calendar 2019の7日目のブログです。
https://adventar.org/calendars/4730

1.今回の環境

GraalVMを動かすべくLinux環境を用意します。とりあえず作っては壊してができるAzure VM (Ubuntu 18.04.3 LTS) をしゅっと立てることにしました。

とりあえず後で必要になるのでこれだけ入れておきます。

$ apt update && apt upgrade openssl
$ apt-get install zip unzip 

2. GraalVMとGraalとTruffleなにそれそいつら

Java界のみなさま的にはすでに鉄板ネタですが、GraalとGraalVMは別のものを指します。

Pythonが動く環境はGraalVMです。GraalVMは多言語仮想マシン(Polyglot Virtual Machine)と定義されており、一つの言語にこだわらずいろんな言語をまぜまぜして書くことができる性質を持っています。もちろんPythonに限らずJava, Scala, Ruby, R, Javascriptなどなど色々取り扱うことができます。  It can run either standalone or in the context of OpenJDK, Node.js or Oracle Database. といっているので、なんとOracle DBでも動くようです。なんてこった。

(今日はこの中のJava+Pythonのコードを動かすことを目標にするよ)

じゃあGraalってなんでしょう。
Graal は Javaで書かれたJITコンパイラです。JITコンパイラというのは Just In Time Compiler の略で、プログラムが実行される時にコンパイルされる仕組みのことを指します。JITコンパイラについて、単語と意味をちょっとだけ知ってる程度の知識しかなかったので今回ちょっぴり調べたんですが、沼的に難しいのでこのメモブログでは割愛します。知りたい人はぜひググってください。

このGraalをJITコンパイラとして採用しているのがGraalVMです。名前が似ていて大変ややこしいですが、Graalを採用したVMということでGraalVMです。

Polyglotを実現するにはさらにTruffleという機能を必要としているのがGraalVMです。

TruffleはASTインタプリタ(抽出構文木インタプリタ)のフレームワークです。このTruffleさんが多言語実装を可能にしてくれている大事な役目を担っています。Graalと一緒に使うことで、自動的にJITコンパイルしてくれ、Java的なパフォーマンスを出せるんだぜ!という代物です。ちなみにASTについても今回全然知らなかったので少し調べたんですが、こちらも沼的に難しくなっていくので、このメモブログではこちらも割愛します。。。
余談ですがJavaなどJVM言語についてはGraalと同じ言語基盤になるので、Truffleを通さずに動かすことができます。

つまりすごーくざっくり乱暴に書くとGraal Pythonが動くまでの仕組みはこんなかんじ。

図がわかりにくい。ざっくりすぎ。

昨日のアドベントカレンダー で Jythonがぁぁぁって書かれていましたが、たぶんJythonの後継として期待されているのもこのGraalPythonなんじゃないかと思います。しらんけど。しかもPython2系のEOLにはたぶん間に合わんけど。

3. GraalVM インストール

GraalVMはLinuxにインストールもしくはDockerにて配布されています。今回は初めてなのでとりあえず面倒な方のLinuxインストールをやってみます。

GraalVMのサイトからダウンロードします。とりあえずこのブログを書いている時点で一番最新そうなやつを入れます。
https://www.graalvm.org/downloads/

$ cd /user/local
$ wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-19.3.0/graalvm-ce-java11-linux-amd64-19.3.0.tar.gz
$ tar xf graalvm-ce-java11-linux-amd64-19.3.0.tar.gz
$ cd graalvm-ce-java11-19.3.0/

必要なランタイム系はすべてbinディレクトリに紐づいてるのでパスを通してあげるとしゅっと使えるようになります。

$ PATH=/usr/local/graalvm-ce-java11-19.3.0/bin:$PATH

$ java -version
openjdk version "11.0.5" 2019-10-15
OpenJDK Runtime Environment (build 11.0.5+10-jvmci-19.3-b05-LTS)
OpenJDK 64-Bit GraalVM CE 19.3.0 (build 11.0.5+10-jvmci-19.3-b05-LTS, mixed mode, sharing)

$ node -v
v12.10.0

Node.jsとJavaはこれでOK。

4. GraalPythonインストール

Pythonを使うにはgu(GraalVMm Updator)コマンドからインストールを行います。ちなみにこのブログ書いてる時点ではPython3.7.4に対応しています。

$ gu install python 

これでもうばっちり動きます。起動ログのところにJavaって文字出てくるの新鮮ね。

$ graalpython
Python 3.7.4 (Fri Nov 15 17:42:57 UTC 2019)
[GraalVM CE, Java 11.0.5] on linux
Type "help", "copyright", "credits" or "license" for more information.
Please note: This Python implementation is in the very early stages, and can run little more than basic benchmarks at this point.
>>> 1+2
3
>>> a='maaya'
>>> b='hello'
>>> print( b + a )
hellomaaya

5. Pythonあれこれ

venvの作成

$ graalpython -m venv maaya_venv
$ source maaya_venv/bin/activate

各ライブラリのインストールにはginstallというコマンドを利用します。たぶんpipみたいな立ち位置。
このブログを書いている時点で使えるライブラリを見てみましょう。

$ graalpython -m ginstall install --help
Please note: This Python implementation is in the very early stages, and can run little more than basic benchmarks at this point.
usage: ginstall.py install [-h] [--prefix PREFIX] package

Install a known package. Known packages are pytest, py, attrs, pyparsing,
packaging, more_itertools, atomicwrites, pluggy, zipp, importlib_metadata,
wcwidth, PyYAML, six, Cython, setuptools, pkgconfig, wheel, protobuf,
Keras_preprocessing, gast, astor, absl_py, mock, Markdown, Werkzeug,
setuptools_scm, numpy, dateutil, certifi, idna, chardet, urllib3, requests,
lightfm, pytz, pandas

pytest, numpy, pandas, requests, Cython くらいの基本パッケージのみ現在対応していることがわかります。pandas, numpyが使えるだけでもうれしい人は多そうな気がします。

6. requests

試しにみんな大好きrequestsをインストールしてみます。

 $ graalpython -m ginstall install requests
Please note: This Python implementation is in the very early stages, and can run little more than basic benchmarks at this point.
Installing required dependency: requests
Installing required dependency: idna
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 27638  100 27638    0     0   117k      0 --:--:-- --:--:-- --:--:--  117k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  170k  100  170k    0     0  2505k      0 --:--:-- --:--:-- --:--:-- 2505k
+ tar xzf /tmp/tmpfhk4tiju/idna-2.8.tar.gz -C /tmp/tmpfhk4tiju
+ cd /tmp/tmpfhk4tiju/idna-2.8; CFLAGS="-v "  /usr/local/graalvm-ce-java11-19.3.0/languages/python/bin/graalpython setup.py install --user
Please note: This Python implementation is in the very early stages, and can run little more than basic benchmarks at this point.
Traceback (most recent call last):
  File "/tmp/tmpfhk4tiju/idna-2.8/setup.py", line 10, in <module 'setup.py'>
    from setuptools import setup
ModuleNotFoundError: No module named 'setuptools'

setuptoolsないって怒られた。。。
インストール作業、それぞれそれなりに時間かかったなーというイメージ(環境スペックの問題かもしれない)

$ graalpython -m ginstall install setuptools
$ graalpython -m ginstall install requests
(たくさんのログ)
Using /root/.local/lib/python3.7/site-packages/chardet-3.0.4-py3.7.egg
Finished processing dependencies for requests==2.22.0

requestsの2.22.0が入りました。最新バージョンですね。
使ってみます。

>>> import requests
>>> requests.get('https://pyladiestokyo.github.io/')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module '<expression>'>
  File "/root/.local/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/root/.local/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/root/.local/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/root/.local/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/root/.local/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/adapters.py", line 514, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='pyladiestokyo.github.io', port=443): Max retries exceeded with url: / (Caused by SSLError: Can't connect to HTTPS URL because the SSL module is not available.)

ふーむ。この手のやつってopensslをアップグレードして再起動とかで治ったりそこらへんもにゅもにゅすると治っていくイメージがあるんですが、一通り思いつく手段やってみたもののなんかうまくいかない。なんじゃろなー。

後日の宿題とします。

7. numpy

pandasやnumpyにもチャレンジ。こちらはinstallコマンド中にC壊れたよエラーがでる。

$ graalpython -m ginstall install numpy
....(略)
  File "/tmp/tmp5_3fgcc0/numpy-1.16.4/numpy/core/setup.py", line 667, in get_mathlib_info
    raise RuntimeError("Broken toolchain: cannot link a simple C program")
RuntimeError: Broken toolchain: cannot link a simple C program

これはclangをインストールしておいてあげると治ります。そしてnumpyのインストールめっちゃ時間かかった(サーバのスペックかもしれない)

apt-get install clang

特に難しい処理などは試してないですが、ただただ多次元配列とかだけならしゅっと通常のPythonと変わりなく動きます。

>>> import numpy as np
>>> np_array = np.asarray([[1,0,1], [0,1,0]])
>>> np_array
array([[1, 0, 1],
       [0, 1, 0]])
>>> np_array.shape
(2, 3)

全然関係ないですがちゃんと予測も出てきます。

>>> np      <-予測処理させてみる
np         np_array

8. 合宿のおわりとブログのまとめ

最初のlinux側インストールもにゅもにゅあたりにはまりましてなかなか進まず、合宿はここでタイムアップ。Polyglotしてみるところまでは進めませんでした。残念。

GraalPythonの使いどころとしては、私個人的にはPolyglotコードにひっそり期待していたりします。

https://www.graalvm.org/docs/reference-manual/polyglot/

PythonにしかないライブラリをJavaで使うとか、Javaにしかない機能をPythonに使うとかがスムーズにできるようになると楽しいなと思います。

速度とかも早くなるのかな。なると聞いた。速度確認なんかも今後進めてい行きたいと思います。でもまぁ、とりあえず次回ブログはPolyglotを。

special thanks

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください