So the problem is the ‘cuMemAllocManaged’ require the ‘CUdeviceptr ptr’ and I can’t make relation between ‘CUdeviceptr ptr’ and ‘double CPUarray[]’. This relation I can make in ‘cuMemcpyHtoD’ but the sense of Unified Memory is the absence of ‘cuMemcpyHtoD’.
Another way is the usage ‘Pointer.to(CPUarray)’ but ‘cuMemAllocManaged’ pointer should be of ‘CUdeviceptr’ type.
First of all, I have to mention that I have not yet really used the Unified Memory functionality (because it is relatively new, and my hardware is … rather old -_- )
But in general, there is no real “relation” between the memory that is allocated with CUDA, and a Java array. When you allocate managed memory with
then you simply cannot access this as a java double[] array: The managed memory is handled by CUDA. But a Java array is managed by the Java Virtual Machine (JVM).
However, you can* access this memory from Java: You can call Pointer#getByteBuffer on this pointer. This ByteBuffer can then be viewn as a DoubleBuffer, and with this buffer, you can read/write data from/to the managed memory from Java:
cuMemAllocManaged(ptr, CPUarray.length*Sizeof.DOUBLE, 0);
ByteBuffer bb = ptr.toByteBuffer(0, CPUarray.length*Sizeof.DOUBLE);
DoubleBuffer db = bb.order(ByteOrder.nativeOrder()).asDoubleBuffer();
db.put(index, 123.456); // Write to unified memory
double d = db.get(index); // Read from unified memory
I know that this somewhat limits the application scope: When a Java method creates or expects a double[] array, then this can not easily be replaced with CUDA managed memory. But there is no way to circumvent that, because the fact that Java arrays always have to be handled solely by the JVM can not be changed…
*: Again, I could not test this myself, but it should work this way…