我正在尝试编译并运行一个简单的Cuda / thrust程序,当扩展名是.cu
时,它可以工作,但是当源扩展名是.cpp
时,它会失败。我已经在cmake中对cpp文件应用了所需的更改,但是我正在得到
错误:静态断言失败:此系统未实现THRUST_STATIC_ASSERT_MSG
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(thrust_test LANGUAGES CXX CUDA)
find_package(CUDA 10.0 REQUIRED)
message(STATUS "CUDA ${CUDA_VERSION_STRING} at ${CUDA_TOOLKIT_ROOT_DIR}")
set(CUDA_LINK_LIBRARIES_KEYWORD PUBLIC)
include_directories(${CUDA_INCLUDE_DIRS})
link_directories(${CUDA_LIBRARY_DIRS})
set(CMAKE_CUDA_STANDARD 14)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
set(CUDA_SEPARABLE_COMPILATION ON)
set_source_files_properties(
main.cpp
PROPERTIES
CUDA_SOURCE_PROPERTY_FORMAT
OBJ)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} ${CUDA_LIBRARIES})
和main.cpp:
__host__
__device__
int foo() {
// generate random data serially
thrust::host_vector<int> h_vec(100);
std::generate(h_vec.begin(), h_vec.end(), rand);
// transfer to device and compute sum
thrust::device_vector<int> d_vec = h_vec;
return thrust::reduce(d_vec.begin(), d_vec.end(), 0, thrust::plus<int>());
}
int main(void) {
std::cout << "Thrust v" << THRUST_MAJOR_VERSION << "." << THRUST_MINOR_VERSION << std::endl;
std::cout << foo() << std::endl;
return 0;
}
在cmake中使用CUDA一流的语言支持(这是在确定CUDA
是项目所使用的语言时所做的事情),这意味着cmake将对.cu
文件使用NVidia编译器以及其他文件上的其他一些编译器(例如gcc)。当您使用add_executable
时,cmake还将检查.cu
文件扩展名,以确定如何正确链接您的应用程序。
FindCUDA
是一组较旧的工具,不一定覆盖这些行为。使用FindCUDA
提供的宏,您已经花了90%的时间来复制一流的语言功能,但是add_executable
无法执行一些必要的附加步骤,因此您的应用程序大爆炸。通常,在使用CUDA_ADD_EXECUTABLE
工具时,您将使用FindCUDA
宏指定CUDA可执行文件。
因此,这是您应该做的:如果您不希望主文件具有.cu
扩展名,则只需将foo
函数移动到一个单独的.cu
文件中,该文件具有您自己的标头,并包含在main.cpp
中]。您无需使用set_source_files_properties
,因为您的设备代码将被正确地分离为自己的.cu
,从而使cmake可以采取适当的步骤。
请查看本文以获取更多详细信息和参考:https://shawnliu.me/post/cuda-as-a-language-in-cmake/