Search code examples
java-native-interfacenvcc

nvcc generating invalid error compiling JNI code


$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Sep__1_21:08:03_CDT_2017
Cuda compilation tools, release 9.0, V9.0.176

The error is:

MyFile.cu(231): error: expression must have pointer type

The relevant code:

JNIEXPORT jboolean JNICALL Java_MyFile_convergeMatrixCuda (
    JNIEnv *env, jclass clazz, jfloatArray fxnMatrixJ, jfloatArray mulMatrixJ, jfloatArray addMatrixJ, 
    jfloatArray resultsJ, jint numRowsJ, jint numColsJ, jint maxIterations, jfloat epsilonJ)
{
    int     numRows = (int) numRowsJ;
    int     numCols = (int) numColsJ;
    int     maxIter = (int) maxIterations;
    float   epsilon = (float) epsilonJ;
    float   *fxnMatrixH = (*env)->GetFloatArrayElements (env, fxnMatrixJ, NULL);

GetFloatArrayElements returns a float*. Replacing "(*env)->GetFloatArrayElements" with "env->GetFloatArrayElements" gets these errors:

float   *fxnMatrixH = env->GetFloatArrayElements (env, fxnMatrixJ, NULL);

MyFile.cu(231): error: argument of type "JNIEnv *" is incompatible with parameter of type "jfloatArray"

MyFile.cu(231): error: argument of type "jfloatArray" is incompatible with parameter of type "jboolean *"

MyFile.cu(231): error: too many arguments in function call

nvcc does work correctly when compiling non-JNI code


Solution

  • NVidia's documentation states that

    Source files for CUDA applications consist of a mixture of conventional C++ host code, plus GPU device functions.

    (*env)->GetFloatArrayElements (env, fxnMatrixJ, NULL); is the way you'd invoke a JNI function in C. But in C++ it would be env->GetFloatArrayElements(fxnMatrixJ, NULL);