LoginSignup
3
3

More than 5 years have passed since last update.

MacでPyCUDA環境構築からGPGPUプログラミング (MacOS 10.12 Sierra)

Last updated at Posted at 2017-08-16

はじめに

対象者

PyCUDAをMacにインストールする手順を説明します。
以下に該当する方が対象となりえます。
- Python3.xを使用
- Chainer, Tensorflow, KerasなどのDeep Learningライブラリを使用しないでGPUで計算したい
- Mac上でPythonを使ってGPGPUプログラミングをしたい
- NVIDIA製のGPUを搭載したMac/Macbook Proを所有している

開発環境

使用したMacのスペックは以下の通り。
- Macbook Pro, 2014 Mid
- MacOS Sierra 10.12.6
- Core i7 2.8GHz/16GBメモリ
- NVIDIA GeForce GT 750M 2GB GDDR5
- Xcode 7.3.1 & Command Line Tools (Xcode 8.xはCUDA8が対応していません)
最後のXcodeについて補足ですが、Xcode8をインストール済みでもXcode7と共存させる方法がありますので後述します。

PyCUDA環境構築

Xcode7 Installation

記事執筆時ではXcode 7.3.1がXcode7では最新でした。Downloads for Apple DeveloperからSee more downloadsを選んで、検索ボックスに「Xcode 7」と入力します。Xcode 7.3.1Command Line Tools for Xcode 7.3.1をダウンロードします。

ダウンロードしたdmgファイルを開いてXcode 7.3.1をインストールします。続いてCommand Line Tools for Xcode7.3.1もインストールします。

続いて、Command Line Toolsのdmgを開いてをインストールします。

Xcode8がインストール済みの場合

Xcode8を既にインストールしているときは、Xcode7をXcode7.appとして/Applicationsにコピーします。Xcode7をアクティブにするには
$ sudo mv /Applications/Xcode.app /Applications/Xcode8.app
$ sudo mv /Applications/Xcode7.app /Applications/Xcode.app
$ sudo xcode-select -s /Applications/Xcode.app

逆にXcode8をアクティブにするには
$ sudo mv /Applications/Xcode.app /Applications/Xcode7.app
$ sudo mv /Applications/Xcode8.app /Applications/Xcode.app
$ sudo xcode-select -s /Applications/Xcode.app

CUDA/PyCUDAを使用するにはXcode7をアクティブにしてください。CUDA8はXcode8非対応です。

CUDA8 Installation

CUDAはNVIDIAが提供するGPGPUのためのライブラリ、コンパイルなどの統合開発環境です。要はNVIDIA製のGPUを使って並列計算するためのツール群です。PyCUDAがCUDAを必要とするためCUDA8をインストールします。

CUDA8 Installation

CUDA Toolkit Download | NVIDIA DeveloperからOS、バージョンを選んでパッケージをダウンロードします。インストーラーの指示通りインストールします。

インストール後、MacOSのシステム環境設定からCUDAを選んでInstall CUDA UpdateをクリックしてCUDAをアップデートします。

cuDNN Installation

NVIDIA cuDNN | NVIDIA Developerからcudnnをダウンロードします。メンバー登録が必要な場合があります。

ダウンロードしたcudnn-8.0-osx-x64-v6.0.tgzを解凍します。
$ tar zxvf cudnn-8.0-osx-x64-v6.0.tgz

ファイルをシステムにデプロイします。
$ sudo mv <解凍フォルダ>/lib/libcudnn* /usr/local/cuda/lib
$ sudo mv <解凍フォルダ>/include/cudnn.h /usr/local/cuda/include

DYLD_LIBRARY_PATHPATHを設定
.bashrcに追加します。
export DYLD_LIBRARY_PATH=/usr/local/cuda/lib:/Developer/NVIDIA/CUDA-8.0/lib:$DYLD_LIBRARY_PATH
export PATH=/Developer/NVIDIA/CUDA-8.0/bin:$PATH

変更内容を反映。
$ source .bashrc

CUDAサンプルプログラム

サンプルプログラムでインストールを確認できます。ただしコンパイルに時間が結構かかりますのでスキップしても結構です。

$ /Developer/NVIDIA/CUDA-8.0/bin/cuda-install-samples-8.0.sh ~/Downloads
$ cd ~/Downloads
$ make -C 1_Utilities/deviceQuery
$ 1_Utilities/deviceQuery/deviceQuery
$ make -C 5_Simulations/smokeParticles
$ 5_Simulations/smokeParticles/smokeParticles

コンパイルエラーが出る場合は、Xcodeの切り替え、DYLD_LIBRARY_PATHとPATHの設定、システム環境設定省エネルギーの設定グラフィックスの自動切り替えをオフ)をチェックします。

Homebrew Installation

Homebrewのインストールがまだなら、
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”

Python3のインストールがまだなら、
$ brew install python3

Python3確認
$ python3 --version

pip Installation

pipのインストールがまだなら、
$ curl -kL https://raw.github.com/pypa/pip/master/contrib/get-pip.p

Numpy Installation

numpyのインストールがまだなら、
$ pip3 install numpy
$ pip3 install scipy

注意) Python2.xにNumpyがインストールされていても、Python3.x用にインストールする必要があります。

numpy確認
$ python3
>>> import numpy as np

PyCUDA Installation

いよいよPyCUDAのインストールです。
$ pip3 install pycuda

PyCUDA確認
$ python3 -c "import pycuda.autoinit

エラーが出なければとりあえずOKです。エラーが出る場合は、Xcode7への切り替え、DYLD_LIBRARY_PATHとPATHの設定、システム環境設定省エネルギーの設定グラフィックスの自動切り替えをオフ)を疑ってみてください。

続いて、scikit-cuda (skcuda)をインストールします。
$ pip3 install scikit-cuda

PyCUDAでGPGPUプログラミング

テストスクリプト test_gpu.py

import pycuda.autoinit
import pycuda.driver as cuda
from pycuda import gpuarray
from skcuda import linalg
import numpy as np

linalg.init()

a = np.random.rand(2, 1).astype(np.float32)
b = np.ones(2).astype(np.float32).reshape(1, 2)

a_gpu = gpuarray.to_gpu(a)
b_gpu = gpuarray.to_gpu(b)

c_gpu = linalg.dot(a_gpu, b_gpu)
c = c_gpu.get()

print(a)
print(b)
# 内積をCPUで計算した結果
print(np.dot(a, b))
# 内積をGPUで計算した結果
print(c)

上のスクリプトをtest_gpu.pyとして保存して実行します。

$ python3 test_gpu.py

[[ 0.85600704]
 [ 0.02441464]]
[[ 1.  1.]]
[[ 0.85600704  0.85600704]
 [ 0.02441464  0.02441464]]
[[ 0.85600704  0.85600704]
 [ 0.02441464  0.02441464]]

テストスクリプトtest_gpu.pyを説明します。

まず、PythonでGPUを利用するための初期化処理等の準備をします。

import pycuda.autoinit
...
linalg.init()

GPUで処理する前に一旦Numpyのndarrayを作ります。データタイプはfloat32を使用します。

a = random.rand(2, 1).astype(np.float32)
b = np.ones(2).astype(np.float32).reshape(1, 2)

次にndarrayをgpuarrayに変換します。

a_gpu = gpuarray.to_gpu(a)
b_gpu = gpuarray.to_gpu(b)

この処理でCPU用のメモリからGPU用のメモリに配列データが変換・転送されます(CPU→GPU)。

Numpyのnp.dotに相当するGPU内積演算です。

c_gpu = linalg.dot(ga, gb)

結果を確認するにはgpuarray (GPU)からndarray (CPU)に戻す必要があります。

c = c_gpu.get()
print(c)

今度はGPU→CPUの流れです。

PyCUDAプログラミングの注意点

PyCUDAを利用したプログラミングでは、CPUとGPUを行き来するため、変数がndarrayかgpuarrayかを常に意識することが重要です。また、CPU/GPU間のデータ変換はパフォーマンスに大きな影響を与えるため、最小限に止めることが望ましいです。

GPUメモリが少ないMacでgpuarrayサイズを大きくすると、システムが極端にもっさりして、簡単に操作不能に陥ります。GPUメモリの少ないマシンでスクリプトを実行する際は、ウィンドウを閉じてアプリケーションを完全に終了した方が無難です。特にSafariは結構メモリを消費するので、ご注意ください。

便利な関数

gpuarrayとlinalgには下記のような便利な関数があります。ただし、x, y, zをgpuarrayとします。
- linalg.dot(x, y): 内積
- linalg.transpose(x): 転置行列
- gpuarray.max(x): 最大値
- abs(x): 絶対値
- x.shape: ndarrayのshapeと同じ
- gpuarray.if_positive(x > z, x, z): zが0ならrelu
- linalg.mdot(x, y): reshapeすることで、外積として利用できる

API Docs

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3