CMakeでCUDAの-ccbinの正しい指定方法

半年ぶりの更新です.
半年の間に,しらすの春の旬と秋の旬をまたぐことになりました.
っていうか,寒いよ!夏がいいよ!!><

さて,Linux上のCMakeでCUDAを使っているんですが,CUDAではたいてい最新のGCCはサポートされません.
ということで,nvccの-ccbinオプションによってCUDA関連のコンパイルのみを古いGCCにすることができます.
普段のC++コードは最新のGCCで,CUDA関連のみはサポートされたGCCでご利用いただけます.

CMakeにおいてこれを行うときは少しクセがあり,だいぶ格闘したのでメモ.

-ccbinの例

例えば次のソースを用意します.

// prog.cu
int main()
{
}

GCCの4.8.1を使ってnvccでコンパイルしてみると.

$ g++ --version
g++ (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ nvcc prog.cu
In file included from /usr/local/cuda/bin/../include/cuda_runtime.h:59:0,
                 from <command-line>:0:
/usr/local/cuda/bin/../include/host_config.h:82:2: error: #error -- unsupported GNU version! gcc 4.7 and up are not supported!
 #error -- unsupported GNU version! gcc 4.7 and up are not supported!
  ^

$ nvcc prog.cu -ccbin g++-4.4
$ ./a.out
(うごいた)

こうなります.
ちなみに今回はCUDA 4.2の環境.

CUDAソースによる小さいサンプル

本題.

CMakeだとnvccは自動的に実行されるので,nvccに与えるオプションはちゃんと与える必要があります.

ということで,CMakeLists.txtの最小の例.
上のprog.cuと同じディレクトリに置きます.

#A tiny example of CMakeLists.txt

cmake_minimum_required(VERSION 2.8)                     # おまじない
project(osakanacuda)                                    # プロジェクト名

set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -ccbin g++-4.4)  # GCCへのパス.PATHが通っていればこのように名前のみの指定でもOK
#list(APPEND CUDA_NVCC_FLAGS -ccbin g++-4.4)            # これでもOK

#以下はどちらもダメ.違いがわかりますか?
#set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -ccbin=g++-4.4)
#list(APPEND CUDA_NVCC_FLAGS=-ccbin g++-4.4)

find_package(CUDA)                                      # CUDA環境を見つけてくれる.やらないとダメ
cuda_add_executable(prog prog.cu)                       # progっていう実行ファイルをビルドしてくれる設定になる

こんな配置だとすると,

.
├── CMakeLists.txt
├── prog.cu
└── build/

次のようにしてビルドします.

$ ls
CMakeLists.txt prog.cu build/

$ cd build
$ cmake ..
$ make

ダメって書いてある方の指定をすると,

nvcc fatal   : redefinition of argument 'compiler-bindir'
CMake Error at prog_generated_prog.cu.o.cmake:206 (message):
  Error generating
  /hogehogehogehogheohgoehgoehoge/build/CMakeFiles/prog.dir//./prog_generated_prog.cu.o

っていう内容を含んだエラーが出ます.

理由

正しい指定と誤った指定の違いは見ての通り,”-ccbin=hogehoge”か”-ccbin hogehoge”の違いなんですが,CMakeのFindCUDAにあるrun_nvcc.cmakeを読んでみると,
“-ccbin”という文節があった場合にその指定を優先するようになっており,
ない場合はCMakeの中でのデフォルトの指定をすることになっています.

なので,”-ccbin=hogehoge”をCUDA_NVCC_FLAGSに指定すると,nvccが呼び出されるときは

nvcc ... -ccbin=hogehoge -ccbin fugafuga ...

となり,「多重指定はダメだっちゃ」と怒られます.

なんちゅー仕様.誰か修正してくださ・・・

なお今回の環境は,

  • Debian 6.0
  • CMake version 2.8.11.1
  • CUDA 4.2
  • GCC 4.8.1/4.4.5

です.

コメントを残す

メールアドレスが公開されることはありません。