【问题标题】:OpenCL program execution fails using GPU device使用 GPU 设备执行 OpenCL 程序失败
【发布时间】:2013-12-19 13:48:49
【问题描述】:

我是 OpenCL 的初学者。为了了解该库的基础知识,我尝试在以下 URL 执行第一个程序:

https://www.olcf.ornl.gov/tutorials/opencl-vector-addition/

我之前链接了 NVIDIA GPU Computing SDK 中的 openCL 包含和库,当然程序的编译是可以的。但是,如果我运行它,clCreateContext 函数内的执行将失败。

// Bind to platform
err = clGetPlatformIDs(1, &cpPlatform, NULL);

// Get ID for the device
err = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);

// Create a context  
context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);

问题来自之前的方法clGetDeviceIDs,它似乎感觉不到device_id 变量(如果在函数clGetDeviceIDs 中替换标志CL_DEVICE_TYPE_GPUCL_DEVICE_TYPE_CPU 程序完美运行)。不过,我的显卡驱动程序已经更新。根据执行情况,我的计算机上似乎没有任何 GPU 设备。这很奇怪。您是否认为我的驱动程序不正确并且缺少依赖项?我真的迷路了。有人可以帮帮我吗?

非常感谢您的帮助。

【问题讨论】:

    标签: opencl


    【解决方案1】:

    您是否检查以确保您只定义了 1 个平台?

    cl_uint nPlatforms;
    cl_uint err = CL_SUCCESS;
    err = clGetPlatformIDs(1, NULL, &nPlatforms);
    

    如果有多个平台,您可以这样做:

    cl_platform_id* platformID_Array;
    platformID_Array = (cl_platform_id *)malloc(sizeof(cl_platform_id)*nPlatforms);
    err = CL_SUCCESS;
    err = clGetPlatformIDs(nPlatforms, platformID_Array, NULL);
    

    然后检查名称:

    for (cl_uint i = 0; i < nPlatforms; i++) {
        size_t vendorSize;
        char* vendorCstring;
        err = clGetPlatformInfo(platformID_Array[i], CL_PLATFORM_VENDOR, 0, NULL, &vendorSize);
        vendorCstring = (char*)malloc(sizeof(char)*vendorSize);
        err = clGetPlatformInfo(platformID_Array[i], CL_PLATFORM_VENDOR, vendorSize, vendorCstring, NULL);
        printf("Platform name = %s\n",vendorCstring);
    }
    

    你也可以试试:

    err = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL); 
    

    注意平台 ID 的 NULL 参数。在这种情况下,行为是实现定义的,因此您可以查看支持的设备。我怀疑你会取回一个 CPU 设备,但它值得检查。

    【讨论】:

    • 是的,我有 2 个设备(一个英特尔 CPU 设备和一个 NVIDIA GPU 设备)。如果没有平台阵列,默认情况下我只能访问 CPU 设备。现在,一切正常,我可以加载 GPU 设备了。非常感谢您的帮助。再见。
    【解决方案2】:

    如果如您所说,选项 CL_DEVICE_TYPE_CPU 适合您,那么您获得的平台没有 GPU 设备。

    您应该尝试其他平台,因为 Intel 和 nVIDIA 设备位于不同的平台上。

    您可以尝试使用 err = clGetPlatformIDs(2, &amp;cpPlatform, NULL); 并获得两个平台而不是 1 个,或者使用另一种更聪明的算法来找到跨所有可用平台的有效 GPU。

    这绝对不是链接或编译问题,因为方法可以正常工作。

    我会这样做:

    // Num of platforms
    int numplat;
    err = clGetPlatformIDs(0, NULL, &numplat);
    
    // Num of platforms
    int cpPlat[numplat];
    err = clGetPlatformIDs(numplat, &cpPlat, NULL);
    
    // Get ID for the device
    for(int i=0; i<numplat; i++){
        err = clGetDeviceIDs(cpPlatform[i], CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
        if (err == CL_SUCCESS )
           break;
    }
    
    // Create a context  
    context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      • 2015-06-23
      • 1970-01-01
      相关资源
      最近更新 更多