CUDA3.2RCを入れてみた

動機

仕事で、GPUを使ったシミュレータのアクセラレートを計画しているが、CUDAを使ってプログラミングできる人が1人だと、何かがあったときに仕事が滞るので、自分も技術を身につけようと一念発起(というほどのことでもないけど)。

インストール

NVidiaのホームページ
http://developer.nvidia.com/object/cuda_3_2_toolkit_rc.html
から、Mac用ドライバ、CUDAツールキット、GPU SDKをゲット。

CUDAツールキットは、/usr/local/cuda, GPU SDKは、/Developer/GPU\ Computing にそれぞれインストールされる模様。

シェルセッティング

パスやライブラリをリンクするために、下記を追加。

## CUDAの設定
export PATH=/usr/local/cuda/bin:$PATH
export CPLUS_INCLUDE_PATH="/Developer/GPU Computing/C/common/inc":/usr/local/cuda/include:$CPLUS_INCLUDE_PATH
export C_INCLUDE_PATH="/Developer/GPU Computing/C/common/inc":/usr/local/cuda/include:$C_INCLUDE_PATH
export LIBRARY_PATH="/Developer/GPU Computing/C/common/lib":"/Developer/GPU Computing/C/lib":/usr/local/lib:$LIBRARY_PATH
export DYLD_LIBRARY_PATH=/usr/local/cuda/lib:$DYLD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib:$LD_LIBRARY_PATH

コンパイル

とりあえず何も機能しないプログラムをコンパイル出来るかどうかテスト。

// test.cu
int main()
{
  return 0;
}

<|
nvcc test.cu

を実行すると、

/usr/local/cuda/include/surface_functions.h: In function ‘void surf1Dread(T*, surface, int, int, cudaSurfaceBoundaryMode)’:
/usr/local/cuda/include/surface_functions.h:100: error: there are no arguments to ‘__surf1Dreadc1’ that depend on a template parameter, so a declaration of ‘__surf1Dreadc1’ must be available
/usr/local/cuda/include/surface_functions.h:100: error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
/usr/local/cuda/include/surface_functions.h:101: error: there are no arguments to ‘__surf1Dreads1’ that depend on a template parameter, so a declaration of ‘__surf1Dreads1’ must be available
/usr/local/cuda/include/surface_functions.h:102: error: there are no arguments to ‘__surf1Dreadu1’ that depend on a template parameter, so a declaration of ‘__surf1Dreadu1’ must be available
/usr/local/cuda/include/surface_functions.h:103: error: there are no arguments to ‘__surf1Dreadu2’ that depend on a template parameter, so a declaration of ‘__surf1Dreadu2’ must be available
/usr/local/cuda/include/surface_functions.h:104: error: there are no arguments to ‘__surf1Dreadu4’ that depend on a template parameter, so a declaration of ‘__surf1Dreadu4’ must be available
/usr/local/cuda/include/surface_functions.h: In function ‘void surf2Dread(T*, surface, int, int, int, cudaSurfaceBoundaryMode)’:
/usr/local/cuda/include/surface_functions.h:460: error: there are no arguments to ‘__surf2Dreadc1’ that depend on a template parameter, so a declaration of ‘__surf2Dreadc1’ must be available
/usr/local/cuda/include/surface_functions.h:461: error: there are no arguments to ‘__surf2Dreads1’ that depend on a template parameter, so a declaration of ‘__surf2Dreads1’ must be available
/usr/local/cuda/include/surface_functions.h:462: error: there are no arguments to ‘__surf2Dreadu1’ that depend on a template parameter, so a declaration of ‘__surf2Dreadu1’ must be available
/usr/local/cuda/include/surface_functions.h:463: error: there are no arguments to ‘__surf2Dreadu2’ that depend on a template parameter, so a declaration of ‘__surf2Dreadu2’ must be available
/usr/local/cuda/include/surface_functions.h:464: error: there are no arguments to ‘__surf2Dreadu4’ that depend on a template parameter, so a declaration of ‘__surf2Dreadu4’ must be available

うにょ〜ん。。。。大量のエラーが発生。そしてよくわからない。

回避策

メッセージにあるとおり、gccのオプション-fpermissiveをつけて実行してみる。

nvcc --compiler-options -fpermissive test.cu

とすると、下記のワーニングがでるものの、コンパイルはされる。

cc1: warning: command line option "-fpermissive" is valid for C++/ObjC++ but not for C
cc1: warning: command line option "-fpermissive" is valid for C++/ObjC++ but not for C

ちなみに、このオプション(fpermissive)は、

  • fpermissive

規格に準拠していないコードについてのメッセージをエラーから警告に格下げする。デフォルトでは、g++ は -pedantic を指定しない場合は実質的に -pedantic-errors を指定している。このオプションはそれを逆にする。この動作とオプションは、-pedantic により打ち消される。-pedatnic は GNU C の場合と同様の動作になる。

ということでできるだけ使いたくない。

CUDAとgccの相性を疑ってみる

どこかのページでCUDAとgcc4.2の相性が悪い、ということが書いてあったので、gcc4.3, gcc4.0などで試してみるが、結局同じエラーがでて、デフォルトではコンパイルできない。

仕方が無いので、このオプションをつける。

GPU SDKをコンパイルするとき

インストールしたSDKをコンパイルしたい場合は、
/Developer/GPU Computing/C/common/common.mk
のNVCCFLAGSにつけとけばいいだろう。

MBPのGPU

とりあえず我がMBPのdeviceQuery結果

There is 1 device supporting CUDA

Device 0: "GeForce GT 330M"
  CUDA Driver Version:                           3.20
  CUDA Runtime Version:                          3.20
  CUDA Capability Major/Minor version number:    1.2
  Total amount of global memory:                 536543232 bytes
  Multiprocessors x Cores/MP = Cores:            6 (MP) x 8 (Cores/MP) = 48 (Cores)
  Total amount of constant memory:               65536 bytes
  Total amount of shared memory per block:       16384 bytes
  Total number of registers available per block: 16384
  Warp size:                                     32
  Maximum number of threads per block:           512
  Maximum sizes of each dimension of a block:    512 x 512 x 64
  Maximum sizes of each dimension of a grid:     65535 x 65535 x 1
  Maximum memory pitch:                          2147483647 bytes
  Texture alignment:                             256 bytes
  Clock rate:                                    1.10 GHz
  Concurrent copy and execution:                 Yes
  Run time limit on kernels:                     Yes
  Integrated:                                    No
  Support host page-locked memory mapping:       Yes
  Compute mode:                                  Default (multiple host threads can use this device simultaneously)
  Concurrent kernel execution:                   No
  Device has ECC support enabled:                No
  Device is using TCC driver mode:               No

今後

いちおうCUDAのインストールとコンパイルはできたようなので、実際にデバイス上でコードが動くかどうか、ですね。