重要な質問は、エイリアス テンプレートが CUDA コンパイラでサポートされているかどうかです。
gcc-4.8でUbuntuでCUDA 7.5を使用しています。すべてのテンプレート クラスはヘッダー ファイルで定義され、#include
コンパイル中に 1 つの翻訳単位に変換されます。
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>;
operator*
型の安全性と使いやすさのために、行列とベクトルの乗算 CUDA カーネルをオーバーロードされたカーネルにマップしたいと考えています (正しく呼び出されることを確認するのは呼び出し元に任されています) 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 はまだエイリアス テンプレートをサポートしていないようです。それとも、私が理解できないばかげたことをしましたか?