代码正在运行,但不会执行gpu函数

时间:2019-06-18 09:17:53

标签: c++ cuda

我有两个功能: add_cpu函数工作正常,但add_gpu函数无效。

我试图检查我的GPU驱动程序软件上的sum选项,并一遍又一遍地读取我的代码。我在另一台机器上尝试了完全相同的代码,并且工作正常。 当前计算机上的checkError结果为1,不应为1。 而且我的笔记本电脑上的checkError结果为0,这是正确的。 是否有人对图形卡或系统有什么问题的建议? 我不知道这是什么问题。 我错过了某种选择吗?

#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <iostream>
#include <math.h>

#define out std::cout <<
#define end << std::endl

__global__
void add_gpu( int n, float* x, float* y ) {
    for ( int i = 0; i < n; i++ ) y[i] = x[i] + y[i];
}

void add_cpu( int n, float* x, float* y ) {
    for ( int i = 0; i < n; i++ ) y[i] = x[i] + y[i];
}

void init( int n, float* x, float* y ) {
    for ( int i = 0; i < n; i++ ) {
        x[i] = 1.0f;
        y[i] = 2.0f;
    }
}

int checkError( int n, float f, float* y ) {
    float c = 0.0f;
    for ( int i = 0; i < n; i++ ) c = fmax( c, fabs( y[i] - f ) );
    return c;
}

void print( int n, float* obj, char* str = "obj: " ) {
    out str << obj[0];
    for ( int i = 1; i < n; i++ ) out ", " << obj[i];
    out "" end;
}

int main( ) {
    int n = 1 << 5;
    float* x, * y;
    float error = 0.0f;

    cudaMallocManaged( &x, n * sizeof( float ) );
    cudaMallocManaged( &y, n * sizeof( float ) );

    init( n, x, y );
    print( n, x, "x" );
    print( n, y, "y" );
    add_gpu<< <1, 1 >> > ( n, x, y );
    //add_cpu(n, x, y);
    cudaDeviceSynchronize( );
    print( n, y, "y" );

    error = checkError( n, 3.0f, y );
    out "error: " << error end;

    cudaFree( x );
    cudaFree( y );

    return 0;
}

2 个答案:

答案 0 :(得分:0)

https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__MEMORY.html#group__CUDART__MEMORY_1gc263dbe6574220cc776b45438fc351e8

在不将数据复制到设备的情况下,GPU不知道数据,而在不将数据复制回设备的情况下,主机不知道结果

答案 1 :(得分:0)

我看不到问题出在哪里,但是要进行调试,您应该检查cuda错误。

大多数cuda函数返回一个cuda状态。您也许可以使用像这样的小包装函数来检查错误

checkCudaError(const cudaError_t error) {
    if (error != cudaSuccess) {
        std::cout << "Cuda error: " << cudaGetErrorString(error) << std::endl;
        // maybe do something else
    }
}

并通过这种方式调用 cudaMallocManaged()之类的功能

checkCudaError(cudaMallocManaged(&x, n * sizeof(float));

对于在设备上执行的所有操作(例如自定义内核),您应该运行内核,然后调用

cudaGetLastError()

,也许还使用 checkCudaError()

checkCudaError(cudaGetLastError())

请注意,如果在某个时刻发生错误, cudaGetLastError()将始终返回错误,因此您必须找到第一个错误发生的位置。这就是为什么每次以某种方式使用GPU时都要检查cuda错误。