KaiSpace
Uncategorized

torch.compile 技术剖析(三):Lowering

Original source

1. realize 是什么?

在 Inductor 里,realize 的意思是:把一个还没有真正落到内存里的中间表达式,强制变成一个真实 buffer。

例如:

out = relu(a + b)

a + b 不一定会生成中间 tensor。Inductor 可以直接融合成:

out[i] = relu(a[i] + b[i])

这里 a+b 没有 realize,没有写 HBM。

但如果是:

out = mm(a + b, w)

如果 mm lowering 到 cuBLAS,cuBLAS 只能接受真实矩阵指针:

A pointer, B pointer, C pointer

它不能接受表达式:

A[i,j] = a[i,j] + b[i,j]

所以必须先:

tmp = a + b      # realize 成真实 buffer
out = cuBLAS_mm(tmp, w)

因此:

x = x.realize_input()

不是因为“后面要读数据”,而是因为后面的 extern kernel 需要真实 storage pointer

Reduction 不一定需要 realize,因为如果 reduction 是 Inductor 自己生成的 kernel,它可以把表达式 inline 进去:

s = sum(a + b)

可以生成:

acc += a[i] + b[i]

不需要先生成 tmp = a+b

一句话:realize 是 materialize;它会把 lazy IR / view / expression 变成真实 buffer,常见于进入 cuBLAS/cuDNN 这种 extern kernel 前。realize 本质上是在 IR 上加了一个“必须物化成真实 buffer”的约束;它会切断 lazy 表达式继续被重写、融合、inline 的自由度。

2. Channels-last layout 是什么?

Channels-last 是一种 4D 图像 tensor 的内存布局。逻辑 shape 仍然通常是:

[N, C, H, W]

但物理内存顺序更像:

[N, H, W, C]

也就是:同一个像素位置的不同 channel 连续存放。

普通 NCHW contiguous:

size   = [N, C, H, W]
stride = [C*H*W, H*W, W, 1]

例如访问:

x[n,c,h,w] offset = n*C*H*W + c*H*W + h*W + w

这表示同一个 channel 内的 H/W 连续。

Channels-last:

stride = [H*W*C, 1, W*C, C]

访问:

x[n,c,h,w] offset = n*H*W*C + c + h*W*C + w*C

所以:

x[n,0,h,w]
x[n,1,h,w]
x[n,2,h,w]

在内存中是连续的。

这对卷积有好处,因为卷积经常在同一个 (h,w) 位置遍历 channel:

for c in C:
    use x[n,c,h,w]

channels-last 让这些访问连续,更容易 coalesced load、vectorized load、cache line 利用率更高,也更适合 cuDNN 的一些 NHWC/Tensor Core 路径。

一句话:channels-last 不是改变 tensor 的逻辑索引,而是改变底层 stride,让 channel 维在物理内存里最连续。

Comments

No comments yet.