2012-04-29 119 views
0

后,内存中的数据损坏请看看这个代码:Cuda的:内核调用

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

int N, L, I; 
float * inputs; 
float * temp; 

// first kernel 
__global__ void mulKernel (float * output, float * inputs)///, float * weights) 
{ 
    int idx = blockIdx.x * blockDim.x + threadIdx.x; 

    output [idx] = inputs [idx] * 3;//weights [idx]; 
    //weights [idx] = 4; 

    //__syncthreads(); 
} 

//second kernel 
__global__ void sumKernel (float * output, float * input) 
{ 
    int idx = blockIdx.x * blockDim.x + threadIdx.x; 
    output [idx] = input[idx]*2; 

    __syncthreads(); 
} 

void printVector (const float *p, const int N) { 
    for (int i=0; i<N; i++) 
    printf("%f\n",p[i]); 
} 

int main(int argc, char *argv[]) 
{ 
    if(argc < 3) 
     printf("Usage: cuda <layers> <inputs>\n"); 
    else 
    { 
     L = atoi(argv[1]); 
     N = atoi(argv[2]); 
     I = atoi(argv[2]); 
     inputs = (float*)malloc(I*sizeof(float)); 
     float * weights = (float*)malloc(I*sizeof(float)); 

     // and fill with some arbitrary values 
     for (int i=0; i<I; i++) 
     { 
      inputs[i] = 1; 
     } 
     for (int i=0; i<I; i++) 
     { 
      weights[i] = 1.5; 
     } 

     // allocate device memory 
     float * devInputs = NULL; 
     float * devTemp = NULL; 
     float * devWeights = NULL; 

     cudaMalloc ((void**)&devInputs, I*sizeof(float)); 
     cudaMalloc ((void**)&devTemp, I*sizeof(float)); 
     cudaMalloc ((void**)&devWeights, I*sizeof(float)); 

     // set kernel launch configuration 
     dim3 threadsMul = dim3(512, 1); 
     int blocksCount = floor(I/threadsMul.x) + 1; 
     dim3 blocksMul = dim3(blocksCount, 1); 

     dim3 threadsSum = dim3(512, 1); 
     blocksCount = floor(I/threadsSum.x) + 1; 
     dim3 blocksSum = dim3(blocksCount, 1); 

     cudaMemcpy  (devInputs, inputs, I*sizeof(float), cudaMemcpyHostToDevice); 
     cudaMemcpy  (devWeights, weights,I*sizeof(float), cudaMemcpyHostToDevice); 

     //kernels calling in this cycle 
     for(int j=0;j<L;j++) 
     { 
      // copying data to see that's ok 
      cudaMemcpy  (inputs, devInputs, I*sizeof(float), cudaMemcpyDeviceToHost); 
      cudaMemcpy  (weights, devWeights, I*sizeof(float), cudaMemcpyDeviceToHost); 

      // print it 
      printf("inputs:\n"); 
      printVector (inputs, N); 
      printf("weights:\n"); 
      printVector (weights, N); 
      printf("\n"); 

      // running first kernel 
      mulKernel<<<blocksMul, threadsMul>>>(devTemp, devInputs);//, devWeights); 

      // copying and printing data. We can see thats array weights contains a wrong values 
      cudaMemcpy  (inputs, devInputs, I*sizeof(float), cudaMemcpyDeviceToHost); 
      cudaMemcpy  (weights, devWeights, I*sizeof(float), cudaMemcpyDeviceToHost); 

      printf("inputs:\n"); 
      printVector (inputs, N); 
      printf("weights:\n"); 
      printVector (weights, N); 
      printf("\n"); 

      if(cudaDeviceSynchronize() == cudaSuccess) 
      printf("threads syncronized\n"); 

      cudaMemcpy  (inputs, devInputs, I*sizeof(float), cudaMemcpyDeviceToHost); 
      cudaMemcpy  (weights, devWeights, I*sizeof(float), cudaMemcpyDeviceToHost); 

      printf("inputs:\n"); 
      printVector (inputs, N); 
      printf("weights:\n"); 
      printVector (weights, N); 
      printf("\n"); 

      sumKernel<<<blocksSum, threadsSum>>>(devInputs, devTemp); 

      cudaMemcpy  (inputs, devInputs, I*sizeof(float), cudaMemcpyDeviceToHost); 
      cudaMemcpy  (weights, devWeights, I*sizeof(float), cudaMemcpyDeviceToHost); 

      printf("inputs:\n"); 
      printVector (inputs, N); 
      printf("weights:\n"); 
      printVector (weights, N); 
      printf("\n\n"); 

      if(cudaDeviceSynchronize() == cudaSuccess) 
      printf("threads syncronized\n"); 

      cudaMemcpy  (inputs, devInputs, I*sizeof(float), cudaMemcpyDeviceToHost); 
      cudaMemcpy  (weights, devWeights, I*sizeof(float), cudaMemcpyDeviceToHost); 

      printf("inputs:\n"); 
      printVector (inputs, N); 
      printf("weights:\n"); 
      printVector (weights, N); 
      printf("\n\n"); 
     } 

     cudaMemcpy  (inputs, devInputs, I*sizeof(float), cudaMemcpyDeviceToHost); 

     cudaFree   (devInputs ); 
     cudaFree   (devTemp ); 
     cudaFree   (devWeights ); 

     printVector (inputs, N); 

     free(inputs); 
     free(weights); 
    } 
    return 0; 
} 

,并期待输出。在callig第一个内核之后,devWeights数组丢失了它的数据。但它并没有在任何地方使用。我只是将它复制到内存中,运行内核(不影响它)并将其复制回主机。在输出中,我看到它发生了变化。为什么?我究竟做错了什么?

在主函数中可以看到循环。其中我运行了两个内核:sumKernel和mulKernel。在运行内核之前,之后和同步线程之后,我将数组复制到主机并进行打印。所以,我在调用内核后看到错误的数据。请参阅代码中的评论。

我没有看到任何错误(只有cudaSuccess)。

+3

您根本不检查CUDA错误。如果你不检查错误,你永远不会知道是否有任何问题。 – harrism

+1

没有内核调用代码,我们可以猜测。它是如何改变的?你确定你以正确的顺序用正确的参数调用你的内核? – djmj

+1

你问我们“看看输出”。但是你没有解释什么应该看起来像什么代码或者什么值的问题发生时使用的命令行参数。如果其他人应该知道你的代码应该做什么,并且如果你不努力向他们解释或者告诉他们你应该如何运行代码来产生问题,那么他们应该帮助确定问题。 – talonmies

回答

0

哦,我发现了错误。我忘记在我的内核中使用if(idx < N),并且CUDA在输出数组维度时没有打印错误。所以,当我改变输入数组时,我也改变了输入后位于内存中的数据。