使用cmake在虚拟环境下编译demon lmbspecialops以及遇到的问题及解决

15 篇文章 1 订阅
9 篇文章 0 订阅
0. 写在最前面

  这一节是我在尝试了各种版本配置后终于完全配置成功后补充的。lmbspecialops是真的折磨人,只能说这个坑真的太深了,前前后后我总共花了将近一周的时间。原因是lmbspecialops是作者17年的产物了,使用到的一些配置也都比较老旧(下面会说)。而且,它涉及到一些对版本比较敏感却又相互关联的配置,包括(cuda、gcc、tensorflow的版本),这几个版本稍有偏差,就会造成编译运行失败。比如它使用的是cuda8.0,而cuda8.0支持的gcc版本最高只能是5,但是我们现在动辄ubuntu20.04的,其默认的配置gcc都是7、9的了。也就意味着,我们需要去安装gcc5并对多版本gcc进行管理。而这里又有一个坑,一开始我是安装了gcc5.5.0(教程),以为这样就可以使用cuda8.0进行编译了,但是没想到的是,gcc5.5.0有版本自身问题,于是,我只能另寻它路,换成gcc5.4.0(教程)。而gcc5.4.0的安装并非一帆风顺,耗时也是非常之久(两小时那样)。我也曾尝试过使用作者说的pew管理虚拟环境,但是不是很好用,最后我还是使用conda管理。其次,作者在其github上给的配置不够详细,甚至于说,具有很强的误导性。下图是作者推荐的库版本:
在这里插入图片描述
  但是,就算这里提到的所有配置版本与作者的一致,我也还是无法成功编译并使用。虽然中途我确实编译成功过,而且配置还不是和作者的完全一致,也就是本博客原本要讲解的配置流程以及遇到的问题解答。但是,当我配置好之后,该库在使用过程中也还是会出错(心累)。还有很多吐槽点,但是,已经叨磕挺多了(满腹抱怨),废话不多说了,进入正题。
  总结来说就是,编译lmbspecialops对环境版本要求极高,一些小的版本差异就会导致配置失败。比如tensorflow和cuda、cudnncuda和gcc之间的版本都有关联。我的ubuntu系统版本是20.04,使用anaconda管理的虚拟环境。我最后的配置是参考了github上的一个issue,现在将可以成功编译的详细配置总结如下(划重点):

ubuntu 版本不重要,作者用的16.04,我用的20.04,都可以
cmake 3.7.1以上就行,比如我的是3.16.3
gcc 5.4.0(不要用5.5.0,会报错)-> 配置教程
python 3.5.2          -> 在创建虚拟环境时就指定好
numpy 1.16.4          -> 安装命令:pip install numpy==1.16.4(非必须,但是版本过高在import tensorflow的时候会有支持问题)
tensorflow 1.3.0         -> 安装命令:pip install tensorflow-gpu==1.3.0
cuda 8.0.61          -> 配置教程
cudnn 6.0.21          -> 下载链接(选择cuDNN v6.0 (April 27, 2017), for CUDA 8.0)

  上面有提到的版本最好保持一致,没有提到的库版本则不重要。下面是原来的正文(使用cuda10.0),有提到一些编译过程中遇到的错误及解决,可供参考。以及,最后将根据上述环境编译成功lmbspecialops并运行example的结果附上了。

========================================================================

========================================================================

  需要使用demon网络来跑深度图和相机位姿,其github上有详细的build教程,如下图所示:
在这里插入图片描述
  但是由于使用的cuda版本以及虚拟环境管理方式不太一样(我是用conda管理的虚拟环境,然后cuda版本是10.0),所以在make的时候连着遇到几个问题(其实就算版本和作者的一模一样,还是会出现这些错误,因为我也试过了。配深度学习环境真是太麻烦了。),在此按照遇到问题的顺序依次记录一下。
  

1. fatal error: tensorflow/core/framework/op_kernel.h: 没有那个文件或目录

详情

fatal error: tensorflow/core/framework/op_kernel.h: 没有那个文件或目录
 #include "tensorflow/core/framework/op_kernel.h"
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

解决方法链接
  

2. fatal error: math_functions.hpp: 没有那个文件或目录

详情

/home/jianping/anaconda3/envs/demon-env/lib/python3.5/site-packages/tensorflow/include/unsupported/Eigen/CXX11/../../../Eigen/Core:59:14: fatal error: math_functions.hpp: 没有那个文件或目录
     #include <math_functions.hpp>
              ^~~~~~~~~~~~~~~~~~~~
compilation terminated.
CMake Error at lmbspecialops_generated_warp2d_cuda.cu.o.Release.cmake:220 (message):
  Error generating
  /home/jianping/workspace/demon/lmbspecialops/build/lib/CMakeFiles/lmbspecialops.dir//./lmbspecialops_generated_warp2d_cuda.cu.o

原因
  不同cuda版本,其某些文件存放的路径也不太一样。比如这里的math_functions.hpp文件,在cuda8.0下,其路径为:/usr/local/cuda-8.0/include/math_functions.hpp,而在cuda10.0里,其路径为:/usr/local/cuda-10.0/include/crt/math_functions.hpp。参考链接
解决方法
  使用软链接,在终端执行命令sudo ln -s /usr/local/cuda/include/crt/math_functions.hpp /usr/local/cuda/include/math_functions.hpp即可。
  

3. fatal error: nsync_cv.h: 没有那个文件或目录

详情

/home/jianping/anaconda3/envs/demon-env/lib/python3.5/site-packages/tensorflow/include/tensorflow/core/platform/default/mutex.h:25:10: fatal error: nsync_cv.h: 没有那个文件或目录
 #include "nsync_cv.h"
          ^~~~~~~~~~~~
compilation terminated.
CMake Error at lmbspecialops_generated_warp2d_cuda.cu.o.Release.cmake:220 (message):
  Error generating
  /home/jianping/workspace/demon/lmbspecialops/build/lib/CMakeFiles/lmbspecialops.dir//./lmbspecialops_generated_warp2d_cuda.cu.o

解决方法
  locate一下nsync_cv.h文件,可以发现它的路径是/home/jianping/anaconda3/envs/demon-env/lib/python3.5/site-packages/tensorflow/include/external/nsync/public/nsync_cv.h。而在第一个问题处,我们已经将tensorflow/include这个路径添加到cmakelists文件里了,也就是cmake是可以找到这个路径的,那么接下来的问题就是include时候路径没有告诉完整。方法就是,将tensorflow/core/platform/default/mutex.h里的

#include "nsync_cv.h"
#include "nsync_mu.h"

  改为:

#include "external/nsync/public/nsync_cv.h"
#include "external/nsync/public/nsync_mu.h"

  

4. #error – unsupported GNU version! gcc versions later than 5 are not supported!

详情

In file included from /usr/local/cuda/include/cuda_runtime.h:78:0,
                 from <command-line>:0:
/usr/local/cuda/include/host_config.h:119:2: error: #error -- unsupported GNU version! gcc versions later than 5 are not supported!
 #error -- unsupported GNU version! gcc versions later than 5 are not supported!
  ^~~~~
In file included from /usr/local/cuda/include/cuda_runtime.h:78:0,
                 from <command-line>:0:
/usr/local/cuda/include/host_config.h:119:2: error: #error -- unsupported GNU version! gcc versions later than 5 are not supported!
 #error -- unsupported GNU version! gcc versions later than 5 are not supported!
  ^~~~~

解决方法链接
  

5. 最后

  再make,就可以成功到100%了!make时候有个小tips,可以在最后添加参数-j来使用多线程make。比如make -j8就是使用8线程。
  

6. plus一个隐秘的错误

  在执行cmake ..命令的时候,会很快速地输出一堆东西,没有明显的红色错误信息,如果你没有返回去仔细查看一下这一堆信息的话,很容易把它给忽略掉。而且问题还在于,如果你不管这个错误信息,直接继续编译下去的话,是可以成功编译好lmbspecialops的。但是在后面你使用tensorflow和这个包的时候,你还是会遇到这个错误的(亲身经历)。所以不将其解决也不是办法。报错信息如下:

-- Found PythonInterp: /home/jianping/anaconda3/envs/demon/bin/python (found version "3.5.6") 
Traceback (most recent call last):
  File "/home/jianping/anaconda3/envs/demon/lib/python3.5/site-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
    from tensorflow.python.pywrap_tensorflow_internal import *
  File "/home/jianping/anaconda3/envs/demon/lib/python3.5/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 28, in <module>
    _pywrap_tensorflow_internal = swig_import_helper()
  File "/home/jianping/anaconda3/envs/demon/lib/python3.5/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 24, in swig_import_helper
    _mod = imp.load_module('_pywrap_tensorflow_internal', fp, pathname, description)
  File "/home/jianping/anaconda3/envs/demon/lib/python3.5/imp.py", line 243, in load_module
    return load_dynamic(name, filename, file)
  File "/home/jianping/anaconda3/envs/demon/lib/python3.5/imp.py", line 343, in load_dynamic
    return _load(spec)
ImportError: libcudnn.so.6: cannot open shared object file: No such file or directory

  其实直接看这里的最后这行就可以了,意思是找不到libcudnn.so.6。这个文件到底代表着什么?这里的6,感觉是和某某的版本有关。其实就是字面意思,cudnn的版本。这段报错其实是我在cuda8.0环境下编译lmbspecialops报错的(上面一开始提到的cuda10.0是昨天的事了,然后当时给我报的错是libcudnn.so.8,后来修改了tensorflow版本什么的,弄得环境有点乱,于是我又重新建了一个和作者版本配置一样的虚拟环境,打算重新配环境)。这会儿我就很纳闷了,昨天用的cuda10.0,你给我报错libcudnn.so.8,今天换成cuda8.0,报错就变成了libcudnn.so.6。???(黑人问号)难不成我还要去试试cuda6.0?然后也许你还会给我报错libcudnn.so.4?(开玩笑的)。
  其实这里的6和8,指的是cudnn的版本。由于作者并没有说明他使用的cudnn是什么版本,而cuda8.0既有cudnn6的,也有cudnn7的,然后7是比较新一些的。所以我当时安装好cuda8.0之后就直接下载了cudnn7版本的。而实际上,这里需要的是cudnn6。内鬼找到了,解决办法很简单,去cudnn官网下适用于cuda8.0的cudnn v6.0(2017年的,真的是有点古老了),如下图所示:
在这里插入图片描述
  下好之后解压,使用这里头的文件去替换之前7版本的就可以了。如果不知道怎么替换,参考这里吧。修改好之后再次运行cmake ..的时候,就不会再出现这个错误了!
  

7. Cannot find lmbspecialops.so

  这个问题是编译好lmbspecialops要使用它的时候报错的。报错信息是:

'Cannot find lmbspecialops.so . Set the environment variable LMBSPECIALOPS_LIB to the path to lmbspecialops.so file')
ValueError: Cannot find lmbspecialops.so . Set the environment variable LMBSPECIALOPS_LIB to the path to lmbspecialops.so file

  找不到的这个文件在lmbspecialops目录下的/build/lib目录下。一开始我以为就是程序找不到so链接文件,于是尝试了很多方法,包括但不限于修改~/.bashrc文件、修改/etc/ld.so.conf文件然后sudo /sbin/ldconfig,甚至将该so文件拷贝到usr/lib和/lib路径下。但是,都无济于事。而实际上,这段报错信息是lmbspecialops.py文件里面的,该文件的第23~29行内容如下:

if 'LMBSPECIALOPS_LIB' in os.environ:
    _lib_path = os.environ['LMBSPECIALOPS_LIB']
else:  # try to find the lib in the build directory relative to this file
    _lib_path = os.path.abspath(os.path.join(os.path.split(__file__)[0], '..', 'build', 'lib', 'lmbspecialops.so'))
if not os.path.isfile(_lib_path):
    raise ValueError(
        'Cannot find lmbspecialops.so . Set the environment variable LMBSPECIALOPS_LIB to the path to lmbspecialops.so file')

  这里,os是python自带的一个包,os.environ可以用来获取与设置系统变量,一个比较好的讲解可以点击这里。上面的语句不难理解:如果系统变量中有定义了LMBSPECIALOPS_LIB这个变量,那么获取该变量值,然后检验其是否是需要的lmbspecialops.so文件;如果没有设置该变量,则自动构建lmbspecialops.so的文件路径。如果我们没有改变编译好的lmbspecialops的文件结构,那么就算我们没有设置LMBSPECIALOPS_LIB这个环境变量,自动构建的路径应该也是能找到lmbspecialops.so文件的。可是,它没找到。问题就出在,自动构建的相对路径…/build/lib/lmbspecialops.so中的…,在环境变量里头是不认的。所以这个自动构建路径根本就没用。那么还一个问题,我在前面不是试了很多方法去添加环境变量吗,为什么也没有用呢?因为这里作者又挖了个坑,一般我们添加环境变量都是到所需文件的路径而已,而作者这里,是要把文件名都加上!
  上面已经把原因都说明了,所以解决方法就是,要么在添加名为LMBSPECIALOPS_LIB的环境变量时把文件名也加上,要么在文件内构建路径时,构建绝对路径而不是相对路径,这样就可以了。
  

8. 编译成功的结果

在这里插入图片描述
  

9. 环境配置

  在作者github上,编译好lmbspecialops之后,是使用如下命令将lmbspecialops配置到python环境变量中去的:

pew add $DEMON_DIR/lmbspecialops/python # add to python path

  但是我们用的是conda,没有这个操作(应该是没有吧,至少我没听过也没使用过)。但是可以通过如下两步进行配置:

9.1 如果直接运行example.py文件,会遇到错误:ImportError: No module named ‘lmbspecialops’。解决办法是,打开/python/depthmotionnet/helpers.py文件,在import lmbspecialops as sops这行代码前面加上如下两行代码:
import sys
sys.path.append('/home/xxx/workspace/demon/lmbspecialops/python')

  上面需要填的是lmbspecialops.py文件所在的绝对路径,依据自己的实际路径进行修改即可。

9.2 第二个错误:‘Cannot find lmbspecialops.so . Set the environment variable LMBSPECIALOPS_LIB to the path to lmbspecialops.so file’)。原因是找不到链接文件lmbspecialops.so。解决办法是,打开/lmbspecialops/python/lmbspecialops.py文件,将第26行的_lib_path = os.path.abspath(os.path.join(os.path.split(file)[0], ‘…’, ‘build’, ‘lib’, ‘lmbspecialops.so’))直接修改为lmbspecialops.so文件所在的绝对路径,比如:
_lib_path = '/home/xxx/workspace/demon/lmbspecialops/build/lib/lmbspecialops.so'

  

10. 运行example

  修改好上述错误后,进入examples文件夹,打开终端执行:

python3 example.py

  可以看到如下输出:
在这里插入图片描述
  然后会自动弹出一张深度图结果:
在这里插入图片描述
  以及,关闭图像后可以获得一个可视化的点云:
在这里插入图片描述
  这个过程可能会报错:

vis_cython.c:620:31: 致命错误:numpy/arrayobject.h:没有那个文件或目录
编译中断。

  解决方法是,在终端执行如下命令:

sudo apt-get install python-numpy

  安装成功后再执行example文件,就可以看到点云了。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zeeq_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值