我制作了一个宏来简化CUDA内核调用:
#define LAUNCH LAUNCH_ASYNC
#define LAUNCH_ASYNC(kernel_name, gridsize, blocksize, ...) \
LOG("Async kernel launch: " #kernel_name); \
kernel_name <<< (gridsize), (blocksize) >>> (__VA_ARGS__);
#define LAUNCH_SYNC(kernel_name, gridsize, blocksize, ...) \
LOG("Sync kernel launch: " #kernel_name); \
kernel_name <<< (gridsize), (blocksize) >>> (__VA_ARGS__); \
cudaDeviceSynchronize(); \
// error check, etc...
用法:
LAUNCH(my_kernel, 32, 32, param1, param2)
LAUNCH(my_kernel<int>, 32, 32, param1, param2)
这很好用;使用第一个定义,我可以启用同步调用和错误检查以进行调试。
但是它不适用于多个模板参数,如下所示:
LAUNCH(my_kernel<int,float>, 32, 32, param1, param3)
我在调用宏的行中得到的错误消息:
error : expected a ">"
是否可以使此宏使用多个模板参数?
答案 0 :(得分:4)
问题是预处理器对尖括号嵌套一无所知,所以它将它们之间的逗号解释为宏参数分隔符。
如果内核启动语法支持内核名称周围的括号(我现在无法检查,而不是在CUDA机器上检查),您可以这样做:
LAUNCH((my_kernel<int, float>), 32, 32, param1, param3)
答案 1 :(得分:1)
我可以尝试使用的其他东西(基于您发布的宏)将内核块大小和网格大小参数包装在它们自己的宏中:
y = 1
现在你应该可以像这样使用你的宏了:
#define KERNEL_ARGS2(grid, block) <<< grid, block >>>
#define KERNEL_ARGS3(grid, block, sh_mem) <<< grid, block, sh_mem >>>
#define KERNEL_ARGS4(grid, block, sh_mem, stream) <<< grid, block, sh_mem, stream >>>
您可以像以下一样使用它:
#define CUDA_LAUNCH(kernel_name, gridsize, blocksize, ...) \
kernel_name KERNEL_ARGS2(gridsize, blocksize)(__VA_ARGS__);
这将使用给定的网格和块大小以及输入参数启动名为“my_kernal”的内核。
答案 2 :(得分:0)
考虑这个也会引发错误的解决方案
inline void echoError(cudaError_t e, const char *strs) {
char a[255];
if (e != cudaSuccess) {
strncpy(a, strs, 255);
fprintf(stderr, "Failed to %s,errorCode %s",
a, cudaGetErrorString(e));
exit(EXIT_FAILURE);
}
}
#define CUDA_KERNEL_DYN(kernel, bpg, tpb, shd, ...){ \
kernel<<<bpg,tpb,shd>>>( __VA_ARGS__ ); \
cudaError_t err = cudaGetLastError(); \
echoError(err, #kernel); \
}