C++ 健壮的兼容性检查?

C++ 健壮的兼容性检查?,c++,windows,opencl,C++,Windows,Opencl,我正在构建一个在windows上使用OpenCLGPU加速的应用程序,包括OpenCL2.0+功能 在我自己的机器上,有兼容的硬件和最新的驱动程序,我运行构建没有问题 然而,我一直在将它部署到其他机器上,并且在初始化OpenCL内核/程序/等等的过程中,由于各种原因遇到了冻结/崩溃 其他机器要么有不兼容的硬件(没有gfx卡,要么gfx卡与OCL2.0+不兼容)、过期的gfx驱动程序、过期的OpenCL驱动程序等。简单地更新它们并不是解决方案,因为它们是为了模拟真实的用户环境(也就是说,我最终部署

我正在构建一个在windows上使用OpenCLGPU加速的应用程序,包括OpenCL2.0+功能

在我自己的机器上,有兼容的硬件和最新的驱动程序,我运行构建没有问题

然而,我一直在将它部署到其他机器上,并且在初始化OpenCL内核/程序/等等的过程中,由于各种原因遇到了冻结/崩溃

其他机器要么有不兼容的硬件(没有gfx卡,要么gfx卡与OCL2.0+不兼容)、过期的gfx驱动程序、过期的OpenCL驱动程序等。简单地更新它们并不是解决方案,因为它们是为了模拟真实的用户环境(也就是说,我最终部署软件的用户不能保证有兼容的系统)

我已经跟踪了OpenCL返回的错误代码(并在返回错误代码后停止进一步初始化),但在初始化各种OpenCL函数的过程中,这些机器上仍然会出现分段错误,否则它们将在OCL程序初始化过程中挂起(在某些情况下,即使在运行问题函数之前没有返回OpenCL错误代码)

在运行任何OpenCL初始化函数之前,如何在特定机器上执行健壮的兼容性检查


我知道我可以查询设备/驱动程序OpenCL信息,但返回值只是特定于供应商的字符串,尝试预测/解析所有可能的组合似乎是一件愚蠢的事情(而且,似乎根本不能保证它们会返回有用的信息)。有没有更可靠的方法来查询OpenCL(特别是OpenCL 2.0 GPU设备代码)可以在特定机器上执行?

当人们试图分发OpenCL应用程序时,有两个问题

  • 您想检查客户端是否有OpenCL

  • 您需要检查客户端是否具有正确的版本

  • 解决1有点麻烦,因为如果没有OpenCL,OpenCL应用程序通常会崩溃。您可以使用基本上适用于OpenCL的glew。这将允许您检查客户端是否有OpenCL


    之后,您只剩下OpenCL设备/驱动程序查询功能,以检查客户端是否安装了正确的版本。

    您可能会遇到以下几个不兼容问题:

  • 扩展或可选核心功能
  • OpenCL规范中描述了核心语言特性,以及 core的所有功能都应该可以在任何系统上使用,也可以在任何情况下使用 编译器(前提是它支持特定版本的OpenCL)

    还有一组扩展,它们是可选的,您需要 检查系统是否支持它们

    例如,如果您使用
    double
    type,则必须检查
    cl\u khr\u fp64
    支持扩展。您可以获取支持的扩展列表 通过校准扩展
    clGetDeviceInfo(CL\u设备扩展)

  • 未定义的行为或任何其他错误
  • 当程序在本地计算机上运行良好,并且崩溃/冻结时 当您部署它时,这通常表示 程序本身

    如果您(无意中)依赖OpenCL驱动程序,可能会发生这种情况 实施细节(例如,工作组如何排序,如何 要避免这种情况,您应该严格遵守 OpenCL规范的规则,尽管规范是 并不总是完美的

    例如,如果您有以下代码:

    for (int i = 0; i < N; ++i) {
      if (get_global_id() < M) {
        barrier();
      }
    }
    
    for(int i=0;i
    这段代码可以在本地计算机上运行并给出正确的结果 机器,但根据OpenCL规范它是不正确的(您不能 在发散块中调用一个
    barrier()
    ),它将 其他机器上的崩溃/挂起/不匹配

  • 编译器(或驱动程序)错误
  • 编译器努力优化您的程序,但有时会失败 要正确执行此操作,尤其是在某些边缘情况下。可能是最好的 检测这类错误的方法是编写一个自检工具 对程序的关键部分运行单元测试并检查 针对引用的结果

    例如,如果您有一个算法,比如直方图计算,那么 可以将其与程序的其余部分隔离,并确保获得 预期结果

    如果这个自检工具失败了,它可以给你一个关于发生了什么的线索 打开,您将拥有一个好的复制器,可以与OpenCL共享 驱动程序开发人员,以便他们能够解决问题

    除此之外,您还可以基于供应商id应用解决方案, 设备类型、驱动程序版本等。可以查询所有这些信息 从
    clGetDeviceInfo
    ,但不应将其视为稳定的 接口:名称和版本可能会在将来更改
    发布,因此很难跟踪这些更改。

    请指定您的问题。当然,您需要检查内核和硬件/驱动程序的兼容性。几乎没有人能给出完整和全面的答案,我认为问@DmytroDadyka没有任何意义您甚至读过这个问题吗?当然。例如,您编写了“返回值只是特定于供应商的字符串,尝试预测/解析所有可能的组合似乎是愚蠢的任务”这绝对正确。但这是留给您的唯一东西。使用OpenCL的代码几乎总是硬件dependent@DmytroDadyka我问你如何检查兼容性,你的回答是“当然你需要检查兼容性”,这是没有帮助的。告诉我使用OpenCL的代码依赖于硬件(这是我在问题中所说的)也没有帮助。设备/驱动程序查询函数似乎返回特定于供应商的字符串。是否有标准的方法来解析它们以确保提取正确的信息?取决于,如果您只想确保opencl 2.0,您可以传递
    -cl std=cl