RubyでGPUを使って行列計算ができるCumo/NArrayを使ってみたので紹介します。
Cumo/NArray について
Cumo/NArray は、Numo/NArray と同じ書き方でGPUで行列計算ができるライブラリです。
(Numo/NArray はRubyで行列計算を提供するnumpyのようなライブラリです)
https://github.com/sonots/cumo
インストール
公式の通りにインストールします。
gem install cumo
でもインストールできなくはないのでしょうが、cuda に関連するトラブルが発生するときの備えてマニュアルのインストールがよさそうです。
リポジトリのダウンロード
git clone https://github.com/sonots/cumo
CUDAのインストール状況にあわせて環境変数を設定します。
export CUDA_PATH="/usr/local/cuda"
export CPATH="$CUDA_PATH/include:$CPATH"
export LD_LIBRARY_PATH="$CUDA_PATH/lib64:$CUDA_PATH/lib:$LD_LIBRARY_PATH"
export PATH="$CUDA_PATH/bin:$PATH"
export LIBRARY_PATH="$CUDA_PATH/lib64:$CUDA_PATH/lib:$LIBRARY_PATH"
最初から rake install
としてもよいのですが、一度 rake compile
を実行するとエラーメッセージの状況を確認しやすくなります。
bundle install
bundle exec rake compile
# マルチコア
# bundle exec env MAKEFLAG=-j8 rake compile
bundle exec rake build
bundle exec rake install
正しくインストールできているか確認するためにテストを実行します。
bundle exec rake test
GPUの使用率が上昇しているか watch -n 1 nvidia-smi
等で確認してみてください。
リファレンスなど
- Yard
- cumo
- numo-narray
- NumpyとNumo/Narrayの対応表
- Numo vs numpy
- Numo vs ndarray
- 公式 RubyKaigi 2018スライド
- Fast Numerical Computing and Deep Learning in Ruby with Cumo
Numo/NArray への対応状況
Numo/NArray の機能にどこまで対応しているかはGithubのissueで公開されています。
簡単な使い方
配列を生成する
require 'cumo'
a = Cumo::SFloat.new(3,3).seq
b = Cumo::SFloat.new(3,3).seq + 1
p a
p b
実行結果
Cumo::SFloat#shape=[3,3]
[[0, 1, 2],
[3, 4, 5],
[6, 7, 8]]
Cumo::SFloat#shape=[3,3]
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
行列の和・積
p a + b
p a * b
実行結果
Cumo::SFloat#shape=[3,3]
[[1, 3, 5],
[7, 9, 11],
[13, 15, 17]]
Cumo::SFloat#shape=[3,3]
[[0, 2, 6],
[12, 20, 30],
[42, 56, 72]]
ほぼNumo::NArrayと同様の使用感です。
簡単なベンチマーク
四則演算について簡単なベンチマークをしてみました。
なお、Benchmarkのちゃんとした取り方はわかっておらず、色々おかしいかもしれないので、参考程度に思ってください。1
https://gist.github.com/kojix2/9d22fecf8c7c5f304c2311f005b7ecc1
- Cumo/NArray
- Numo/NArray
- Ruby標準のMatrixライブラリ
について(1000,1000)の行列の四則演算を比較します。環境は以下のとおりです。
- OS Ubuntu 18.10
- CPU Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
- GPU GeForce GTX 1070
結果です。とにかくRubyのMatrixが遅いのがわかります。
右端 RubyのMatrix の掛け算と割り算の結果がないのは、速いからではなく、時間がかかりすぎるため途中で実行をキャンセルしたからです。最低でもグラフに表示されている和・差のさらに10倍以上の時間がかかるようです。
Ruby Matrix を取り除いた結果はこんな感じです。
とりあえず、UInt8の演算や、和算に関しては、Cumo/NArray は爆速なんだなあと思います。
Arrayのサイズを変えるとまた違う結果が出るかもしれません。
-
Cumoの公式のベンチマークがある https://github.com/sonots/cumo/blob/master/bench/cumo_bench.rb ↩