将存储在主机内存中的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案例中所做的相符。
所以我想我真的有两个问题
修改
我将维基百科文章视为通用布局方案。 “行”或“列”是次要标签词。无论您处理的元组(行,列,切片)是否限于(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
不是。但是,我想你可以选择你想要的任何方案。
答案 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=col
和y=row
,确实是
index = slice*NUM_ROWS*NUM_COLS + row*NUM_COLS + col
这正是OpenCL使用的。所以回答你实际的问题:
正如您在问题的第一部分中所解释的那样。
因为你得到了维基百科错误并混淆了基于矩阵的(row,col)
- 使用基于图像的(x,y)
索引 - 索引以及OpenCL使用的对应于 Wikipedia 的内容调用column-major。
编辑:这种基于索引的寻址(如矩阵)和基于坐标的寻址(如图像)的混淆是混淆的常见原因。例如,在OpenCV(一个着名的图像处理库)中,图像被表示为矩阵,因此像(row,col)
一样,对于实际图像来说,(y,x)
。