Hello
Yes, I mentioned this in this post, referring to a question that I posted a while ago in the AMD forums: Detecting which functions are available depending ... - AMD Community
As JOCL is a 1:1 mapping of OpenCL, there will be no automatic fallback. An OpenCL program that uses an OpenCL 1.2 platform and tries to call clCreateCommandQueueWithProperties
will crash painfully, and a JOCL program that uses an OpenCL 1.2 platform and tries to call clCreateCommandQueueWithProperties
will crash painfully.
The above mentioned post may already have made clear that I also think that this behavior is … -_- well, not satisfactory. On the one hand, the user may always cause nasty crashes (in doubt, by writing to invalid memory locations in kernels - something that can never be checked on Java side). On the other hand, simply calling a certain function should not cause such an unpredicable behavior. I mean, seriously, how should something like this be tested? You would ALWAYS have to run tests with ALL possible platform versions, which is impossible considering that you can’t install an OpenCL 1.0 and OpenCL 1.1 driver (from the same vendor) in parallel…
I can’t imagine a reasonable solution for this - neither for OpenCL in general, nor for JOCL. The problem could, to some extent, be alleviated, by introducing an abstraction layer or utility functions (like the Utilities that I intend to update and publish at GitHub ASAP). But regardless of whether such a fallback was supported by „pure“ JOCL, or by an abstraction layer: The real problem comes up when the functions become „incompatible“ in any way. What if someone wants to clCreateCommandQueueWithProperties
with Properties that are not offered in the original clCreateCommandQueue
call? And this is one of the easier examples: When „new“ functions really do something completely new (like the pipes and SVM in CL 2.0), then any „fallback“ would basically boil down to „trying to emulate OpenCL 2.0 by using OpenCL 1.0 calls“…
So quoting from the answer from the AMD forum:
just check versin
(sic!)
I think there are different possible levels of granularity for this, depending on the exact application pattern. Roughly speaking: One could either do version checks „inlined“, on the fly, for „minor differences“, at places that are not time critical:
void setUp()
{
// Query platform, devices etc...
// Create context...
cl_context context = ...
if (queryVersion(context) >= 2.0)
{
clCreateCommandQueueWithProperties(...);
}
else
{
clCreateCommandQueue(...);
}
}
But of course, such version queries are NOT suitable for the „inner core“ of time-critical functions:
void calledMillionsOfTimes(cl_mem mem)
{
// NOT FEASIBLE when this is calledMillionsOfTimes
cl_context context = queryContrext(mem);
cl_device devices[] = queryDevices(context);
cl_platform platform = queryPlatform(devices);
if (queryVersion(platform) >= 2.0)
{
doSomeStuffWithSVM(mem);
}
else
{
doSomeStuffWithoutSVM(mem);
}
}
In these cases, one would probably „pull up“ the version check
void calledOnlyOnce(cl_mem mem)
{
// OK when this is calledOnlyOnce
cl_context context = queryContrext(mem);
cl_device devices[] = queryDevices(context);
cl_platform platform = queryPlatform(devices);
if (queryVersion(platform) >= 2.0)
{
for (int i=0; i<1000000; i++) doSomeStuffWithSVM(mem);
}
else
{
for (int i=0; i<1000000; i++) doSomeStuffWithoutSVM(mem);
}
}
But I also think that the goal of having platform-agnostic programs becomes far harder to achieve when not only the platforms, but also their supported OpenCL versions have expected to be different…
If anybody has ideas of how this problem could be tackled (again: it does not refer to JOCL, but to OpenCL in general), I’d be happy to hear about it.
bye
Marco