まんぼう日記

takataka's diary

Theano + CUDA

というわけで( Pylearn2 の tutorial でお勉強 - 3時間目 - まんぼう日記 ),Theano で GPU 使って計算できるようにしたいのです.そのためにまずは CUDA を入れましょー.

対象は MacBook Pro Retina 15inch, Mid 2012 で,GPUは Intel HD Graphics 4000 512MB (Integrated) と NVIDIA GeForce GT 650M 1GB (discrete) の2本立てです.

CUDAのインストール

  1. CUDA Zone ==> Downloads ==> CUDA 6.5 Production Release をダウンロード.
  2. Getting Started Mac OS X :: CUDA Toolkit Documentation  にしたがっていろいろ.

 

まずは上記ページの 2. Prerequisites,たかたかは MacPorts 使ってるから Xcode のインストールと xcode-select --install は当然済み.次は 3. Installation,CUDAのPKGを展開して適切な場所に置かれていることを確認したら,環境変数 PATH と DYLD_LIBRARY_PATH の設定.あと,上記 MacBook Pro の場合は「Note:」の2つの項目も要チェック. そして 4. Verification,指示通りサンプルプログラムをコンパイルして,できた deviceQuery と bandwidthTest を実行してみます.うん,ちゃんと動いてるみたいです.

TheanoでGPUを使う

Theano のインストールについてはこちら: Theano + Pylearn2 - まんぼう日記

 

こっちはすんなりいかず,いろいろ手間がかかりました.以下そのメモ. 

 

2014年9月9日追記: MacBook Pro では以下のようにいろいろ変なことになりましたが,iMac で試したらすんなりいきました 続 Theano + CUDA - まんぼう日記

 

Using the GPU — Theano 0.6 documentation (CUDA backend の Testing Theano with GPU) の Python プログラムを手元に保存して,説明通りに実行してみます.すると,

$ THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python check1.py
   :
ERROR (theano.sandbox.cuda): Failed to compile cuda_ndarray.cu:
   :
WARNING (theano.sandbox.cuda): CUDA is installed, but device gpu is not available
   :

となって,CPUの方で動いちゃう….むー.

 

上記のエラーメッセージを見て,実行してるコマンドを手動で実行してみると

$ nvcc -shared -g -O3 -m64 -Xcompiler -DCUDA_NDARRAY_CUH=d67f7c8a21306c67152a70a88a837011,-fPIC -Xlinker -rpath,/Users/takataka/.theano/compiledir_Darwin-12.5.0-x86_64-i386-64bit-i386-2.7.8-64/cuda_ndarray -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/theano/sandbox/cuda -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/core/include -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -o /Users/takataka/.theano/compiledir_Darwin-12.5.0-x86_64-i386-64bit-i386-2.7.8-64/cuda_ndarray/cuda_ndarray.so mod.cu -LNone/lib -lcublas -lcudart -L/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -ldl -lpython2.7 -Xcompiler -framework,CoreFoundation -Xlinker -pie
gcc: error: mod.cu: No such file or directory

nvcc に渡ってるオプションがおかしいらしい.Googleさんに頼ったりして,

/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/theano/sandbox/cuda/nvcc_compiler.py

がそれを作ってるらしいとあたりをつける.

def compile_str(
            module_name, src_code,
            location=None, include_dirs=[], lib_dirs=[], libs=[], preargs=[],
            rpaths=rpath_defaults, py_module=True):
        """:param module_name: string (this has been embedded in the src_code
        :param src_code: a complete c or c++ source listing for the module
        :param location: a pre-existing filesystem directory where the
                         cpp file and .so will be written

のlocationが怪しいんやけど…

 

mod.cu が ~/.theano/compiledir_<中略>/cuda_ndarray/ にあることがわかったので,手動でパスを指定し,さらに nvcc のオプションに -ccbin=/usr/bin/clang を追加したら,warning は出るもののコンパイルは通ったみたい.

 

というわけで,次のように対処してみました.

  1. ~/.theanorc を書く.たかたかの場合,内容は次の通り.
    [gcc]
    cxxflags=-march=corei7
    [nvcc]
    compiler_bindir=/usr/bin/clang
    
    gcc の cxxflags は,こちらのページの情報から: "import theano " fails · Issue #1622 · Theano/Theano · GitHub
  2. nvcc_compile.py に手を入れる.Googleさんにお尋ねしたりしても,そういう問題と対処の話が見つからないので,間違った対応である可能性大ですが… nvcc_compile.py を以下のように修正しました(nvcc_compiler.pyのフルパスは上の方に書いてます).
    $ diff nvcc_compiler.py.org nvcc_compiler.py
    347c347,348
    <         cmd.append(os.path.split(cppfilename)[-1])
    ---
    >         #cmd.append(os.path.split(cppfilename)[-1])
    > 	cmd.append(cppfilename)
    

その結果,次のようになりました.このサンプルでは4倍の高速化.

  • GPUで実行
    $ THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python check1.py
    Using gpu device 0: GeForce GT 650M
    [GpuElemwise{exp,no_inplace}(<CudaNdarrayType(float32, vector)>), HostFromGpu(GpuElemwise{exp,no_inplace}.0)]
    Looping 1000 times took 0.52633190155 seconds
    Result is [ 1.23178029  1.61879349  1.52278066 ...,  2.20771813  2.29967761
      1.62323296]
    Used the gpu
    
  • CPUで実行
    $ THEANO_FLAGS=mode=FAST_RUN,device=cpu,floatX=float32 python check1.py
    WARNING (theano.gof.cmodule): WARNING: your Theano flags `gcc.cxxflags` specify an `-march=X` flags.
             It is better to let Theano/g++ find it automatically, but we don't do it now
    [Elemwise{exp,no_inplace}(<TensorType(float32, vector)>)]
    Looping 1000 times took 2.19054603577 seconds
    Result is [ 1.23178029  1.61879337  1.52278066 ...,  2.20771813  2.29967761
      1.62323284]
    Used the cpu

本当は,Theano の developer さんたちに問題を報告すべきなんやけど,最新版おっかけたりディスカッションしたりする元気がないのでここにメモ書くだけ…すいません.

 

ちなみに,~/.theano/hoge (たかたかの上記の例では hoge = compiledir_Darwin-12.5.0-x86_64-i386-64bit-i386-2.7.8-64 )というディレクトリ内にいろいろファイルができますが,一度コンパイルしたものはここに置いといてできるだけ再利用するみたいなので,おかしいときはここを一度削除してみるのも手かもしれません.

 

また,gfxCardStatus by cody krieger という free and open-source なソフトを入れると, integrated な GPU と discreteな GPU を手動で切り替えられます.内蔵の方が動いてたら当然GPU使ってくれないので,そういうときはこれで切り替えたらよいのでしょう.Dynamic Switching にしておくと,integrated な方が動いてる状態で上記 check1.py を起動すると,すぐに discrete な方に切り替わって計算してくれるようです.

 

というわけでようやく GPU 使える人になった…かな?