Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid argument in cudaMemcpy3D using width in bytes?

Tags:

cuda

I've made a simple texture3D test and found a strange behavior when copying data to device. The function cudaMemcpy3D return an 'invalid argument'.

I found the problem is related with cudaExtent. According to the CUDA Toolkit Reference Manual 4.0, cudaExtent Parameters are as follow:

  • w - Width in bytes
  • h - Height in elements
  • d - Depth in elements

So, I prepared the texture as follows:

// prepare texture 
cudaChannelFormatDesc t_desc = cudaCreateChannelDesc<baseType>();
// CUDA extent parameters w - Width in bytes, h - Height in elements, d - Depth in elements
cudaExtent t_extent = make_cudaExtent(NCOLS*sizeof(baseType), NROWS, DEPTH);
// CUDA arrays are opaque memory layouts optimized for texture fetching
cudaArray *i_ArrayPtr = NULL;
// allocate 3D
status = cudaMalloc3DArray(&i_ArrayPtr, &t_desc, t_extent);

And configured the 3D parameters as follow:

// prepare input data
cudaMemcpy3DParms i_3DParms = { 0 };
i_3DParms.srcPtr   = make_cudaPitchedPtr( (void*)h_idata, NCOLS*sizeof(baseType), NCOLS, NROWS);
i_3DParms.dstArray = i_ArrayPtr;
i_3DParms.extent   = t_extent;
i_3DParms.kind     = cudaMemcpyHostToDevice;

And finally copied the data to device memory:

// copy input data from host to device
status = cudaMemcpy3D( &i_3DParms );

The problem is solved if I only specified the number of element in the x dimension as:

cudaExtent t_extent = make_cudaExtent(NCOLS, NROWS, DEPTH);

which does not produce any error and the test work as expected.

I'm wondering if I miss something with the cudaExtent function or something else. Why the width parameter is not needed to be expressed in bytes ?

like image 488
pQB Avatar asked Feb 22 '12 17:02

pQB


1 Answers

For CUDA arrays, the extent is specified with the width given in array elements. For allocating linear memory, the extent is specified with the width given in bytes. Because you are allocating an array with cudaMalloc3DArray, use the width in elements. If you were using cudaMalloc3D, the extent would have a width in bytes.

like image 68
talonmies Avatar answered Oct 19 '22 15:10

talonmies