CommandQueue/Buffer change request

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

CommandQueue/Buffer change request

Matthias
Hello,

first, you have done great work with your libraries especially OpenCL.

But ... i have a problem when writing data to a device:

in CLCommanQueue you do:...

public CLCommandQueue putWriteBuffer(...
...
cl.clEnqueueWriteBuffer(
    ID, writeBuffer.ID, clBoolean(blockingWrite),
    0, writeBuffer.getNIOSize(), writeBuffer.buffer,                                                                                                  
    conditions, conditionIDs, events==null ? null : events.IDs);
...

is it possible to add a method in which the offset and length of the copy operation can be set,
or is it possible to replace writeBuffer.getNIOSize() with writeBuffer.limit() .. and offset 0 with .mark()?
So that buffers can be partially written to a device.

regards
Reply | Threaded
Open this post in threaded view
|

Re: CommandQueue/Buffer change request

Michael Bien

On 11/21/2011 08:19 PM, Matthias [via jogamp] wrote:
> Hello,
Hi,

>
> first, you have done great work with your libraries especially OpenCL.
thank you for using it ;)

>
> But ... i have a problem when writing data to a device:
>
> in CLCommanQueue you do:...
>
> public CLCommandQueue putWriteBuffer(...
> ...
> cl.clEnqueueWriteBuffer(
>     ID, writeBuffer.ID, clBoolean(blockingWrite),
>     0, writeBuffer.getNIOSize(), writeBuffer.buffer,
>     conditions, conditionIDs, events==null ? null : events.IDs);
> ...
>
yeah, right. what have i thought? Lets see. Read+Write have all the
offset missing.

Thanks for bringing this up, the more recent methods like writeRect
however have offsets.

> is it possible to add a method in which the offset and length of the
> copy operation can be set,
> or is it possible to replace writeBuffer.getNIOSize() with
> writeBuffer.limit() .. and offset 0 with .mark()?
> So that buffers can be partially written to a device.
well. Problem here is that the NIO buffer is just the java
representation of the device buffer. It can be the same buffer but quite
often it is just a vehicle to move data between java and the device. So
you can have multiple CLBuffer objects with different NIO buffers
pointing to the same CL buffer (in this case buffer.ID would be the
identical all buffers; see buffer.cloneWith(nioBuffer)).

so we would have 2 offsets and 2 ranges for the 1D case. One for the
device buffer and one taken from the nio buffer.

The position of the nio buffer is already taken into account in the low
level binding (generated code). The range is an argument in the
read/write method.

so what is missing?
device buffer offset to write to or copy from

>
> regards

I'll fix this,
thanks
michael

--
http://michael-bien.com/

Reply | Threaded
Open this post in threaded view
|

Re: CommandQueue/Buffer change request

Matthias
Hello,
...if i saw it correctly
writeBuffer.getNIOSize() just returns writeBuffer.capacity();
...using limit and mark was just an idea how the Java-Api could be used to avoid an additional method.

But an additional method would be great too, thanks a lot for the fast response.

regards

Matthias
Reply | Threaded
Open this post in threaded view
|

Re: CommandQueue/Buffer change request

Michael Bien
On 11/22/2011 06:10 PM, Matthias [via jogamp] wrote:
Hello,
...if i saw it correctly
writeBuffer.getNIOSize() just returns writeBuffer.capacity();
...using limit and mark was just an idea how the Java-Api could be used to avoid an additional method.

But an additional method would be great too, thanks a lot for the fast response.

regards

Matthias


you are right. However i have to admit that i am no big fan of using the position/limit storage in buffers. This leads to bad code (potential bugs) like this:

int pos = buffer.position();
int limit = buffer.limit();

buffer.position(myPos).limit(myLimit); // breaks code if buffer is used in multiple threads
api.doSomething(buffer);
buffer.position(pos).limit(limit)


to do this properly you would have to:
Buffer mybuffer = buffer.duplicate().position(myPos).limit(myLimit);
api.doSomething(buffer);
which basically nobody does since everyone believes that duplicate copies the buffer...



having the two params in the method only looks more verbose if you read the doc but in fact it is:
api.doSomething(buffer, pos, lenght);
or
api.doSomething(buffer, buffer.position(), buffer.limit()-buffer.position());


adding mutable state to nio wasn't a good idea back than IMO.

btw, here is the changeset:
https://github.com/mbien/jocl/commit/023747ae952bbc79c02e2a38d581ab6dd85e72e0

best regards and thanks for bringing this up,
michael

-- 
http://michael-bien.com/
Reply | Threaded
Open this post in threaded view
|

Re: CommandQueue/Buffer change request

Michael Bien
 + i would also love to make the whole low level binding ignore the position attribute entirely. However this would break so many things for people already using jocl that this will probably never happen (maybe in a .0 release).

this would not only simplify the low level binding (less generated code, smaller, maybe faster) but would also simplify client code and help to detect bugs in many cases.

one of the most occurring "facepalm situations" is still the missing .flip() or .rewind(). (which often causes segfaults btw)

-michael
Reply | Threaded
Open this post in threaded view
|

Re: CommandQueue/Buffer change request

Matthias
Thank you very much.

And yeah, i know what you mean with the position, limit mark and stuff
... but somehow many java-hardcore people like it.

But i am glad you don't ;)

regards
Matthias

and some off-topic:
Did you ever try to use more then about 10.000 CLBuffers at once?
My devices behave very strange, also when i implement it in C.
I had a case where i have to handle many small pieces of data and do a lot of work with them.
About 145000 data sets, 200-400 bytes each. I tried to copy them to the device: no chance
The first 10k copied very fast but than i needed minutes to copy 1000 sets.