OpenCL image2d和image3d内存布局

时间:2013-07-17 15:38:50

标签: opencl

将存储在主机内存中的2d图像传输到OpenCL时,如何读取值 - 行主要列还是列主要值?让我们假设行主要。

index = row*NUM_COLS + col

存储在主机内存中的3d图像怎么样?我相信这被视为一堆2D图像(假设是行专业)。然后,就OpenCL而言,限制(NUM_ROWS,NUM_COLS,NUM_SLICES)的像素(行,列,切片)位于:

index = slice*NUM_ROWS*NUM_COLS + row*NUM_COLS + col

但是,根据wikipedia公式,3d Row Major索引

index = slice + NUM_SLICES*(col + NUM_COLS*row) 
      = row*NUM_COLS*NUM_SLICES + col*NUM_SLICES + slices

根据同一篇文章列主要订购访问应该是:

index = row + NUM_ROWS*(col + NUM_COLS*slice)
      = slice*NUM_ROWS*NUM_COLS + col*NUM_ROWS + row

其中没有一个似乎与OpenCL在3d案例中所做的相符。

所以我想我真的有两个问题

  1. 如何布置内存以将2d和3d图像传输到OpenCL?
  2. 为什么OpenCL在3d情况下选择了非标准内存布局?
  3. 修改

    我将维基百科文章视为通用布局方案。 “行”或“列”是次要标签词。无论您处理的元组(行,列,切片)是否限于(NUM_ROWS,NUM_COLS,NUM_SLICES)或(x,y,z)(WIDTH,HEIGHT,DEPTH)都无关紧要,只要它是一致的。它只是告诉你哪个维度在内存中是连续的。在“行主要”中,它是最后一个维度 - z值彼此相邻,在列主要中它是第一个维度 - x。

    所以再一次,我认为x,y,z三维图像索引的“行主要”布局应该是:

    index = z + DEPTH * (y + HEIGHT * x) = x * HEIGHT * DEPTH + y * HEIGHT + z
    

    不是。但是,我想你可以选择你想要的任何方案。

1 个答案:

答案 0 :(得分:3)

首先,您对OpenCL布局的假设是正确的。 OpenCL确实使用了您描述的布局,您为2D和3D情况提供的公式是正确的,组件后面的组件,像素后的像素,后一行的后一个切片。我(拥有OpenGL背景)考虑这个相当标准。

然而这里存在一些命名混淆,因为一般的行主要意味着 Wikipedia 所说的,第一个维度以最低频率变化,最后一个维度是连续的。但是对于图像,该行实际上不是第一个维度,而是 y - 维度,而列是 x 。因此,虽然OpenCL(至少在2D中)使用文字“row-major”布局(因为行更改频率较低),但通常会看到(在维基百科中使用的术语) >)而非column-major,因为第一个维度( x )是连续的。这很好地转换为3D,其中最后一个维度( z )以最低频率变化。所以你的维基百科错了,它实际上说的是一般列专业(扩展到3D)是

index = z*WIDTH*HEIGHT + y*WIDTH + x

,鉴于x=coly=row,确实是

index = slice*NUM_ROWS*NUM_COLS + row*NUM_COLS + col

这正是OpenCL使用的。所以回答你实际的问题:

  1. 正如您在问题的第一部分中所解释的那样。

  2. 因为你得到了维基百科错误并混淆了基于矩阵的(row,col) - 使用基于图像的(x,y)索引 - 索引以及OpenCL使用的对应于 Wikipedia 的内容调用column-major。

  3. 编辑:这种基于索引的寻址(如矩阵)和基于坐标的寻址(如图像)的混淆是混淆的常见原因。例如,在OpenCV(一个着名的图像处理库)中,图像被表示为矩阵,因此像(row,col)一样,对于实际图像来说,(y,x)