Search code examples
jcuda

JCuda's JCublas2.cublasSdot: failed to use a device Pointer for the result Pointer parameter


In the source code's comments of JCublas2.cublasSdot, it's commented that the 'result' parameter can be a 'host or device pointer'.

 public static int cublasSdot(
    cublasHandle handle, 
    int n, 
    Pointer x, 
    int incx, 
    Pointer y, 
    int incy, 
    Pointer result)/** host or device pointer */
{
    return checkResult(cublasSdotNative(handle, n, x, incx, y, incy, result));
}

However, I can use only a host pointer like Pointer.to(fs) with float[] fs ={0}. If I use a device pointer like 'CUdeviceptr devicePtr = new CUdeviceptr(); JCudaDriver.cuMemAlloc(devicePtr, 100 * Sizeof.FLOAT);', the program crashes with console messages like:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007fed93af2a3, pid=9376, tid=0x0000000000003a7c
# .....

Minimization of data transfer between host and device saves time. How to use device Pointer as the 'result' argument for this method, as well as other JCuda methods with result Pointer commented with /** host or device pointer **/?


Solution

  • CUBLAS can write the results of certain computations (like the dot product) either to host or to device memory. The target memory type has to be set explicitly, using cublasSetPointerMode.

    An example of how this can be used is shown in the JCublas2PointerModes sample.

    It once writes the result of the dot product computation to host memory (which is also the default, when no pointer mode is set explicitly):

    // Set the pointer mode to HOST
    cublasSetPointerMode(handle, CUBLAS_POINTER_MODE_HOST);
    
    // Prepare the pointer for the result in HOST memory
    float hostResult[] = { -1.0f };
    Pointer hostResultPointer = Pointer.to(hostResult);
    
    // Execute the 'dot' function
    cublasSdot(handle, n, deviceData, 1, deviceData, 1, hostResultPointer);
    

    And then changes the pointer mode and calls the function again, this time writing the result to device memory:

    cublasSetPointerMode(handle, CUBLAS_POINTER_MODE_DEVICE);
    
    // Prepare the pointer for the result in DEVICE memory
    Pointer deviceResultPointer = new Pointer();
    cudaMalloc(deviceResultPointer, Sizeof.FLOAT);
    
    // Execute the 'dot' function
    cublasSdot(handle, n, deviceData, 1, deviceData, 1, deviceResultPointer);