kenba/opencl3

Mutability of sub-buffers

Opened this issue · 3 comments

vmx commented

In my code I write to a sub-buffer. Due to #27 this sub-buffer needs to be mutable. The buffer the sub-buffer is created from via Buffer::create_sub_buffer() doesn't need (in the Rust type system sense) to be mutable. Though it actually mutates.

I haven't encountered such a case myself in Rust yet, so I don't know if there are any good patterns how those things are usually solved.

This issue isn't really actionable, but I wanted to bring it up, in case someone has a good idea. So feel free to close the issue as "won't fix".

kenba commented

You raise an interesting point Volker. I don't know a Rust pattern for handling this situation either.
I shall leave this issue open as a question in the hope that someone does know a good solution.

vmx commented

A colleague of mine pointed me to https://docs.rs/bytes/1.0.1/bytes/index.html. I then also started to prepare a minimal example, to make the problem easier to understand for people that are not into OpenCl: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2f92e740e64e415dc46474fc397da96f. It doesn't compile and it made me realize how things in pure Rust, without the FFI border would be.

So perhaps there needs to be a wrapper around cl_mem. Currently there is the ClMem trait, but that might not be enough. From just a cl_mem you can't really tell if the underlying data is mutable or not. I think by default a *mut c_void should alwasy be considered mutable. Though this would create an hard to use API, if you know that all you need read-only access only.

One way could be to replace the ClMem trait with two wrapper structs around cl_mem, an immutable and a mutable one (something along the lines of struct ClMem(cl_mem) and struct ClMemMut(cl_mem)). This distinction would then bubble up and you'd have a Buffer and a BufferMut. Functions that need a mutable buffer (like enqueue_write_buffer), would then require a mutable reference to the BufferMut type. Both buffer types would implement create_sub_buffer(). If you need a mutable sub-buffer, it needs to come from a BufferMut. This way you make sure that also the original buffer also was considered mutable.

kenba commented

Thank you Volker.
I think that you are correct. cl_mem needs both immutable and mutable traits like bytes in order to define immutable and mutable Buffers.
However, in addition to Buffer and BufferMut, this will also "bubble up" to Image and maybe Sampler too.
Note: I don't think that this should affect Pipe, since a Pipe must be mutable, however, it may have to in order to keep the API consistent.