2011-09-01 6 views
13

Me gustaría poder hacer coincidir los dispositivos OpenCL con GPU en el sistema en sistemas multi-GPU identificados por ID de PCI.¿Cómo hacer coincidir los dispositivos OpenCL con una GPU específica dado proveedor de PCI, ID de dispositivo y bus en un sistema multi-GPU?

Por ejemplo, si tengo un sistema con varias GPU, posiblemente de diferentes proveedores, puedo enumerar los dispositivos enumerando el bus PCI. Esto me da ID de proveedor, dispositivo y bus PCI. Si elijo uno de estos dispositivos PCI (GPU) para usar para el cálculo de OpenCL en función de algunos criterios de selección, ¿cómo lo relaciono con el dispositivo OpenCL?

Puedo enumerar dispositivos GPU en OpenCL usando clGetDeviceIDs() pero no hay una manera obvia de unir dispositivos OpenCL a dispositivos PCI. La función OpenCL clGetDeviceInfo() proporciona acceso a la identificación del proveedor de PCI y al nombre del dispositivo, pero no a las identificaciones de los dispositivos PCI o bus. Podría intentar hacer coincidir el nombre del dispositivo PCI con el nombre del dispositivo OpenCL pero es posible que tenga más de uno del mismo tipo de dispositivo y los nombres no siempre son los mismos de todos modos.

¿Por qué es esto necesario? Digamos que sé que el programa X está ejecutando CUDA u otra cosa en la GPU A. También quiero evitar el uso de la GPU A para una operación OpenCL, así que elijo la GPU B. Luego necesito descubrir qué dispositivo OpenCL es GPU A y cuál es GPU B. Las ID de PCI parecen ser la única forma consistente y cruzada de identificación de dispositivos de GPU.

BTW, la API CUDA proporciona identificadores PCI, de bus y de ranura (CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID) pero CUDA solo funciona con dispositivos NVidia.

Idealmente necesito una solución usando C o C++.

+0

La especificación dice CL_DEVICE_VENDOR_ID "podría ser la identificación PCIe". Si eso no consigue lo que quieres, entonces no creo que haya nada en la especificación que lo haga. Sin embargo, todavía no estoy seguro de por qué necesita esto. Parece una optimización prematura. – vocaro

+0

@vocaro: Sí, puedo obtener la identificación del vendedor. No creo que entiendas la pregunta. – jcoffland

+0

Dice que desea conocer el ID del dispositivo PCI para evitar conflictos con otro proceso que puede estar usando una ID de dispositivo PCI específica. Me preguntaba cómo sabes qué dispositivos PCI están en uso. ¿Supongo que no estás usando OpenCL para eso? – Matt

Respuesta

5

La forma de hacerlo es usar dos extensiones específicas del proveedor. Para AMD, debe usar CL_DEVICE_TOPOLOGY_AMD, que funciona en Windows y Linux, y devolverá la identificación del bus PCIe, que es única para una GPU. En NVIDIA, consulta el dispositivo para CL_DEVICE_PCI_BUS_ID_NV. Ver también: https://anteru.net/2014/08/01/2483/

+0

No he probado esto todavía, pero parece ser la respuesta correcta. Impresionante, gracias por la respuesta y después de casi 3 años de espera. – jcoffland

+0

Lo siento, tomó tanto tiempo, no tuve el problema antes :) Y gracias por marcar esto como la respuesta correcta. – Anteru

+0

¿'CL_DEVICE_PCI_BUS_ID_NV' funciona para el controlador Nvidia en Windows? Estoy intentando esto en PyOpenCL pero sigo recibiendo un error de que es un valor no válido. – chippies

0

La versión más reciente de AMD tiene la extensión cl_device_topology_amd en Linux ,, que agrega la opción CL_DEVICE_TOPOLOGY_AMD a clGetDeviceInfo(), pero esa es una solución bastante estrecha.

+0

Sí, necesito cubrir también la tarjeta NVidia. – jcoffland

-1

Desarrollé una biblioteca para hacer justamente eso: mantener las simulaciones de OpenCL pisándose los dedos de los pies.

Usted lo encontrará aquí: https://github.com/nbigaouette/oclutils/

En primer lugar, enumerar todas las plataformas y todos los dispositivos para cada plataforma presentes en la máquina. Selecciona la plataforma deseada y elegirá el mejor dispositivo disponible. Lo uso en mi estación de trabajo con 3 tarjetas nvidia: dos GTX 580 para cálculos OpenCL y un GT 210 para la pantalla. Ejecutar dos simulaciones al mismo tiempo se ejecutará en las dos GTX por separado. sin intervención.

También hay una buena clase que mantendrá dos búferes sincronizados: uno en el host y otro en el dispositivo. Llamar a OpenCL_Array :: Host_to_Device() y OpenCL_Array :: Device_to_Host() hace que las transferencias sean simples y simples.

Funciona con estas plataformas:

  • nvidia (sólo GPU)
  • AMD (CPU y/o GPU)
  • Intel (sólo CPU)
  • manzana (CPU y/o GPU)

en cuenta que no le permitirá elegir qué dispositivo usar, pero escoger uno para usted.Si dos instancias de un programa usan la biblioteca, lo sabrán y no se ejecutarán en el mismo dispositivo (si usted también, por supuesto). Tampoco es capaz, ahora mismo, de detectar si la tarjeta de video se usa para la pantalla. ¡Pero al menos es un comienzo!

+0

Según tengo entendido, su respuesta no resuelve el problema de emparejar identificadores de dispositivo PCI con dispositivos informáticos OpenCL. Estás resolviendo un problema relacionado, pero no ayuda con lo que necesito. Si me equivoco, explíquelo. Tenga en cuenta que también quiero poder usar CUDA y seguir haciendo un seguimiento de qué dispositivo es cuál. – jcoffland

1

Lamentablemente, la respuesta que está buscando no es bonita debido a la naturaleza abstracta de openCL.

La única forma confiable de hacerlo es asignar una carga de trabajo exigente a la ID de plataforma + dispositivo en openCL, y luego monitorear el uso del proceso a través de herramientas como ADL de AMD y NVML de Nvidia. Incluso las aplicaciones maduras como cgminer tienen problemas con esto y a menudo mezclan las cargas de trabajo de openCL con métricas de tarjeta, hasta el punto de que asignan variables de configuración para corregirlo manualmente ("gpu-map").

Ojalá hubiera una mejor respuesta por el momento, porque sería genial saber, a través de openCL, qué dispositivo está detrás del punto final. Esto puede cambiar en el futuro, ya que AMD está trabajando para agregar esta capa a openCL como lo señaló el arsenismo.

0

Parece que la respuesta de Anteru es correcta, pero solo si está ejecutando linux/mac. Después de algunas pruebas que hice, parece que Windows no reconoce estas extensiones específicas del proveedor. (Lo he probado tanto en la Geforce GTX Titan & ATI Radeon R9)

Mi solución para usted es utilizar la función clGetGLContextInfoKHR() (disponible desde OpenCL especificación 1.1) con el parámetro "CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR", y que va a asegurarse de que obtiene una ID de dispositivo openCL que coincida con la misma GPU que realiza el procesamiento.

Cierto, eso no le dará ranura de bus físico, pero eso asegurará que la misma GPU que representa es la misma GPU que calcula.

Además, suponiendo que uno trabaje con tarjetas Nvidia Quadro, entonces puede usar el wgl_nv_gpu_affinity para garantizar el acceso OpenGL a una GPU específica, y luego usar el contexto GL & obtener de él la ID del dispositivo openCL.

Cuestiones relacionadas