カーネル テンプレートで CUDA カーネル関数ポインターを受け入れる CUDA ランタイム API 関数を使用したいと考えています。
テンプレートなしで次のことができます。
__global__ myKernel()
{
...
}
void myFunc(const char* kernel_ptr)
{
...
// use API functions like
cudaFuncGetAttributes(&attrib, kernel_ptr);
...
}
int main()
{
myFunc(myKernel);
}
ただし、カーネルがテンプレートの場合、上記は機能しません。
もう一つの例:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
template<typename T>
__global__ void addKernel(T *c, const T *a, const T *b)
{
int i = threadIdx.x;
c[i] = a[i] + b[i];
}
int main()
{
cudaFuncAttributes attrib;
cudaError_t err;
//OK:
err = cudaFuncGetAttributes(&attrib, addKernel<float>); // works fine
printf("result: %s, reg1: %d\n", cudaGetErrorString(err), attrib.numRegs);
//NOT OK:
//try to get function ptr to pass as an argument:
const char* ptr = addKernel<float>; // compile error
err = cudaFuncGetAttributes(&attrib, ptr);
printf("result: %s, reg2: %d\n", cudaGetErrorString(err), attrib.numRegs);
}
上記はコンパイル エラーになります。
エラー:関数テンプレート「addKernel」のインスタンスが必要なタイプと一致しません
編集: これまでに見つけた唯一の回避策は、myFunc (最初のコード例を参照) 内のものをマクロに入れることです。これは醜いですが、ポインター引数の受け渡しを必要とせず、正常に動作します:
#define MY_FUNC(kernel) \
{ \
...\
cudaFuncGetAttributes( &attrib, kernel ); \
...\
}
使用法:
MY_FUNC( myKernel<float> )