cuda算子--矩阵转置

复制代码
#include <cuda_runtime.h>

#define TILE 32
#define BLOCK_ROWS 8   // block 的 y 方向线程数,配合 TILE 减少 padding 浪费

// 用 padding 避免 shared bank conflict
__global__ void transpose_shared_kernel(const float* __restrict__ input,
                                        float* __restrict__ output,
                                        int rows, int cols) {
    __shared__ float tile[TILE][TILE + 1];

    const int tx = threadIdx.x;   // [0, TILE)
    const int ty = threadIdx.y;   // [0, BLOCK_ROWS)

    // ---- 读阶段 ----
    // 该 block 负责 input 的子块:
    //   行 [blockIdx.y*TILE, blockIdx.y*TILE + TILE)
    //   列 [blockIdx.x*TILE, blockIdx.x*TILE + TILE)
    const int col = blockIdx.x * TILE + tx;   // input 列
    const int row = blockIdx.y * TILE + ty;   // input 行起点

    #pragma unroll
    for (int j = 0; j < TILE; j += BLOCK_ROWS) {
        if (col < cols && (row + j) < rows)
            tile[ty + j][tx] = input[(size_t)(row + j) * cols + col];
    }

    __syncthreads();

    // ---- 写阶段 ----
    // 转置后,output 的子块:
    //   行 [blockIdx.x*TILE, blockIdx.x*TILE + TILE)  ← 原来是 input 的列
    //   列 [blockIdx.y*TILE, blockIdx.y*TILE + TILE)  ← 原来是 input 的行
    const int outCol     = blockIdx.y * TILE + tx;   // 输出列 = 原输入行
    const int outRowBase = blockIdx.x * TILE + ty;   // 输出行起点 = 原输入列

    #pragma unroll
    for (int j = 0; j < TILE; j += BLOCK_ROWS) {
        const int outRow = outRowBase + j;           // 关键:j 加到行上
        if (outCol < rows && outRow < cols)
            output[(size_t)outRow * rows + outCol] = tile[tx][ty + j];
    }
}

extern "C" void solve(const float* input, float* output, int rows, int cols) {
    if (rows <= 0 || cols <= 0) return;

    dim3 threadsPerBlock(TILE, BLOCK_ROWS);
    dim3 blocksPerGrid((cols + TILE - 1) / TILE,
                       (rows + TILE - 1) / TILE);

    matrix_transpose_kernel<<<blocksPerGrid, threadsPerBlock>>>(input, output, rows, cols);
    cudaDeviceSynchronize();
}

关键是

for (int j = 0; j < TILE; j += BLOCK_ROWS) {

const int outRow = outRowBase + j; // 关键:j 加到行上

if (outCol < rows && outRow < cols)

output(size_t)outRow \* rows + outCol = tiletxty + j;

}

如果让block都等于0的话,那么base row和col就是ty,tx,那么最后就是outputtytx=tiletxty]很简单的转置。接下来考虑block x增加,此时base row下移,但他不应该影响与tile的对应关系,因为tile只有一块,所以应该还是和block x等于0时一样,去tile的同样的位置去找。需要注意的是,为什么base row对应的是block x,而不是y,因为这样out才对应input矩阵的block级转置,而thread是对应tile级的转置。

相关推荐
Easy_API2 小时前
2.8万亿参数,编程反超GPT-6 Astra:Kimi K3.1 Pro把开源模型推到了哪一步
大数据·人工智能·gpt·深度学习
GlobalInfo2 小时前
2026年机器人多指灵巧手市场分析报告——涵盖行业调查、趋势分析与发展前景
大数据·人工智能·microsoft·微服务·机器人
紧跟先前的步伐3 小时前
Go AI Agent 实战 24|工具系统工程化收尾与阶段验收
人工智能·ai·golang·1024程序员节
释厄6233 小时前
AI学习层更新与跨体转移律——人类社会同构·不缺理解缺 U
人工智能·学习
老金带你玩AI4 小时前
集万家所长,一键复制的Agent.md!
人工智能
ZhuoAIStage4 小时前
舞台工艺多专业审图提速:用 AI 智能体编排 A+B+C+G 四段读图流水线
人工智能·自动化·工作流编排·舞台工艺·审图智能体
小奶包他干奶奶4 小时前
AI学习——1、机器学习概念
人工智能·机器学习
展讯快报4 小时前
悬浮提词器免费App评估报告:说得AI的免费策略与可用性分析
人工智能
Yuzhiyuxia4 小时前
【AI Agent面试系列】AI Agent记忆机制知识点1
人工智能·面试·职场和发展
2601_965448875 小时前
AI视频制作:做系列历史人物视频音色不搭,AI 音色克隆的方法实测
人工智能·音视频