my target is to setup an OpenCL context and present to result to an OpenGL context. Therefore, I successfully setup my OpenCL context from the OpenGL context using GLUT windowing system.
This version runs very well by using a single GPU.
Now I want to setup my OpenCL context with multiple GPUs. Unfortunately, the changes are not straight forward. After some investigation into the AMD APP documentation, I found an interesting article in the document "AMD_OpenCL_Programming_User_Guide.pdf" of AMD APP SDK 3.0 BETA.
There, in the appendix chapter E.1.2, is exactly the explanation how to do a multiple GPU environment by creating CL context from a GL context.
First I removed all my GLUT function calls and setup a windowing system by using Win32 API.
I did all the points are mentioned in the document. At the end I got again a single GPU system running as before except for my windowing system is now managed by Win32 API and not GLUT anymore.
So, I wondering about the clCreateContext call.
// Create OpenCL context from device's id
context = clCreateContext(properties, 1, &interopDevice, 0, 0, &status);
Actually, by a Multi GPU system I expected here to setup the OpenCL context for more than 1 GPU like this (in my case a have 3 AMD GPUs)
context = clCreateContext(properties, 3, &myGPUDevices, 0, 0, &status);
So, myGPUDevices points now to an array of 3 valid created GPU devices:
cl_device_id *myGPUDevices = new cl_device_id;
I did a lot of work to find out how to call it for a multi GPU system, but finally I could not found a solution. I understand that only one GPU can has a GL context, but inside an OpenCL context I want to run my processing on 3 GPUs, combine the result from each command queue of each device in the CL context and present it to GL context. Therefore, I need to setup the CL context at the beginning with GL interoperability too.
Has anyone an idea what is my error in reasoning here? Is the sample in the document running in a CL context on multiple GPUs?
Catalyst Version: 15.7.1
OpenCL 1.2 or 2.0
AMD APP SDK 2.9.1 or 3.0 BETA
AMD Radeon R9 295 X2
AMD Radeon R9 390
Thank you in advance,
Sorry for my late reply,
Yes I also checked with CL_DEVICES_FOR_GL_CONTEXT_KHR. In that case I got only one GPU device and the CPU in the OCL context. The other GPU devices were not present. I think that here the "binding" to the OCL context of the OpenGL context is just exclusive for one GPU only .
My impression is that this usecase is not really possible to have multiple GPU devices in a OCL context associate with a OGL context at a time in one thread. Perhaps a multi-thread context could be a solution to separate OCL context and OGL context in different threads. But how to setup such a multi-thread context and how should the data be exchanged between them is not clear for me.
My current workaround uses the CPU in between of the OCL and OGL context. Unfortunately, I have some frame drops due to data transfer via PCIe.
So, what I don't understand is the part in the "AMD_OpenCL_Programming_User_Guide.pdf" (Appendix chapter E.1.2). Here is exactely my usecase described, but actually I cannot confirm that this scenario can work. It would be nice to have a comment of one of the authors of this document here?
You can share resources with OpenGL only with single device which run that OpenGL context. Otherwise it require copy between GPU which renders OpenGL and GPU which is running OpenCL tasks. So CL_DEVICES_FOR_GL_CONTEXT_KHR return only single GPU which is "optimal" device where this copy is not needed.
Actually, I think it's useless to even try to get an OpenCL context for any other GL device - what kind of "interoperability" can be there? How do you think contexts should access common resources (images, buffers, etc.) if they worked with VRAM on separate video devices? - IMHO, the GL/CL contexts will only work in pairs for each separate GPU (To be honest, I don't know what is possible in this regard for true multi-GPU rendering mode - "crossfire", etc.). Anyway, I played a lot with several GPUs (OpenGL/OpenCL interoperability) in Windows environment a year ago - there were a lot of problems, and I suppose, not much has changed since then. The most suitable way to get working OpenGL/OpenCL context pairs for your GPUs was to enumerate your GPUs with EnumDisplayDevices (filtering mirror/non-active) and then repeat this procedure for each of found: CreateDC, create OpenGL context from that DC, and, finally, create OpenCL context. There is no need to bother with window positions, though, you should still enable all GPUs in Windows and expand your desktop over all of them. Awful, I know, but it seems there is no other way here, sorry. My old post: OpenGL-OpenCL Interoperability