原始题目:LeetGPU - 2D Convolution
编写一个 GPU 程序,执行二维卷积操作。给定输入矩阵和卷积核(滤波器),使用 "valid" 边界条件(无填充,卷积核仅在其与输入完全重叠的位置上应用)计算卷积输出。
输入包括:
input:32 位浮点数的二维矩阵,按行优先顺序以一维数组表示。kernel:32 位浮点数的二维卷积核,同样按行优先顺序以一维数组表示。
输出矩阵维度为:
output_rowsoutput_cols=input_rows−kernel_rows+1=input_cols−kernel_cols+1
卷积操作定义为:
output[i][j]=m=0∑kernel_rows−1n=0∑kernel_cols−1input[i+m][j+n]⋅kernel[m][n]
- 不允许使用外部库。
solve 函数签名必须保持不变。- 最终结果必须存储在数组
output 中。
Input: input (3×3): [[1,2,3], [4,5,6], [7,8,9]]
kernel (2×2): [[0,1], [1,0]]
Output: output (2×2): [[6,8], [12,14]]
Input: input (4×4): [[1,1,1,1], [1,2,3,1], [1,4,5,1], [1,1,1,1]]
kernel (1×3): [[1,0,1]]
Output: output (4×2): [[2,2], [4,3], [6,5], [2,2]]
- 1≤input_rows,input_cols≤3,072。
- 1≤kernel_rows,kernel_cols≤31。
- kernel_rows≤input_rows,kernel_cols≤input_cols。
- 性能测试在 input=3,072×3,072,kernel=15×15 的规模下进行。
二维卷积的每个输出元素需要读取 kernel_rows×kernel_cols 个输入元素,相邻输出之间存在大量数据重用。核心优化是使用共享内存分块:将输入的子区域加载到共享内存中,线程块内的线程协作计算输出子区域。此外,常量内存适合存储小卷积核(≤31×31),利用广播机制减少寄存器压力。对于更大的输入,还可使用 Winograd 或 FFT 加速。欢迎在 GitHub Discussions 分享你的解法。