Ruby
CUDA
sciruby
NArray
red-chainer

Ruby で GPU計算できる Cumo/NArray を使ってみた

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 等で確認してみてください。

リファレンスなど

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

  1. Cumo/NArray
  2. Numo/NArray
  3. 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倍以上の時間がかかるようです。

image.png

Ruby Matrix を取り除いた結果はこんな感じです。

image.png

とりあえず、UInt8の演算や、和算に関しては、Cumo/NArray は爆速なんだなあと思います。
Arrayのサイズを変えるとまた違う結果が出るかもしれません。


  1. Cumoの公式のベンチマークがある https://github.com/sonots/cumo/blob/master/bench/cumo_bench.rb