【问题标题】:CUDA returned error code 77 after launchingCUDA 启动后返回错误代码 77
【发布时间】:2017-11-28 13:29:37
【问题描述】:

我有下一个结构:

typedef struct
{
    float* coordinates;
} Point;

CUDA 中的下一个函数:

cudaError_t calculateCenterUsingCuda(Point* point, const int NUM_OF_DIMENSIONS, const int NUM_OF_POINTS)
{
    Point* point_dev;

    cudaError_t cudaStatus;

    cudaStatus = cudaSetDevice(0);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
    }

    cudaStatus = cudaMalloc((void**)&point_dev, 1 * sizeof(Point));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
    }

    cudaStatus = cudaMalloc((void**)&point_dev->coordinates, NUM_OF_DIMENSIONS * sizeof(float));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
    }

    cudaStatus = cudaMemcpy(point_dev, point, 1 * sizeof(Point), cudaMemcpyHostToDevice);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
    }

    cudaStatus = cudaMemcpy(point_dev->coordinates, point->coordinates, NUM_OF_DIMENSIONS * sizeof(float), cudaMemcpyHostToDevice);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
    }

    calculateCenter<<<1, 52>>>(point_dev, NUM_OF_POINTS);

    cudaStatus = cudaGetLastError();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "calculateCenterlaunch failed: %s\n", cudaGetErrorString(cudaStatus));
    }

    cudaStatus = cudaDeviceSynchronize();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching calculateCenter!\n", cudaStatus);
    }

    // Copy output vector from GPU buffer to host memory.
    cudaStatus = cudaMemcpy(point, point_dev, 1 * sizeof(Point), cudaMemcpyDeviceToHost);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
    }

    cudaStatus = cudaMemcpy(point->coordinates, point_dev->coordinates, NUM_OF_DIMENSIONS * sizeof(float), cudaMemcpyHostToDevice);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
    }

    cudaStatus = cudaDeviceReset();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaDeviceReset failed!");
    }

    return cudaStatus;
}

calculateCenter 是:

__global__ void calculateCenter(Point* point, const int NUM_OF_POINTS)
{
    int i = threadIdx.x;
    point->coordinates[i] = point->coordinates[i] / NUM_OF_POINTS;
    printf("%d\n", i);
}

基本上我使用 CUDA 创建一个平均点,将点中的每个坐标除以点数(默认为 4) 默认维数为 52。

但是当我运行这段代码时出现错误:

cudaDeviceSynchronize returned error code 77 after launching calculateCenter!

任何帮助为什么会发生这种情况?

谢谢!

【问题讨论】:

    标签: cuda


    【解决方案1】:

    您的代码在管理指针的方式上存在一些问题。线

    cudaStatus = cudaMalloc((void**)&point_dev->coordinates, NUM_OF_DIMENSIONS * sizeof(float));
    

    错了。在这个阶段,point_dev 是一个指向设备内存的指针,主机 API 函数调用cudaMalloc 期望主机内存空间中的目标地址。设备指针的存储位置在你的情况下是一个设备指针,这是错误的。

    您可以通过使用中间 Point 数据结构并将设备指针存储在其中然后复制到设备来解决此问题:

    cudaError_t calculateCenterUsingCuda(Point* point, const int NUM_OF_DIMENSIONS, const int NUM_OF_POINTS)
    {
        Point* point_dev;
    
        Point point_for_dev;
    
        cudaError_t cudaStatus;
    
        cudaStatus = cudaSetDevice(0);
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
        }
    
        cudaStatus = cudaMalloc((void**)&point_dev, 1 * sizeof(Point));
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMalloc failed!");
        }
    
        cudaStatus = cudaMalloc((void**)&(point_for_dev.coordinates), NUM_OF_DIMENSIONS * sizeof(float));
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMalloc failed!");
        }
    
        cudaStatus = cudaMemcpy(point_dev, &point_for_dev, 1 * sizeof(Point), cudaMemcpyHostToDevice);
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMemcpy failed!");
        }
    
        cudaStatus = cudaMemcpy(point_for_dev.coordinates, point->coordinates, NUM_OF_DIMENSIONS * sizeof(float), cudaMemcpyHostToDevice);
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMemcpy failed!");
        }
    
        calculateCenter <<< 1, NUM_OF_DIMENSIONS >>>(point_dev, NUM_OF_POINTS);
    
        cudaStatus = cudaGetLastError();
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "calculateCenterlaunch failed: %s\n", cudaGetErrorString(cudaStatus));
        }
    
        cudaStatus = cudaDeviceSynchronize();
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching calculateCenter!\n", cudaStatus);
        }
    
        // Copy output vector from GPU buffer to host memory.
        cudaStatus = cudaMemcpy(point->coordinates, point_for_dev.coordinates, NUM_OF_DIMENSIONS * sizeof(float), cudaMemcpyHostToDevice);
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaMemcpy failed!");
        }
    
        cudaStatus = cudaDeviceReset();
        if (cudaStatus != cudaSuccess) {
            fprintf(stderr, "cudaDeviceReset failed!");
        }
    
        return cudaStatus;
    }
    

    这样,主机 API 方法一直使用主机指针。

    基于指针的结构的深拷贝需要特殊处理。

    【讨论】:

    • 谢谢,但你确定:cudaStatus = cudaMemcpy(point, point_dev, 1 * sizeof(Point), cudaMemcpyDeviceToHost);?在内核 wotk 之后,point_for_dev 协调 sims 为零
    • @ShayZambrovski,很明显,您的代码修复不完整。指针值的复制是没有意义的,唯一相关的部分是坐标数组的内容。虽然支持多个点需要更多的编码工作。
    • 谢谢,不过还是在cudaStatus = cudaMemcpy(point-&gt;coordinates, point_for_dev.coordinates, NUM_OF_DIMENSIONS * sizeof(float), cudaMemcpyHostToDevice);之后数组都是0,你知道为什么吗?
    • @ShayZambrovski,您没有提供围绕内核调用的任何代码。结果取决于您的初始化。我只能用你提供的信息做这么多。最后,SO 不是调试服务。如果您对输出值有后续问题,请考虑使用 NSIGHT 或 cuda-gdb 调试您的代码。
    猜你喜欢
    • 2016-05-03
    • 2021-05-25
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 2015-01-17
    • 1970-01-01
    相关资源
    最近更新 更多