基本问题是CUDA 编译器是否支持别名模板?
我在带有 gcc-4.8 的 Ubuntu 上使用 CUDA 7.5。我所有的模板类都在头文件中定义,并#include
在编译期间 d 到单个翻译单元中。
我有一个简单的cuda_array
类,它提供了一个围绕std::vector
. 它本质上是一个非常简单的版本,thrust::host_vector
结合了thrust::device_vector
. 它的声明是
template <typename T, const size_t N>
class cuda_array {
std::vector<T> host;
T *device;
public:
// lots of type aliases to meet container requirements
void push() { /* cudaMemcpy(...,H2D); */ }
void pull() { /* cudaMemcpy(...,D2H); */ }
// a few others that aren't relevant here
};
为了制作一个矩阵,我只是做了一个快速的模板别名。
template <typename T, const size_t M, const size_t N>
using cuda_matrix = cuda_array<T, M * N>;
我想将我的矩阵向量乘法 CUDA 内核映射到重载operator*
的类型安全和易于使用(它留给调用者以确保push
并pull
正确调用)。
template <typename T, const size_t rows, const size_t cols>
__global__ void matrix_vector_mul(T *A, T *b, T *result) {
__shared__ T shared_b[cols];
// rest of it
}
template <typename T, const size_t M, const size_t N>
__host__ cuda_array<T, M> operator*(cuda_matrix<T, M, N> &m, cuda_array<T, N> &v) {
cuda_array<T, M> result;
matrix_vector_mul<T, M, N><<<16, 32>>>(m.device_data(), v.device_data(), result.device_data());
return result;
}
在我的'main.cpp'中,我有
cuda_matrix<int,16,32> A;
cuda_array<int,32> b;
auto result = A * b;
最后一行抛出一个错误说
error: no operator "*" matches these operands
operand types are: cuda_matrix<int, 16UL, 32UL> * cuda_array<int, 32UL>
我追查了所有我能想到的模板类型推断错误的常见嫌疑人,但没有任何效果。无奈之下,我将我的cuda_matrix
别名模板转换为模板类。
template <typename T, const size_t M, const size_t N>
class cuda_matrix : public cuda_array<T, M * N> {};
编译错误消失了!因此,CUDA 似乎还不支持别名模板。还是我做了一些我想不通的傻事?