问题简述

        对于CUDA编程,thrust库能够很方便地在Host(内存)与Device(显存)之间传输数据,在使用thrust时只用在代码中include头文件,不需要像OpenCV那样配置和链接额外的库。

        但是使用thrust时需要注意这几个问题:

  1. 在c++14标准下编译:可以用使用编译指令-std=c++14,如:
    nvcc -O3 -std=c++14 -Xcompiler -fopenmp *.cpp *.cu -o output
    其中,“-O3”为最大速度编译优化,“-Xcompiler”将指令传给gcc编译器,“-fopenmp”链接openMP库,“-o output”将编译文件命名为output。ps:我个人习惯在编译共享库是才加“-fPIC”指令。如果使用cmake编译则可加入一句(set不区分大小写)
    set(CMAKE_CXX_STANDARD 14)
  2. include了thrust的文件必须用CUDA环境进行编译,例如文件后缀为.cu或通过“-x”指令指定任意后缀的文件通过CUDA环境编译。下面举一个我遇到的例子
    //---------a.h---------//
    #include <thrust/device_vector.h>
    class A
    {
    public:
        void foo();
    protected:
        thrust::device_vector<float> _temp;
    }
    //---------a.cu---------//
    #include "a.h"
    #include <stdio.h>
    void A:foo()
    {
        auto t = vector<float>(10, 0);
        _temp = t;
    }
    //---------b.cpp---------//
    #include "a.h"
    ....

    通过a.h的桥梁,b.cpp中悄悄地include了thrust,而我没使用“-x”指令,故产生错误(如下图,提示thrust库内部文件报错:/usr/local/cuda/include/thrust/detail/internal_functional.h;/usr/local/cuda/include/thrust/system/cuda/detail/par.h;/usr/local/cuda/include/thrust/system/cuda/detail/util.h等)。

    因此,千万别在头文件中include thrust!!!类的成员变量可以考虑改为静态全局变量,注意变量的初始化和实例数不能超过1。

    //---------a.h---------//
    class A
    {
    public:
        void foo();
    }
    //---------a.cu---------//
    #include "a.h"
    #include <stdio.h>
    #include <thrust/device_vector.h> // include放在cpp文件
    static thrust::device_vector<float> _temp; // 改为静态全局变量
    void A:foo()
    {
        auto t = vector<float>(10, 0);
        _temp = t;
    }
    //---------b.cpp---------//
    #include "a.h"
    ....

    即使损失一些成员变量具有的特性,但是这样能够保证安全。有更好方法的朋友欢迎评论区交流~ 

  3. 有些博客说thrust是release编译得到的,用debug模式编译会出现问题,这也值得注意,不过我还没有尝试过。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐