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?
Esa es la conclusión por la que vengo. ¿Está documentado en el manual de referencia o se basa en su experiencia? – pQB
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
Gracias por aclarar. – pQB