【问题标题】:wrong results in cudacuda 中的错误结果
【发布时间】:2014-11-08 01:06:49
【问题描述】:

我尝试用 cuda C 编写一个简单的示例, 我关注了有关此的截屏视频,但结果错误

这是一个例子:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include<windows.h>
#define SIZE    1024

__global__ void VectorAdd(int *a, int *b, int *c, int n)
{
    int i = threadIdx.x;

    if (i < n){
        c[i] = a[i] + b[i];
    }

}

int main()
{
    int *a, *b, *c;
    int *d_a, *d_b, *d_c;
    cudaError_t cudaStatus;
    cudaStatus = cudaSetDevice(0);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU         installed?");

    }
    a = (int *)malloc(SIZE*sizeof(int));
    b = (int *)malloc(SIZE*sizeof(int));
    c = (int *)malloc(SIZE*sizeof(int));

    cudaMalloc(&d_a, SIZE*sizeof(int));
    cudaMalloc(&d_b, SIZE*sizeof(int));
    cudaMalloc(&d_c, SIZE*sizeof(int));

    for (int i = 0; i < SIZE; i++)
    {
        a[i] = i;
        b[i] = i;
        c[i] = 0;
    }

    cudaMemcpy(d_a, a, SIZE*sizeof(int), cudaMemcpyHostToDevice);
    cudaMemcpy(d_b, b, SIZE*sizeof(int), cudaMemcpyHostToDevice);
    cudaMemcpy(d_c, c, SIZE*sizeof(int), cudaMemcpyHostToDevice);

    VectorAdd<<< 1, SIZE >>>(d_a, d_b, d_c, SIZE);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
    }
    cudaMemcpy(c, d_c, SIZE*sizeof(int), cudaMemcpyDeviceToHost);

    for (int i = 0; i < 10; ++i)
        printf("c[%d] = %d\n", i, c[i]);

    free(a);
    free(b);
    free(c);
    enter code here
    cudaFree(d_a);
    cudaFree(d_b);
    cudaFree(d_c);

    return 0;
}

结果是:

c[0]=0
c[1]=0
c[2]=0
c[3]=0
c[4]=0
c[5]=0
c[6]=0
c[7]=0
c[8]=0
c[9]=0

但我期待这个结果:

c[0]=0
c[1]=2
c[2]=4
c[3]=6
c[4]=8
c[5]=10
c[6]=12
c[7]=14
c[8]=16
c[9]=18

请任何人对此提供帮助!

【问题讨论】:

  • 在启动内核后尝试插入cudaDeviceSynchronize() 调用。
  • 执行proper error checking 将为您提供有关问题的线索。您的 GPU 计算能力是多少? CC
  • @DavidLively:这不会有任何影响。 cudaMemcpy 是一个阻塞调用。
  • 您已评论(在其中一个答案中)您拥有 GT210。该 GPU 的计算能力为 1.2。查看架构规范以找到每个块的最大线程数。也就是说,如果将SIZE 更改为512,在您的示例中会发生什么?
  • @talonmies 我的脑子里一定有cudaMemcpyAsync()。我到处都能看到它。 :)

标签: c cuda


【解决方案1】:

我做了一些错误的cmets,所以我会尝试修复我的错误并在这里给出正确的答案。首先,请参加与proper CUDA error checking相关的cmets。

其次,GT210 (CC 1.2) 的最大线程块大小是 512,而不是我在困惑时评论的 256。

也就是说,您应该通过执行上述错误检查得到以下错误:

GPUassert: invalid device function 

在这种情况下,此错误表明您编译代码的架构高于您用于运行示例的架构。您正在为compute capability = 2.0 或更高版本的设备编译示例(正如您所评论的那样),但随后您在 GT210 中执行具有compute capability = 1.2 的代码。

因此,首先,为相应的架构重新编译您的示例。改变

-gencode=arch=compute_20 TO -gencode=arch=compute_12

一旦你为你的架构成功编译了示例,你会得到以下错误(因为你ALREADY正在做proper error checking;)

GPUassert: invalid configuration argument 

在这种情况下,错误表明您使用的资源比架构可用的资源多(计算能力 1.2),因为您尝试启动 SIZE = 1024 的块,但最大线程块大小为 512,也就是说,你不能配置超过 512 个线程的块。

因此,将 SIZE 调整为 512,一切都会按预期工作。下面是你的例子,做proper CUDA error checking

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include<windows.h>
#define SIZE    1024

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
   if (code != cudaSuccess) 
   {
      fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}

__global__ void VectorAdd(int *a, int *b, int *c, int n)
{
    int i = threadIdx.x;

    if (i < n){
        c[i] = a[i] + b[i];
    }
}

int main()
{
    int *a, *b, *c;
    int *d_a, *d_b, *d_c;
    cudaError_t cudaStatus;
    cudaStatus = cudaSetDevice(0);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU         installed?");
    }
    a = (int *)malloc(SIZE*sizeof(int));
    b = (int *)malloc(SIZE*sizeof(int));
    c = (int *)malloc(SIZE*sizeof(int));

    gpuErrchk( cudaMalloc(&d_a, SIZE*sizeof(int)) );
    gpuErrchk( cudaMalloc(&d_b, SIZE*sizeof(int)) );
    gpuErrchk( cudaMalloc(&d_c, SIZE*sizeof(int)) );

    for (int i = 0; i < SIZE; i++)
    {
        a[i] = i;
        b[i] = i;
        c[i] = 0;
    }

    gpuErrchk( cudaMemcpy(d_a, a, SIZE*sizeof(int), cudaMemcpyHostToDevice) );
    gpuErrchk( cudaMemcpy(d_b, b, SIZE*sizeof(int), cudaMemcpyHostToDevice) );
    gpuErrchk( cudaMemcpy(d_c, c, SIZE*sizeof(int), cudaMemcpyHostToDevice) );

    VectorAdd<<< 1, SIZE >>>(d_a, d_b, d_c, SIZE);
    gpuErrchk( cudaPeekAtLastError() );
    gpuErrchk( cudaDeviceSynchronize() );

    gpuErrchk( cudaMemcpy(c, d_c, SIZE*sizeof(int), cudaMemcpyDeviceToHost) );

    for (int i = 0; i < 10; ++i)
        printf("c[%d] = %d\n", i, c[i]);

    free(a);
    free(b);
    free(c);
    // enter code here 
    cudaFree(d_a);
    cudaFree(d_b);
    cudaFree(d_c);

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-22
    • 2014-11-29
    • 1970-01-01
    相关资源
    最近更新 更多