Reputation: 3699
When transferring a 2d image stored in host memory to OpenCL, how is it reading the values - row major or column major? Let's assume row major.
index = row*NUM_COLS + col
How about 3d image stored in host memory? I believe that's treated as a stack of 2D images (which was assumed to be row major). Then pixel (row,col,slice) for limits (NUM_ROWS,NUM_COLS,NUM_SLICES) in terms of OpenCL is at:
index = slice*NUM_ROWS*NUM_COLS + row*NUM_COLS + col
However, according to wikipedia formulas the 3d Row Major indexing should be:
index = slice + NUM_SLICES*(col + NUM_COLS*row)
= row*NUM_COLS*NUM_SLICES + col*NUM_SLICES + slices
According to same article Column Major Ordering access should be:
index = row + NUM_ROWS*(col + NUM_COLS*slice)
= slice*NUM_ROWS*NUM_COLS + col*NUM_ROWS + row
None of which seems to match what OpenCL is doing in 3d case.
So I guess I really have 2 questions
Edit
I view wikipedia article as a generic layout scheme. "row" or "column" are secondary label words. Whether you are dealing with tuples (row, col, slice) limited to (NUM_ROWS, NUM_COLS, NUM_SLICES) or (x,y,z) (WIDTH, HEIGHT, DEPTH) doesn't matter as long as it's consistent. It just tells you which dimension is continuous in memory. In "row major" it's the last dimension - z values that are next to each other, in column major it's the first dimension - x.
So once again I think "row major" layout for x,y,z 3d image indexing should have been:
index = z + DEPTH * (y + HEIGHT * x) = x * HEIGHT * DEPTH + y * HEIGHT + z
It isn't. But, I suppose you can chose whatever scheme you want.
Upvotes: 3
Views: 2053
Reputation: 45948
First of all, your assumptions about the OpenCL layout are correct. OpenCL indeed uses the layout you describe and the formulas you provide for both the 2D and the 3D case are correct, component after component, pixel after pixel, row after row, slice after slice. And I (having an OpenGL background) consider this pretty standard.
Yet there is a bit of a naming confusion here, since what row-major in general means is what Wikipedia says, the first dimension changes with the lowest frequency and the last dimension is contiguous. Yet with images, the row isn't actually the first dimension, but the y-dimension, and columns are x. So while OpenCL (at least in 2D) uses literal "row-major" layout (since rows change less often), it is generally seen (in the terminology as used by Wikipedia) rather column-major, since the first dimension (x) is contiguous. And this translates well to 3D, where the last dimension (z) changes with lowest frequency. So you got Wikipedia wrong, what it is actually saying is that general column-major (as extended to 3D) is
index = z*WIDTH*HEIGHT + y*WIDTH + x
which, given that x=col
and y=row
, is indeed
index = slice*NUM_ROWS*NUM_COLS + row*NUM_COLS + col
which is exactly what OpenCL uses. So to answer you actual questions:
Exactly like you explained in the first part of your question.
Because you got Wikipedia wrong and confused matrix-based (row,col)
-indexing with image-based (x,y)
-indexing and what OpenCL uses corresponds to what Wikipedia generally calls column-major.
EDIT: This confusion of index-based addressing (like matrices) and coordinate-based addressing (like images) is a common source of confusion. For example in OpenCV (a famous image processing library) images are represented and addressed as matrices and thus like (row,col)
, which for an actual image means (y,x)
.
Upvotes: 3