ElasticFusion是Thomas Whelan博士在Dyson Research
做研究员时的经典工作。
环境是Ubuntu16.04
+RTX2080TI
+Cuda10.1
各种依赖安装参考项目的Github主页,Ubuntu16.04
需要注意的是openjdk-7-jdk
的安装,因为Ubuntu16.04
的安装源已经默认没有openjdk7
了,所以要自己手动添加仓库:
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-7-jdk
打开项目根目录的build.sh
,根据里面的编译部分进行代码编译:
cd ../Core
mkdir build
cd build
cmake ../src
make -j8
cd ../../GPUTest
mkdir build
cd build
cmake ../src
make -j8
cd ../../GUI
mkdir build
cd build
cmake ../src
make -j8
可以看到代码目录的三个子项目都需要分别编译,中间也会有各种问题存在,下面展开叙述。
首先是编译Core
项目,这是核心代码,也是最常出问题的。
在编译前,需要根据自己的显卡配置和Cuda对/Core/src
目录下的CMakeLists.txt
进行修改,主要是第32
行的CUDA_ARCH_BIN
,这个算力是通过编译Cuda
目录下的samples
,然后调用./deviceQuery
进行查询的。通常1080
卡可以把这项改成61
,2080
是75
。
set(CUDA_ARCH_BIN "75" CACHE STRING "Specify 'real' GPU arch to build binaries for, BIN(PTX) format is supported. Example: 1.3 2.1(1.3) or 13 21(13)")
修改完进行编译:
cd Core
mkdir build
cd build
cmake ../src
make -j8
在make
时一直报错:/Core/src/Cuda/reduce.cu
文件“__shfl_down” is undefined
错误,查了很多资料也没有很好解决这个问题,有个资料提到cuda9.0之后弃用了该函数。
github issues里luruibo1995
提到‘modify the function __shfl_down to __shfl_down_sync, the mask i choice is 0xFFFFFFFF’
,但是文件里要改的地方太多,也没有尝试这个方法(后来有测试这个方法,确实是可行的,跟后面取巧的方法不论是重建过程还是重建结果都基本没有什么差别)。
为了尽快跑起来程序,这里采用了取巧的方式,查看这个reduce.cu
文件,发现从第56
行到第80
行有对算力不够的device声明__shfl_down
函数:
#if __CUDA_ARCH__ < 300
__inline__ __device__
float __shfl_down(float val, int offset, int width = 32)
{
static __shared__ float shared[MAX_THREADS];
int lane = threadIdx.x % 32;
shared[threadIdx.x] = val;
__syncthreads();
val = (lane + offset < width) ? shared[threadIdx.x + offset] : 0;
__syncthreads();
return val;
}
__inline__ __device__
int __shfl_down(int val, int offset, int width = 32)
{
static __shared__ int shared[MAX_THREADS];
int lane = threadIdx.x % 32;
shared[threadIdx.x] = val;
__syncthreads();
val = (lane + offset < width) ? shared[threadIdx.x + offset] : 0;
__syncthreads();
return val;
}
#endif
将#if __CUDA_ARCH__ < 300
和#endif
两行注释掉,编译就可以顺利通过了。
顺利编译:
cd GPUTest
mkdir build
cd build
cmake ../src
make -j8
然后运行程序:
./GPUTest ../
一阵眼花缭乱之后,输出对应显卡的4行配置,将其复制到/Core/src/Utils/GPUConfig.h
:
icpStepMap["GeForce RTX 2080 Ti"] = std::pair<int, int>(128, 128);
rgbStepMap["GeForce RTX 2080 Ti"] = std::pair<int, int>(96, 128);
rgbResMap["GeForce RTX 2080 Ti"] = std::pair<int, int>(128, 304);
so3StepMap["GeForce RTX 2080 Ti"] = std::pair<int, int>(96, 112);
如果不修改的话,运行完ElasticFusion会报Your GPU ‘’ ‘’ isn't in the ICP Step performance database, please add it
的警告。
改了Core
的文件后,重新编译下Core
。
顺利编译:
cd GUI
mkdir build
cd build
cmake ../src
make -j8
下载数据集,然后运行:
./ElasticFusion -l dyson_lab.klg
程序顺利运行。