半年の間に,しらすの春の旬と秋の旬をまたぐことになりました.
っていうか,寒いよ!夏がいいよ!!><
さて,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
です.