创建变量
I love cpp. So I use new to define malloc
// c-style (以C作为前缀)
#define CAN(type, size) (type *)malloc(size * sizeof(type))
#define CN(type) CAN(type, 1)
#define CANV(type, name, size) type *name = CAN(type, size)
#define CNV(type, name) type *name = CN(type)
// cuda-style (以CD作为前缀)
#define CDAN(type, data, size) cudaMalloc((void **)&data, sizeof(type) * (size))
#define CDANV(type, name, size) \
type *name; \
CDAN(type, name, size)
#define CDN(type, name) CDAN(type, name, 1)
#define CDNV(type, name) CDANV(type, name, 1)
复制变量
本体语句
最基础的cuda复制语句 其他的都是以此为基础的变式
// CD-A-CPY A means array
#define CDACPY(type, dst, src, size, direction) cudaMemcpy(dst, src, size * sizeof(type), direction)
#define CDCPY(type, p_dst, p_src, dircetion) CDACPY(type, p_dst, p_src, 1, direction)
// 常用的四种传输方式 (没有书写default
#define CDDTD cudaMemcpyDeviceToDevice
#define CDDTH cudaMemcpyDeviceToHost
#define CDHTD cudaMemcpyHostToDevice
#define CDHTH cudaMemcpyHostToHost
变体语句
传输变体
将传输方式改写成了宏后缀 比起 cudaMemcpyHostToDevice 我更愿意写成 HTD
#define CDACPYHTD(type, dst, src, size) CDACPY(type, dst, src, size, CDHTD)
#define CDACPYDTH(type, dst, src, size) CDACPY(type, dst, src, size, CDDTH)
#define CDACPYDTD(type, dst, src, size) CDACPY(type, dst, src, size, CDDTD)
#define CDCPYHTD(type, p_dst, p_src) CDACPYHTD(type, p_dst, p_src, 1)
#define CDCPYDTH(type, p_dst, p_src) CDACPYDTH(type, p_dst, p_src, 1)
gpu和cpu的变量拷贝都是基于指针的 所以这一套宏编程默认是指针类型
但编程中往往会遇到已经存在的值变量 如果每次都再创建一个指针指向这个值 再进行复制 是否太过于拥挤呢?
// V means use value
#define CDCPYHTDV(type, p_dst, v_src) CDCPYHTD(type, p_dst, &(v_src))
#define CDCPYDTHV(type, v_dst, p_src) CDCPYDTH(type, &(v_dst), p_src)
融合变体
// CCPY means create variable and copy
// CCPY make sure that the direction is HTD
#define CDACCPY(type, name, size, data) \
CDANV(type, name, size); \
CDACPYHTD(type, name, data, size)
#define CDCCPY(type, name, data) \
CDNV(type, name); \
CDCPYHTD(type, name, data)
#define CDCCPYV(type, name, v_data) \
CDNV(type, name); \
CDCPYHTDV(type, name, v_data)
c和cuda的融合宏
// S means same
#define CDANVS(type, name, size) \
CANV(type, h_##name, size); \
CDANV(type, d_##name, size)
#define CDNVS(type, name) CDANVS(type, name, 1)
#define CDACPYHTDS(type, name, size) CDACPYHTD(type, d_##name, h_##name, size)
#define CDACPYDTHS(type, name, size) CDACPYDTH(type, h_##name, d_##name, size)
#define CDCPYHTDS(type, name) CDCPYHTD(type, d_##name, h_##name)
#define CDCPYDTHS(type, name) CDCPYDTH(type, h_##name, d_##name)
#define CDCPYHTDVS(type, name) CDCPYHTDV(type, d_##name, h_##name)
#define CDCPYDTHVS(type, name) CDCPYDTHV(type, h_##name, d_##name)
#define CDACCPYS(type, name, size) CDACCPY(type, d_##name, size, h_##name)
#define CDCCPYS(type, name) CDCCPY(type, d_##name, h_##name)
#define CDCCPYVS(type, name) CDCCPYV(type, d_##name, h_##name)
// CCD means c and cuda
#define CCDANVS(type, name, size) \
CANV(type, h_##name, size); \
CDANV(type, d_##name, size);
#define CCDACCPY(type, name, size, v_initValue) \
CANV(type, h_##name, size); \
For0(a, size) h_##name[a] = v_initValue; \
CDACCPYS(type, name, size)
// P means parenthesis
// input ({x,y,z}) -> type({x,y,z})
#define CCDACCPYP(type, name, size, raw_initValue) CCDACCPY(type, name, size, type raw_initValue)
#define CCDCCPY(type, name, v_initValue) \
type *h_##name = &v_initValue; \
CDCCPYS(type, name)
#define CCDCCPYV(type, name, v_initValue) \
type h_##name = v_initValue; \
CDCCPYVS(type, name)
#define CCDCCPYP(type, name, v_raw_initValue) CCDCCPYV(type, name, type v_raw_initValue)
释放变量
#define CCDFR(name) \
free(h_##name); \
cudaFree(d_##name)
宏定义像是c语言的黑魔法 cudaMalloc cudaMemcpy 光是这两个方法创建变量的语句展开就实在是太多了 虽然宏定义本质上是文本替换 有些人也会把他理解为语法糖 但是我觉得在这种底层语言他是非常有必要存在的 我提供的宏编程只是其中实现的一种方式 如果有大佬可以给我一些更好的建议 可以在评论区给我留言