由于 cuda 中的向量相加,我得到了零并且没有错误

问题描述 投票:0回答:2

我正在运行一个 cuda vec 加法程序,并稍后得到零作为其总和的输出。我尝试过调试,但无法解决手头的问题。它应该添加数字,但只是简单地打印出零,我无法理解为什么会发生。

我已经尝试对代码执行所有操作,但仍然没有得到任何输出。

using namespace std;

 __global__ void vecADDKernal(double *A, double *B, double *C, int n){
    int id = blockIdx.x*blockDim.x+threadIdx.x;
    if(id<n) C[id] = A[id] + B[id];
}


int main( ){
    int n = 1048576;
    int size = n*sizeof(double);
    double *d_A, *d_B;
    double *d_C;
    double *h_A, *h_B, *h_C;

    h_A = (double*)malloc(size);
    h_B = (double*)malloc(size);
    h_C = (double*)malloc(size);

    cudaMalloc(&d_A, size);
    cudaMalloc(&d_B, size);
    cudaMalloc(&d_C, size);


    int i;
    // Initialize vectors on host
    for( i = 0; i < n; i++ ) {
        h_A[i] = 2*i;
        h_B[i] = 3*i;
    }

    cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
    cudaMemcpy(d_B, h_B, size, cudaMemcpyHostToDevice);

    int blockSize = 256;

    // Number of thread blocks in grid
    int gridSize = ceil(n/blockSize);

    vecADDKernal<<<gridSize, blockSize>>>(d_A, d_B, d_C, n);

    cudaMemcpy(h_C, d_C, size, cudaMemcpyDeviceToHost);

    double sum = 0;
    for(int a = 0; a<n; a++) {
        sum = h_C[a];
        cout<<h_C[a]<<endl;
    }

    cout<<"HI "<< sum <<endl;
    cudaFree(d_A);
    cudaFree(d_B);
    cudaFree(d_C);
    return 0;
}
c++ cuda
2个回答
1
投票

我只是按原样运行您的代码(仅添加必要的包含内容),并且得到非零输出。您是否已验证您的设备可以成功运行 nvidia 提供的示例

该示例正是您尝试使用矢量加法执行的操作,但具有适当的错误检查和结果验证。

一些注意事项:

  • for 循环中的第一行为 sum 分配 (=) 一个值,而不是 将值添加到 sum (+=),因此您只会得到最后一个值 总和而不是累计值。

  • 即使是简单的例子,正确的错误检查也会有所帮助。样品
    提供了一个例子,就像罗伯特链接的答案一样。

  • 您是否尝试打开内存调试器来查看您的值是否为 事实上内存中是0?打印到控制台是另一个地方可以 出错了。

  • 您可以使用向量来存储主机数据。您可以访问原始
    使用 vector.data() 进行 memCpy 操作的数组,它可以让您轻松 访问各种有用的东西,例如基于范围的以及 像累积和填充函数之类的东西。


0
投票

我遇到了同样的问题。这是因为您使用较新版本的 Cuda 驱动程序运行旧 GPU。你运行过Treeman提供的Cuda示例吗?该示例包含调试代码。运行该程序后,我得到的错误消息是

Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Failed to launch vectorAdd kernel (error code no kernel image is available for execution on the device)!

这表明默认编译命令

$nvcc program.cu -o program
编译版本与您的GPU内核版本不兼容。要解决此问题,您必须在主函数中运行以下代码来确定您的 GPU 运行的内核版本。

cudaDeviceProp deviceProp;
printf("Device Compute Capability: %d.%d\n", deviceProp.major, deviceProp.minor);

我的显示为5.0。然后,当您编译程序时,您必须指定 GPU 运行的内核版本,即

$nvcc -arch=sm_50 -o your_program your_program.cu 
,其中
-arch=sm_50
是规范命令。那么程序就不会再产生0了。

顺便说一句,我在 x64 设备上运行带有 Nvidia GeForce 940 MX 和 CUDA-12 的 Linux。希望这个答案可以帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.