我正在构建一个在Windows上使用OpenCL GPU加速的应用程序,包括OpenCL 2.0+功能。
在具有兼容硬件和最新驱动程序的我自己的计算机上,运行版本没有任何问题。
但是,我一直在将其部署到其他计算机上,并且在初始化OpenCL内核/程序/等过程中由于各种原因遇到冻结/崩溃。
其他计算机具有不兼容的硬件(没有gfx卡或与ocl2.0 +不兼容的gfx卡),过时的GFX驱动程序,过时的OpenCL驱动程序等。仅对其进行更新不是这是一个解决方案,因为它们旨在模拟现实世界的用户环境(即,我最终将软件部署到的用户并不能保证具有兼容的系统)。
我已经跟踪了OpenCL返回的错误代码(一旦返回错误代码,就停止进一步的初始化),但是在各种OpenCL函数的初始化过程中,这些机器上仍然出现分段错误,或者它们会在OCL程序初始化期间挂起(在某些情况下,即使在运行问题功能之前没有返回OpenCL错误代码)。
在运行任何OpenCL初始化功能之前,如何在特定计算机上进行健壮兼容性检查?
我知道我可以查询设备/驱动程序OpenCL信息,但是返回值只是特定于供应商的字符串,似乎很愚蠢的尝试/解析所有可能的组合(而且,似乎无法保证它们是正确的)甚至根本不会返回有用的信息)。是否有更健壮的方法来查询OpenCL(尤其是OpenCL 2.0 GPU设备代码)是否可以在特定计算机上执行?
答案 0 :(得分:2)
人们尝试分发OpenCL应用程序时有两个问题。
您要检查客户端是否具有OpenCL。
您要检查客户端是否具有正确的版本。
解决1有点麻烦,因为如果没有OpenCL,OpenCL应用程序通常会崩溃。您可以使用CLEW,这对于opencl来说基本上没有问题。这将使您检查客户端是否具有opencl。
在此之后,您剩下的就是OpenCL设备/驱动程序查询功能,用于检查客户端是否安装了正确的版本。
答案 1 :(得分:0)
您可能会遇到几种不兼容的问题:
OpenCL规范中描述了核心语言功能,并且 核心的所有功能都应该可以在任何系统上和任何环境下使用 编译器(前提是它支持特定版本的OpenCL)。
还有一组扩展名,这些扩展名是可选的,您需要 检查系统是否支持它们。
例如,如果您使用double
类型,则必须检查
支持cl_khr_fp64
扩展名。您可以获得支持的列表
通过计算clGetDeviceInfo(CL_DEVICE_EXTENSIONS)
当程序在本地计算机上运行良好并且崩溃/死机时 部署它时,通常表明 程序本身。
如果您(无意中)依赖OpenCL驱动程序,则可能会发生这种情况 实施细节(例如,工作组的排序方式, 工作项已执行)。为避免这种情况,您应严格遵循 OpenCL规范的规则,尽管该规范是 并不总是完美的。
例如,如果您具有以下代码:
for (int i = 0; i < N; ++i) {
if (get_global_id() < M) {
barrier();
}
}
此代码可以愉快地运行,并为您在本地提供正确的结果
机器,但根据OpenCL规范是不正确的(您不能
在不同的代码块中有一个barrier()
调用),它将
在其他计算机上崩溃/挂起/不匹配。
编译器尽力优化程序,但有时会失败 正确执行此操作,尤其是在某些情况下。可能是最好的 检测这类错误的方法是编写一个自检工具, 对程序的关键部分运行单元测试并检查 结果参考。
例如,如果您有一种算法,例如直方图计算,则您 可以将其与程序的其余部分隔离开来,并确保获得 预期结果。
如果此自检工具失败,它可以为您提供线索 继续,您将拥有一个可以与OpenCL分享的出色复制器 驱动程序开发人员,以便他们可以解决问题。
除此之外,您还可以根据供应商ID应用解决方法,
设备类型,驱动程序版本等。所有这些信息都可以查询
来自clGetDeviceInfo
,但您不应将其视为稳定
界面:名称和版本将来可能会更改
发布,因此很难遵循这些更改。