Task 4 of 5

Transpose: Swap the Axes

Look back at the matmul loop: b[k][x] walks down a column — each step jumps a whole row of memory. GPUs hate that; neighbouring threads reading neighbouring addresses is where their bandwidth comes from. The standard fix is to transpose B first, turning column walks into row walks.

A transpose kernel is one line of insight: the thread that owns output cell [y][x] reads input cell [x][y]. With a rectangular 24×40 input the flip is visible in the shapes too — the result is 40×24, so output: [24, 40].

Goal: transpose the 24×40 matrix matWide — output cell [y][x] holds matWide[x][y], giving a 40×24 result.

Requirements

Hint 1 — who reads what

The thread writing output cell [y][x] must read the input cell whose row and column are swapped. Both this.thread.x and this.thread.y appear — just not in their usual seats.

Hint 2 — the one-liner

return m[this.thread.x][this.thread.y];

Same idea elsewhere

Memory-coalescing is why cuBLAS and rocBLAS pick a different tiled kernel for each setting of GEMM's transA/transB flags — whichever layout you pass, threads must still read side by side — and why Metal and WebGPU matmul kernels pre-stage tiles in threadgroup memory. Reordering data for coalesced access is half of GPU performance work.

All tasks in Matrix Multiply

  1. One Cell, One Dot Product
  2. The Full Grid: Matrix × Matrix
  3. Rectangular: Three Different Sizes
  4. Transpose: Swap the Axes
  5. One Kernel, Any Size

This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.