【问题标题】:A"cudaErrorUnknown" in cudaMemcpy function callcudaMemcpy 函数调用中的“cudaErrorUnknown”
【发布时间】:2013-10-10 22:21:29
【问题描述】:

我使用一个函数来计算三个向量的向量点,并使用reduce来使其更快。 但是,我总是遇到这样的错误:

CUDA error at kernel.cu:120 code=30(cudaErrorUnknown) "cudaMemcpy(partia
l_c, dev_partial_c,sizeofblock,cudaMemcpyDeviceToHost )"

我不知道为什么,因为代码看起来很正常。分配函数没有返回错误。有什么可能的解决方案吗? 非常感谢。

double vector_dot(double* d_A,double* d_B,double *d_C,int numElements)
{
    int size = sizeof(double) * numElements;
    int c_size = sizeof(char) * numElements;
    double *d_D=NULL;
    checkCudaErrors(cudaMalloc((void**)&d_D,size)); 
    // Launch the Vector Add CUDA Kernel
    int threadsPerBlock = 256;
    int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock;
    vectorMPL<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_D, numElements);
    double *partial_c;
    double*dev_partial_c;
    int sizeofblock=blocksPerGrid*sizeof(double);
    partial_c = (double*)malloc(sizeofblock);
    checkCudaErrors( cudaMalloc( (void**)&dev_partial_c,sizeofblock )) ;
    vector_dot_h<<<blocksPerGrid, threadsPerBlock>>>(d_D, d_C, dev_partial_c, numElements);

    double sum = 0;
    checkCudaErrors(cudaMemcpy(partial_c,dev_partial_c,sizeofblock,cudaMemcpyDeviceToHost));

    for (int i=0; i<blocksPerGrid; i++) {
        sum += partial_c[i];
    }

    checkCudaErrors(cudaFree(d_D));
    checkCudaErrors(cudaFree(dev_partial_c));  
    free(partial_c);
    // Reset the device and exit
    checkCudaErrors(cudaDeviceReset());
    return sum;
}

如果我删除这个,我会在 cudafree 调用中收到未知错误。似乎所有的 cuda API 调用都无法完成。我想知道为什么? 什么是未知的cuda错误?原因是什么?

【问题讨论】:

  • 内核启动和执行正确的保证是什么?在调用内核后尝试使用 cudaGetLastError() 并查看它是否返回正确的值。如果可能,还可以分享 vector_dot_h 内核代码。

标签: c++ cuda gpgpu gpu


【解决方案1】:

cudaMemcpycudaFreedocumentation 包含以下注释:

请注意,此函数也可能返回以前的错误代码, 异步启动。

即。该错误没有发生在cudaMemcpycudaFree 中,而是发生在之前的内核启动或执行期间。如果您关注this advice 并将您的代码修改为以下内容:

vectorMPL<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_D, numElements);
checkCudaErrors(cudaPeekAtLastError());
checkCudaErrors(cudaDeviceSynchronize());

你应该会发现错误是cudaDeviceSynchronize()调用报错的,说明错误发生在内核执行时。错误的根本原因很可能是vector_dot_h 内的内存访问越界,但由于您没有为相关内核调用提供代码或执行参数,因此无法为您提供更准确的诊断. CUDA 工具包附带一个名为cuda-memcheck 的实用程序,您可以使用它来获取有关正在运行的内核中非法内存访问模式的更多信息。我建议您尝试在此代码上使用它。

【讨论】:

  • 谢谢!我正在尝试 cuda-memcheck。
  • 无效的 global 在块 (0) 中由线程 (8,0,0) 在 vectorMPL(double*, double*, double*, int) 中 0x00000068 处读取大小为 8 ,0,0) 地址 0x0554aa40 越界
  • @kururu:正如我所说 - 你有一个内核问题。要么你传递了一个无效的指针,要么你的内核代码中有一个索引错误。我的建议是接受这个答案(将问题标记为已回答),并花一些时间调试内核。如果你发现你仍然无法解决这个问题,请使用内核代码和其他人可以编译和运行的最短的完整示例代码提出一个新问题。
  • 谢谢。我会听从你的建议的。
猜你喜欢
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-13
  • 2020-12-25
  • 2011-08-02
相关资源
最近更新 更多