2013-07-30 21 views
9

Mam problemy z używaniem wielu procesorów graficznych z interakcją OpenCL/OpenGL. Próbuję napisać aplikację, która oddaje wynik intensywnych obliczeń. Na koniec będzie to powodować problem optymalizacyjny, a następnie, na podstawie wyniku, wyrenderować coś na ekranie. Jako przypadek testowy, zaczynam od kodu przykładowego symulacji cząstek z tego kursu: http://web.engr.oregonstate.edu/~mjb/sig13/Interakcja OpenCL/OpenGL z wieloma procesorami GPU

Kod przykładowy tworzy i kontekst OpenGL, następnie tworzy kontekst OpenCL, który współużytkuje stan, używając rozszerzenia cl_khr_gl_sharing. Wszystko działa poprawnie, gdy korzystam z pojedynczego procesora graficznego. Tworzenie kontekstu wygląda następująco:

3. create an opencl context based on the opengl context: 
    cl_context_properties props[ ] = 
    { 
     CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), 
     CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(), 
     CL_CONTEXT_PLATFORM, (cl_context_properties) Platform, 
     0 
    }; 

    cl_context Context = clCreateContext(props, 1, Device, NULL, NULL, &status); 
    if(status != CL_SUCCESS) 
    { 
     PrintCLError(status, "clCreateContext: "); 
     exit(1); 
    } 

Później przykład tworzy współdzielone bufory CL/GL z clCreateFromGLBuffer.

Teraz chciałbym stworzyć kontekst z dwoma urządzeniami GPU:

cl_context Context = clCreateContext(props, 2, Device, NULL, NULL, &status); 

Mam pomyślnie otwarty urządzeń, a może zapytać, że obaj cl_khr_gl_sharing wsparcia, a zarówno praca indywidualnie. Jednak podczas próby utworzenia kontekstu jak wyżej, mam

CL_INVALID_OPERATION 

co oznacza kod błędu dodana przez rozszerzenie cl_khr_gl_sharing. W opisie przedłużacza (powiązany powyżej) mówi

  • CL_INVALID_OPERATION jeśli kontekst lub grupa akcji obiekt został określona dla jednego z CGL, EGL, GLX lub WGL i każdy z następujących warunkach pomieścić:

    • implementacja OpenGL nie obsługuje window-system wiążącej API dla których kontekst lub udział Grupy obiektów było określony.
    • Ponad jedna z CL_CGL_SHAREGROUP_KHR atrybutów CL_EGL_DISPLAY_KHR, CL_GLX_DISPLAY_KHR i CL_WGL_HDC_KHR jest ustawiona na wartość inną niż domyślna.
    • Oba atrybuty CL_CGL_SHAREGROUP_KHR i CL_GL_CONTEXT_KHR są ustawione na wartości inne niż domyślne.
    • Każde z urządzeń określonych w argumentacji nie można wsparcia obiekty OpenCL, które mają wspólną składnicę danych obiektu OpenGL , jak to opisano w rozdziale 9.12.”

opis ten nie Wydaje się pasować do każdego z moich przypadków, czy nie jest możliwe współdziałanie OpenCL/OpenGL z wieloma procesorami graficznymi, czy jest to, że mam heterogeniczny sprzęt? Wydrukowałem kilka parametrów z moich wyliczonych urządzeń. Procesory graficzne, które mogłem zdobyć.

PlatformID: 18483216 
Num Devices: 2 

-------- Device 00 --------- 
CL_DEVICE_NAME: GeForce GTX 285 
CL_DEVICE_VENDOR: NVIDIA Corporation 
CL_DEVICE_VERSION: OpenCL 1.0 CUDA 
CL_DRIVER_VERSION: 304.88 
CL_DEVICE_MAX_COMPUTE_UNITS: 30 
CL_DEVICE_MAX_CLOCK_FREQUENCY: 1476 
CL_DEVICE_TYPE: CL_DEVICE_TYPE_GPU 

-------- Device 01 --------- 
CL_DEVICE_NAME: Quadro FX 580 
CL_DEVICE_VENDOR: NVIDIA Corporation 
CL_DEVICE_VERSION: OpenCL 1.0 CUDA 
CL_DRIVER_VERSION: 304.88 
CL_DEVICE_MAX_COMPUTE_UNITS: 4 
CL_DEVICE_MAX_CLOCK_FREQUENCY: 1125 
CL_DEVICE_TYPE: CL_DEVICE_TYPE_GPU 

cl_khr_gl_sharing is supported on dev 0. 
cl_khr_gl_sharing is supported on dev 1. 

Zwróć uwagę, że jeśli utworzę kontekst bez części współdziałania (tak, że tablica rekwizytów wygląda jak poniżej), to z powodzeniem tworzy kontekst, ale oczywiście nie może współużytkować buforów po stronie OpenGL aplikacji.

cl_context_properties props[ ] = 
{ 
    CL_CONTEXT_PLATFORM, (cl_context_properties) Platform, 
    0 
}; 
+0

Niekoniecznie z powodu twojego problemu, ale gdybym był twoim, najpierw zaktualizowałbym moje sterowniki ... Są one dość stare, na przykład obecna wersja sterownika dla Linuxa 64-bitowego dla twojego GTX 285 to 319.32 (v 325,08 w wersji beta). – CaptainObvious

+0

Czy twój kontekst OpenCL zawiera oba procesory graficzne? Trzeba to zrobić, aby implementacja przenosiła dane między dwoma procesorami graficznymi, aby wyniki z jednego GPU mogły być renderowane przez drugi. – chippies

+0

@chippies Otrzymuję błąd podczas próby utworzenia kontekstu OpenCL. W kodzie tam na górze, Urządzenie jest tablicą zawierającą oba GPU. – matth

Odpowiedz

1

Kiedy nazywają te dwie linie:

CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),

rozmowy muszą pochodzić z wewnątrz nowego wątku z nowym kontekście OpenGL. Zwykle można powiązać tylko jeden kontekst OpenCL z jednym kontekstem OpenGL dla jednego urządzenia naraz na wątek.

+0

Dzięki za poświęcenie czasu na odpowiedź. Nie używałem OpenCL od jakiegoś czasu i nie mam łatwego sposobu, aby to przetestować, ale twoja odpowiedź brzmi wiarygodnie, więc po prostu to przyjmuję. – matth

2

kilku powiązanych pytania i przykłady

  • Oto related example czystego podejścia OpenGL do wspólnego przetwarzania pomiędzy wieloma procesorami graficznymi
  • Innym czysty OpenGL mulitiple gpu pytanie
  • producer/consumer example użyciu wielu GPU zobacz plik źródłowy producenta dla wywołań, aby uzyskać aktualny (wyszukuje okna, ale przepływ w chory może być podobny gdzie indziej). Zobacz glContext szczegółowe informacje

    bool stageProducer::preExecution() 
    { 
     if(!glContext::getInstance().makeCurrent(_rc)) 
     { 
      window::getInstance().messageBoxWithLastError("wglMakeCurrent"); 
      return false; 
     } 
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fboID); 
     return true; 
    } 

OpenCL specyficzny, ale istotne dla tej kwestii:

„Jeśli enqueue zapisie do bufora na queueA (deviceA) następnie OpenCL będzie używać tego urządzenia do zrób to, ale jeśli użyjesz bufora w kolejce B (urządzenie B) w tym samym kontekście, OpenCL rozpozna, że ​​urządzenie A ma najnowsze dane i przeniesie je do urządzenia B, zanim je wykorzystasz. użyj zdarzeń, aby upewnić się, że żadne dwa urządzenia nie próbują uzyskać dostępu do tego samego obiektu pamięci w tym samym czasie, OpenCL w chory upewnij się, że każde użycie obiektu pamięci zawiera najnowsze dane, niezależnie od tego, które urządzenie go ostatnio używało. "

Zakładam, że kiedy wyjmujesz OpenGL z pamięci dzielenia równań między procesami gpus działa zgodnie z oczekiwaniami?

Powiązane problemy