__kernel void conv2d(__read_only image2d_t input,
__read_only image2d_t weight,
__write_only image2d_t output,
__global const float* bias,
int stride, int pad,
int in_c4, int out_c4,
int KH, int KW,
int outH, int outW) {
int x = get_global_id; // 列索引
int y = get_global_id; // 行索引
if return;
// 解码得到 w_out、c4_out、h_out、batch
// ……
}
kan,这段代码每行一句,douhen短,你懂的,就是这么直白。
先把全局 ID 拆成 w_out 和 c4_out,两者相乘才是图像宽度方向的实际坐标。
y 同理拆成 batch和 h_out。
三层循环——卷积公式的直接翻译
float4 sum = ;
int out_c_base = c4_out * 4;
for {
for {
for {
// 计算输入坐标
int h_in = h_out * stride + kh - pad;
int w_in = w_out * stride + kw - pad;
// 边界检查
float4 iv = ;
if {
int ix = w_in * in_c4 + inslice;
iv = read_imagef);
}
// 权重读取
int kx = kw * in_c4 + inslice;
int ky = out_c_base / 4 * KH + kh;
float4 kv = read_imagef);
sum += dot;
}
}
}
sum += vload4; // 加上 bias
write_imagef, sum);
这里面Zui关键的是 dot。
一次 dot 完事儿,相当于四路乘加同时进行,省时省力。
边界处理——Zero Padding 的细节
hen多新手会问:“为什么不直接让 sampler 自动Zuo padding?”
害,其实Ke以但我们这里手动判断geng可控,也避免了不同硬件对 clamp 行为的不一致性。
Ru果坐标越界,就让 iv 保持全零,这就是所谓 zero‑padding 的语义啦。
为什么百度不收录这篇文章?
嗯,说实话,有时候百度爬虫会挑剔页面结构。
Crawler 喜欢干净的标题层级和明确的 meta 信息,而我们的文章里大量使用了短句换行和随意的口语化表达,可Neng导致爬虫抓取不到完整正文。