Skip to content
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

[RFE] passing data in is too slow via slice assign on memory buffer #700

Open
muayyad-alsadi opened this issue Feb 28, 2023 · 2 comments
Open
Labels
🎉 enhancement New feature or request

Comments

@muayyad-alsadi
Copy link

muayyad-alsadi commented Feb 28, 2023

Motivation

I made a simple WASM image filter, I tested it on the browser, compare it to pure js version and tried wasmer to run the filter.
There was a huge bottleneck when moving the large data to wasm memory. several seconds instead of milliseconds.
more over assigning multidimensional data was even slower (30x) slower.

Proposed solution

  • implement faster assign to a memory slice
  • Make slice assign on np.ndarray(A, dtype=np.uint8) and array.array('B') as fast as bytearray
  • if multidimensional make unwinding/flattening outside python, move it to the c implementation
class Uint8Array(object)
 |  
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.

this function seems to walk into the slice items one by one

u8buf.__setitem__(slice(start_offset,end_offset,None), value)

Alternatives

Iterating over the WxHxC multidimensional array in python is a huge wast of time
As the only reason for moving to WASM is to do the hot/active loop.

Additional context

import numpy as np
import array
from wasmer import Store, Module, Instance, Memory, MemoryType
from PIL import Image

memory = Memory(Store(), MemoryType(minimum=200))
u8buf = memory.uint8_view(100)

a3d = np.zeros((1920, 1080,4), dtype=np.uint8)
flat = a3d.flatten()
flata = array.array('B', flat)
img = Image.fromarray(a3d, 'RGBA')
pil_a3d = img.getdata()

offset = 200
size = 1920*1080*4

u8buf[offset:offset+size]=bytearray(flat) # <------ `bytearray` type is fast but not fast enough
u8buf[offset:offset+size]=flat # <-------- `np.ndarray`  is slow
u8buf[offset:offset+size]=flata # <-------- `array.array` is slow
u8buf[offset:offset+size]=a3d # <-------- multidimensional `np.ndarray` is impossible
u8buf[offset:offset+size]=pil_a3d # <-------- `PIL img.getdata()` is impossible

NOTE: I'm using Fedora 36, Python 3.10.9, python wasmer 1.1.0, wasmer-compiler-singlepass 1.1.0

@muayyad-alsadi muayyad-alsadi added the 🎉 enhancement New feature or request label Feb 28, 2023
@muayyad-alsadi
Copy link
Author

this is also slow

d3=img.getdata()
u8buf[offset:offset+size]=bytearray([ d1 for d2 in d3 for d1 in d2 ])

@muayyad-alsadi
Copy link
Author

muayyad-alsadi commented Feb 28, 2023

this is also slow

u8buf[offset:offset+size] = bytearray(itertools.chain(*img.getdata()))

note things I marked as slow are at least 30x times slower.

@muayyad-alsadi muayyad-alsadi changed the title [RFE] multidimensional memory buffer assign is too slow [RFE] passing data in is too slow via slice assign on memory buffer Mar 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎉 enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant