Skip to content

opencl_ruby_ffi で遊ぶ

今日はRubyでOpenCLしてみようと思った。
(追記:NMatrix で Cudaできるようにしてほしい。)

だが、そもそもOpenCLとは何かわからないことに気づいた。OpenCLってなんだろうか。
テン*シー*シー OpenCLでいくぜ!のシリーズを読んだ。すごくわかりやすい。まずは hello world してみることにした。あとはこのAMDの資料がまとまってる。

RubyのOpenCLのバインディングはタケノコのように現れ、その後多くが放置されている。その中で最近開発が始まったのが、このopencl_ruby_ffiである。フランスの Brice Videau という方が作ってるみたい。

コードを書き始めること数時間。ついに完成。

Hello World!

うん。動いた。Hello, World! これだけ書くのに数時間かかったよRubyさん。。 Pythonの情報量とユーザー層の厚さが羨ましいよ。

巡回中に見つけたこちらのサイトさんなんか、

OpenCLを用いたプログラミングは高度な内容です。プログラミングの初心者を対象としないため、一部の解説を割愛したりしています。コンテンツを読み進められるかどうかは、最初のページを参考にしてください。

って親切に忠告してくれている。余計なお世話だ。初心者には厳しい世界のようだ。困った。

SUM

pyopencl/examples/demo.py を参考に、NArrayの和を計算するものを書いてみる。READ_ONLYにする方法わからんし困る。demo_array.py が簡潔すぎる。Pythonの情報量とユーザー層の厚さが羨ましいよ(本日2回目)。

カーネルのコンパイル時のエラーの捕縛

まずはこんな感じで大丈夫

そのまえにFFIって何?

FFIとは、他のプログラミング言語を無理やり呼び出すためのインターフェイスのようなもので、libffiを利用していると。Ruby公式だと、Fiddleというのもやはりlibffi利用していると。
RubyからC言語を呼び出す方法は、

などがあるらしい。
単純計算の速度早めたいだけならNArrayが一番手軽。

Intel CPU に OpenCL (Beignet) を導入してみる。

CUDAがNVIDIA製品しか動かないのに対して、OpenCLはIntel CPUでも動く。GPUのないUbuntu14.04に入れてみることにした。
かつては単独の “Intel OpenCL SDK” (Intel SDK for OpenCL) が存在したが、2015年に Intel INDE に統合されたそうなのでIntelのホームページからIntel INDEをダウンロードしようとするが、Linuxでは使えないと判明。ググると、Beignetというオープンソースのパッケージがあることが判明。公式サイトに従って、ソースからのコンパイルを試みる。

さらに公式に従ってテストを実行。

するがFAILが少々ある。既知の問題の項目に、Haswell系のCPUでは__localが使えないエラー出ると書いてある。その解決策は、カーネルにパッチ当てて自分でビルドするか、諦めてテストをスルーする設定にしてくださいと書いてある。カーネルって何? カーネル・サンダース? カーネルを自分でビルド? その恐ろしい響きから、次のLinxuの本当にあった怖い話が頭をよぎる。
本の虫:危険な誘惑

これは初心者が手を出したらアカンやつだろ、と思いながらググると、Haswell系Intel CPUでBeignet 1.0.0を動かすお話を発見。カーネルのビルドで何か失敗しても即座に文鎮化するわけではなく、GRUBで今までのカーネルを選べることが判明したので、やってみることにする。こちらのページに menuconfigで、Processor family => Core 2/newer Xeon, Timer frequency => 1000 HZ すると、目に見えて起動が捗ると書いてあるので、そのように設定。また、Local vision-append to kernel release に「-local」と設定。 あとは CONCURRENCY_LEVEL=4 にしてHaswell系Intel CPUでBeignet 1.0.0を動かすお話にひたすら従った。

再起動してGRUBで自分でビルドしたカーネルを選択。再度 /utest_run するが全部FAILして悲しい気持ちになったが、

とすればよいことが判明。それでも1個テスト失敗するが満足。

 Ruby/Tkに引き続いて、また辺境の地に着いてしまったようだ。Ruby初心者のブログはたくさんあるのに、OpenCLだのFFIだのBeignetだの騒いでる素人のブログはあまり多くないのはなぜだろう。趣味のRubyプログラミングはちょっと歩くとすぐに市街地を出て田舎になってしまう。この界隈でC言語って何ですか?とか、ポインタと構造体って何ですか?同じものですか? とか言ったらクマに殴られそうな気がする…実際わからないのだが。時間もないし、困ったもんだ。二度とカーネルのビルドはしない。

デバイスの情報を取得してみる

Rubyでマルチプロセス

CPUでOpenCL以前に、Rubyでマルチプロセスした方がよっぽど簡単で、日常生活で役立つのではないかという疑問が。

Rubyはコードが短くてなごむなぁ

#実行結果
# fork0: 58
# fork1: 25
# fork2: 92


(forkした)プロセスにオブジェクトを渡す方法
によると、Marshal.dump でオブジェクトを文字列に変換すれば、プロセス同士でパイプを使ってRubyのオブジェクトをやりとりできると。

One Trackback/Pingback

  1. […]  あとは旧NArray + opencl_ruby_ffiを使えばGPUによる高速計算もある程度できると思う。しかしC言語も読み書きできない私のような素人さんにはちょっと敷居が高すぎるというのが正直なところだ。NarrayからGPUのメモリに移動して、GPUのメモリからNArrayに移動して、NArrayからGPUのメモリに移動して、を繰り返す時間的ロスってどのぐらいなのか気になる。OpenCLは手元のパソコンで試していてPCがフリーズしたりした時に萎えるけど、Amazon EC2 のGPUインスタンスでもopencl_ruby_ffiが動くことを確認したので今度試してみたいところ。 […]

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*