zoukankan      html  css  js  c++  java
  • Linux平台CUDA+OpenCV3.4配置

    前段时间,在TX2上装了OpenCV3.4,TX2更新源失败的问题,OpenCV内部很多函数都已经实现了GPU加速,但是我们手动写的函数,想要通过GPU加速就需要手动调用CUDA进行加速。下面介绍Linux平台的环境配置以及与OpenCV混合编译。

    Linux平台CUDA+OpenCV3.4配置

    1 环境安装

    首先需要安装OpenCV及CUDA环境安装,有TX2平台下OpenCV和CUDA参考百度。注意TX2自带了OpenCV2.14,如果需要安装高版本的OpenCV话需要注意多版本管理的问题。安装完成后,可以编译OpenCV例程来判断OpenCV是否安转完成,CUDA安装可以在终端输入

    nvcc

    如果终端打印下面信息,表示安装完成

    2 CUDA编译流程

    CUDA的程序通过nvcc编译器编译成可执行文件,CUDA的可执行文件有两种,分别是在Host上执行的CPU相关代码,另一部分是在Device上执行的GPU代码,nvcc编译的指令与gcc/g++编译器差不多,基本指令如下

    nvcc --gpu-architecture=compute_62 --gpu-code=compute_62 -I/usr/local/cuda/include/  -c kernels.cu -o kernels.o

    其中:

    --gpu-architecture和--gpu-code指定了GPU的计算能力,请根据自己GPU的运算能力修改,有关GPU运算能力可以在这里查找(NVIDIA官网挂了,将就着在维基百科里面看吧),--gpu-architecture指定ptx将来可以生成怎么样的版本,--gpu-code指定马上生成的代码版本,--gpu-architecture和--gpu-code可以有多个值,这样nvcc会将多个版本的代码一同放在fatbin文件中,

    -I/usr/local/cuda/include/指定了CUDA包含头文件的目录,如果还有其他的头文件,要将这些头文件的路径包含进来(见3)

    -c表示只对源文件进行编译,不进行链接,及将.cu文件编译生成.cu文件

    -o指定要生成.o文件的文件名

    还有其他的一些编译选项可以参考NVIDIA的nvcc编译手册,在CUDA的安装目录下可以找到

    3 CUDA与OpenCV混合编译

    CUDA与OpenCV的混合编译其实就是讲.cu文件与.c/.cpp文件混合编译,编译的方法比较多,NVIDIA官网有介绍利用cmake进行编译的方法,点这里,网上介绍的比较多的也是利用cmake进行编译,使用Makefile编译的教程比较少,这里介绍一下利用Makefile对CUDA与c++进行混合编译。

    其实CUDA与c/c++一起编译原理很简单,CUDA C也只是一个拓展的c语言集,所以我采用的是利用nvcc编译器和g++分别对.cu文件和.cpp文件进行编译,生成.o文件,然后利用g++进行链接,实测方法可行。因为我CUDA的程序全部都在.cu文件中,然后在.cpp文件中通过extern对CUDA的函数申明,像下面这样:

    /*main.cpp*/
    
    extern int buildMaps(float *model, float *input, float *output, int height, int width);
    
    int main()
    {
        /*初始化代码*/
        ......    
    
        buildMaps((float *)model, (float *)input, output, width, width);
    
        /*other*/
        ......
    }
    /*kernel.cu*/
    
    /*GPU内核函数*/
    __global__ void kernel_compute(float *model, float *input, float *output)
    {
        ......
    }
    
    int buildMaps(float *model, float *input, float *output, int height, int width)
    {
         /*init*/
        ......
    
        kernel_compute <<<grid, block>>> (dev_m, dev_i, dev_o);
    
        /*other*/
        ......
    }

    所以这里的OpenCV代码像普通OpenCV代码一样写Makefile就行,写CUDA的代码的Makefile时注意,如果.cu文件中有OpenCV的相关代码的话,需要在nvcc编译的时候添加

    -DOPENCV `pkg-config --cflags opencv-3.4`

    用来指定OpenCV的包含头文件路径,没有错误的话,编译完成就可以使用g++链接就可以了。

    这里贴一下我自己在用的一个Makefile模板,写的比较粗糙,不过平常的编译基本够了,中小型的工程的Makefile都可以用这个模板修改的到,模板有不完善的地方还请大家指正

    #cpp源文件路径
    SRCS = $(wildcard ./src/*.cpp)
    
    #cu文件路径
    CU_SRC = $(wildcard ./src/*.cu)
    
    #.o文件
    OBJS = $(patsubst %.cpp,%.o,$(SRCS))
    CU_OBJ = $(patsubst %.cu,%.o,$(CU_SRC))
    
    #g++和nvcc编译器
    CXX = g++
    NVCC = nvcc
    
    #C/C++编译选项  --  OpenCV头文件路径
    CFLAGS = `pkg-config --cflags opencv-3.4`
    
    #C/C++编译选项  --  当前工程头文件路径及优化选项(-O3)
    CFLAGS += -I./include/ -std=c++11 -O3 
    
    #开启OpenMP
    CFLAGS += -fopenmp
    
    #CUDA C编译选项
    NVFLAGS = --gpu-architecture=compute_62 --gpu-code=compute_62 
    NVFLAGS += -DOPENCV `pkg-config --cflags opencv-3.4`
    
    #C/C++链接器选项  -- OpenCV库及其路径
    LDFLAGS = `pkg-config --libs opencv-3.4` -O3
    LDFLAGS += -fopenmp
    
    #C/C++链接器选项  -- CUDA8.0库及其路径
    NVLDFLAGS = `pkg-config --libs cuda-8.0`
    
    #最终目标
    EXE = video
    
    #OpenMP选项  --  指定绑定CPU
    GOMP_CPU_AFFINITY="0 3 4 5"
    
    #链接
    $(EXE) : $(OBJS) $(CU_OBJ)
        @echo Linking ...
        @$(CXX) -o $@ $^ $(LDFLAGS) $(NVLDFLAGS)
    
    #C/C++编译
    %.o : %.cpp
        @echo Compiling $< ...
        @$(CXX) $(CFLAGS) -c $<
        @-mv *.o src/
    
    #CUDA C编译
    %.o : %.cu
        @echo NVCC Compiling $< ...
        @$(NVCC) $(NVFLAGS) -c $<
        @-mv *.o src/
    
    .PHONY:clean
    
    clean :
        -rm src/*.o
        -rm $(EXE)

    作者:Brccq
    出处:http://www.cnblogs.com/br170525// 出处:http://www.loveyfyq.com//
    欢迎转载,必须在文章页面明显位置给出原文连接,如需本博文源代码或者有任何问题,请在博文留下您的邮箱或者问题说明。

  • 相关阅读:
    我的知识库(4) java获取页面编码(Z)
    知识库(3)JAVA 正则表达式 (超详细)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts
    某人总结的《英语听力的技巧 》,挺搞的
    我的知识库(5)java单例模式详解
    构建可扩展程序
    SerialPort (RS232 Serial COM Port) in C# .NET
    Python学习笔记——String、Sequences
    UI题目我的答案
    jQuery学习系列学会操纵Form表单元素(1)
  • 原文地址:https://www.cnblogs.com/br170525/p/8331640.html
Copyright © 2011-2022 走看看