半年ぶりの更新です.
半年の間に,しらすの春の旬と秋の旬をまたぐことになりました.
っていうか,寒いよ!夏がいいよ!!><
さて,Linux上のCMakeでCUDAを使っているんですが,CUDAではたいてい最新のGCCはサポートされません.
ということで,nvccの-ccbinオプションによってCUDA関連のコンパイルのみを古いGCCにすることができます.
普段のC++コードは最新のGCCで,CUDA関連のみはサポートされたGCCでご利用いただけます.
CMakeにおいてこれを行うときは少しクセがあり,だいぶ格闘したのでメモ.
例えば次のソースを用意します.
// 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の環境.
本題.
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
です.