Multiple platform implementations in one application?

Is it possible to create 3 opencl contexts within one application, one of which uses the ATI Stream implementation, another with the NVIDIA Cuda implementation, and the third with the Intel OpenCL implementation?

Would I have to dynamically link to different OpenCL libraries? Is there a simple sample or code snippet of this kind of thing that I can look at?

Would there be blocking/synchronization issues with multiple platforms accessing the same devices?

http://www.khronos.org/message_boards/viewtopic.php?f=28&t=2278

already been posted :P…

I’ll post results if I get the dynamic linker working anyways

As promised, here’s a mini-review on how to dynamically link multiple OCL implementations

cl.h has all the function prototypes for OCL which look like this:


extern CL_API_ENTRY cl_int CL_API_CALL
clGetPlatformIDs(cl_uint          /* num_entries */,
                 cl_platform_id * /* platforms */,
                 cl_uint *        /* num_platforms */) CL_API_SUFFIX__VERSION_1_0;

These are “extern” functions, which means their actual definitions are located during linking, which are in the OpenCL.dll library. We need to define a type for these functions, link it using GetProcAddress, and write a non-extern wrapper function which calls the linked function. I created a cpp file and header for these typedefs and linking functions, then include the header from my OCL program.

For each of these prototypes, create a type definition for the function type under a different name:


// function type definition, CL_API_CALL pointer to the function with the parameters uncommented
typedef CL_API_ENTRY cl_int  (CL_API_CALL*clGetPlatformIDsFuncType) (
	cl_uint          num_entries,
	cl_platform_id * platforms,
	cl_uint *        num_platforms) CL_API_SUFFIX__VERSION_1_0;
clGetPlatformIDsFuncType clGetPlatformIDsFunc;

Then link it in a separate function, here is mine:


HMODULE hCLModule;

void LoadOCLLib()
{
	hCLModule = LoadLibrary(TEXT("OpenCL.dll"));

	clGetPlatformIDsFunc=(clGetPlatformIDsFuncType) GetProcAddress(pLibModule,"clGetPlatformIDs");
	// other functions here
}

Finally, to use the same function names as defined in cl.h, create function wrappers like so (function types are the same as the cl.h functions but without extern):


CL_API_ENTRY cl_int CL_API_CALL clGetPlatformIDs(	cl_uint          num_entries,
	cl_platform_id * platforms,
	cl_uint *        num_platforms)
{ 
	return clGetPlatformIDsFunc(num_entries, platforms, num_platforms);
}

Then use LoadOCLLib() before using any cl API functions and create an UnloadOCLLib() using FreeLibrary(hCLModule) to unload on program exit. Take OpenCL.lib out of your linker and you’re set to dynamically link.

Now will rename OpenCL.dll’s that i have to OpenCL_Intel.dll, OpenCL_ATI.dll, OpenCL_NV.dll and link them all separately.

Any feedback is much appreciated also!

I didn’t mention before, this is only for windows.

Also, trying to link against different OpenCL implementations, but having some issues with how this is to be done.

I have 3 OpenCL.lib files, one from the Intel sdk, another from ATI sdk, and last from NVIDIA sdk, but only one OpenCL.dll. How exactly do I use one specific library in run-time? do i have to compile separate dlls for each? What is the relation between all these files?

Is all this really necessary? Can’t we just call clGetPlatformIDs and then clCreateContext once for each platform found?

I was under the impression that if you do not dynamically link to another library, you can only use a single implementation. I have tried to do multiple platforms using clGetPlatformIDs, to no avail–whichever vendor’s OpenCL.lib i link to during compilation appears as the only available platform. Can anyone verify if this is the only way to get multiple platforms available?

The other nice thing about “wrapping” all the functions dynamically is that I can profile individual API calls and provide more debug information.

Still haven’t figured out how to link to multiple different implementations, however. the vendor’s OpenCL.lib files are static libraries that are used in compile time, and the OpenCL.dll is the only dynamic library i can link to in run-time.

Don’t all vendors use the OpenCL ICD? You should be able to use the OpenCL.lib from any vendor and then query what platforms are available. It should show one platform for each of the vendors that you have installed in your system.

In other words, what ibbles said.

:stuck_out_tongue: looking into this more after reading responses, the dynamic functions were definitely unnecessary for multiple platforms. I’m keeping it for the uses mentioned above though.

I’m still getting errors with more than 1 platform, the second platform id is crashing my application; I thought this was because I was statically linking to a specific vendor’s library and trying to access a different platform, but since that’s not the case, i’m suspecting that it’s the implementation itself that’s giving me issues (when i call clGetPlatformInfo(…) on the Intel platform, I get a memory access violation with no other debug output). I’ll play with it a bit more and try to file a bug if necessary.

Thanks for clearing that up for me ibbles and david!