【问题标题】:Cannot run CUDA kernel : too many resources requested for launch无法运行 CUDA 内核:启动请求的资源过多
【发布时间】:2014-04-06 02:57:53
【问题描述】:

看看我自己编写的 cuda 内核。我有一个大内核,但它返回了错误消息。然后我对其进行了简化,发现它在一个循环中失败。我简化了这个循环,发现如果我使用 int 值或常量值在循环中填充 data[threadIdx.x] ,它工作正常。但是如果我使用 double 类型的值,它会返回一个错误。

建议:如果您没有正确地将数据从主机传输到设备,您可能会在使用 Nsight 时收到“警告:检测到 Cuda API 错误:返回 cudaLaunch (0x7)”消息,或者您可以从终端运行应用程序时出现分段错误错误

__global__ void sumSeries(double* dSum,int* totalThreadNumber){
    volatile  __shared__ double data[768];
    double var=0;
    data[threadIdx.x]=0;
    for ( int i = 10 ; i < 20 ;++i){
        var=i;
        data[threadIdx.x] += (var)/(var*var+1);
        __syncthreads();
    }


}

为什么它不起作用?

int main() {

    int threadsPerBlock=768;
    int blockCount=8;

    int *hostThreadNumber=new int ;
        *hostThreadNumber=threadsPerBlock*blockCount;
    int* deviceThreadNumber=NULL;

    double* deviceSum=NULL;
    double* hostSum=(double*)malloc(blockCount);


    cudaError_t cuerr=cudaDeviceSetCacheConfig(cudaFuncCachePreferShared);
    if (cuerr != cudaSuccess){
        std::cout<<"Cant SetCacheConfig: "<<cudaGetErrorString(cuerr)<<std::endl;
        return -1;
    }

    cuerr=cudaMalloc(&deviceSum,blockCount*sizeof(double));//размер дабла*число блоков
    if (cuerr != cudaSuccess){
        std::cout<<"Cant allocate memory for deviceSum: "<<cudaGetErrorString(cuerr)<<std::endl;
        return -1;
    }
    cuerr=cudaMalloc(&deviceThreadNumber,sizeof(int));
    if (cuerr != cudaSuccess){
        std::cout<<"Cant allocate memory for deviceThreadNumber: "<<cudaGetErrorString(cuerr)<<std::endl;
        return -1;
    }

    cuerr = cudaMemcpy(deviceSum,hostSum,blockCount*sizeof(double),cudaMemcpyHostToDevice);
    if (cuerr != cudaSuccess){
        std::cout<<"Can not copy hostSum to device: "<<cudaGetErrorString(cuerr)<<std::endl;
        return -1;
    }
    cuerr = cudaMemcpy(deviceThreadNumber,hostThreadNumber,sizeof(int),cudaMemcpyHostToDevice);
    if (cuerr != cudaSuccess){
        std::cout<<"Can not copy hostThreadNumber to device: "<<cudaGetErrorString(cuerr)<<std::endl;
        return -1;
    }

    sumSeries<<<dim3(blockCount),dim3(threadsPerBlock)>>>(deviceSum,deviceThreadNumber);
    cuerr=cudaGetLastError();
    if (cuerr != cudaSuccess){
        std::cout<<"Cuda kernel error: "<<cudaGetErrorString(cuerr)<<std::endl;
        return -1;
    }
    cuerr= cudaDeviceSynchronize();
    if (cuerr != cudaSuccess){
        std::cout<<"Can not synchronize cuda kernel : "<<cudaGetErrorString(cuerr)<<std::endl;
        return -1;
    }
    cuerr= cudaMemcpy(hostSum,deviceSum,blockCount*sizeof(double),cudaMemcpyDeviceToHost);
    if (cuerr != cudaSuccess){
        std::cout<<"Can not copy data to host: "<<cudaGetErrorString(cuerr)<<std::endl;
        return -1;
    }
    cudaFree(deviceSum);
    cudaFree(deviceThreadNumber);
    return 0;
}

【问题讨论】:

  • 您遇到的确切错误是什么?你能提供一个完整的样本吗?您正在启动的线程/块的数量?
  • 请同时指定您正在使用的特定卡。
  • 我每块使用 768 个线程和 8 个块。我的 GPU 是 GeForce® GTS 450。完整示例由两部分组成(cuda 内核和主要功能(我刚刚添加))
  • 警告:检测到 Cuda API 错误:返回 cudaLaunch (0x7)
  • 在内核的for 循环之前直接添加#pragma unroll 1 会发生什么?

标签: cuda


【解决方案1】:

你刚刚为hostSum分配了8字节内存

double* hostSum=(double*)malloc(blockCount)

如果我假设你想为它分配blockCount * sizeof(double) 字节,那就错了,因为你为deviceSum 分配了这个内存量,并将它用于主机和设备之间的内存复制。

cuerr = cudaMalloc(&deviceSum,blockCount*sizeof(double));

cuerr = cudaMemcpy(deviceSum,hostSum,blockCount*sizeof(double),cudaMemcpyHostToDevice);

cuerr= cudaMemcpy(hostSum,deviceSum,blockCount*sizeof(double),cudaMemcpyDeviceToHost);

【讨论】:

    猜你喜欢
    • 2014-11-18
    • 2012-08-23
    • 2022-01-14
    • 2012-10-28
    • 2012-04-23
    • 1970-01-01
    • 2013-01-31
    相关资源
    最近更新 更多