有没有一种方法可以指定对四重像素进行操作的 Halide 计算?

Is there a way to specifiy a Halide computation that operates on quartets of pixels?

在 Halide 中,有没有一种方法可以将输入图像拆分为 2x2 四方像素并在四方的每个像素中实施独特的计算?

例如,我想对四重奏中的每个像素执行以下计算:

Upper left: (x + 1, y) + (x - 1, y) + (x, y + 1) + (x, y - 1)
Upper right: (x + 1, y) + (x - 1, y)
Lower left: (x, y + 1) + (x, y - 1)
Lower right: (x - 1, y - 1) + (x + 1, y - 1) + (x - 1, y + 1) + (x + 1, y + 1)

而且我希望这种计算模式扩展到整个输入图像。

有多种方法可以做到这一点。您可以最直接地使用 x%2==0y%2==0 上的 select 来做到这一点。类似于:

// Sub-terms
Expr ul = in(x+1,y) + in(x-1,y) + in(x,y+1) + in(x,y-1);
Expr ur = in(x+1,y) + in(x-1,y);
Expr ll = in(x,y+1) + in(x,y-1);
Expr ul = in(x-1,y-1) + in(x+1,y-1) + in(x-1,y+1) + in(x+1,y+1);

Expr ix = x%2==0;
Expr iy = y%2==0;

out(x,y) = select(iy,
             select(ix, ul, ur),
             select(ix, ll, lr));

(还有一个 selectmulti-condition version,你可以把它打包进去。)

如果然后 unroll outxy 维度各乘以 2,您将在没有控制流的情况下对四重奏进行紧密循环:

out.unroll(x,2).unroll(y,2);

这与您在去马赛克算法中看到的模式非常相似,您可以在官方 Halide 参考应用程序中找到其中的一个 here。受此启发,您可能还会发现将数据从 2D 打包到 3D 很自然,第 3 维是四重奏的 4 个元素:

packed(x,y,c) = in(x+c%2, y+c/2);

您可能会发现在某些情况下更容易使用。