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)

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

相关推荐
自传.5 分钟前
尚硅谷 Vibe Coding|第三章(1) Claude Code深度使用与进阶技巧 学习笔记
笔记·学习·尚硅谷·vibecoding
.千余1 小时前
【C++】模板进阶全解:非类型参数|全特化|偏特化|分离编译完全指南
开发语言·c++·笔记·学习·其他
自传.1 小时前
尚硅谷 Vibe Coding|第二章 AI编程工具生态 学习笔记
笔记·学习·ai编程·尚硅谷·vibe coding
秋波。未央2 小时前
Java Agent 开发 · Day 1 学习笔记(含作业完整标准答案)
java·笔记·学习
中屹指纹浏览器3 小时前
2026指纹浏览器字体指纹、字体渲染偏差检测与全维度虚拟字体池搭建方案
经验分享·笔记
RickyWasYoung3 小时前
经典轮胎模型对比(弦模型、环模型、刷子模型、魔术公式、FTire模型、Unitire模型)
笔记
codexu_4612291873 小时前
NoteGen 里一条记录如何变成 Markdown
前端·笔记·rust·tauri
Upsy-Daisy3 小时前
Hermes Agent 学习笔记 10:源码结构与整体架构总结,Hermes 到底是如何运转起来的?
笔记·学习·架构
Upsy-Daisy4 小时前
Hermes Agent 学习笔记 09:MCP 集成,让 Agent 连接外部工具生态
笔记·学习