tl;dr CUDA関連はターゲットを分けろ(初心者)
何が起きていたか
CUDAは現状C++11にしか対応していないことは周知の事実とします。
以下のようなCMakeLists.txt
を作って作業をしてました。
cmake_minimum_required(VERSION 3.10) if(NOT DEFINED CMAKE_CUDA_COMPILER) set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc) endif() project(sample LANGUAGES CXX CUDA) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CUDA_STANDARD 11) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${sample_SOURCE_DIR}/bin) cmake_policy(SET CMP0079 NEW) find_package(CUDA REQUIRED) include_directories("${CUDA_INCLUDE_DIRS}") if(NOT DEFINED CMAKE_CUDA_STANDARD) set(CMAKE_CUDA_STANDARD 11) set(CMAKE_CUDA_STANDARD_REQUIRED ON) endif() add_executable(sample main.cpp) target_sources(sample PRIVATE cuda.hpp gpu_functions.h gpu_functions.cpp) target_link_libraries(sample ${CUDA_LIBRARIES})
gpu_functions.h
#pragma once #include "cuda.hpp" __global__ void kernel(void); void proxy(void);
gpu_functions.cu
#include <cstdio> #include "gpu_functions.h" __global__ void kernel(void) { printf("Hello from CUDA kernel.\n"); } void proxy(void) { kernel<<<1,1>>>(); }
cuda.hpp
というのは、以下記事に転がっていた有益なコードを拝借してます。が、今回は特にGPUメモリへデータを転送するということはしていないのであくまでcuda_runtime_api.h
用
proc-cpuinfo.fixstars.com
さてビルドをしてみると以下のエラーが。
CUDA_STANDARD is set to invalid value '17'
このメッセージでググっても記事が出てきません。冷静に考えてみると、いくらCMakeにCUDAが統合されたからとはいえ、どれがCUDAのソースかはCMakeにはわかりません。
当然分けないといけないわけなんですが、上記のCMakeLists.txtは通常のC++ソースファイル類と同じターゲットに加えてしまっていました。これではCUDAのソースもg++へ投げられてしまいます。
(CUDA_STANDARD
の値が17になっていた原因がさっぱりですが、CXX_STANDARD
が17になっていたため、CUDA_STANDARD
も17にセットされてしまっていたのでしょうか…わかりません)
解決
ちゃんとターゲットを分けてリンクしましょう。
cmake_minimum_required(VERSION 3.10) if(NOT DEFINED CMAKE_CUDA_COMPILER) set(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc) endif() project(sample LANGUAGES CXX CUDA) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CUDA_STANDARD 11) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${sample_SOURCE_DIR}/bin) cmake_policy(SET CMP0079 NEW) find_package(CUDA REQUIRED) include_directories("${CUDA_INCLUDE_DIRS}") if(NOT DEFINED CMAKE_CUDA_STANDARD) set(CMAKE_CUDA_STANDARD 11) set(CMAKE_CUDA_STANDARD_REQUIRED ON) endif() add_executable(sample main.cpp) add_library(cudalib cuda.hpp gpu_functions.h gpu_functions.cu) set_target_properties(cudalib PROPERTIES CUDA_SEPERABLE_COMPILATION ON) target_link_libraries(sample cudalib) target_link_libraries(sample ${CUDA_LIBRARIES})
参考
https://cliutils.gitlab.io/modern-cmake/chapters/packages/CUDA.html