javacpp Cuda starter ?

181 views
Skip to first unread message

Kai

unread,
Apr 5, 2018, 5:04:25 AM4/5/18
to javacpp...@googlegroups.com
Hello everyone!

First let me thank you for this wonderful project. I'm just starting to get using it, but it looks very promising.

Now for my question. ;)

I'm working on a Java project that up to now used jcuda and the original OpenCV Java bindings. To be able to use the newer, installed versions of Cuda and OpenCV (instead of bundled ones), I'd like to migrate to javacpp for both (the mavenised 1.4.1 and 9.1-7.1-141).
Migration to javacv I seem to have managed (test cases running now, interactive testing to come after the stuff compiles again).
But I have a hard time getting the Cuda stuff working. I guess I have to use the Cuda Driver API, like I did with jcuda. The Nvidia tutorial proposes something along this lines to initialise the driver API:

cuInit(0);
CUdevice cuDevice;
cuDeviceGet(&cuDevice, 0);
CUcontext cuContext;
cuCtxCreate(&cuContext, 0, cuDevice);
CUmodule cuModule;
cuModuleLoad(&cuModule, "VecAdd.ptx");
[...]
(condensed example, see http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#driver-api)

That's also about what I did with jcuda. On the way porting this to cuda-platform I'm getting confused with - what seems - different data types:
cuda.cuDeviceGet takes an IntPointer, IntBuffer or int[] for the cuDevice, but
cuda.cuCtxCreate wants an int there
These types are annotated as "CUdeviceptr*". In other places I find other types annotated this way (LongPointer, LongBuffer, long[], BytePointer, ...).

How can I find my way through this? Has anybody point me to a working example, or a short tutorial or something that set's me on the right track? :)
Any pointers would be very much appreciated. :)

Cheers, Kai

Samuel Audet

unread,
Apr 5, 2018, 5:16:55 AM4/5/18
to javacpp...@googlegroups.com
Hi,

CUdevice is just a typedef of "int" and since there isn't an equivalent in Java, it just uses "int" by default, so just replace "CUdevice" by "int" and it will work, something like:

    cuInit(0);
    int[] cuDevice = {0};
    cuDeviceGet(cuDevice, 0);
    CUctx_st cuContext = new CUctx_st(null);
    cuCtxCreate(cuContext, 0, cuDevice[0]);
    ...

If there is anything else unclear just keep asking questions and I will answer! If you feel like contributing, a tutorial or a sample project would be welcome!

Samuel

2018年4月5日(木) 18:04 Kai <kai...@gmx.de>:
--
You received this message because you are subscribed to the Google Groups "javacpp" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javacpp-proje...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kai

unread,
Apr 5, 2018, 9:22:21 AM4/5/18
to javacpp...@googlegroups.com
Hi,
 
Samuel, thanks for the quick answer!
 
I seem to get a general idea now: When a Cuda function want's to deliver a result into a paramter (as a side effect), I should pass it an array of size 1. When I later need that value, I use the first element of this array. Is that kinda general rule of thumb?
For the cuDevice this seems to work (getting no errors _here_ so far ;) ).
 
I guess, a simmilar procedure works for cuMemAlloc and cuMemcpyHtoD (or cuMemFree)?
But as cuLaunchKernel expects a "PointerPointer" for the kernel parameters, can I also use a different approach here? Currently I'm trying to use the version cuMemAlloc(LongPointer,long) with a new LongPointer(1), because it seems, I can add a LongPointer directly to the constructor of PointerPointer!?
When I now want to use the LongPointer in - say - cuMemcpyHtoD, would it then be correct to use LongPointer.get() (like lp[0] in the array-version)? Or should it be LongPointer.address()?
[NB: My code doesn't run up to this point, yet, so I cannot the see the result myself right now.]
 
But I'm stuck at a different point right now, so I'd like to add that question as well:
The C function cuModuleLoadData can be used to load a module out of a String that directly contains ptx code. In the jcuda-case I successfully used JCudaDriver.cuModuleLoadData(module,my_ptx_str), so the general procedure and the ptx should be all right. The javacpp-version expects a "@Const Pointer" instead of the String.
What kind of Pointer should work here? I tried a "new CharPointer(my_ptx_str)", but this triggers a Cuda error (200).
 
Cheers, Kai
 
 
Gesendet: Donnerstag, 05. April 2018 um 11:16 Uhr
Von: "Samuel Audet" <samuel...@gmail.com>
An: javacpp...@googlegroups.com
Betreff: Re: [javacpp-project] javacpp Cuda starter ?

Samuel Audet

unread,
Apr 5, 2018, 10:00:32 PM4/5/18
to javacpp...@googlegroups.com, Kai
Yes, you're getting the general idea. That's how JavaCPP deals with C/C++ pointers. Just like in C/C++, you will most likely never need to bother with the address of pointers, and so you shouldn't be trying to access the address of Pointer peer classes either, unless you know that you really need it.

PointerPointer is usually just a native array of arrays, so it has convenience constructors for Java arrays like String[] or long[][], which is probably what cuLaunchKernel() is looking for. I'm sure that's specified in CUDA's documentation somewhere...

CharPointer gives you UTF-16, but that's very unusual for C/C++ libraries. It most likely wants a BytePointer, which encodes with the default OS character set by default. That's also probably documented in CUDA's documentation, but if it's not, they probably expect developers to do the obvious thing!

Samuel

Samuel Audet

unread,
Apr 6, 2018, 5:31:15 PM4/6/18
to javacpp...@googlegroups.com, Kai
In any case, if you have sample code either in C++ or in Java with JCuda you are having problems "translating", please provide it. It would make it easier to help...

2018/04/06 11:00 "Samuel Audet" <samuel...@gmail.com>:

Samuel Audet

unread,
Apr 9, 2018, 7:02:32 PM4/9/18
to Kai, javacpp...@googlegroups.com
Hi,

Good to hear you've solved this!

If you mainly want to contribute code, https://github.com/bytedeco/sample-projects would be the place for that. You could also write benchmark to compare with JCuda if you'd like...

In any case you can also update the wikis if you wish. They are stored in repos yes:

Samuel

2018年4月10日(火) 0:40 Kai <kai...@gmx.de>:
Hi again!
 
Maybe I sent the previous mail a bit too early (sorry for that!). Had, for today, a final look at code, docs & everything and maybe found the answer myself - at least the test class is working correctly now, have to try an the real project tomorrow.
I copied back the result this way:
  float [] hostResult = new float[mysize];
  cuMemcpyDtoH( new FloatPointer(hostResult), deviceResult[0], mysize*Float.BYTES );
(Like more or less directly translated from JCuda.)
Having a 1001th look at the FloatPointer docs, I suddenly realized that it might be better to do this:
  FloatPointer natResult = new FloatPointer(mysize);
  cuMemcpyDtoH( natResult, deviceResult[0], mysize*Float.BYTES );
  float [] hostResult = new float[mysize];
  natResult.get( hostResult );
This now works as expected. :)
 
About writing a small example (like this) as tutorial for the next newcome: what medium, what place would be the best for it? The wikis in your repositories seem to concentrate more on have to use JavaCPP on a native library, so a tutorial might be misplaced there!?
I now found https://github.com/bytedeco/javacpp-presets/issues/475 which hints to the (sadly) empty repo named benchmark. While planed for something else, might the wiki of this repo be a good place for such a quick tutorial? (meta-questions: do I clone the wiki as well when I clobe the repo? can I include wiki pages in a pull request?)
 
Cheers, Kai
 
 
 
Gesendet: Freitag, 06. April 2018 um 23:31 Uhr
Von: "Samuel Audet" <samuel...@gmail.com>
An: javacpp...@googlegroups.com, Kai <kai...@gmx.de>
Betreff: Re: Aw: Re: [javacpp-project] javacpp Cuda starter ?
Reply all
Reply to author
Forward
0 new messages