スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

CUDA 6.0RCをUbuntu 13.04にインストール

先のエントリで13.10をいったんインストールしたのだが、結局その後再びダウングレードして、13.04になった。
それはCUDA 6.0RCをうまく動かすことができなかったからである。

何が問題だったかというと、やはりディスプレイドライバ回りなのだが、CUDA 6.0RCに同梱のドライバは、331.44というバージョンである。NVIDIAのダウンロードサイトから持ってきたdebファイルを用いてCUDA 6.0RCをインストールすると、この331.44ドライバがインストールされるのだが、これだとウィンドウ画面が表示されない。

一方で、スタンドアローンでNVIDIAから配布されているディスプレイドライバの方は331.38で概ね近くはあったが、これをCUDA 6.0RCに上書きインストールすると、画面表示は行われる。しかしこの状態ではCUDAの方が動作しない。CUDA関連のプログラムを起動すると、nvidia-331-uvmモジュールに関連するシンボルが見つからないというメッセージが表示される。uvmは"Unified Memory kernel module"ということなので、CUDA 6.0のフィーチャーの一つであるユニファイドメモリスペースのためのドライバなのであろう。表示専用のスタンドアロンドライバでは、この機能が提供されないということかと考えている。とにかくこれではだめである。

CUDA 6.0RCのインストール時に表示されるメッセージを睨んでいると、ディスプレイドライバモジュールの作成ステップで、カーネル3.10.* (末尾の数字は忘れた)に対するパッチを適用しようとして失敗しているように見えた。Ubuntu 13.10ではカーネルバージョンが3.11なので、NVIDIAが用意したこのパッチがうまく当たらないのかもしれない。そこで、カーネルバージョンが3.10以前のものであればなんとかなりそうだと推測できる。結局、今回はCUDA 6.0RCで公式にサポートされているUbuntu 13.04にすることで、動作させることに成功した。

さらに、Ubuntu 13.04上でpyCUDAからCUDA 5.5を使うの手法を今回も適用して、pyCUDAを動かすことにも成功した。また最近使い始めたpythonのTheanoというマシンラーニング関連のパッケージも、どうやらGPUを利用して動かすことができているようだ。

スポンサーサイト

Ubuntu 13.04上でpyCUDAからCUDA 5.5を使う

先のエントリでCUDA 5.5をUbuntu 13.04にインストールすることには成功したが、このときCUDA 5.0をアンインストールしたので、それに伴って、pyCUDAのような、Ubuntuによって用意されたCUDA 5.0に依存するパッケージは使えなくなってしまった。データの前処理や生成、テストなど様々な場面でスクリプト言語からもCUDAを利用したいので、なんとかpyCUDAも利用できるようにしようと若干試行錯誤した結果、まだかなり醜い方法ではあるが、とりあえず目的は達成できたので、ここにメモしておこう。

CUDA自体はNVIDIAによってCUDA 5.5からUbuntu用のインストール用パッケージも用意されているので、先のエントリではそれを利用してインストールしたわけであるが、一方でUbuntu 13.04では、CUDA 5.0のパッケージはUbuntu側によって作成、用意されている。問題は、この両者のパッケージングのスキームがまったく異なり、Ubuntu上でCUDA 5.5をインストールしていても、それはUbuntuのパッケージ管理システム上はCUDA 5.0の上位互換パッケージとはみなされないという点である。

より具体的に言うと、Ubuntuの作成したCUDA 5.0のパッケージは、ライブラリは通常のライブラリと同様のlibcudart5.0といった命名規則、その他は一部(OpenCL関連とディスプレイドライバ)部分を除き、すべてnvidia-cuda-*というパッケージ名になっている。一方で、NVIDIAの作成したCUDA 5.5のパッケージは、抽象パッケージ名"cuda"の下に他の全てのパッケージがまとめられており、個々のパッケージはcuda-*という名前になっている。

このように、命名規則やパッケージへの分割の仕方が両者で大きく異なっているために、機能としては同等(上位互換)であっても、CUDA 5.0を必要とするパッケージの依存性を満たすことができない。

このような場合にUbuntuのようなDebian系システムで標準的な方法は、フェイクパッケージというものを作成して、システムにあたかも必要なパッケージがインストールされているかのように思わせてやるという方法である。と偉そうに書いたが、私は実際にDebianのパッケージを作成するのは今回が初めてで、まだ理解できていない点が若干ある。そのせいで、今回は3つもフェイクパッケージを用意することになってしまった。もっと深く理解できていればおそらくパッケージ一つで要求を満たすことができるのではないかと思うが、ご容赦いただきたい。

またシステムのデータベースに自分で作った信頼のおけないパッケージを加える以上、いろいろと不都合が起きる可能性もないわけではない。また、CUDAのバージョンが上がった際には再びパッケージ構成をチェックして同等の作業を行わなければならない。そういったことを踏まえた上で、例によって自分で試す場合は、自己責任でお願いしたい。(自己責任は自由の代償、Ubuntuユーザーなら言うまでもないとは思うが)

さて、フェイクパッケージの作成方法に移ろう。作成には、equivsパッケージが必要なのであらかじめインストールしておく。そして、任意の作業ディレクトリを作成し、そこに移動する。

作成するパッケージ名を、ここでは"mycudaglue"とする。またバージョンは、後でわかりやすいよう、NVIDIAのCUDAのバージョンに合わせて5.5とする。

作業ディレクトリで、

$ equivs-control mycudaglue
とすると、mycudaglueというテキストファイルが生成される。
### Commented entries have reasonable defaults.
### Uncomment to edit them.
# Source:
Section: misc
Priority: optional
# Homepage:
Standards-Version: 3.9.2

Package:
# Version:
# Maintainer: Your Name
# Pre-Depends:
# Depends:
# Recommends:
# Suggests:
# Provides:
# Replaces:
(以下略)

これのエントリを、エディタで次のように編集した。#で始まる行はコメント扱いなので、必要ない行は削除した。
### Uncomment to edit them.
# Source:
Section: misc
Priority: extra
Homepage: http://gm3d.blog.fc2.com
Standards-Version: 3.9.2

Package: mycudaglue
Version: 5.5.0
Maintainer: GM3D (@gm3d2 on twitter)
Depends: cuda (>= 5.5)
Provides: libcublas5.0, libcufft5.0, libcusparse5.0, libnpp5.0, libcuinj64-5.0, libnvtoolsext5.0, libthrust-dev, nvidia-cuda-dev, nvidia-cuda-toolkit, nvidia-cuda-doc

HomepageとかMaintainerは自分のものに書き換えていただきたい。PriorityはCUDAのパッケージに合わせてとりあえずextraとしておいた。一番重要なのは、Providesの部分である。ここに記述したものは、このパッケージによって機能が提供されているという扱いになるので、依存性が満たされるはずである。

このファイルを元に、

$ equivs-build mycudaglue

とすると、mycudaglue_5.5.0_all.debというパッケージが作成されるので、これを

sudo gdebi mycudaglue_5.5.0_all.deb

としてインストールしてやればよい。

ただし、実際に試してみると、libcudart5.0とlibcurand5.0については、このパッケージのProvidesに含めただけでは不十分らしく、

aptitude install --dry-run python-pycuda

でインストールのシミュレーションをしてみると、まだlibcudart5.0とlibcurand5.0の二つのパッケージは自動的にインストールが行われてしまうようである。そこで、これらのライブラリに対してもそれぞれフェイクパッケージを作成する。上のmycudaglueと合わせて計3つのフェイクパッケージ、いかにも不格好である。先に理解が不十分と描いた所以である。どうもProvoidesに記述するパッケージのパッケージ名とバージョン名の切り分けがシステムによってどう解釈されるかが分かっていない気がする。

ともあれ、先ほどと同様に作業ディレクトリを作り、まずlibcudart5.0のフェイクパッケージを作成する。

$ equivs-control libcudart5.0
Section: misc
Priority: optional
# Homepage:
Standards-Version: 3.9.2

Package: libcudart5.0
Version: 5.0.99
Maintainer: GM3D (@gm3d2 on twitter)

ほとんどスカスカのパッケージである。バージョン名を、5.0系列であることを保証しながら、一応Ubuntuで用意している5.0.35-4Ubuntu1より新しいことを表すために5.0.99としてある。そして先程と同様に、

$ equivs-build libcudart5.0
$ sudo gdebi libcudart5.0_5.0.99_all.deb
でインストールする。また同様に、libcuramd5.0のパッケージも作成、インストールする。

$ equivs-control libcurand5.0
vi libcurand5.0

Section: misc
Priority: optional
Standards-Version: 3.9.2

Package: libcurand5.0
Version: 5.0.99
Maintainer: GM3D (@gm3d2 on twitter)

$ equivs-build libcurand5.0
$ sudo gdebi libcurand5.0_5.0.99_all.deb

これでpython-pycudaパッケージに関してはCUDA関連の依存性がすべて満たされる。

$ sudo aptitude install python-pycuda

でインストールを行い、pyCUDAの最初のサンプルhello_gpu.pyを実行してみる。

$ python hello_gpu.py
Traceback (most recent call last):
File "hello_gpu.py", line 1, in
import pycuda.autoinit
File "/usr/lib/python2.7/dist-packages/pycuda/autoinit.py", line 1, in
import pycuda.driver as cuda
File "/usr/lib/python2.7/dist-packages/pycuda/driver.py", line 2, in
from pycuda._driver import *
ImportError: libcurand.so.5.0: cannot open shared object file: No such file or directory

共有ライブラリlibcurand.so.5.0が開けない…と、まあそうである。パッケージングシステム上は無理やり入っていると思わせたが、このライブラリファイルは実在していない。そこで、

$ sudo -i
# cd /usr/local/cuda/lib64
# ln -s libcurand.so.5.5 libcurand.so.5.0
# ln -s libcudart.so.5.5 libcudart.so.5.0

として、CUDA 5.5のライブラリを5.0のライブラリとして使うようにする。pyCUDAが使用しているAPIが5.0と5.5で変更されていなければこれで動くはずである。(そうでなければそもそもこの方向性ではうまくいきようがない)

果たして、今度は実行してみると
$ python hello_gpu.py
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0.]

と400個の0が表示される。これでテスト成功である。

あと忘れてはならないのは、次にCUDAがアップデートされた時にこれらのフェイクパッケージも(pyCUDAも必要なら)一旦アンインストールし、内容を新しいCUDAにマッチするものに作り替えて更新することだ。

以上、かなり無理やりではあるが所期の目的を達成した。Debianのパッケージングシステムに詳しい方からよりスマートな手法などを教えていただければありがたいと思う。

Ubuntu 13.04にCUDA 5.5をインストールする

CUDA 5.5のプロダクションリリースが最近公開された。そこでこれを、現在メイン環境として使用しているUbuntu 13.04にインストールしたのだが、思ったより簡単であった。簡単過ぎて特にメモもいらないくらいなのだが、特別なメモもいらないというその事実をメモしておく。

前段として、本来NVIDIAはどのバージョンでも今の時点ではUbuntu 13.04をCUDAのサポート対象プラットフォームとして挙げてはいない。しかしCanonical側の努力で、Ubuntu 13.04では、Ubuntuの制式パッケージとしてCUDA 5.0が使用できることは、以前のエントリに書いた通りである。

私としては、特にCUDA 5.5でとうとう念願の、Linuxのグラフィカル環境で、シングルGPU構成のマシンでのGDBサポートが実現されたので、これの恩恵に預かるためにもCUDA 5.5にアップグレードする必要があった。

そこでまず、インストールに先立って、既にインストールされているCUDA 5.0関連のパッケージを根こそぎアンインストールするところから始めた。

dpkg -l | grep nvidia | grep '^ii'

で、インストールされているパッケージを調べ、(sudo) apt-get removeで全てアンインストールする。

その後、NVIDIAのダウンロードサイトから、Ubuntu 12.10用の cuda-repo-ubuntu1210_5.5-0_amd64.deb ファイルを持ってきて、

sudo gdebi cuda-repo-ubuntu1210_5.5-0_amd64.deb

でインストールする。これは、UbuntuマシンのリポジトリデータベースにNVIDIAのCUDAリポジトリを追加するだけである。この後は、

sudo apt-get update

でこのリポジトリ情報を反映させ、

sudo apt-get install cuda

で、CUDA関連のパッケージをインストールするだけである。ここで、cudaはNVIDIAによって定義された抽象パッケージ名で、これによって、ディスプレイドライバまで含め、CUDA 5.5関連のパッケージがすべてインストールされる。

また、CUDA 5.5からARMアーキテクチャがサポートされるようになり、そのクロスコンパイル環境もインストールすることができる。あいにく私はまだTegra4を所持していないので試していないが、

apt-get install cuda-cross

でインストールできるとドキュメントにはある。

あと、CUDAのサンプルソースについても、リードオンリで/usr/local/cuda-5.5/samples にインストールされるが、自分で書き換えていろいろ試したい場合は

cuda-install-samples-5.5.sh ターゲットディレクトリ

としてやれば、書き込み可能なコピーがターゲットディレクトリに作られる。

まとめ: Ubuntu 13.04でもUbuntu 12.10とまったく同じにCUDA 5.5がインストールできる。

CUDAで "too many resources requested for launch"

FermiアーキテクチャのGPUは、Compute capablity 2.xに対応しており、1ブロックあたり1024スレッドを走らせることが仕様上可能のはずである。しかし、自分でプログラムを書いている間に、なぜかブロック毎のスレッド数を1024にすると、表題のようなエラーによりカーネルが走らない、という現象に遭遇した。

この現象は、簡単なサンプルプログラム等では発生しない。ある程度の規模のカーネルコードでないと起きないのだが、ブロック毎のスレッド数を512に減らすと問題なく動作する。

しばらく原因が分からず苦しんだのだが、Stack Overflowのこのスレッドあたりを見てようやく解決した。

原因は何だったかというと、nvccのフラグに-Gオプションを指定していたことである。これはデバッグ用のオプションであるが、これを指定すると、通常のコードよりもレジスタを多く使用するコードが生成されるらしい。その結果、カーネルがある程度以上にレジスタに確保される変数を多用している場合、1024スレッド並列に動かそうとするとブロック全体で使用可能なレジスタ容量の上限を超え、結果としてカーネルの起動エラーとなるらしい。

-Gオプションの指定をやめると、同じコードで問題なく動作するようになった。デバッグ用のオプション指定でかえってデバッグにえらく手間取るはめになってしまい、なんとも本末転倒であった。

Ubuntu 13.04とCUDA 5

Ubuntu 13.04が公開されて、12.10からアップグレードして使用している。CUDAを使う上で何よりありがたいのは、今回Ubuntuの側でCUDA 5に正式対応してくれたことである。CUDA toolkitもUbuntuのパッケージとして提供され、もうNVIDIAから独自にパッケージをダウンロードしてインストールする必要はなくなった。

nvidia-cuda-{dev,doc,gdb,tookit}
nvidia-opencl-dev
nvidia-profiler
nvidia-visual-profiler
nvidia-common

あたりが関連パッケージである。またディスプレイドライバも同じく、通常はnvidia-currentだけ入れておけばいいようだ。私は今のところ明示的にバージョンを指定して、nvidia-304 (304.88-0ubuntu1)を入れている。

今まではUbuntuで収録しているCUDAのバージョンは4.28だったので、直接CUDA 5 を使用して開発を行う場合はNVIDIAからのパッケージを入れる必要があったし、その場合、Ubuntu提供のCUDA 4.28は切り替えが面倒なので入れていなかったのだが、そうするとPyCUDAなどのUbuntuのCUDAパッケージに依存するパッケージが入れられないという面倒さがあった。またgccも4.6と4.7を共存させて、必要に応じて切り替えるなどの対処が必要だったが、これも得に対処は必要なくなった。今回のアップデートでそういう諸々の面倒さが解消されたのは大変に助かる。


今までNVIDIAからダウンロードしたパッケージを使用していたので、ヘッダーは/usr/local/cuda/include、ライブラリは/usr/local/cuda/lib64にインストールされていたのだが、どちらもシステム標準の/usr/include、/usr/lib64に変わった。そのため、コンパイル時にMakefile中で-Iや-Lオプションでこれらのパスを明示的に指定する必要はなくなった。

ただし、例外として、cuDevice*等のCUDAドライバAPIを直接ソース中で使用している場合、つまりMakefile中で対応するライブラリlibcuda.soを明示的に-lcudaでリンクしている場合は、このライブラリだけは

/usr/lib/nvidia-304/libcuda.so

のように、ドライババージョンに明示的に依存するパスに置かれているので、このディレクトリを-Lオプションで
指定してやる必要がある。私は自分のプログラムを見直して、基本的にドライバAPIに依存せず、すべてランタイムライブラリだけで済ませるようにしたので、-Lオプションはなしで-lcudartだけを指定している。

今回のアップデートで非常にCUDA開発の環境もすっきりしたが、ちょっと微妙なのはCUDA関連の多数のヘッダーファイルが/usr/includeの直下にインストールされるようになっていることである。これは/usr/include/cuda内とかにしてくれても良かったかなという気がする。

あと、もう一つの注意点は、thrustを使用する場合、

/usr/include/thrust/iterator/iterator_facade.h(326): warning: a __host__ function("thrust::experimental::operator==") redeclared with __host__ __device__, hence treated as a __host__ __device__ function

のような警告が出力される場合がある。これは、いずれthrust側で修正されると思うが、当面GitHubのここにあるパッチを手動で当てればいいようだ。


プロフィール

GM3D

Author:GM3D
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
FC2カウンター
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。