如何正确访问金属内核函数中的邻居单元

how to access the neighbor unit in metal kernel function correctly

我用金属做了一些插值任务。我写的内核函数如下:

kernel void kf_interpolation( device short *dst, device uchar *src, uint id [[ thread_position_in_grid ]] )    
{
  dst[id] = src[id-1] + src[id] + src[id+1];
}

该核函数无法给出预期值。我发现原因是 src[id-1] 始终为 0,这是错误的值。但是,src[id+1] 包含正确的值。问题是我怎样才能正确使用邻居单位,例如[id-1],在内核函数中。提前致谢。

处理这种边缘情况的最有效方法通常是在每一端增加源数组并偏移索引。因此,对于 N 次计算,为 src 数组分配 N+2 个元素,用源数据填充元素 1 到 N(含),并将元素 0 和 N+1 设置为您想要的边缘条件。

一种更有效的方法是使用 MTLTextures 而不是 MTLBuffers。 MTLTextures 有一个附加的寻址模式,当您读取纹理的边缘时,它会导致硬件自动替换为零或最近的有效纹素。他们还可以免费在硬件中进行线性插值,假设双线性插值对您来说足够好,这对重采样有很大帮助。如果没有,我建议查看 MPSImageLanczosScale 作为替代方案。

您可以从 MTLBuffer 制作 MTLTexture。两者将别名相同的像素数据。