初心者すぎて変なところで詰んでいたので今後のためにもメモ。
何が起きていたか
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
用
https://proc-cpuinfo.fixstars.com/2019/02/cuda_smart_pointer/
さてビルドをしてみると以下のエラーが。
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})
参考