-
Notifications
You must be signed in to change notification settings - Fork 751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to create a function pointer and call it? #833
Comments
Are you saying that you would like to call that function using your native platform's C/C++ compiler? |
I updated the question. |
Since you're using LLVM, you might as well keep using that. There is an example of function calling here: |
I have read this article and tried to follow it to try this lib, however I have to (I don't know other ways) to use It seems I thought converting pointer to a function pointer is quite often in C. |
I see, you're talking about the limitation of LLVM discussed on this page? |
I created function wrapper like this: public class Fn extends FunctionPointer {
/** Pointer cast constructor. Invokes {@link Pointer#Pointer(Pointer)}. */
public Fn(Pointer p) { super(p); }
public Fn(Long addr) {
this.address = addr;
}
//protected Fn() { allocate(); }
//private native void allocate();
public native int call( int a,
int b);
} call it with and get error
The function is compiled in LLVM's JIT at run time. I think I cannot use c++ compiler? Also I didn't find ORC JIT in javacpp-presets LLVM. It seems |
That just means you didn't run the Builder. Check the README.md file for some instructions.
That seems to be part of the C API so it shouldn't be too hard to add. |
Thanks, I might try to add OrcBindings.h into llvm |
There were other header files missing, so I've added all of them in one fell swoop. Please give it a try with the snapshots: http://bytedeco.org/builds/ In this case though, for your custom function pointer, you'll still need use JavaCPP to generate some JNI and use your C++ compiler to build a native library, either manually or via JavaCPP. Let me know if you're having any issues with that. |
Hi saudet I got trouble to try the 1.5.3 snapshot. However I got following error.
Looks like it cannot find maven-metadata?
|
You'll need to update to OpenCV 4.2.0.
|
I changed to
In fact I try to add llvm dependency like
Running same command, but got similar error
|
Make sure that the snapshot repository is in your settings: http://bytedeco.org/builds/ |
Also, the Nexus server of Sonatype OSS is configured to remove snapshot artifacts after 3 days, so they might have been only temporarily missing. |
Version 1.5.3 has been released, so please try again with those artifacts: |
JNA uses libffi to do that, so we could do the same with JavaCPP. |
/cc @yukoba |
JNA has quite an overhead. I've created a small library which combines LLVM compilation and native function invocation via JNR. This makes all the calls type-safe and reduces the overhead since JNR is better than JNA. There is a small benchmark based on @yukoba pull-request. It suggests for small matrices (20x20) the matrix multiplication via LLVM+Polly+JNR is faster than calling MKL with its JIT optimizer. |
@Neiko2002 Thanks for testing! Have you also tried with "just" libffi? BTW, it looks like https://github.com/WhenPerformanceMatters/llvm-jnr isn't accessible publicly. |
My fault, it is now public. What do you mean with just libffi? JNR is based on jffi which is a JNI binding for the libffi. |
Looks good, thanks! MKL is notably not super fast on AMD processors, so you might want to run that on an Intel box as well, where it's most likely going to the fastest even for small matrices. Another thing, apparently MKL's JIT doesn't use threads so setting the number of threads probably doesn't do anything (for small matrices that is):
Well, with some small wrappers using JavaCPP. Actually, if you're after speed, using FunctionPointer is most likely going to be faster than even JNR anyway. |
True, but I want to be able to parse, compile, and run LLVM IR without any c-compiler. I don't think a JavaCPP wrapper around libffi will be much faster than jffi. The biggest problem are all the optimized invocation functions depending on the return type and input parameters. You are right MKL JIT is single-threaded as is the LLVM and Java implementation. More importantly, is the performance gain of JNR vs JNA for small matrices. |
... and the performance gain of JavaCPP vs JNR/jffi/libffi ;) I'm sure we
can use Clang as a JIT C++ compiler, somehow. It just requires more work,
but it is most definitely faster than libffi.
|
BTW, I think this is the kind of thing @cypof was trying to achieve in pull bytedeco/javacpp#138. |
My biggest problem with the clang c-API is the absence of functions to translate C/C++ to LLVM IR. We can do all the code analysis with it but never go a step further in the compiler chain, which is a pity. If javacpp would produce LLVM IR we could use the LLVM preset as a runtime compiler like @cypof suggested, but that's to much work. A other way is the cpp API of clang where we have CompilerInstance and EmitLLVMOnlyAction.
Making javacpp build its self at runtime with the help of preinstalled compilers is a good step. Even calling gradle or maven from within java to do the heavy lifting is sufficient as long as javacpp setups all the dependencies (e.g. download Gradle via its wrapper). Different topic. I also tried using LLVM ORC but the LLVMOrcAddEagerlyCompiledIR method never called the provided symbol resolver callback function. If you like I can provide a small repository to show you the code. |
Well, the thing is, Java needs to load JNI code from a library file anyway, so it doesn't really matter that we have to use an external tool to create a library, and then load that library. We're not losing anything. We're not going to be able to do in-memory JIT with JNI either way. It's actually pretty easy to run a bundled version of
Sure, please post anything you have! I'm sure @oneengineer will be interested in looking at it. |
Actually, (due to my limited knowledge, the content below might has mistakes) However it is not convenient, even though it is only one step. You cannot do it on runtime. You have to use a C/C++ compiler to compile it through JavaCPP implicitly. I hope to do it in pure java, and on runntime. "A callback function can be created on runtime, without C/C++ compiler" is my request. Using LLVM is also an good option. I think it is a little bit overkill or too heavy? Since you may want to support android. @Neiko2002 out of curiosity, what do you want to achieve? Run C directly in Java at runtime and interactive with Java environment? Or even write Java wrapper with JavaCPP, translate it into C and then make things in the last sentence happen? I think this gonna be a really cool feature. Doing it well makes JavaCPP have numba feature. However for now, as a user I just need something like Some personal thoughts: a fundamental features of these kind of language binding infrasturcture is to provide the glue language, and python did it well. For high performance part, leave it to C, or as you suggested through LLVM. |
Are you guys talking about a In any case, I've bundled the String clang = Loader.load(org.bytedeco.llvm.program.clang.class);
ProcessBuilder pb = new ProcessBuilder(clang, "--version");
pb.inheritIO().start().waitFor(); |
Yes, that's what I am talk about. |
I think callback functions work in general but those But then I have a version with LLVMOrcAddLazilyCompiledIR which produces an invokable LLVM function but the So right now ORC compilation does only work with
I just wanted to produce and run LLVM code in Java at runtime. Thanks to @saudet I now can even write C/C++ code, translate it to LLVM IR and run it. |
Your example reminds me that I can pass multiple parameter even with MCJIT compiled function, with
This is what I was looking for at the first place! Thanks a lot! BTW, does anyone what's the purpose of |
@oneengineer please take a look at my new library even if you do not plan to use the Polly compiler there, just use the LLVMProgram class and its two dependency classes. This way your native function calls are type-safe. |
I see, you implemented the check at |
You are right. I have added it. The conversion between the Java data types and native data types is handled by JNR. |
FYI, I've added presets for libffi in commit 3075f99, so we can now use that directly at least to avoid any overhead from JNA or JNR. /cc @yukoba @supergrecko |
That's good to hear, will take a closer look at this. Thank you |
Updated the gcc preset samples in bytedeco/gcc@b265a18 - Will also add a couple examples for the LLVM preset. |
The presets for libffi have been released with version 1.5.6. Enjoy! |
I need to call
LLVMGetFunctionAddress
like the C code above in Java, however it returns a pointer and I need to convert it to(int (*)(int, int))
function.More specifically, I guess the code would be like:
The text was updated successfully, but these errors were encountered: