在ubuntu上运行cuda - 是否需要本机设备驱动程序(使用nvidia显卡)?

时间:2014-08-03 14:36:50

标签: c++ cuda gpu nvidia ubuntu-14.04

我正在尝试使用GeForce GTX 660M显卡在Ubuntu 14上运行cuda / opencl GPU计算的基本入门示例。

即使我设法编译并运行示例代码,似乎GPU没有计算任何东西或cudaMemcpy操作不起作用,因为我的结果值在调用内核并执行之后不会更新DeviceToHost-copy操作。

我想知道,我是否需要在Ubuntu上安装nvidia的某个本机驱动程序才能使用cuda或opencl。

这是我的基本入门代码(对于cuda):

#include <iostream>

using namespace std;

// global constants
#define THREADS 4

const int N = 100;

int fill_content = 1;

__global__ void sum(int* a, int* b, int* c)
{
    int i = blockIdx.x * blockDim.x * threadIdx.x;
    c[i] = a[i] + b[i];
}

void check( int* a, int N )
{
    cout << endl;

    for(int i = 0; i < N; ++i)
    {
        int num = a[i];
        cout << i << ": " << num << endl;
    }

    cout << endl;
}

void fill_vectors(int*p , int size)
{
    for(int i = 0; i < size; ++i)
    {
        p[i] = fill_content;
    }
}

int main(int argc, char **argv)
{
    int host_a[N], host_b[N], host_c[N];
    size_t s_a,s_b,s_c;
    s_a = s_b = s_c = sizeof(int) * N;
    int *dev_a, *dev_b, *dev_c;


    // allocate memory on the device for calculation input and results
    cudaMalloc(&dev_a, s_a);
    cudaMalloc(&dev_b, s_b);
    cudaMalloc(&dev_c, s_c);

    fill_content = 1;
    fill_vectors(host_a, N);

    fill_content = 2;
    fill_vectors(host_b, N);

    fill_content = 0;
    fill_vectors(host_c, N);

    // copy the input values to the gpu-memory
    cudaMemcpy(dev_a, host_a, s_a, cudaMemcpyHostToDevice);
    cudaMemcpy(dev_b, host_b, s_b, cudaMemcpyHostToDevice);

    // invokes kernel-method sum on device using device-memory dev_a, dev_b, dev_c
    //sum<<<N/THREADS, THREADS,1>>>(dev_a, dev_b, dev_c);

    // copy the result values back from the device_memory to the host-memory
    cudaMemcpy(host_c, dev_c, s_c, cudaMemcpyDeviceToHost);

    // free memory allocated on device (for input and result values)
    cudaFree(dev_a); cudaFree(dev_b); cudaFree(dev_c);

    // expected to print out 3
    check(host_c,N);
}

我用以下代码编译它:

nvcc -o vector-sum2 vector-sum2.cu

安装了nvidia-cuda-toolkit

如上所述,每个数组元素只输出0

0: 0
1: 0
2: 0
3: 0
4: 0
5: 0

......继续。

您知道吗,为了让这个例子有效,我需要改变什么?

1 个答案:

答案 0 :(得分:4)

首先,您的内核调用已被注释掉:

//sum<<<N/THREADS, THREADS,1>>>(dev_a, dev_b, dev_c);

因此,您的输出全部为零,因为您实际上并未运行内核。

如果取消注释内核,则存在问题。如果您在使用CUDA代码时遇到问题,则应使用proper cuda error checking并使用cuda-memcheck运行代码。

取消注释内核并使用cuda-memcheck运行会显示内核的许多越界访问。这些最终归因于以下代码:

int i = blockIdx.x * blockDim.x * threadIdx.x;

这不是创建唯一线程索引的正确方法。相反,我们想要:

int i = blockIdx.x * blockDim.x + threadIdx.x;

通过这些更改,您的代码可以正常运行。如果它仍然不适合您,您可能会遇到机器设置问题,在这种情况下,正确的cuda错误检查可能会为您提供一些线索。