Well, all the objects that are represented as a typedef’ed pointer in C are represented by classes extending the “NativePointerObject” class in JCuda. This base class does not much more than store the native pointer in a long variable, and accordingly, this hack does the same as a simple assignment like
someCUstream.nativePointer = someCudaStream.nativePointer;
but uses reflection to circumvent the private visibility of the ‘nativePointer’ variable:
// XXX Remove this method as soon as the conversion cudaStream_t<->CUstream is supported!
private static CUstream convert(cudaStream_t s)
{
try
{
CUstream stream = new CUstream();
java.lang.reflect.Field field =
jcuda.NativePointerObject.class.getDeclaredField(
"nativePointer");
field.setAccessible(true);
long value = field.getLong(s);
field.setLong(stream, value);
field.setAccessible(false);;
return stream;
}
catch (NoSuchFieldException e)
{
throw new RuntimeException(e);
}
catch (SecurityException e)
{
throw new RuntimeException(e);
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
Note that this is really an ugly hack, and the ‘XXX’ should be taken serious.
It might have been easier to simply offer a
public long getNativePointer()
method and add constructors accepting a ‘long’ value to all theses classes right from the beginning. And in fact, JCuda is such a thin layer around CUDA that the current restriction does not really bring much additional safety. But maybe some type safety and clarity, once the appropriate conversions are all supported: Section 5.26 of the reference manual lists some other legal conversions (CUevent<->cudaEvent etc…) that will also be introduced in the next version. Maybe I’ll publish a dedicated update for this - it should not be such a great effort, because it only affects the Java side and no recompilation of the native libs will be required.
Thanks for pointing this out!
Marco