Help us understand the problem. What is going on with this article?

Windows7 64bitにPyCUDAとTheanoをインストールしてGPU計算する

More than 5 years have passed since last update.

前回構築したTDM-GCCとMinGW-w64で64bitのPython2.7環境にPyCUDAとTheanoをインストールしてGPUを使って計算してみます。Installing Theano with GPU on Windows 64-bitの続きを参考にして構築していきます。

NumPyとSciPy

msys.batのショートカットをダブルクリックしてMSYSを起動します。まずMinGW-w64環境にpipをインストールします。

$ wget --no-check-certificate -O-  https://bootstrap.pypa.io/get-pip.py | python

NumPySciPyは、Unofficial Windows Binaries for Python Extension Packagesのパッケージを使います。

NumPynumpy‑1.8.2+mkl‑cp27‑none‑win_amd64.whlをダウンロードしてpip installします。

$ pip install /c/Users/masato/Downloads/numpy-1.8.2+mkl-cp27-none-win_amd64.whl

SciPyscipy-0.15.1-cp27-none-win_amd64.whlをダウンロードします。

$ pip install /c/Users/masato/Downloads/scipy-0.15.1-cp27-none-win_amd64.whl

PyCUDA

CUDA Toolkit 6.5以前Windows 7 64bit版のインストーラーをダウンロードしてインストールしてあります。C/C++のCUDA拡張でプログラムを書くのは大変です。Pythonを使ってコンパイル不要で実行できるのは便利です。PuCUDApycuda-2014.1+cuda6519-cp27-none-win_amd64.whlをダウンロードします。

$ pip install /c/Users/masato/Downloads/pycuda-2014.1+cuda6519-cp27-none-win_amd64.whl

nvccがcl.exeを見つけられない

Error compiling CUDA from Command Promptを参考にして、 c:\mingw\msys\msys.batの最初にVisual StudioのPATHを設定します。

c\mingw\msys\msys.bat
rem ember value of GOTO: is used to know recursion has happened.

call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat"

if "%1" == "GOTO:" goto %2

UnicodeDecodeErrorがでる

このままpycudaパッケージを使うと実行時にUnicodeDecodeErrorが出てしまします。UnicodeDecodeError: 'utf8' codec can't decode byte #37によると、nvccからUTF-8として有効でない文字が出力されているようです。compiler.pyの250行目辺りに以下のコードを追加します。

c\Python27\lib\site-packages\pycuda\compiler.py
...
        self._check_arch(arch)

        if options is not None:
            options.extend(["-Xcompiler","/wd 4819"])
        else:
            options = ["-Xcompiler","/wd 4819"]

        cubin = compile(source, nvcc, options, keep, no_extern_c,
                arch, code, cache_dir, include_dirs)
...

テスト

こちらのTutorialを参考にしてサンプルコードを用意して実行してみます。

~/pycuda-test.py
import pycuda.gpuarray as gpuarray
import pycuda.driver as cuda
import pycuda.autoinit
import numpy
a_gpu = gpuarray.to_gpu(numpy.random.randn(4,4).astype(numpy.float32))
a_doubled = (2*a_gpu).get()
print a_doubled
print a_gpu

簡単な配列計算の実行ですが、PyCUDAのインストールに成功したようです。

$ python pycuda-test.py
[[-5.03633499 -1.2504214   0.87832445  0.86452949]
 [ 0.01358639  0.98460299  2.50277209  3.76451278]
 [ 0.14301641 -2.11651611  0.39508429 -0.88320005]
 [ 2.66914272  0.87537336 -1.17862082  1.94231701]]
[[-2.5181675  -0.6252107   0.43916222  0.43226475]
 [ 0.0067932   0.49230149  1.25138605  1.88225639]
 [ 0.07150821 -1.05825806  0.19754215 -0.44160002]
 [ 1.33457136  0.43768668 -0.58931041  0.9711585 ]]

Theano

Theanoは最近話題のDeep Learningで使うPythonの数値計算ライブラリです。実行時のC++コード生成と、CUDAでGPU計算もできるのが特徴です。TheanoTheano-0.6.0-py2-none-any.whlをダウンロードします。

$ pip install /c/Users/masato/Downloads/Theano-0.6.0-py2-none-any.whl

MSYSのホームディレクトリにTheanoの環境設定ファイルを作成します。

~/.theanorc
[global]
device = gpu
floatX = float32

inconsistent dll linkage

サンプルコードを実行すると、'round' : dll リンクが一貫していません。というエラーがでます。

$ python theano-test.py
...
c:\python27\include\pymath.h(22) : warning C4273: 'round' : dll リンクが一貫して
いません。
        c:\program files\nvidia gpu computing toolkit\cuda\v6.5\include\math_fun
ctions.h(2455) : 'round' の前の定義を確認してください

"inconsistent dll linkage" when using Theano with CUDA 6.5 #2055にissueがありました。リポジトリのcuda_ndarray.cuhはすでに修正済みです。Unofficial Windows Binaries for Python Extension Packagesで配布しているパッケージは未対応なので#include <algorithm>を追加します。

C\Python27\Lib\site-packages\theano\sandbox\cuda\cuda_ndarray.cuh
#ifndef _CUDA_NDARRAY_H
#define _CUDA_NDARRAY_H

#include <algorithm>

テスト

最初にtheanoパッケージが正常にインストールされているか確認します。

$ pip install nose
$ python -c 'import theano; print theano.config' | less
...

Testing Theano with GPUあるサンプルコードを実行してみます。

~/theano-test.py
from theano import function, config, shared, sandbox
import theano.tensor as T
import numpy
import time

vlen = 10 * 30 * 768  # 10 x #cores x # threads per core
iters = 1000

rng = numpy.random.RandomState(22)
x = shared(numpy.asarray(rng.rand(vlen), config.floatX))
f = function([], T.exp(x))
print f.maker.fgraph.toposort()
t0 = time.time()
for i in xrange(iters):
    r = f()
t1 = time.time()
print 'Looping %d times took' % iters, t1 - t0, 'seconds'
print 'Result is', r
if numpy.any([isinstance(x.op, T.Elemwise) for x in f.maker.fgraph.toposort()]):
    print 'Used the cpu'
else:
    print 'Used the gpu'

まだ警告がでますが最後にUsed the gpuと表示されるのでGPU計算ができているようです。

$ python theano-test.py
...
c:\python27\include\pymath.h(22) : warning C4273: 'round' : dll リンクが一貫して
いません。
        c:\program files\nvidia gpu computing toolkit\cuda\v6.5\include\math_fun
ctions.h(2455) : 'round' の前の定義を確認してください
c:\python27\lib\site-packages\numpy\core\include\numpy\npy_1_7_deprecated_api.h(
12) : Warning Msg: Using deprecated NumPy API, disable it by #defining NPY_NO_DE
PRECATED_API NPY_1_7_API_VERSION
   ライブラリ C:/Users/masato/AppData/Local/Theano/compiledir_Windows-7-6.1.7601
-SP1-Intel64_Family_6_Model_58_Stepping_9_GenuineIntel-2.7.0-64/tmptykper/73dc8d
0fb3ff37614826ceae3280f478.lib とオブジェクト C:/Users/masato/AppData/Local/Thea
no/compiledir_Windows-7-6.1.7601-SP1-Intel64_Family_6_Model_58_Stepping_9_Genuin
eIntel-2.7.0-64/tmptykper/73dc8d0fb3ff37614826ceae3280f478.exp を作成中

[GpuElemwise{exp,no_inplace}(<CudaNdarrayType(float32, vector)>), HostFromGpu(Gp
uElemwise{exp,no_inplace}.0)]
Looping 1000 times took 1.23299980164 seconds
Result is [ 1.23178029  1.61879349  1.52278066 ...,  2.20771813  2.29967761
  1.62323296]
Used the gpu
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away