3

我正在尝试使用 CUDA 创建神经网络:

我的内核看起来像:

__global__ void feedForward(float *input, float *output, float **weight) {

//Here the threadId uniquely identifies weight in a neuron
int weightIndex = threadIdx.x;

//Here the blockId uniquely identifies a neuron
int neuronIndex = blockIdx.x;

if(neuronIndex<NO_OF_NEURONS && weightIndex<NO_OF_WEIGHTS)
output[neuronIndex] += weight[neuronIndex][weightIndex]
        * input[weightIndex];
}

将输出复制回主机时,出现错误

在第 xx 行出现错误未指定的启动失败

在第 xx 行:

CUDA_CHECK_RETURN(cudaMemcpy(h_output, d_Output, output_size, cudaMemcpyDeviceToHost));

我在这里做错了吗?

是因为我如何同时使用块索引和线程索引来引用权重矩阵。还是问题出在其他地方?

我将权重矩阵分配如下:

cudaMallocPitch((void**)&d_Weight, &pitch_W,input_size,NO_OF_NEURONS);

我的内核调用是:

feedForward<<<NO_OF_NEURONS,NO_OF_WEIGHTS>>>(d_Input,d_Output,d_Weight);

之后我打电话: cudaThreadSynchronize();

我是使用 CUDA 编程的新手。任何帮助,将不胜感激。

谢谢

4

3 回答 3

1

输出代码有问题。虽然它不会产生所描述的错误,但它会产生不正确的结果。

int neuronIndex = blockIdx.x;

if(neuronIndex<NO_OF_NEURONS && weightIndex<NO_OF_WEIGHTS)
output[neuronIndex] += weight[neuronIndex][weightIndex] * input[weightIndex];

我们可以看到单个块中的所有线程都在同时写入一个内存单元。所以 udefined 结果是预期的。为了避免这种情况,我建议减少共享内存中一个块内的所有值,并对全局内存执行一次写入。像这样的东西:

__global__ void feedForward(float *input, float *output, float **weight) {

  int weightIndex = threadIdx.x;
  int neuronIndex = blockIdx.x;
  __shared__ float out_reduce[NO_OF_WEIGHTS];

  out_reduce[weightIndex] = 
     (weightIndex<NO_OF_WEIGHTS && neuronIndex<NO_OF_NEURONS) ? 
       weight[neuronIndex][weightIndex] * input[weightIndex]
       : 0.0;
  __syncthreads();

  for (int s = NO_OF_WEIGHTS; s > 0 ; s >>= 1)
  {
    if (weightIndex < s) out_reduce[weightIndex] += out_reduce[weightIndex + s];
    __syncthreads();
  }

  if (weightIndex == 0) output[neuronIndex] += out_reduce[weightIndex]; 
}

原来我不得不重写你一半的小内核来帮助减少代码......

于 2013-01-21T21:19:02.683 回答
1

我使用 CUDA 构建了一个非常简单的 MLP 网络。如果您可能感兴趣,您可以在这里找到我的代码:https ://github.com/PirosB3/CudaNeuralNetworks/ 如有任何问题,请拍!

丹尼尔

于 2014-10-02T23:22:06.860 回答
0

您正在使用 cudaMallocPitch,但不显示变量是如何初始化的;我愿意打赌这就是你的错误的根源。cudaMallocPitch 相当棘手;第三个参数应该以字节为单位,而第四个参数不是。IE

int width = 64, height = 64;
float* devPtr;
size_t pitch;
cudaMallocPitch(&device_Ptr, &pitch, width * sizeof(float), height);

您的变量 input_size 是否以字节为单位?如果不是,那么您可能分配的内存太少(即您会认为您正在请求 64 个元素,但实际上您将获得 64 个字节),因此您将访问内核中超出范围的内存. 根据我的经验,“未指定的启动失败”错误通常意味着我有段错误

于 2013-01-21T18:04:31.657 回答