How to forward JOCL cl_mem to 3-rd party native library via JNI

I would like to experiment with CLBlast by calling it through JNI. Now, the JNI part is not a problem - I’ve already done such stuff. The part that I’m wondering about is that CLBlast’s C functions require cl_mem references. JOCL wraps such pointers into its Java cl_mem objects.

It seems to me that you are using initNative function to do this in JOCLBLAS but I can not find where that function is defined. What is the preferred way for that and where to find the right example to follow?

You’re impatient :wink: (I hope to be able to build the first working version today, likely not later than tomorrow)

First, regarding the initNative function: Compared to JOCL, I changed the code generator a bit, to do these initializations/releases in dedicated methods. These methods are basically responsible for the conversions between the Java Objects and the Native Objects. Which method is actually called there solely depends on the arguments. I hesitated a bit here: I considered to generate more specific names, like initNative_cl_mem, but this would become a bit fiddly when it comes to generating names like initNative_array_of_cl_mems_from_jobjectArray_with_cl_mems (or so…) - and abbreviations (like the Name mangling that is done under the hood) wouldn’t be helpful here either…

However, the cl_mem is a NativePointerObject, which is the base class for all “shallow pointers”, and stores the actual pointer value as a long field that is called nativePointer. The initialization of cl_mem is something that is needed in every JOCL-based library, and thus, is one of the functions that was already moved to the JOCLCommon project:

The initialization of the jfieldID and the jclass are done only once during the initialization, but if you want to do a quick, “dependency-free” local test, you can obtain the jclass and the jfieldID locally, and convert a cl_mem Java Object into a native cl_mem as follows:

jclass cls = env->FindClass("org/jocl/NativePointerObject");
jfieldID field = env->GetFieldID(cls, "nativePointer", "J");
jobject mem = ...; // the cl_mem Java Object
cl_mem mem_native = (cl_mem)env->GetLongField(mem, field); // the native cl_mem object

(hope there’s no typo, but you get the idea)

Seems clear enough.

And if I try to extract it by calling (private) getNativePointer and then call JNI methods by simply forwarding that long, should it work? It seems less messy to me…

Sure, you could also obtain the nativePointer value from Java and simply pass it as a “long”/“jlong” to the JNI function - but as it is private, you’ll have to use some Reflection/setAccessible hacks here as well.

(The fact that it is accessible from JNI is intentional. At least, there are several cases in the JDK where this is done as well).

However, I have to admit (or at least should mention) that the “NativePointerObject” class and the Pointer handling in general is not the smartest and most versatile way of doing things. The “Pointer”/“NativePointerObject” class have been inherited quite a while ago, from JCuda, where I created it many years ago, with the “naive” intention to emulate “void” pointers. There are libraries (e.g. JNA, or what LWJGL does) where the concept of a “Pointer” is mapped to Java much more thoroughly (e.g. one can create a pointer to an arbitrary memory region, or obtain the internal “long” pointer value). Whether or not the Pointer class of JOCL will one day be extended to, for example, expose the “nativePointer” also depends on the development of OpenCL. (For example, currently there is no concept in OpenCL for a “cl_mem containing other cl_mems”. If something like this is introduced, I’ll have to refactor the Pointer class accordingly.