Error de lanzamiento no especificado en Memcpy

Me encuentro con una “falla de lanzamiento no especificada” al ejecutar mi progtwig en Cuda. Revisé los errores.

El progtwig es un solucionador de una ecuación diferencial. Repite TOTAL_ITER veces. ROOM_X ans ROOM_Y son el ancho y alto de las matrices.

Aquí está el encabezado, su nombre es “único:

#define ITER_BETWEEN_SAVES 10000 #define TOTAL_ITER 10000 #define ROOM_X 2048 #define ROOM_Y 2048 #define SOURCE_DIM_X 200 #define SOURCE_DIM_Y 1000 #define ALPHA 1.11e-4 #define DELTA_T 10 #define H 0.1 #include  void Matrix(float* M); void SolverCPU(float* M1, float* M2); __global__ void SolverGPU(float* M1, float* M2); 

Aquí está el kernel y una función que llena una matriz:

 #include "solver.h" #include void Matrix(float* M) { for (int j = 0; j < SOURCE_DIM_Y; ++j) { for (int i = 0; i < SOURCE_DIM_X; ++i) { M[(i+(ROOM_X/2 - SOURCE_DIM_X/2)) + ROOM_X * (j+(ROOM_Y/2 - SOURCE_DIM_Y/2))] = 100; } } } __global__ void SolverGPU(float* M1,float *M2) { int i =threadIdx.x + blockIdx.x * blockDim.x; int j = threadIdx.y + blockIdx.y * blockDim.y; float M1_Index = M1[i + ROOM_X * j]; float M1_IndexUp = M1[i+1 + ROOM_X * j]; float M1_IndexDown =M1[i-1 + ROOM_X * j]; float M1_IndexLeft = M1[i + ROOM_X * (j+1)]; float M1_IndexRight = M1[i + ROOM_X *(j-1)]; M2[i + ROOM_X * j] = M1_Index + (ALPHA * DELTA_T / (H*H)) * (M1_IndexUp + M1_IndexDown + M1_IndexLeft +M1_IndexRight - 4*M1_Index); } 

Y aquí está el principal

 int main(int argc, char* argv[] ){ float *M1_h, *M1_d,*M2_h, *M2_d; int size = ROOM_X * ROOM_Y * sizeof(float); cudaError_t err = cudaSuccess; //Allocating Memories on Host M1_h = (float *)malloc(size); M2_h = (float *)malloc(size); //Allocating Memories on Host err=cudaMalloc((void**)&M1_d, size); if (err != cudaSuccess) { fprintf(stderr, "Failed to allocate array_d ... %s .\n", cudaGetErrorString(err)); exit(EXIT_FAILURE); } err=cudaMalloc((void**)&M2_d, size); if (err != cudaSuccess) { fprintf(stderr, "Failed to allocate array_d ... %s .\n", cudaGetErrorString(err)); exit(EXIT_FAILURE); } //Filling the Matrix Matrix(M1_h); //Copy on Device err = cudaMemcpy(M1_d, M1_h, size, cudaMemcpyHostToDevice); if(err !=0){ printf("%s-%d\n",cudaGetErrorString(err),1); getchar(); } err=cudaMemcpy(M2_d, M2_h, size, cudaMemcpyHostToDevice); if(err !=0){ printf("%s-%d",cudaGetErrorString(err),2); getchar(); } dim3 dimGrid(64,64); dim3 dimBlock(32,32); //SolverGPU<< > >(M1_d,M2_d); for(int i=0;i<TOTAL_ITER;i++) { if (i%2==0) SolverGPU<< > >(M1_d,M2_d); else SolverGPU<< > >(M2_d,M1_d); } err=cudaMemcpy(M1_h, M1_d, size, cudaMemcpyDeviceToHost); if(err !=0){ printf("%s-%d",cudaGetErrorString(err),3); getchar(); } cudaFree(M1_d); cudaFree(M2_d); free(M1_h); free(M2_h); return 0; } 

No hay problema en la comstackción.

Cuando compruebo mis errores, aparece la “falla de lanzamiento no especificada” en memcpy DESPUÉS del kernel.

Ok, entonces he leído que generalmente se debe al kernel que no funciona correctamente. Pero no puedo encontrar los errores en el núcleo … Supongo que ese es el error, es bastante simple, pero no puedo encontrarlo.

Cuando compilo y ejecuto su código, obtengo:

 an illegal memory access was encountered-3 

impreso.

De hecho, puede estar obteniendo “fallas de lanzamiento no especificadas”. El informe de error exacto dependerá de la versión de CUDA, la GPU y la plataforma. Pero podemos seguir adelante independientemente.

Cualquiera de los dos mensajes indica que el kernel se inició pero encontró un error y, por lo tanto, no se completó correctamente. Puede depurar problemas de ejecución del kernel utilizando un depurador, como cuda-gdb en Linux o Nsight VSE en Windows. Pero no necesitamos sacar el depurador por el momento.

Una herramienta útil es cuda-memcheck . Si ejecutamos su progtwig con cuda-memcheck , obtendremos algún resultado adicional que indique que el kernel está realizando lecturas globales no válidas de tamaño 4. Esto significa que está realizando un acceso a la memoria fuera de límites. Podemos obtener una mayor claridad si volvemos a comstackr su código agregando el -lineinfo , y luego cuda-memcheck ejecutar su código con cuda-memcheck . Ahora obtenemos una salida que se ve así:

 $ nvcc -arch=sm_20 -lineinfo -o t615 t615.cu $ cuda-memcheck ./t615 |more ========= CUDA-MEMCHECK ========= Invalid __global__ read of size 4 ========= at 0x00000070 in /home/bob/misc/t615.cu:34:SolverGPU(float*, float*) ========= by thread (31,0,0) in block (3,0,0) ========= Address 0x4024fe1fc is out of bounds ========= Saved host backtrace up to driver entry point at kernel launch time ========= Host Frame:/usr/lib64/libcuda.so.1 (cuLaunchKernel + 0x2cd) [0x150a7d] ========= Host Frame:./t615 [0x11ef8] ========= Host Frame:./t615 [0x3b143] ========= Host Frame:./t615 [0x297d] ========= Host Frame:./t615 (__gxx_personality_v0 + 0x378) [0x26a0] ========= Host Frame:./t615 (__gxx_personality_v0 + 0x397) [0x26bf] ========= Host Frame:./t615 [0x2889] ========= Host Frame:/lib64/libc.so.6 (__libc_start_main + 0xf4) [0x1d994] ========= Host Frame:./t615 (__gxx_personality_v0 + 0x111) [0x2439] ========= --More-- 

(y hay mucho más salida de error)

Esto significa que el primer error que encontró su kernel fue una lectura global inválida de tamaño 4 (es decir, un acceso fuera de límites tratando de leer una cantidad int o float , por ejemplo). Con la información de lineinfo, podemos ver que esto ocurrió:

 ========= at 0x00000070 in /home/bob/misc/t615.cu:34:SolverGPU(float*, float*) 

es decir, en la línea 34 del archivo. Esta línea pasa a ser esta línea de código de kernel:

  float M1_IndexRight = M1[i + ROOM_X *(j-1)]; 

podríamos depurar aún más, tal vez usando declaraciones printf en el kernel para descubrir dónde está el problema. Pero ya tenemos una pista de que estamos indexando fuera de límites, así que vamos a inspeccionar la indexación:

  i + ROOM_X *(j-1) 

¿Qué evalúa esto cuando i = 0 j = 0 (es decir, para el hilo (0,0) en su matriz de hilos 2D)? Se evalúa a -2048 (es decir, ROOM_X ), que es un índice ilegal. Intentar leer desde M1[-2048] creará una falla.

En su kernel hay mucha indexación complicada, así que estoy bastante seguro de que también hay otros errores. Puede utilizar un método similar para rastrear esos archivos (quizás utilizando printf para escupir los índices calculados o, de lo contrario, probar los índices de validez).