2011-09-01 11 views
13

Mi piacerebbe essere in grado di abbinare i dispositivi OpenCL con le GPU nel sistema su sistemi multi-GPU identificati dagli ID PCI.Come abbinare i dispositivi OpenCL a una GPU specifica in base al fornitore PCI, agli ID dispositivo e bus in un sistema multi-GPU?

Ad esempio, se si dispone di un sistema con più GPU, possibilmente di diversi fornitori, è possibile elencare i dispositivi enumerando il bus PCI. Questo mi dà l'identità del fornitore, del dispositivo e del bus PCI. Se scelgo uno di questi dispositivi (GPU) PCI da utilizzare per il calcolo di OpenCL sulla base di alcuni criteri di selezione, come posso abbinarlo al dispositivo OpenCL?

Posso elencare i dispositivi GPU in OpenCL utilizzando clGetDeviceIDs() ma non esiste un modo ovvio per associare i dispositivi OpenCL ai dispositivi PCI. La funzione OpenCL clGetDeviceInfo() fornisce l'accesso all'ID del fornitore PCI e al nome del dispositivo, ma non agli ID del dispositivo o del bus PCI. Potrei provare ad abbinare il nome del dispositivo PCI al nome del dispositivo OpenCL, ma è possibile che tu abbia più di uno dello stesso tipo di dispositivo e che i nomi non siano sempre uguali.

Perché è necessario? Dite che so che il programma X sta eseguendo CUDA o qualcos'altro su GPU A. Voglio evitare anche l'uso della GPU A per un'operazione OpenCL quindi scelgo GPU B. Devo quindi capire quale dispositivo OpenCL è GPU A e quale è GPU B. Gli ID PCI sembrano essere l'unico modo coerente e multipiattaforma per identificare i dispositivi GPU.

BTW, l'API CUDA fornisce ID PCI, bus e slot (CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID) ma CUDA funziona solo con dispositivi NVidia.

Idealmente ho bisogno di una soluzione utilizzando C o C++.

+0

La specifica dice CL_DEVICE_VENDOR_ID "potrebbe essere l'ID PCIe". Se questo non ottiene quello che vuoi, allora non penso che ci sia qualcosa nelle specifiche che lo faranno. Ancora non sono sicuro del motivo per cui hai bisogno di questo, però. Sembra un'ottimizzazione prematura. – vocaro

+0

@vocaro: Sì, posso ottenere l'ID fornitore. Non penso che tu capisca la domanda. – jcoffland

+0

Si dice di voler conoscere l'ID del dispositivo PCI per evitare il conflitto con un altro processo che potrebbe utilizzare un ID dispositivo PCI specifico. Mi sono chiesto come sai quali dispositivi PCI sono in uso? Immagino che tu non stia usando OpenCL per questo? – Matt

risposta

5

Il modo per farlo è utilizzare due estensioni specifiche del fornitore. Per AMD, devi usare CL_DEVICE_TOPOLOGY_AMD che funziona su Windows e Linux e restituirà l'id del bus PCIe, che è unico per una GPU. Su NVIDIA, interrogare il dispositivo per CL_DEVICE_PCI_BUS_ID_NV. Vedi anche: https://anteru.net/2014/08/01/2483/

+0

Non ho ancora provato questo, ma sembra essere la risposta corretta. Fantastico, grazie per la risposta e dopo quasi 3 anni di attesa. – jcoffland

+0

Mi dispiace che ci sia voluto così tanto tempo, non ho avuto il problema prima :) E grazie per averlo indicato come risposta corretta. – Anteru

+0

'CL_DEVICE_PCI_BUS_ID_NV' funziona per il driver Nvidia su Windows? Sto provando questo in PyOpenCL ma continuo a ricevere un errore che è un valore non valido. – chippies

0

La versione più recente di AMD ha l'estensione cl_device_topology_amd su Linux ,, che aggiunge l'opzione CL_DEVICE_TOPOLOGY_AMD a clGetDeviceInfo(), ma questa è una soluzione piuttosto stretta.

+0

Sì, è necessario coprire anche le schede NVidia. – jcoffland

-1

Ho sviluppato una libreria per fare proprio questo: mantenere le simulazioni OpenCL dall'andare a vicenda.

Lo troverete qui: https://github.com/nbigaouette/oclutils/

E prima enumerare tutte le piattaforme e tutti i dispositivi per ogni piattaforma presente sulla macchina. Seleziona la piattaforma desiderata e sceglierà il miglior dispositivo disponibile. Lo uso sulla mia workstation con 3 schede nvidia: due GTX 580 per i calcoli OpenCL e uno GT 210 per il display. L'esecuzione simultanea di due simulazioni verrà eseguita separatamente sulle due GTX. senza intervento.

C'è anche una bella classe che manterrà due buffer in sincrono: uno sull'host e uno sul dispositivo. Chiamare OpenCL_Array :: Host_to_Device() e OpenCL_Array :: Device_to_Host() rende i trasferimenti avanti e indietro semplici.

Funziona con queste piattaforme:

  • nvidia (GPU solo)
  • AMD (CPU e/o GPU)
  • Intel (solo CPU)
  • mela (CPU e/o GPU)

Nota che non vi permetterà di scegliere quale dispositivo da usare, ma sceglierne uno per voi.Se due istanze di un programma utilizzano la libreria, la conosceranno e non verranno eseguite sullo stesso dispositivo (se ne hai anche, ovviamente). Inoltre, non è in grado, in questo momento, di rilevare se la scheda video viene utilizzata per il display. Ma almeno è un inizio!

+0

A quanto ho capito, la risposta non risolve il problema di associare gli ID dei dispositivi PCI ai dispositivi di elaborazione OpenCL. Stai risolvendo un problema correlato ma non aiuta per quello di cui ho bisogno. Se sbaglio, spiegami. Tieni presente che voglio anche essere in grado di utilizzare CUDA e tenere traccia di quale dispositivo è. – jcoffland

1

Sfortunatamente la risposta che stai cercando non è carina a causa della natura astratta di openCL.

L'unico modo che ho trovato per farlo in modo affidabile è assegnare un carico di lavoro impegnativo all'ID piattaforma + dispositivo in openCL e quindi monitorare l'utilizzo del processo tramite strumenti come ADL di AMD e NVML di Nvidia. Anche le applicazioni mature come cgminer hanno problemi con questo e spesso confondono i carichi di lavoro openCL con le metriche delle carte, tanto che assegnano variabili di configurazione per correggerli manualmente ("gpu-map").

Vorrei che ci fosse una risposta migliore per ora perché sarebbe bello sapere, tramite openCL, quale dispositivo è dietro l'endpoint! Questo potrebbe cambiare in futuro, dato che AMD sta lavorando per aggiungere questo livello ad openCL come sottolineato da arsenm.

0

Sembra che la risposta di Anteru sia corretta, ma solo se si sta eseguendo linux/mac. Dopo alcuni test, sembra che Windows non riconosca queste estensioni specifiche del fornitore. (Ho provato sia su Geforce GTX Titan & ATI Radeon R9)

La mia soluzione per voi è quello di utilizzare la funzione clGetGLContextInfoKHR() (disponibile in quanto OpenCL spec 1.1) con il parametro "CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR", e che farà in modo di ottenere un ID dispositivo openCL che trova la stessa GPU che esegue il rendering.

Vero, questo non ti darà lo slot del bus fisico, ma ciò assicurerà la stessa GPU che esegue il rendering della stessa GPU che calcola!

Inoltre, supponendo che si lavori con schede Nvidia Quadro, quindi può usare wgl_nv_gpu_affinity per garantire l'accesso openGL a una specifica GPU e quindi utilizzare il contesto GL & ottenere dall'ID dispositivo openCL.

Problemi correlati