在多GPU系统中,给定PCI供应商、设备和总线ID,如何将OpenCL设备与特定GPU匹配?

在多GPU系统中,给定PCI供应商、设备和总线ID,如何将OpenCL设备与特定GPU匹配?,opencl,gpu,pci,Opencl,Gpu,Pci,我希望能够在由PCI ID标识的多GPU系统上,将OpenCL设备与系统中的GPU进行匹配 例如,如果我的系统有多个GPU,可能来自不同的供应商,我可以通过列举PCI总线列出设备。这给了我PCI供应商、设备和总线ID。如果我根据一些选择标准选择其中一个(GPU)PCI设备用于OpenCL计算,我如何将其与OpenCL设备匹配 我可以使用CLGetDeviceID()枚举OpenCL中的GPU设备,但是没有明显的方法将OpenCL设备与PCI设备相匹配。OpenCL函数clGetDeviceInf

我希望能够在由PCI ID标识的多GPU系统上,将OpenCL设备与系统中的GPU进行匹配

例如,如果我的系统有多个GPU,可能来自不同的供应商,我可以通过列举PCI总线列出设备。这给了我PCI供应商、设备和总线ID。如果我根据一些选择标准选择其中一个(GPU)PCI设备用于OpenCL计算,我如何将其与OpenCL设备匹配

我可以使用CLGetDeviceID()枚举OpenCL中的GPU设备,但是没有明显的方法将OpenCL设备与PCI设备相匹配。OpenCL函数clGetDeviceInfo()提供对PCI供应商ID和设备名称的访问,但不提供对PCI设备或总线ID的访问。我可以尝试将PCI设备名称与OpenCL设备名称进行匹配,但也有可能您有多个相同类型的设备,并且这些设备的名称并不总是相同的

为什么这是必要的?假设我知道程序X在GPU A上运行CUDA或其他东西。我想避免也使用GPU A进行OpenCL操作,所以我选择GPU B。然后我需要找出哪个OpenCL设备是GPU A,哪个是GPU B。PCI ID似乎是唯一一致且跨平台的识别GPU设备的方法

顺便说一句,CUDA API确实提供PCI、总线和插槽ID(CU_设备\属性\ PCI_总线\ ID、CU_设备\属性\ PCI_设备\ ID),但CUDA仅适用于NVidia设备


<理想的是,我需要一个C或C++的解决方案。

< P>最近的AMD版本在Linux上有CLSI DeVICEX拓扑结构,它将CLD DeVice TopOrthyYAMD选项加到CelGeDeGestIn()中,但是这是一个很窄的解决方案。

< P>我开发了一个库,这样做:保持OpenCL的模拟步进彼此的脚趾。< /P> 你可以在这里找到它:

它首先枚举机器上存在的每个平台的所有平台和每个设备。您选择想要的平台,它将选择可用的最佳设备。我在我的工作站上使用3个nvidia卡:两个GTX 580用于OpenCL计算,一个GT 210用于显示。同时运行两个模拟将分别在两个GTX上运行。没有干预

还有一个很好的类可以保持两个缓冲区同步:一个在主机上,一个在设备上。调用OpenCL_数组::Host_to_Device()和OpenCL_数组::Device_to_Host()可以简化来回传输

它适用于以下平台:

  • nvidia(仅限GPU)
  • amd(CPU和/或GPU)
  • 英特尔(仅限CPU)
  • 苹果(CPU和/或GPU)

请注意,它不会让您选择要使用的设备,而是为您选择一个。如果一个程序的两个实例使用该库,它们将知道该库,并且不会在同一设备上运行(当然,如果您也有)。现在也无法检测视频卡是否用于显示。但至少这是一个开始

不幸的是,由于openCL的抽象特性,您所寻找的答案并不漂亮

我发现唯一可靠的方法是在openCL中为平台+设备ID分配一个苛刻的工作负载,然后通过AMD的ADL和Nvidia的NVML等工具监控进程的使用情况。即使是像cgminer这样的成熟应用程序也存在这方面的问题,并且经常将openCL工作负载与卡度量混为一谈,以至于它们会分配配置变量来手动更正它(“gpu映射”)


我希望现在有一个更好的答案,因为通过openCL知道哪个设备在端点后面会更好!正如arsenm指出的那样,AMD正在努力将这一层添加到openCL中,这一点在未来可能会有所改变。

方法是使用两个特定于供应商的扩展。对于AMD,您必须使用适用于Windows和Linux的
CL\u DEVICE\u TOPOLOGY\u AMD
,它将返回PCIe总线id,这对于GPU是唯一的。在NVIDIA上,查询设备的CL_device_PCI_BUS_ID_NV。另请参见:

答案似乎是正确的,但前提是您运行的是linux/mac。 在我做了一些测试之后,windows似乎无法识别这些特定于供应商的扩展。(我已经在Geforce GTX Titan和ATI Radeon R9上对其进行了测试)

我的解决方案是使用clGetGLContextInfoKHR()函数(从openCL spec 1.1开始提供)和“CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR”参数,这将确保获得与执行渲染的相同GPU匹配的openCL设备ID

没错,这不会给你物理总线插槽,但这将确保渲染的相同GPU与计算的相同GPU


此外,假设一个人使用Nvidia Quadro卡,那么他可以使用wgl_nv_gpu亲缘关系来确保openGL访问特定的gpu,然后使用GL上下文并从中获取openCL设备ID。

规范说CL_设备供应商ID“可能是PCIe ID”。如果这不能满足你的要求,那么我认为规范中没有任何东西可以满足你的要求。但还是不知道你为什么需要这个。听起来像是过早的优化。@vocaro:是的,我可以得到供应商ID。我想你不明白这个问题。你说你想知道PCI设备ID,以避免与另一个可能使用特定PCI设备ID的进程发生冲突。我想知道你是如何知道哪些PCI设备正在使用的?我猜你没有使用OpenCL?是的,还需要涵盖NVidia卡。据我所知,你的回答没有解决将PCI设备ID与OpenCL计算设备匹配的问题。你正在解决一个相关的问题,但这对我的需要没有帮助。如果我错了,请解释。请记住,我也希望能够使用CUDA,并且仍然能够跟踪哪个设备是哪个。我还没有尝试过这一点,但这似乎是正确的答案。太棒了,谢谢你的回答,在等待了将近3年之后。很抱歉花了这么长时间,我之前没有遇到这个问题:)谢谢你将此标记为正确答案