I am trying to compile and run a simple Cuda/thrust program, it works when the extension is .cu
but it fails when the extension of source is .cpp
.
I already applied the required changes for cpp file in cmake but I am getting
error: static assertion failed: unimplemented for this system 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})
and the 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;
}
Using the CUDA first-class language support in cmake (which is what you're doing when you establish that CUDA
is a language used by your project) means that cmake is going to use the NVidia compiler for .cu
files and some other compiler (such as gcc) on other files. When you use add_executable
, cmake is also checking for .cu
file extensions to ascertain how to properly link together your application.
FindCUDA
is an older set of tools that does not necessarily override these behaviors. You've gone 90% of the way toward replicating the first-class language features using the macros provided by FindCUDA
, but add_executable
fails to perform some necessary additional steps so your application bombs. Normally you'd use the CUDA_ADD_EXECUTABLE
macro to designate a CUDA executable when using the FindCUDA
tools.
So here's what you should do: if you don't want your main file to have a .cu
extension then just move your foo
function to a separate .cu
file with its own header that you include in main.cpp
. You won't need to use set_source_files_properties
since your device code will be properly segregated into its own .cu
, allowing cmake to take the proper steps.
Have a look at this article for more details and references: https://shawnliu.me/post/cuda-as-a-language-in-cmake/