nvcc generating invalid error compiling JNI code - java-native-interface

$ 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

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);

Related

Cannot compile `enqueue_kernel` on opencl 2.1 NEO device

I have the following code on the device Intel(R) Gen9 HD Graphics NEO -- OpenCL 2.1 NEO :
__kernel void update(
const __global uint* positions,
const __global float3* offsets,
const int size,
__global int* cost
) {
int global_id = get_global_id(0);
if (global_id >= size) {
return;
}
int3 update_index = position_from_index(grid_centroid_positions[global_id], SIZE) -
offset_grid;
ndrange_t ndrange = ndrange_3d(size, size, size);
enqueue_kernel(get_default_queue(), ndrange,
^{update_surrouding_cells(offsets, global_id, update_index, update_edge_size, size, cost)});
}
But i get the following compiler error:
6:158:5: error: use of undeclared identifier 'ndrange_t'
ndrange_t ndrange = ndrange_3d(size, size, size);
^
6:161:5: error: implicit declaration of function 'enqueue_kernel' is invalid in OpenCL
enqueue_kernel(get_default_queue(), ndrange,
^
6:161:20: error: implicit declaration of function 'get_default_queue' is invalid in OpenCL
enqueue_kernel(get_default_queue(), ndrange,
^
6:162:163: error: expected ';' after expression
^{update_surrouding_cells(offsets, global_id, update_index, update_edge_size, size, cost)});
^
;
6:161:41: error: use of undeclared identifier 'ndrange'
enqueue_kernel(get_default_queue(), ndrange,
Compilation options are as follows:
-I "/home/development/cl" -g
-D SIZE=256
The device supports opencl 2.1, yet when compiling it seems none of the things for enqueue_kernel exist. Do i need a special extension or something? I am reading the spec here, but it doesn't seem to say anything about actually compiling the examples with dynamic parallelism.
When compiling, it is not just the version of the device that is important. The compiled version of cl code is passed into the compilation options. AKA the compilation options when compiling the opencl program (kernel code) should include:
-cl-std=CL2.0
Or the specific standard that you are looking for.

Error in Parsing functions Calling Conventions using Libtooling ASTFrontendAction

I'm using Libtooling to parse Windows SDK headers but there is a problem in getting functions calling conventions, The libtooling always return __cdell for WINAPI or __stdcall calling convention which is the defualt calling convention of Win32 API's.
This is an input example
VOID
__stdcall
TestFunction (_In_ BOOLEAN is_valid);
This is my Function Visitor function of my RecursiveASTVisitor
virtual bool VisitFunctionDecl(clang::FunctionDecl *func)
{
// ...
if (m_AstContext->getSourceManager().isInMainFile(func->getLocation()))
{
if (func->hasAttrs())
{
auto stdcall = func->hasAttr<StdCallAttr>(); // always return False
}
const clang::FunctionProtoType * prototype = func->getType()->getAs<FunctionProtoType>();
if (prototype)
{
auto stdcall = prototype->hasAttr(attr::Kind::StdCall); // always return False
errs() << clang::FunctionType::getNameForCallConv(prototype->getCallConv()).str() << " "; // always return cdecl
}
func->dumpColor(); // But there is __attribute__((stdcall)) in dumped output!
}
// ...
}
And finally output of func->dumpColor(); for input example!
^
FunctionDecl 0x218c95bb6f0 <C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\um\winnt.h:430:14, C:\ExampleInput.h:18:36> col:1 TestFunction 'void (BOOLEAN) __attribute__((stdcall))':'void (BOOLEAN)'
`-ParmVarDecl 0x218c95bb5c0 <col:20, col:28> col:28 is_valid 'BOOLEAN':'unsigned char'
I ran it with/without this options too, for compatibility reasons but no difference at all :-(
-fms-compatibility
-fms-extensions
-fms-compatibility-version=19
Any idea?
Update
I found the problem, It's because of defualt compile config of #Clang. It's 64-bit (in 64-bit toolchain), And it doesn't work with __stdcall in 64-bit mode
If I use the 32-bit version (or -m32 option) then it will works correctly
Any idea why it happens in 64-bit mode?

exception "error: expected ';' after top level declarator" from ndk-build

OS:macOS 10.13.3
IDE:Android studio 1.5.1
g++:4.2.1
scene:
I wanna develop with NDK using c++.When I define a c++ class to build,the Gradle Console return an error like below:
> src/main/jni/addcomputer.c:23:12: error: expected ';' after top level declarator
jclass Test{
^
;
1 error generated.
make: *** [build/intermediates/ndk/obj/local/arm64-v8a/objs/addcomputer/addcomputer.o] Error 1
:app:ndkBuild FAILED
and my .cpp like below:
#include "com_BTC_ui_JNI.h"
//......
JNIEXPORT jstring JNICALL
Java_com_BTC_ui_JNI_getString(JNIEnv *env, jobject instance)
{
return (*env)->NewStringUTF(env, "mytest-sample-x");
}
JNIEXPORT jint JNICALL
Java_com_BTC_ui_JNI_plus(JNIEnv *env, jobject instance, jint a, jint b)
{
return a+b;
}
jclass Test{//this is where the error occur
private:
jint mytest;
};
When I open a terminal to build a .cpp file which contain a class define,it return a same error.I cannot find the reason.Anyone can help me?
The error has gone , I just fixed some basic problem.Although the compile process is ok, the running time has occur another error of cannot find implementation of native method.I guess that's caused by compiler.Now I should close this question.Thanks all for focusing this question.

Proper array type for execvp

I'm having difficulty figuring out exactly how to use execvp in C++. I'm not having any issues getting my code to work, but I'm specifically trying to figure out how to do it in a way that doesn't make the compiler complain.
I have looked at various questions on Stack Overflow and other resources, but I have been unable to find a solution that results in zero warnings from the compiler.
Consider the following C++ program, which prints its own source code:
#include <unistd.h>
int main(int argc, char *argv[])
{
char *args[3];
args[0] = "/bin/cat";
args[1] = __FILE__;
args[2] = NULL;
execvp(args[0], args);
return 0;
}
(I know that the return 0 should never be reached; I'm not so concerned with error handling in this question.)
When I compile it, the compiler emits two warnings:
$ g++ -Wall exec.cpp
exec.cpp: In function ‘int main(int, char**)’:
exec.cpp:6:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
args[0] = "/bin/cat";
^~~~~~~~~~
exec.cpp:7:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
args[1] = __FILE__;
^~~~~~~~
The compiled program successfully prints the source file. However, I'd really like to get the program to compile without any warnings. Since the compiler doesn't like that the string literals are being assigned to a pointer of type char* (not const char*), I suppose it would make sense to mark args as an array of const char* pointers. Consider this version of the program:
#include <unistd.h>
int main(int argc, char *argv[])
{
const char *args[3];
args[0] = "/bin/cat";
args[1] = __FILE__;
args[2] = NULL;
execvp(args[0], args);
return 0;
}
I would think that this program should compile and run with no warnings or errors, but the compiler does emit an error:
$ g++ -Wall exec.cpp
exec.cpp: In function ‘int main(int, char**)’:
exec.cpp:10:25: error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]
execvp(args[0], args);
^
In file included from exec.cpp:1:0:
/usr/include/unistd.h:581:12: note: initializing argument 2 of ‘int execvp(const char*, char* const*)’
extern int execvp (const char *__file, char *const __argv[])
^~~~~~
I also tried declaring args as char const *args[3], but the compiler emits the same error. The only way I am able to get it to compile with no warnings is by casting args in the call to execvp:
const char *args[3];
...
execvp(args[0], (char* const*)args);
This version compiles without warnings and runs successfully. However, I prefer to avoid casting when I can, because it makes it harder for me to reason about the type conversions going on.
Are one of the two working ways that I have shown above the best way to create an argument array to pass to execvp, or is there a better way that is clear and does not result in the compiler complaining?
I am using two different compilers - g++ 6.2.0 for native compilation on Ubuntu x86_64, and g++ 4.5.3 for cross compilation to an ARM platform.
Edit:
I do not believe that my question is a duplicate of this question. I understand the different effects of using const in different ways with respect to a char* variable. I am specifically asking which type is conventionally used for execvp calls, which is not answered by the linked question.

Why does GCC accept convertion from 'const char *' to 'char *' on std::strrchr() returned value?

While adding a detailed answer, I noticed that GCC does not warn the following code while Visual C++ complains.
#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = std::strrchr (CONSTSTR, '/');
// cannot convert from 'const char *' to 'char *'
*nonconst++ = 'B';
*nonconst++ = 'A';
*nonconst++ = 'D';
}
I have tested three different GCC versions:
4.1.2 on Red Hat (Linux)
4.5.3 on Cygwin (Windows)
4.7.2 on MinGW (Windows)
But all these three GCC versions compiled this code without any warning/error:
> g++ -Wall -Wextra -pedantic -ansi test.cpp && echo "success"
success
While Microsoft compiler v16 complains:
> cl -c test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(5) : error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'
Conversion loses qualifiers
(from my office, I do not have access to ideone/codepad/... to test it using other versions)
As this code uses std::strrchr, I do not understand why GCC does not complain.
const char* strrchr( const char* str, int ch ); //the code above uses this declaration
char* strrchr( char* str, int ch );
My question: Why does g++ successfully compile this code without any warning/error? Is it a bug? a feature? a miss-configuration on my side?
Actually your g++ does not accept the conversion from 'const char *' to 'char *', it's just that on your version std::strrchr() returns a char* (incorrectly, instead of a const char*).
To verify the first part of my statement, try to compile the following on your GCC versions, I predict that all will correctly issue an error:
int main()
{
const char* p = "foo";
char* q = p; // error, invalid conversion from 'const char*' to 'char*'
}
Now for the second part, I tried to compile the following minimal code, whose actual aim is to trigger an error in order to list the declared overloads of std::strrchr:
#include <cstring>
void (*p)() = &std::strrchr; // error here, with "candidates are: ..."
int main() {}
Well, with gcc 4.7.2 the message shows the expected "all non-const" and "all const" overloads:
prog.cpp:2:21: error: no matches converting function ‘strrchr’ to type ‘void (*)()’
In file included from /usr/include/c++/4.7/cstring:44:0,
from prog.cpp:1:
/usr/include/string.h:249:1: error: candidates are: char* strrchr(char*, int)
/usr/include/string.h:255:1: error: const char* strrchr(const char*, int)
i.e. the prototypes
char* strrchr( char* , int );
const char* strrchr( const char* , int ); // Question's code will use this one (-> error)
But with gcc 4.3.2 the message was different:
prog.cpp:2: error: no matches converting function 'strrchr' to type 'void (*)()'
/usr/include/string.h:171: error: candidates are: char* strrchr(const char*, int)
/usr/include/c++/4.3/cstring:118: error: char* std::strrchr(char*, int)
i.e. the overloads were
char* strrchr( const char* , int ); // Question's code would use this one (-> no error...)
char* strrchr( char* , int );
(the second one is the C++ non-const overload; but the first one is the old C version, and should instead be the C++ const overload).
This it seems that the headers (<cstring> and/or <string.h>) were incorrect on this version, and I suspect that it's the same on yours.
Edit: I found for example a discussion, a blog post and a bug report (for strchr not strrchr but it's the same story).