sein's blog

ディープラーニング, 人工知能, 自然言語処理 ~ Deep Learning, AI, NLP ~

【PyCUDA環境構築その4】 PyCUDAをMacOS 10.12 Sierraにインストール

この記事は、PyCUDAでDeep LearningをするためのMac環境構築その4です。PyCUDAをMacにインストールする手順を説明します。

前提条件は以下の通りです。

  • NVIDIAGPUを搭載したMacで、GPUがCUDA8に対応
  • Python3、Numpy、Scipyがインストール済み
  • CUDA8がインストール済み
  • Xcode7がインストール済み

上述でインストールがまだのものがありましたら、下記の記事リストからインストールしてください。

開発環境

使用した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が対応していません)

DYLD_LIBRARY_PATHとPATHを設定

.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

常にNVIDIA GeForceを使用するように設定

Macbook Proには省電力のためにGPUが自動で切り替わるモデルがあります。常にNVIDIAGPUが使われるように設定を変更します。
[システム環境設定]-[省エネルギー]-[グラフィックスの自動切り替え]オフ

Xcode7に切り替え

CUDA8はXcode8に対応していません。Xcode7.x (執筆時Xcode7.3.1が最新)およびCommand Line Toolsが必要となります。Xcode8とXcode7をインストールしている場合は、xcode-selectコマンドでXcode7に切り替えます。

PyCUDAのインストール

# pip3 install pycuda

PyCUDAの確認

# python3 -c "import pycuda.autoinit

scikit-cuda (skcuda)をインストール

# pip3 install scikit-cuda

テストスクリプトで動作確認

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を説明します。
PythonGPUを利用するための初期化処理等の準備をします。

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間のデータ変換はパフォーマンスに大きな影響を与えるため、最小限に止めることが望ましいです。

便利な関数

gpuarrayとlinalgには下記のような便利な関数があります。

  • 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

ただし、xをgpuarrayとします。

関連書籍

Python Parallel Programming Cookbook
洋書だがPyCUDAについて解説した数少ない書籍。PyCUDAについて約50ページが割かれている。

はじめてのCUDAプログラミング―驚異の開発環境[GPU+CUDA]を使いこなす! (I・O BOOKS)
CUDAの入門におすすめ。初心者にわかりやすいと定評がある。

CUDA C プロフェッショナル プログラミング (impress top gear)
CUDA中〜上級者におすすめ。マルチGPUについての解説あり。