2014-05-10 1 views
0

malloc을 사용하여 2 차원 행렬을 할당하고 상대 주소에 값을 삽입하려고합니다. 왜 코어 덤프 오류인지 이해할 수 없습니다. 아래 내 코드를 살펴보십시오.캔트가 CUDA의 2 차원 상대 행렬 주소를 읽었습니다.

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    int width = 4; 
    FILE *fp = fopen("matB.txt", "r"); 
    int *x; 
    x = (int*)malloc(width*width*sizeof(int)); 
    int i, j; 
    for(i=0; i<width; i++) 
    { 
     for(j=0; j<width; j++) 
     { 
      fscanf(fp, "%d", x[i*width+j]); 
     } 
    } 

    for(i=0; i<width; i++) 
    { 
     for(j=0; j<width; j++) 
     { 
      printf("%d", x[i*width+j]); 
     } 
    } 
    return 0; 
} 

matB.txt 
1 2 3 4 
1 2 3 4 
1 2 3 4 
1 2 3 4 

I는 상대 주소 확인 상기 샘플 프로그램을 제작하고 배치 & X는 [] fscanf이 문제를 클리어.

위의 샘플 C 코드는 Cuda와 동일한 읽기 문제로 인해 수행되었습니다. 동일한 방식으로 2 차원 배열과 상대 주소를 사용할 때 파일을 읽었을 때 같은 것을 인쇄하려고 할 때 1,2,3,4 대신 0이 인쇄됩니다. CUDA의 학습 단계에 있습니다. . 호스트 배열에 대한 할당 문제가없고 상대 주소에 배치되는 것을 볼 수 있지만 파일 읽기는 0을 인쇄하는 이유는 무엇입니까 ??

//Matrix multiplication using shared and non shared kernal 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#define TILE_WIDTH 2 

/*matrix multiplication kernels*/ 

//non shared 
__global__ void MatrixMul(float *Md , float *Nd , float *Pd , const int WIDTH) 
{ 
      // calculate thread id 
     unsigned int col = TILE_WIDTH*blockIdx.x + threadIdx.x ; 
     unsigned int row = TILE_WIDTH*blockIdx.y + threadIdx.y ; 
     for (int k = 0 ; k<WIDTH ; k++) 
     { 
      Pd[row*WIDTH + col]+= Md[row * WIDTH + k ] * Nd[ k * WIDTH + col] ; 
     } 
} 

// shared 
__global__ void MatrixMulSh(float *Md , float *Nd , float *Pd , const int WIDTH) 
{ 
     //Taking shared array to break the MAtrix in Tile widht and fatch them in that array per ele 
      __shared__ float Mds [TILE_WIDTH][TILE_WIDTH] ; 
      __shared__ float Nds [TILE_WIDTH][TILE_WIDTH] ; 

     // calculate thread id 
      unsigned int col = TILE_WIDTH*blockIdx.x + threadIdx.x ; 
      unsigned int row = TILE_WIDTH*blockIdx.y + threadIdx.y ; 
     for (int m = 0 ; m<WIDTH/TILE_WIDTH ; m++) // m indicate number of phase 
     { 
      Mds[threadIdx.y][threadIdx.x] = Md[row*WIDTH + (m*TILE_WIDTH + threadIdx.x)] ; 
      Nds[threadIdx.y][threadIdx.x] = Nd[ (m*TILE_WIDTH + threadIdx.y) * WIDTH + col] ; 
     __syncthreads() ; // for syncronizeing the threads 
     // Do for tile 
      for (int k = 0; k<TILE_WIDTH ; k++) 
         Pd[row*WIDTH + col]+= Mds[threadIdx.x][k] * Nds[k][threadIdx.y] ; 
     __syncthreads() ; // for syncronizeing the threads 
    } 
} 

// main routine 
int main (int argc, char* argv[]) 
{ 

    const int WIDTH = 4 ; 
    printf("%d\n", WIDTH); 
    //float array1_h[WIDTH][WIDTH] ,array2_h[WIDTH][WIDTH], M_result_array_h[WIDTH][WIDTH] ; 
    float *array1_h, *array2_h, *M_result_array_h; 
    float *array1_d , *array2_d ,*result_array_d ,*M_result_array_d; // device array 
    int i , j ; 
    cudaEvent_t start_full,stop_full; 
    float time; 
    cudaEventCreate(&start_full); 
    cudaEventCreate(&stop_full); 
    cudaEventRecord(start_full, 0); 

    //char *file1 = argv[2]; 
    //char *file2 = argv[3]; 
    //char *file3 = argv[4]; 

    FILE *fp1 = fopen("matA.txt", "r"); 
    FILE *fp2 = fopen("matB.txt", "r"); 
    FILE *fp3 = fopen("matC.txt", "w"); 

    //create device array cudaMalloc ((void **)&array_name, sizeofmatrixinbytes) ; 
    cudaMallocHost((void **) &array1_h , WIDTH*WIDTH*sizeof (float)) ; 
    cudaMallocHost((void **) &array2_h , WIDTH*WIDTH*sizeof (float)) ; 
    cudaMallocHost((void **) &M_result_array_h , WIDTH*WIDTH*sizeof (float)) ; 
    //input in host array 
    for (i = 0 ; i<WIDTH ; i++) 
    { 
     for (j = 0 ; j<WIDTH ; j++) 
     { 
      fscanf(fp1, "%d", &array1_h[i*WIDTH + j]); 
      printf("%d\t", array1_h[i*WIDTH + j]); 
     } 
     // fscanf(fp1, "\n"); 
    } 
    /* 
    for (i = 0 ; i<WIDTH ; i++) 
    { 
     for (j = 0 ; j<WIDTH ; j++) 
     { 
      printf("%d\t", array1_h[i*WIDTH+j]); 
     } 
     printf("\n"); 
    }*/ 
    for (i = 0 ; i<WIDTH ; i++) 
    { 
     for (j = 0 ; j<WIDTH ; j++) 
     { 
      fscanf(fp2, "%d", &array2_h[i*WIDTH+j]); 
     } 
     fscanf(fp2, "\n"); 
    } 

    //create device array cudaMalloc ((void **)&array_name, sizeofmatrixinbytes) ; 
    cudaMalloc((void **) &array1_d , WIDTH*WIDTH*sizeof (float)) ; 
    cudaMalloc((void **) &array2_d , WIDTH*WIDTH*sizeof (float)) ; 

    //copy host array to device array; cudaMemcpy (dest , source , WIDTH , direction) 
    cudaMemcpy (array1_d , array1_h , WIDTH*WIDTH*sizeof (float) , cudaMemcpyHostToDevice) ; 
    cudaMemcpy (array2_d , array2_h , WIDTH*WIDTH*sizeof (float) , cudaMemcpyHostToDevice) ; 

    //allocating memory for resultant device array 
    cudaMalloc((void **) &result_array_d , WIDTH*WIDTH*sizeof (float)) ; 
    cudaMalloc((void **) &M_result_array_d , WIDTH*WIDTH*sizeof (float)) ; 

    //calling kernal 
    dim3 dimGrid (WIDTH/TILE_WIDTH , WIDTH/TILE_WIDTH ,1) ; 
    dim3 dimBlock(TILE_WIDTH, TILE_WIDTH, 1) ; 

    // Change if 0 to if 1 for running non shared code and make if 0 for shared memory code 
    #if 0 
      MatrixMul <<<dimGrid,dimBlock>>> (array1_d , array2_d ,M_result_array_d , WIDTH) ; 
    #endif 

    #if 1 
      MatrixMulSh<<<dimGrid,dimBlock>>> (array1_d , array2_d ,M_result_array_d , WIDTH) ; 
    #endif 

    // all GPU function blocked till kernel is working 
    //copy back result_array_d to result_array_h 
    cudaMemcpy(M_result_array_h , M_result_array_d , WIDTH*WIDTH*sizeof(int), cudaMemcpyDeviceToHost) ; 

    //printf the result array 
    for (i = 0 ; i<WIDTH ; i++) 
    { 
     for (j = 0 ; j < WIDTH ; j++) 
     { 
      fprintf (fp3, "%d\t", M_result_array_h[i*WIDTH+j]) ; 
     } 
     fprintf (fp3, "\n") ; 
    } 
    //system("pause") ; 
    cudaFree(array1_d); 
    cudaFree(array2_d); 
    cudaFree(M_result_array_d); 

    cudaFreeHost(array1_h); 
    cudaFreeHost(array2_h); 
    cudaFreeHost(M_result_array_h); 

    cudaEventRecord(stop_full, 0); 
    cudaEventSynchronize(stop_full); 

    cudaEventElapsedTime(&time, start_full, stop_full); 
    printf ("Total execution Time is : %1.5f ms\n", time); 

} 

답변

1

fscanf(fp, "%d", &x[i*width+j]);을이어야한다 아래

CUDA는 프로그램이다. scanf 패밀리에는 스캔 한 값을 쓸 위치의 주소가 필요합니다.

또한 don't cast malloc입니다.

+0

Worked .. 고맙다 .. 전에도 x와 함께 시도했지만 .. 어쨌든 덕분에 .. 그리고 우리가 malloc을 캐스팅 할 필요가없는 이유는 무엇입니까? – Deepak

+1

링크를 클릭하면 –

+0

Ok가됩니다. 위의 샘플 CUDA 프로그래밍에서 파일 및 상대 주소를 읽는 것을 기반으로하는 몇 가지 문제에 직면했기 때문에 나에 의해 수행됩니다 .. 내 cuda 프로그램에서 동일한 변경을했을 때 파일에서 올바른 값을 읽지 못합니다. 이전과 같이. 나는 상대 주소에 문제가 있습니까? – Deepak