Looking over JOCL
Posted by jcpalmer on May 21, 2010; 10:52pm
URL: https://forum.jogamp.org/Looking-over-JOCL-tp835533.html
Michael,
I wanted to checkout what you have done for JOCL. The whole JogAmp site looks very professionally done (get rid of the under construction thing). Integrating everything but the actual media/repositories into one site works well. Similar color schemes between Nabble & github was fortuitous. I did not even realize for a minute I left the site. I have a mouse button for back & one on the browser, so who needs one on the page.
With 2 young guys working on different implementations of something I need, I cannot afford to skip due diligence in case one or the other loses interest(usually due to career or women). The metric I am using to evaluate JOCL IS NOT based on call overhead, since this is not like OpenGL where you might need to do 1000 calls to produce 1 frame. The metric is how fast could I switch between them.
I do not actually need a distribution to do an evaluation, after writing my own oo wrappers on top of OpenCL4Java, and almost doing a conversion to JavaCL. Looking at the latest source, this looks like it handles all my needs as is.
The major difference of JOCL is the same difference between my home grown wrappers and JavaCL. That is how big a role is played by the "command queue" class. You and I gave it a big role with it's methods being passed memory & kernel objects. JavaCL gave it's memory & kernel objects those methods with the command queue being passed. This is pretty much just different sides of the same coin. JavaCL has methods to wait for events both in it's CLEvent & CLQueue.
One difference I have between both is that my am multi-level. I had the general use classes with a sub-set of only the methods I use, and a higher level that integrated the lower level with java.util.concurrent.ThreadPoolExecutor. The application only calls the higher level (just 3 classes: ContextPool, Context, & OpenCLCapabilities which actually instances the single device Context[] for ContextPool). The higher level allows for multi-GPU's. You state how many kernel & mem objects you are going to need in the ContextPool constructor, and only reference them by index in methods, to avoid touching of the lower level by the application. This higher level would be tough to make general use without having a wrapper for every method in the lower level. I just do the ones I need.
The reason I mentioned the high level is it is key to switching between the 2. Only 3 classes need to change. In fact, I did a conversion to JavaCL in about 4 days. I still felt insecure not having source I could modify easily, so I took another day and re-worked my lower level wrappers to emulate JavaCL. I can go back and forth just switching 3 import statements & a jar. I could probably emulate a big part of JOCL at the same time, made easier with the class names for the "command queue" being different.
I did see that there are no finalizers in classes ensuring OpenCL resources are cleaned up, should the developer fail to do so. This might be by design, because Garbage collection is only concerned about it's own memory. However, OpenCL release calls return an error if they are attempted more than once (actual after the ref count == 0). CLProgram does have a member that indicates it has been released, but it not used to stop from attempting release more than once. It kind of confuses me that CLProgram.release calls the release of CLKernels that are based on it. In truth, I do not think it was even worth the effort of having both Program & Kernel in the spec.
Reccommend to eliminate the tiny interface CLResource, unless there is a class that implements CLResource that is NOT a subclass of CLObject. Add to CLObject:
protected volatile boolean releasedAlready; // keep release from getting exception if attempted more than once
@Override
public void finalize(){ release(); }
public void release(){} // placeholder for those CLObjects which do not require releasing, e.g. CLDevice
In the case of CLKernel have:
@Override
public void release(){
if (!releasedAlready){
int ret = cl.clReleaseKernel(ID);
program.onKernelReleased(this);
if(ret != CL.CL_SUCCESS) {
throw newException(ret, "can not release "+this);
}
}
}
You could even say CLObject implements CLResource, if you wanted to keep it. That is really the only thing that jumps out. Args could have JavaDoc entries, but having that is not going to allow someone to use this without reading the OpenCL spec. Good Job!
Jeff