最近在写tsdf的程序,同时使用了OpenCV,PCL和CUDA。在编译工程的时候发现了不少问题,在这里整理一下。
1. cu和cpp文件
__global__,__host__,__device__
这样开头的cuda程序只能写在cu文件中。
kernal<<< i,j >>>
这样的核函数只能写在cu文件中。如果想在cpp文件中调用,可以将核函数封装在cu文件中,再调用。
其余的一些cuda命令如cudaMalloc,cudaMemcpy
可以在cpp文件中使用。
2. include头文件在引用pcl的头文件前,要添加CUDACC宏定义下的boost内容
因为pcl/io/boost.h这个文件中做了关于宏CUDACC的编译选项,使用CUDA编译时,很多boost的头文件不包含了。所以在引用pcl头文件前添加:
#ifndef __CUDACC__
#ifndef Q_MOC_RUN
#include <boost/version.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread.hpp>
#include <boost/thread/thread.hpp>
#include <boost/filesystem.hpp>
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
#include <boost/function.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/algorithm/string.hpp>
#ifndef Q_MOC_RUN
#include <boost/date_time/posix_time/posix_time.hpp>
#endif
#if BOOST_VERSION >= 104700
#include <boost/chrono.hpp>
#endif
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
#include <boost/shared_array.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
#if BOOST_VERSION >= 104900
#include <boost/interprocess/permissions.hpp>
#endif
#include <boost/iostreams/device/mapped_file.hpp>
#define BOOST_PARAMETER_MAX_ARITY 7
#include <boost/signals2.hpp>
#include <boost/signals2/slot.hpp>
#endif
#endif
3. 在c++11下使用cudaMalloc
需要添加在导入变量前添加(void**)
。如:
cudaMalloc((void**)&gpu_voxel_grid_TSDF, voxel_grid_dim_x * voxel_grid_dim_y * voxel_grid_dim_z * sizeof(float));
gpu_voxel_grid_TSDF
是float型变量。若不添加(void**)
,则会报错: error: invalid conversion from ‘float**’ to ‘void**’ [-fpermissive]
4. cuda是可以和cpp文件进行联合编译的。 CMakelists里要注意添加:
gpu部分的包和路径
#GPU
option(USE_CUDA "Use CUDA" ON)
find_package(CUDA REQUIRED)
find_package(CUDA 8.0)
include_directories(${CUDA_INCLUDE_DIRS})
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};--disable-warnings;--ptxas-options=-v;-use_fast_math;-lineinfo;-std=c++11)
解决pcl和cuda冲突的vtk问题
get_directory_property(dir_defs DIRECTORY ${PROJECT_SOURCE_DIR} COMPILE_DEFINITIONS)
set(vtk_flags)
foreach(it ${dir_defs})
if(it MATCHES "vtk*")
list(APPEND vtk_flags ${it})
endif()
endforeach()
foreach(d ${vtk_flags})
remove_definitions(-D${d})
endforeach()
使用CUDA_ADD_EXECUTABLE
联合编译cpp和cu文件
CUDA_ADD_EXECUTABLE(mytsdf src/mytsdf.cpp ${cpu_source_files} src/tsdf_gpu.cu)
否则会警告:
CMake Warning (dev) in cuda_gpu_generated_test.cu.o.cmake:
Syntax Warning in cmake code at
/home/xxx/mytsdf-fusion/build/mytsdf/CMakeFiles/cuda_gpu.dir/src/cuda_gpu_generated_test.cu.o.cmake:79:137
Argument not separated from preceding token by whitespace.
This warning is for project developers. Use -Wno-dev to suppress it.
并且报错:
nvcc fatal : A single input file is required for a non-link phase when an outputfile is specified
CMake Error at cuda_gpu_generated_test.cu.o.cmake:207 (message):
Error generating
/home/xxx/mytsdf-fusion/build/mytsdf/CMakeFiles/cuda_gpu.dir/src/./cuda_gpu_generated_test.cu.o
mytsdf/CMakeFiles/cuda_gpu.dir/build.make:63: recipe for target 'mytsdf/CMakeFiles/cuda_gpu.dir/src/cuda_gpu_generated_test.cu.o' failed
目前就发现了这些问题,后面如有发现再继续补充。
参考:
[1] https://www.jianshu.com/p/6bf114685a6a