Reputation: 718
I used the example create cuda library with cmake to create a small cuda based library. The library contains a class called CudaImage which is supposed to run a Cuda kernel on an image.
CMakeLists is as follows:
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(cudaMPbTools LANGUAGES CXX CUDA)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../common
)
add_library(cudaMPbTools STATIC
cudaimage.cu
cudaimage.h
cvector.h
cvector.cpp
)
target_link_libraries(cudaMPbTools libCommon)
target_compile_features(cudaMPbTools PUBLIC cxx_std_11)
set_target_properties( cudaMPbTools
PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
cudaimage.h contains the following code:
class CudaImage {
public:
CudaImage(unsigned char* image_data, int image_width, int image_height, int scale);
private:
__device__
void addToHistoArray(int val, int i, int j);
};
The libraries compiles fine with cmake, but now I am trying to use the CudaImage class inside a main.cpp outside the library:
CudaImage cudaImg(img1.data, img1.cols, img1.rows, 10);
but this generates a compilation error in the main project because it does not recognize the device keyword in the cudaimage.h.
CMakeLists.txt for the main project is something like:
cmake_minimum_required (VERSION 3.10)
project (mPb)
cmake_policy(SET CMP0020 NEW)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../common
${CMAKE_CURRENT_SOURCE_DIR}/../cudaMPbTools
${Qt5Core_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS})
set(MPB_SRCS
main.cpp
pbdetector.cpp
)
set(MPB_HEADR
pbdetector.h)
add_executable(mPb ${MPB_SRCS} ${MPB_HEADR})
target_link_libraries(mPb
libCommon
${OpenCV_LIBS}
cudaMPbTools)
qt5_use_modules(mPb Core)
Can anyone give advice on this matter ? Is the CMakeLists.txt in the main project correct?
Update I extracted the function addToHistoArray from the class CudaImage and declared it as follows:
__device__ void addToHistoArray(struct CVector* dHalfDiscInfluencePoints, int totalHalfInfluencePoints, unsigned int** dHistograms, int image_width, int image_height, int scale, int arcno, int val, int i, int j);
and I still cannot compile my project. I updated the source code in github as well.
Upvotes: 0
Views: 243
Reputation: 718
I have found a solution such that my project compiles. It requires the following:
The CMake files look are for the library:
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(cudaMPbTools)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../common
)
find_package(CUDA)
cuda_add_library(cudaMPbTools
cudaimage.cu
cudaimage.h
cvector.h
cvector.cpp
STATIC
)
target_link_libraries(cudaMPbTools libCommon ${CUDA_LIBRARIES})
target_compile_features(cudaMPbTools PUBLIC cxx_std_11)
and for project:
cmake_minimum_required (VERSION 3.10)
project (mPb)
find_package(CUDA)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../common
${CMAKE_CURRENT_SOURCE_DIR}/../cudaMPbTools
${Qt5Core_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
${CUDA_INCLUDE_DIRS})
set(MPB_SRCS
main.cpp
pbdetector.cpp
)
set(MPB_HEADR
pbdetector.h)
cuda_add_executable(mPb ${MPB_SRCS} ${MPB_HEADR})
target_link_libraries(mPb
libCommon
${OpenCV_LIBS}
cudaMPbTools)
qt5_use_modules(mPb Core)
Upvotes: 0
Reputation: 1145
As MSalters said, the problem is that device methods are meant to be called from GPU to be executed on GPU. I'm not sure that's what you meant to do. If not, you should read this: Difference between global and device functions
(sorry I can't comment posts yet)
Upvotes: 1
Reputation: 180305
__device__ void CudaImage::addToHistoArray(int val, int i, int j)
is rather suspect. The whole point of a member function is that it has a this
pointer, i.e. a CudaImage*
. That is of course a host pointer (CudaImage
lives on the CPU). So what's your __device__
(GPU) function trying to do with a host pointer?!
That it doesn't compile is a lucky side-effect. Presumably addToHistoArray
doesn't need a CudaImage*
, so it could have been a free function inside cudaimage.cu
Upvotes: 1