C++ Cuda中的链接错误

C++ Cuda中的链接错误,c++,cuda,thrust,nvcc,C++,Cuda,Thrust,Nvcc,为了更熟悉GPU编程,我在尝试构建基本的cuda/推力代码时遇到了问题。我可能没有正确编译它,所以我想知道我做错了什么 我正在使用以下说明进行构建 nvcc -c gpu_functions.cu nvcc gpu_functions.o gpu_test.cu -o gpu_test 但是,我得到一个链接错误: jim@pezbox:~/dev/analytics/src$ nvcc gpu_functions.o gpu_test.cu -o gpu_test /tmp/tmpxft_00

为了更熟悉GPU编程,我在尝试构建基本的cuda/推力代码时遇到了问题。我可能没有正确编译它,所以我想知道我做错了什么

我正在使用以下说明进行构建

nvcc -c gpu_functions.cu
nvcc gpu_functions.o gpu_test.cu -o gpu_test
但是,我得到一个链接错误:

jim@pezbox:~/dev/analytics/src$ nvcc gpu_functions.o gpu_test.cu -o gpu_test
/tmp/tmpxft_00002383_00000000-14_gpu_test.o: In function `main':
tmpxft_00002383_00000000-3_gpu_test.cudafe1.cpp:(.text+0x6e): undefined reference to `void add<thrust::device_vector<int, thrust::device_malloc_allocator<int> > >(thrust::device_vector<int, thrust::device_malloc_allocator<int> > const&, thrust::device_vector<int, thrust::device_malloc_allocator<int> > const&, thrust::device_vector<int, thrust::device_malloc_allocator<int> >&)'
collect2: ld returned 1 exit status
jim@pezbox:~/dev/analytics/src$nvcc gpu_functions.o gpu_test.cu-o gpu_test
/tmp/tmpxft_00002383_00000000-14_gpu_test.o:在函数“main”中:
tmpxft_00002383_00000000-3_gpu_测试.cudafe1.cpp:(.text+0x6e):未定义对“无效添加(推力::设备_向量常数&,推力::设备_向量常数&,推力::设备_向量&)”的引用
collect2:ld返回了1个退出状态
我有三个文件:

  • gpu_functions.h(gpu函数的头函数)
  • gpu_functions.cu(gpu功能的实现)
  • gpu_test.cu(调用我定义的gpu函数的主循环)
  • gpu_函数.h

    template<typename Vector>
    void add(const Vector& in1, const Vector& in2, Vector& out);
    
    模板
    void add(常量向量&in1,常量向量&in2,向量&out);
    
    gpu_functions.cu

    #include "gpu_functions.h"
    #include <thrust/sequence.h>
    #include <thrust/transform.h>
    #include <thrust/sequence.h>
    #include <thrust/copy.h>
    #include <thrust/fill.h>
    #include <thrust/replace.h>
    #include <thrust/functional.h>
    
    using namespace thrust;
    
    template<typename Vector>
    void add(const Vector& in1, const Vector& in2, Vector& out) {
    transform(in1.begin(), in1.end(), in2.begin(), out.begin(), 
              plus<typename Vector::value_type>()); 
    }
    
    #包括“gpu函数.h”
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    使用名称空间推力;
    模板
    void add(常量向量&in1,常量向量&in2,向量&out){
    转换(in1.begin()、in1.end()、in2.begin()、out.begin(),
    正());
    }
    
    gpu_test.cu

    #include "piston_functions.h"
    #include <thrust/device_vector.h>
    #include <iostream>
    #include <stdio.h>
    
    using namespace thrust;
    
    int main(void) {
        const int n = 100000000;
        // allocate three device_vectors with 10 elements
        device_vector<int> in1(n, 1);
        device_vector<int> in2(n, 2);
        device_vector<int> out(n, 0);
    
        add(in1, in2, out);
    
        thrust::copy(out.begin(), out.begin()+10, std::ostream_iterator<int>(std::cout,"\n"));
    
        return 0;    
    }
    
    #包括“活塞功能.h”
    #包括
    #包括
    #包括
    使用名称空间推力;
    内部主(空){
    常数整数n=100000000;
    //分配三个包含10个元素的设备_向量
    器件_矢量in1(n,1);
    器件_矢量in2(n,2);
    设备_矢量输出(n,0);
    添加(in1、in2、out);
    推力::复制(out.begin(),out.begin()+10,std::ostream_迭代器(std::cout,“\n”);
    返回0;
    }
    

    我可能在做一些愚蠢的事情,或者我错过了一些非常明显的事情。

    一旦声明,模板函数需要显式或隐式实例化,即为模板参数的特定组合生成具体函数(实例)

    gpu\u functions.cu
    编译单元中,您缺少这两个函数。换句话说,编译器没有生成函数
    add
    的实例,因此链接器找不到任何要链接的内容

    您应该通过在隐式实例化模板化函数声明的位置(即构成
    main
    函数的编译单元)包含模板化函数声明来解决此问题

    换句话说,下面的代码将正确编译

    #include <thrust/device_vector.h>
    #include <iostream>
    #include <stdio.h>
    
    using namespace thrust;
    
    template<typename Vector>
    void add(const Vector& in1, const Vector& in2, Vector& out) {
    transform(in1.begin(), in1.end(), in2.begin(), out.begin(), 
        plus<typename Vector::value_type>()); 
    }
    
    int main(void) {
        const int n = 100000000;
        device_vector<int> in1(n, 1);
        device_vector<int> in2(n, 2);
        device_vector<int> out(n, 0);
    
        add(in1, in2, out);
    
        thrust::copy(out.begin(), out.begin()+10, std::ostream_iterator<int>(std::cout,"\n"));
    
        return 0;    
    }
    
    #包括
    #包括
    #包括
    使用名称空间推力;
    模板
    void add(常量向量&in1,常量向量&in2,向量&out){
    转换(in1.begin()、in1.end()、in2.begin()、out.begin(),
    正());
    }
    内部主(空){
    常数整数n=100000000;
    器件_矢量in1(n,1);
    器件_矢量in2(n,2);
    设备_矢量输出(n,0);
    添加(in1、in2、out);
    推力::复制(out.begin(),out.begin()+10,std::ostream_迭代器(std::cout,“\n”);
    返回0;
    }
    
    当然,您可以在单独的
    .cuh
    文件中移动模板化函数声明,并通过
    #include
    指令将其包括在内


    最后,始终记得添加。

    在使用模板时,所有显式专门化声明必须在模板实例化时可见。在您的情况下,
    add
    gpu\u functions.cu
    中定义,但未实例化,并且在
    gpu\u test.cu
    中没有可见内容。尝试将
    add
    的定义从
    gpu\u函数.cu
    移动到
    gpu\u测试.cu
    @jackolanten请将此作为答案发布。@harrism我已经发布了答案。