Closed haesleinhuepf closed 3 years ago
Oh no! This feels very high priority. definitely can't directly monkeypatch the pyopencl Array class. You can use a subclass instead of wrapOclArray if you want to add those magic methods for use in this lib.
Curious though, why didn't the builtin __add__
and stuff work?
You can use a subclass instead of wrapOclArray if you want to add those magic methods for use in this lib.
I'm on it. I think I will struggle with constructing a cl-array. But let's see. I'll send it as PR to you for review asap.
Curious though, why didn't the builtin
__add__
and stuff work?
pyopencl doesn't support cl_array + np_array
, cl_array + cupy_array
and cl_array + dask_array
. pyclesperanto does.
pyopencl doesn't support
I think the best way to fix that might be to add some special numpy dunder methods to your subclass (not necessarily just to call pyclesperanto methods) see here: https://numpy.org/doc/stable/user/basics.dispatch.html
will write a short example
edited
from numpy.lib.arraysetops import isin
import pyopencl as cl
import numpy as np
import pyopencl.array as cla
import numpy.lib.mixins
context = cl.create_some_context(interactive=False)
queue = cl.CommandQueue(context)
class OcA(cla.Array, numpy.lib.mixins.NDArrayOperatorsMixin):
def __array__(self, dtype=None):
return self.get().astype(dtype)
@classmethod
def to_device(cls, ary, queue):
if isinstance(ary, OcA):
return ary
cl_a = OcA(queue, ary.shape, ary.dtype, strides=ary.strides)
cl_a.set(ary, queue=queue)
return cl_a
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
if method == "__call__":
func = getattr(OcA, f'__{ufunc.__name__}__', None)
if func is not None:
return func(*[OcA.to_device(i, self.queue) for i in inputs], **kwargs)
return NotImplemented
np_a = np.random.rand(4, 4)
cl_a = OcA.to_device(np_a, queue=queue)
# now this will work
cl_b = cl_a + np_a
assert isinstance(cl_a, OcA)
assert isinstance(np_a, np.ndarray)
assert isinstance(cl_b, OcA)
more details at the link above
i updated the code above to give an example of how a subclass of cla.Array can overload the +
operator to take np.arrays as input while keeping the data on the GPU
At the moment, when using pyopencl and clesperanto together, pyclesperanto breaks pyopencl in some contexts, e.g.
Related: https://forum.image.sc/t/migrating-from-clij-to-clesperanto/54985/50
Example code adding two 5D-images:
This works. After I import pyclesperanto_prototype, the + operator gets [overwritten]() and repeating the same code fails:
Error: