在通用类

时间:2016-04-27 12:11:46

标签: c++ cuda

我创建了一个包装内核函数的模板类。因此,当另一个类需要使用内核时,它可以简单地调用类函数而不必担心CUDA的术语和功能。由于该类是模板类,因此所有定义和声明都包含在同一文件中。

Scanner.h

#include <iostream>
#include "ScanKernals.h"

class Scanner {
public :
    template<typename T>
    void ScanDevice(T * h_in, int size);

    template<typename T>
    void ScanHost();

};

template<typename T>
void Scanner::ScanHost()
{

}

template<typename T>
void Scanner::ScanDevice(T * h_in, int size)
{
  T * d_in;
  cudaMalloc(&d_in, size * sizeof(T));
  cudaMemcpy(d_in , h_in, size * sizeof(T), cudaMemcpyHostToDevice);
  // runs kernel that is required to calculate the scan 
}

ScanKernals.h

template<typename T>
__global__
void scan(T * d_in, T* d_out, int size)
{
   // keranel code
}

然后在主函数中使用上面的类,如下所示

的main.cpp

#include <iostream>
#include "Scanner.h"

int main()
{
    Scanner scanner;

    return 0;
}

但是当我编译代码时,编译器会出错,而不是识别CUDA特定的关键字。

如果我将 Scanner 类的定义分离为单独的 .cpp 文件,则不会生成此错误,但由于无法声明模板类,在两个单独的文件中定义,这不是一个选项

我在这里遗漏了什么,是否有解决方法?

2 个答案:

答案 0 :(得分:2)

如果您的代码路径包含包含C ++编译代码的CUDA语法,那么您必须做两件事:

  1. 使用nvcc编译器驱动程序编译代码
  2. 使用.cu扩展名重命名正在编译的文件。 nvcc使用文件扩展名来确定给定文件的编译轨迹,如果文件的扩展名为.cpp,则代码将直接传递给主机编译器,编译将失败。
  3. 你显然没有做到这两件事或两件事。

答案 1 :(得分:0)

nvcc在您的文件上的默认行为不是您所期望的@talonmies下划线。但是,您可能需要尝试以下编译器命令行选项:

--x {c|c++|cu}                             (-x)
    Explicitly specify the language for the input files, rather than letting
    the compiler choose a default based on the file name suffix.
    Allowed values for this option:  'c','c++','cu'.

明确指出输入代码是cuda,即使以.cpp后缀命名。以下是main.cpp文件的示例:

__global__ void f() {}

没有旗帜:

/usr/local/cuda-7.5/bin/nvcc -c main.cpp
main.cpp:1:1: error: ‘__global__’ does not name a type
 __global__ void f() {}
 ^

带标志(无错误):

/usr/local/cuda-7.5/bin/nvcc -c main.cpp -x cu

文件命名自由似乎是安全的。