Convert a Single Index to 2D or 3D Index?

What is the best and simplest way of using blockIdx and threadIdx to get indices for a 2D or 3D grid?

For example, I want to execute a block of code using i, j, k within predefined ranges inside my kernel:

global void kernel(int* range)
{
int i = 0;
int j = 0;
int k = 0;

if (i < 0 || i >= range[0])    return;
if (j < 0 || j >= range[1])    return;
if (k < 0 || k >= range[2])    return;

// execute kernel code...

}

Best and simplest rarely go hand in hand.

Here is the simplest:

const int idx = (blockIdx.y*blockDim.x*gridDim.x)+blockIdx.x*blockDim.x+threadIdx.x;

	const int k = idx/(ginfo.x_dim*ginfo.y_dim);

	const int j = (idx - k * ginfo.x_dim * ginfo.y_dim) / ginfo.x_dim;

	const int i =  (idx - k * ginfo.x_dim * ginfo.y_dim - j * ginfo.x_dim);

Lots of operations but if you have a large enough kernel, it should become irrelevant.

One easy way to improve on this would be to store 1.0f/(width*height) and 1.0f/(width) in constant memory, replace 2 divisions and 1 multiplication with 2 multiplications…

for 3-D index map, please see the thread

http://forums.nvidia.com/index.php?showtop…rt=#entry591025

[quote name=‘danuk’ date=‘Dec 9 2009, 08:15 AM’ post=‘962039’]

What is the best and simplest way of using blockIdx and threadIdx to get indices for a 2D or 3D grid?

The SDK example FLuidsGL has a workable structure for a 512x512 2D grid. I find it esthetically inelegant, but it works, it’s already debugged, and it has a convenient emulation-mode option.