2012-02-22 12 views
5

He realizado una prueba simple texture3D y he encontrado un comportamiento extraño al copiar datos en el dispositivo. La función cudaMemcpy3D devuelve un 'argumento inválido'.Argumento no válido en cudaMemcpy3D utilizando ancho en bytes?

Encontré que el problema está relacionado con cudaExtent. Según la CUDA Toolkit Manual de referencia 4.0, Parámetros cudaExtent son los siguientes:

  • w - Ancho en bytes
  • h - Altura en elementos
  • d - Profundidad en elementos

Por lo tanto, preparé la textura de la siguiente manera:

// 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); 

y configurados los parámetros 3D de la siguiente manera:

// 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; 

Y finalmente copiar los datos en la memoria del dispositivo:

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

El problema se resuelve si sólo se especifica el número de elementos en la dimensión x como:

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

cuales no produce ningún correo rror y la prueba funciona como se esperaba.

Me pregunto si extraño algo con la función cudaExtent u otra cosa. ¿Por qué no es necesario que el parámetro de ancho se exprese en bytes?

Respuesta

6

Para las matrices CUDA, la extensión se especifica con el ancho dado en los elementos de la matriz. Para asignar memoria lineal, la extensión se especifica con el ancho dado en bytes. Como está asignando una matriz con cudaMalloc3DArray, use el ancho en los elementos. Si estuviera usando cudaMalloc3D, la extensión tendría un ancho en bytes.

+0

Esa es la conclusión por la que vengo. ¿Está documentado en el manual de referencia o se basa en su experiencia? – pQB

+1

Está documentado en la referencia de la API, pero puede que no esté donde usted miró. En la página 'cudaMalloc3Darray' se lee" Para matrices 3D, los rangos válidos de extensión son {(1, maxTexture3D [0]), (1, maxTexture3D [1]), (1, maxTexture3D [2])} ". La documentación 'make_cudaExtent' es un poco ambigua porque solo documenta los argumentos tal como se aplican al caso lineal 3D, no al caso de matriz 3D. – talonmies

+0

Gracias por aclarar. – pQB

Cuestiones relacionadas