-
Notifications
You must be signed in to change notification settings - Fork 58
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
Setting a slice of memory without having to enumerate #81
Comments
Ah sorry I don't know much about python bulk array assignment, but if a different type should be returned by the methods here that's more idiomatic that seems like a reasonable thing to do! |
Agree, but I have no idea how to achieve it. All I know is bulk assignment works with an actual list of bytes, and |
This seems to work: >>> import ctypes
>>> data = (ctypes.c_ubyte*memory.data_len(store)).from_address(ctypes.addressof(memory.data_ptr(store).contents))
>>> data[0:10] = "helloworld".encode('utf-8')
>>> data[0:10]
[104, 101, 108, 108, 111, 119, 111, 114, 108, 100]
>>> memory.data_ptr(store)[0:10]
[104, 101, 108, 108, 111, 119, 111, 114, 108, 100] |
I've also been playing around with wasmtime, got a toy program running but I was reading and writing memory one byte at a time. Glad to see there's a bulk read method available (it didn't occur to me to use a slice), a bulk write would also be very welcome! |
Playing around with this a little more, |
this is very important as it's the most obvious bottleneck I believe if set_item is passed a slice instead of index, it should iterate instead of raising exception ptr = memory.data_len(store)
ptr[start:end]=bytearray(b'helloworld')
TypeError: sequence index must be integer, not 'slice' >>> buff=bytearray(b'hello world')
>>> buff[0:5]=b'HELLO'
>>> for i in buff: print(i)
72
69
76
76
79
32
119
111
114
108
100 |
for comparison, on my example of slice setting of 15MB from images
this is 900x slower!! |
here they suggest to cast the C pointer to memory_ptr = memory.data_ptr(store)
buff = memoryview(ctypes.cast(memory_ptr, ctypes.POINTER(ctypes.c_ubyte*size)))
buff_bytes = buff.bytes() but I got endianess problems https://bugs.python.org/issue39610
any clue how to set a slice to |
@dsyer the following line was too slow, it was even slower than setting the slice
how can we make it into |
here is my implementation which is 300x times faster than @dsyer def set_slice(val, start=0, end=None):
size = memory.data_len(store)
if end is None: end=start+len(val)
val_size = len(val)
if end-start>val_size or end>size:
raise IndexError("out of memory size")
src_ptr = (ctypes.c_ubyte * val_size).from_buffer(val)
dst_ptr = ctypes.addressof((ctypes.c_ubyte*val_size).from_address(ctypes.addressof(memory_ptr.contents)+start))
ctypes.memmove(dst_ptr, src_ptr, val_size)
return it seems that there was endianess difference thats why @dsyer was slower |
Hi folks, a related note here: it would be very nice if wasmtime-py could expose the wasm module memory with Python's Buffer Protocol. This would enable efficient binary array access, slicing and more, via the standard numpy interface. wasmer-python has this implemented. |
While I agree with the above comment, I think it should not be in the scope of this issue here and the already in-progress PR. @thewtex Maybe you can create a new issue? |
@thewtex no, it was worse in terms of performance, please check my article here |
@j-blue-arz yes, that's right. This would be in addition to @muayyad-alsadi nice setitem / slicing improvements. Issue created in #135 .
@muayyad-alsadi awesome article!! Sorry if I was not clear, I meant the use of the buffer protocol with numpy instead of setitem / slicing. An example is here: The results:
|
@thewtex thank you that was very useful here is the memory = instance.exports(store)['memory']
ptr_type = ctypes.c_ubyte * (memory.data_len(store))
memory_ptr = (ptr_type).from_address(ctypes.addressof(memory.data_ptr(store).contents))
np_mem = np.frombuffer(memory_ptr, dtype=np.uint8, offset=hb) |
It's nice that the WASM memory can be inspected with a slice operator:
Then
but it's not possible to set it that way which seems like a bug, or at least a missing feature:
You can work around it by iterating:
The text was updated successfully, but these errors were encountered: