header image
[ # ] CUDA 3D Array Pitch
August 17th, 2009 under OpenGL

The CUDA manual isn’t really precise in telling how to use the pitch with 3D Array (memory obtained by using

1
cudaMallocPitch, cudaMalloc3D
cudaMallocPitch, cudaMalloc3D
, not 3D cudaArrays). So here is a brief summary of how (I think) everything works.

What nVidia means by a pitch is basically the width in byte of an array (2D or 3D). We can specify the width of the array in bytes like this

1
volumeSize.width *sizeof(YOUR_TYPE)
volumeSize.width *sizeof(YOUR_TYPE)
. With this information we can access any element in a 3D array. We can compute the
1
slicePitch
slicePitch
(for a 3D array) which is
1
volumeSize.height*pitch
volumeSize.height*pitch
. The
1
slicePitch
slicePitch
is the offset in bytes from one slice in a 3D array to the next slice.

Now let’s say we want to access the element (x,y,z) in a 3D array

(which is the base pointer). This is how we can do it:

1
(myType) (((char*)data)[x*sizeof(myType) + y*pitch + z*slicePitch])
(myType) (((char*)data)[x*sizeof(myType) + y*pitch + z*slicePitch])

So what we get from the methods

1
cudaMallocPitch, cudaMalloc3D
cudaMallocPitch, cudaMalloc3D
is linear memory which need to be accessed in the way described above.
We need to know how pitches work when we want to copy arrays (when the copy method expects a pitched pointer which we can create with
1
make_cudaPitchedPtr(baseAddress, pitch, width, height)
make_cudaPitchedPtr(baseAddress, pitch, width, height)
). This is also sufficient for the copy process. Let’s assume we use
1
cudaMemcpy3D
cudaMemcpy3D
. In this case we must specify the extent, in other words the size of our array. All necessary information to execute the copy are now present (it can be ensured that no invalid memory will be accessed) . Each element can be accessed by
1
cudaMemcpy3D
cudaMemcpy3D
as described above. So, this means that we do not need to use the depth (in case of a 3D array) when we
1
make_cudaPitchedPtr
make_cudaPitchedPtr
.