我创建了一个包装内核函数的模板类。因此,当另一个类需要使用内核时,它可以简单地调用类函数而不必担心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 文件,则不会生成此错误,但由于无法声明模板类,在两个单独的文件中定义,这不是一个选项
我在这里遗漏了什么,是否有解决方法?
答案 0 :(得分:2)
如果您的代码路径包含包含C ++编译代码的CUDA语法,那么您必须做两件事:
.cu
扩展名重命名正在编译的文件。 nvcc使用文件扩展名来确定给定文件的编译轨迹,如果文件的扩展名为.cpp
,则代码将直接传递给主机编译器,编译将失败。你显然没有做到这两件事或两件事。
答案 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
文件命名自由似乎是安全的。