初始化目标设备

OpenCL 内核可以在 GPU 或 CPU 上执行。这允许后备解决方案,其中客户可能具有非常过时的系统。程序员还可以选择将其功能限制为 CPU 或 GPU。

要开始使用 OpenCL,你需要一个上下文和一个设备。两者都是由 OpenCL API(也称为 cl::Context 或 clContext&~Device)定义的结构,并定义使用的目标处理器。

要获取设备和上下文,你需要查询可用平台列表,每个平台可以托管多个设备。平台代表你的物理 GPU 和 CPU,而设备可以进一步区分所包含的计算单元。对于 GPU,大多数平台只有一个设备。但 CPU 可能会在其 CPU 功能之外提供额外的集成 GPU。

上下文管理内存,命令队列,不同的内核和程序。上下文可以限于单个设备,也可以引用多个设备。

在我们开始编码之前的快速 API 说明:几乎每次调用 OpenCL 都会给出一个错误值,可以是返回值,也可以是 ref 值(C 中的指针)。现在让我们开始吧。

ErrorCode err;
var platforms = Cl.GetPlatformIDs(out err);
if(!CheckError(err, "Cl.GetPlatformIDs")) return;
foreach (var platform in platforms) {
    foreach (var device in Cl.GetDeviceIDs(platform, DeviceType.Gpu, out err)) {
        if(!CheckError(err, "Cl.GetDeviceIDs")) continue;
        [...]
    }
}

此代码段会查询系统上所有可用的 GPU 设备。你现在可以将它们添加到列表中,或直接使用第一个匹配项启动上下文。 ‘CheckError(...)‘函数是一个简单的实用程序,它检查错误代码是否具有成功值或不同的值,并且可以为你提供一些日志记录。建议使用单独的函数或宏,因为你会调用很多。

ErrorCode 只是 C#数据类型 cl_int 的枚举,C / C++可以将 int 值与此处列出的预定义错误常量进行比较: https//www.khronos.org/registry/OpenCL/sdk/1.0/docs/man/ XHTML / errors.html

你还可能想要检查设备是否支持所有需要的功能,否则你的内核可能会在运行时崩溃。你可以使用查询设备功能

Cl.GetDeviceInfo(_device, DeviceInfo.ImageSupport, out err)

此示例询问设备是否可以执行图像功能。对于下一步和最后一步,我们需要从收集的设备中构建我们的上下文。

_context = Cl.CreateContext(null, 1, new[] { _device }, ContextNotify, IntPtr.Zero, out err);

有些东西在这里发生。对于 C / C++人来说,IntPtr 是 C#中的指针地址。我将专注于这里的重要部分。

  • 第二个参数定义要使用的设备数
  • 第三个参数是这些设备的数组(或 C / C++中的指针)
  • 第三个参数是回调函数的函数指针。只要在上下文中发生错误,就会使用此函数。

为了进一步使用,你需要在某处保留你使用过的设备和上下文。

完成所有 OpenCL 交互后,你需要再次发布上下文

Cl.ReleaseContext(_context);