【问题标题】:OpenCL not finding platforms?OpenCL 找不到平台?
【发布时间】:2015-03-20 16:35:35
【问题描述】:

我正在尝试将 C++ API 用于 OpenCL。我已经安装了我的 NVIDIA 驱动程序并且我已经测试我可以运行提供的简单矢量添加程序here。我可以用下面的 gcc 调用编译这个程序,程序运行没有问题。

gcc main.c -o vectorAddition -l OpenCL -I/usr/local/cuda-6.5/include

但是,我更喜欢使用 C++ API,而不是 C 所需的非常冗长的主机文件。

我从 here 下载了 Khronos 的 C++ 绑定,并将 cl.hpp 文件与我的另一个 cl.h 文件放在同一位置。该代码使用了一些 C++11,因此我可以使用以下代码编译代码:

g++ main.cpp -o vectorAddition_cpp -std=c++11 -l OpenCL -I/usr/local/cuda-6.5/include

但是当我尝试运行程序时出现错误:

clGetPlatformIDs(-1001)

我还尝试了here 提供的示例,它提供了更有用的错误消息。

No platforms found. Check OpenCL installation!

提供此错误的特定代码是这样的:

std::vector<cl::Platform> all_platforms;
    cl::Platform::get(&all_platforms);
    if(all_platforms.size()==0){
    std::cout<<" No platforms found. Check OpenCL installation!\n";
    exit(1);
    }

考虑到 C 实现运行没有问题,这看起来很奇怪。任何见解将不胜感激。

编辑

C 实现实际上没有正确运行。每个加法都打印为零。检查ret_num_platforms 也返回0。由于某种原因,我的设置无法找到我的GPU。我可能错过了什么?我的安装包括分别通过apt-get.run 文件安装的nvidia-340 驱动程序和cuda-6.5。

【问题讨论】:

    标签: c++ opencl gpu


    【解决方案1】:

    衷心感谢@pasternak 帮助我解决了这个问题。然而,为了解决它,我最终需要避免基本上所有 ubuntu apt-get 安装调用,只使用 cuda 运行文件进行完整安装。这是解决问题的方法。

    1. 清除现有的 nvidia 和 cuda 实现 (sudo apt-get purge cuda* nvidia-*)
    2. CUDA toolkit archive 下载 cuda-6.5 工具包
    3. 重启电脑
    4. 切换到 ttyl (Ctrl-Alt-F1)
    5. 停止 X 服务器 (sudo stop lightdm)
    6. 运行 cuda 运行文件 (sh cuda_6.5.14_linux_64.run)
    7. 选择“是”并接受所有默认值
    8. 需要重新启动
    9. 切换到 ttyl,停止 X 服务器并再次运行 cuda 运行文件,然后选择“是”并默认所有内容(再次包括驱动程序)
    10. 更新PATH 以包括/usr/local/cuda-6.5/binLD_LIBRARY_PATH 包括/usr/local/cuda-6.5/lib64
    11. 再次重启
    12. 编译 main.c 程序 (gcc main.c -o vectorAddition -l OpenCL -I/usr/local/cuda-6.5/include)
    13. 验证与./vectorAddition 一起工作

    C++ API

    1. 从 Khronos here 下载 cl.hpp 文件,注意它是 1.1 版
    2. 将 cl.hpp 文件与其他 cl 头文件放在 /usr/local/cuda-6.5/include/CL 中。
    3. 编译 main.cpp (g++ main.cpp -o vectorAddition_cpp -std=c++11 -l OpenCL -I/usr/local/cuda-6.5/include)
    4. 验证它是否有效 (./vectorAddition_cpp)

    两个程序的所有输出都显示了向量之间相加的正确输出。

    我个人觉得有趣的是 Ubuntu 的 nvidia 驱动程序似乎不能很好地与 cuda 工具包配合使用。可能只是针对旧版本,但仍然非常出乎意料。

    【讨论】:

      【解决方案2】:

      如果不在您的机器上运行特定代码很难说,但是查看您所说的示例 C 代码与 cl.hpp 之间的区别可能会给我们一个线索。特别注意,C 示例使用以下行来简单地读取单个平台 ID:

      cl_platform_id platform_id = NULL; 
      cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
      

      注意,它传递 1 作为它的第一个参数。这假设至少存在一个 OpenCL 平台,并请求将找到的第一个平台放在 platform_id 中。此外,请注意,即使返回代码被分配给“ret”,它也不会用于实际检查是否返回错误。

      现在,如果我们看一下用于在 cl.hpp 中对平台集进行排队的静态方法的实现,即 cl::Platform::get:

      static cl_int get(
          VECTOR_CLASS<Platform>* platforms)
      {
          cl_uint n = 0;
          cl_int err = ::clGetPlatformIDs(0, NULL, &n);
          if (err != CL_SUCCESS) {
              return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
          }
      
          cl_platform_id* ids = (cl_platform_id*) alloca(
              n * sizeof(cl_platform_id));
          err = ::clGetPlatformIDs(n, ids, NULL);
          if (err != CL_SUCCESS) {
              return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
          }
      
          platforms->assign(&ids[0], &ids[n]);
          return CL_SUCCESS;
      }
      

      我们看到它首先调用了

      ::clGetPlatformIDs(0, NULL, &n);
      

      注意第一个参数是 0,它告诉 OpenCL 运行时返回“n”中的平台数。如果这成功了,那么它会继续请求实际的“n”个平台 ID。

      所以这里的区别在于 C 版本没有检查是否存在至少一个平台,只是假设存在一个平台,而 cl.hpp 变体是,因此可能是这个调用失败了。

      这一切最可能的原因是没有正确安装 ICD。您可以查看此线程以获取有关如何解决此问题的示例:

      ERROR: clGetPlatformIDs -1001 when running OpenCL code (Linux)

      我希望这会有所帮助。

      【讨论】:

      • 感谢您的回答,但我已经在 /etc/OpenCL/vendors/nvidia.icd 中找到了 nvidia.icd。奇怪的是,/usr/share/nvidia-334/ 中没有这样的文件,只有nvidia-346.grub 文件和nvidia-application-profiles
      • 在您的示例 C 代码中,我会从以下位置查看“ret”:cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);在调试器中检查“ret_num_platforms”的值是否分别为 0 (CL_SUCCESS) 和 1,然后查看 get 的 cl.hpp 实现中的类似值。
      • 我检查了ret_num_platforms,在我的 C 代码中它是 0。我刚刚使用我的 nvidia-340 驱动程序和 cuda-6.5 进行了全新安装,但这段代码告诉我我没有可用的平台。对于代码找不到平台的原因,您还有其他想法吗?
      • C 代码是否仍然适用于新安装,即当它不检查返回码或平台数量时?
      • 它实际上似乎不起作用。输出显示每个加法等于 0。关于如何帮助代码找到平台的任何想法?
      猜你喜欢
      • 1970-01-01
      • 2018-09-05
      • 2015-12-07
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2021-04-28
      相关资源
      最近更新 更多