强大的兼容性检查?

时间:2018-12-21 00:21:27

标签: c++ windows opencl

我正在构建一个在Windows上使用OpenCL GPU加速的应用程序,包括OpenCL 2.0+功能。

在具有兼容硬件和最新驱动程序的我自己的计算机上,运行版本没有任何问题。

但是,我一直在将其部署到其他计算机上,并且在初始化OpenCL内核/程序/等过程中由于各种原因遇到冻结/崩溃。

其他计算机具有不兼容的硬件(没有gfx卡或与ocl2.0 +不兼容的gfx卡),过时的GFX驱动程序,过时的OpenCL驱动程序等。仅对其进行更新不是这是一个解决方案,因为它们旨在模拟现实世界的用户环境(即,我最终将软件部署到的用户并不能保证具有兼容的系统)。

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

在运行任何OpenCL初始化功能之前,如何在特定计算机上进行健壮兼容性检查?

我知道我可以查询设备/驱动程序OpenCL信息,但是返回值只是特定于供应商的字符串,似乎很愚蠢的尝试/解析所有可能的组合(而且,似乎无法保证它们是正确的)甚至根本不会返回有用的信息)。是否有更健壮的方法来查询OpenCL(尤其是OpenCL 2.0 GPU设备代码)是否可以在特定计算机上执行?

2 个答案:

答案 0 :(得分:2)

人们尝试分发OpenCL应用程序时有两个问题。

  1. 您要检查客户端是否具有OpenCL。

  2. 您要检查客户端是否具有正确的版本。

解决1有点麻烦,因为如果没有OpenCL,OpenCL应用程序通常会崩溃。您可以使用CLEW,这对于opencl来说基本上没有问题。这将使您检查客户端是否具有opencl。

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

答案 1 :(得分:0)

您可能会遇到几种不兼容的问题:

  1. 扩展或可选核心功能

OpenCL规范中描述了核心语言功能,并且 核心的所有功能都应该可以在任何系统上和任何环境下使用 编译器(前提是它支持特定版本的OpenCL)。

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

例如,如果您使用double类型,则必须检查 支持cl_khr_fp64扩展名。您可以获得支持的列表 通过计算clGetDeviceInfo(CL_DEVICE_EXTENSIONS)

扩展
  1. 未定义的行为或任何其他错误

当程序在本地计算机上运行良好并且崩溃/死机时 部署它时,通常表明 程序本身。

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

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

for (int i = 0; i < N; ++i) {
  if (get_global_id() < M) {
    barrier();
  }
}

此代码可以愉快地运行,并为您在本地提供正确的结果 机器,但根据OpenCL规范是不正确的(您不能 在不同的代码块中有一个barrier()调用),它将 在其他计算机上崩溃/挂起/不匹配。

  1. 编译器(或驱动程序)错误

编译器尽力优化程序,但有时会失败 正确执行此操作,尤其是在某些情况下。可能是最好的 检测这类错误的方法是编写一个自检工具, 对程序的关键部分运行单元测试并检查 结果参考。

例如,如果您有一种算法,例如直方图计算,则您 可以将其与程序的其余部分隔离开来,并确保获得 预期结果。

如果此自检工具失败,它可以为您提供线索 继续,您将拥有一个可以与OpenCL分享的出色复制器 驱动程序开发人员,以便他们可以解决问题。

除此之外,您还可以根据供应商ID应用解决方法, 设备类型,驱动程序版本等。所有这些信息都可以查询 来自clGetDeviceInfo,但您不应将其视为稳定 界面:名称和版本将来可能会更改 发布,因此很难遵循这些更改。