Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CUDA内核启动宏与模板_C++_Templates_Macros_Cuda_Kernel - Fatal编程技术网

C++ CUDA内核启动宏与模板

C++ CUDA内核启动宏与模板,c++,templates,macros,cuda,kernel,C++,Templates,Macros,Cuda,Kernel,我制作了一个宏来简化CUDA内核调用: #define LAUNCH LAUNCH_ASYNC #define LAUNCH_ASYNC(kernel_name, gridsize, blocksize, ...) \ LOG("Async kernel launch: " #kernel_name); \ kernel_name <<< (gridsize), (blocksize) >>> (__VA_ARGS_

我制作了一个宏来简化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...

是否可以使该宏与多个模板参数一起工作?

问题是预处理器对尖括号嵌套一无所知,因此它将它们之间的逗号解释为宏参数分隔符

如果内核启动语法支持内核名称周围的括号(我现在无法检查,CUDA机器上没有),您可以执行以下操作:

LAUNCH((my_kernel<int, float>), 32, 32, param1, param3)
LAUNCH((我的内核),32,32,param1,param3)

问题在于预处理器对尖括号嵌套一无所知,因此它将它们之间的逗号解释为宏参数分隔符

如果内核启动语法支持内核名称周围的括号(我现在无法检查,CUDA机器上没有),您可以执行以下操作:

LAUNCH((my_kernel<int, float>), 32, 32, param1, param3)
LAUNCH((我的内核),32,32,param1,param3)

您可以尝试的其他方法(基于您发布的宏)是将内核块大小和网格大小参数包装到它们自己的宏中:

#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 >>>
您可以像这样使用它:

CUDA_LAUNCH(my_kernel, grid_size, block_size, float* input, float* output, int size);

这将使用给定的网格和块大小以及输入参数启动名为“my_kernal”的内核

您可以尝试使用的另一种方法(基于您发布的宏)是将内核块大小和网格大小参数包装到它们自己的宏中:

#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 >>>
您可以像这样使用它:

CUDA_LAUNCH(my_kernel, grid_size, block_size, float* input, float* output, int size);

这将使用给定的网格和块大小以及输入参数启动名为“my_kernal”的内核

考虑这个也会引发错误的解决方案

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);                                              \
}
内联无效回音错误(cudaError\u t e,const char*strs){
字符a[255];
如果(e!=cudaSuccess){
strncpy(a,strs,255);
fprintf(标准,“未能发送到%s,错误代码%s”,
a、 cudaGetErrorString(e));
退出(退出失败);
}
}
#定义CUDA_KERNEL_DYN(KERNEL、bpg、tpb、shd等){\
内核(_VA_ARGS__)\
cudaError_t err=cudaGetLastError()\
回声错误(err,#内核)\
}

考虑这个也会引发错误的解决方案

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);                                              \
}
内联无效回音错误(cudaError\u t e,const char*strs){
字符a[255];
如果(e!=cudaSuccess){
strncpy(a,strs,255);
fprintf(标准,“未能发送到%s,错误代码%s”,
a、 cudaGetErrorString(e));
退出(退出失败);
}
}
#定义CUDA_KERNEL_DYN(KERNEL、bpg、tpb、shd等){\
内核(_VA_ARGS__)\
cudaError_t err=cudaGetLastError()\
回声错误(err,#内核)\
}

在您给出的情况下是否真的会发生这种情况,或者仅当模板有多个参数时才会发生这种情况?是的,它只会在多个参数下失败。我要纠正这个问题。问题是,预处理器对尖括号嵌套一无所知,因此它将它们之间的逗号解释为宏参数分隔符。这种情况真的发生在您给出的情况下,还是仅当模板有多个参数时才发生?是的,它仅在多个参数时失败。我要纠正这个问题,问题是预处理器对尖括号嵌套一无所知,所以它将它们之间的逗号解释为宏参数分隔符。