cuda编程笔记(25)-- 如何像函数对象一样使用核函数

在C++中,函数可以被归类为可调用对象,可以像参数一样传给其他函数。那么cuda里的核函数想要实现这样的效果应该怎么办呢?

很明显,核函数不可以像普通函数一样被抽象成可调用对象传给std::function,那应该怎么实现?

既然高级语言的抽象用不了,只能使用低级的方式了,那就是宏定义

cpp 复制代码
#define CUDA_KERNEL_CALL(kernel, nblks, nthrs, shmem, stream, ...)   \
  {                                                                  \
      (kernel)<<<(nblks), (nthrs), (shmem), (stream)>>>(__VA_ARGS__);\
      cudaError_t e = cudaGetLastError();                            \
      if (!(e == cudaSuccess || e == cudaErrorCudartUnloading)) {    \
        std::cerr << "CUDA kernel launch error: " << cudaGetErrorString(e) << std::endl;\
        }                                                            \
  }                                                                  \

这个其实和 C/C++ 宏(macro)里的可变参数语法有关,和 CUDA 本身没关系。

宏里的 ...__VA_ARGS__

在宏定义里,如果最后写上 ...,就表示这个宏可以接收可变数量的参数

例如:

cpp 复制代码
#define PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)

调用时:

cpp 复制代码
PRINTF("a=%d, b=%d\n", 1, 2);

展开后就是:

cpp 复制代码
printf("a=%d, b=%d\n", 1, 2);

这里 ... 就是占位符,__VA_ARGS__ 是一个特殊的标识符,表示"把传进来的所有可变参数原封不动填进去"。

必须成对用 ...__VA_ARGS__

  • ... 是宏定义时的"声明"

  • __VA_ARGS__ 是宏展开时的"使用"

就像函数声明参数,然后函数体里使用参数一样。

例子

cpp 复制代码
#define CUDA_KERNEL_CALL(kernel, nblks, nthrs, shmem, stream, ...)   \
  {                                                                  \
      (kernel)<<<(nblks), (nthrs), (shmem), (stream)>>>(__VA_ARGS__);\
      cudaError_t e = cudaGetLastError();                            \
      if (!(e == cudaSuccess || e == cudaErrorCudartUnloading)) {    \
        std::cerr << "CUDA kernel launch error: " << cudaGetErrorString(e) << std::endl;\
        }                                                            \
  }                                                                  \

__global__ void globalCopy(const float* data, float* out,const int N) {
    int idx = threadIdx.x + blockIdx.x * blockDim.x;
    if (idx < N) {
        out[idx] = data[idx];
    }
}

//调用端
CUDA_KERNEL_CALL(globalCopy,1,32,0,0,d_data,d_out,32)

这样想调用哪个核函数,都可以用这个宏

相关推荐
charlie11451419128 分钟前
HTML 理论笔记
开发语言·前端·笔记·学习·html·1024程序员节
岑梓铭2 小时前
考研408《操作系统》复习笔记,第二章《2.3 进程调度》
笔记·考研·操作系统·os
生物小卡拉2 小时前
指定列交集内容合并-Rscript_v1.0
笔记·学习·r语言
流星5211223 小时前
GC 如何判断对象该回收?从可达性分析到回收时机的关键逻辑
java·jvm·笔记·学习·算法
新子y3 小时前
【小白笔记】「while」在程序语言中的角色
笔记·python
狡猾大先生4 小时前
ESP32S3-Cam实践(OLED表情动画-手搓)
笔记·1024程序员节
2301_800256115 小时前
地理空间数据库作业笔记——查询最偏僻的城市
数据库·笔记·sql·postgresql·1024程序员节
Cathy Bryant6 小时前
线性代数直觉(四):找到特征向量
笔记·神经网络·考研·机器学习·数学建模
012925207 小时前
1.1 笔记 html 基础 初认识
前端·笔记·html
DKPT7 小时前
JVM直接内存和堆内存比例如何设置?
java·jvm·笔记·学习·spring